33#ifndef REMORA_CPU_TRAITS_HPP
34#define REMORA_CPU_TRAITS_HPP
36#include "../expression_types.hpp"
53struct device_traits<cpu_tag>{
55 typedef no_queue queue_type;
57 static queue_type& default_queue(){
58 static queue_type queue;
63 static std::size_t index_add(std::size_t i, std::size_t j){
68 static typename E::reference linearized_matrix_element(matrix_expression<E, cpu_tag>
const& e, std::size_t i){
69 std::size_t leading_dimension = E::orientation::index_m(e().size1(), e().size2());
70 std::size_t i1 = i / leading_dimension;
71 std::size_t i2 = i % leading_dimension;
72 return e()(E::orientation::index_M(i1,i2), E::orientation::index_m(i1,i2));
75 template <
class Iterator,
class Functor>
76 struct transform_iterator{
77 typedef iterators::transform_iterator<Iterator, Functor> type;
80 template <
class Iterator1,
class Iterator2,
class Functor>
81 struct binary_transform_iterator{
82 typedef iterators::binary_transform_iterator<Iterator1,Iterator2, Functor> type;
86 struct constant_iterator{
87 typedef iterators::constant_iterator<T> type;
91 struct one_hot_iterator{
92 typedef iterators::one_hot_iterator<T> type;
95 template<
class Closure>
96 struct indexed_iterator{
97 typedef iterators::indexed_iterator<Closure> type;
104 typedef T result_type;
105 constant(T
const& value): m_value(value){}
108 T operator()(Arg
const&)
const{
111 template<
class Arg1,
class Arg2>
112 T operator()(Arg1
const&, Arg2
const&)
const{
121 static const bool left_zero_remains =
false;
122 static const bool right_zero_remains =
false;
123 static const bool right_zero_identity =
true;
124 static const bool left_zero_identity =
false;
125 typedef T result_type;
126 T operator()(T x, T y)
const{
132 static const bool left_zero_remains =
false;
133 static const bool right_zero_remains =
false;
134 static const bool right_zero_identity =
true;
135 static const bool left_zero_identity =
false;
136 typedef T result_type;
137 T operator()(T x, T y)
const{
144 static const bool left_zero_remains =
true;
145 static const bool right_zero_remains =
true;
146 static const bool right_zero_identity =
false;
147 static const bool left_zero_identity =
true;
148 typedef T result_type;
149 T operator()(T x, T y)
const{
156 static const bool left_zero_remains =
true;
157 static const bool right_zero_remains =
false;
158 static const bool right_zero_identity =
false;
159 static const bool left_zero_identity =
true;
160 typedef T result_type;
161 T operator()(T x, T y)
const{
167 struct multiply_and_add{
168 static const bool left_zero_remains =
false;
169 static const bool right_zero_remains =
false;
170 static const bool right_zero_identity =
true;
171 static const bool left_zero_identity =
false;
172 typedef T result_type;
173 multiply_and_add(T scalar):scalar(scalar){}
174 T operator()(T x, T y)
const{
181 struct multiply_assign{
182 static const bool left_zero_remains =
false;
183 static const bool right_zero_remains =
false;
184 static const bool right_zero_identity =
true;
185 static const bool left_zero_identity =
false;
186 typedef T result_type;
187 multiply_assign(T scalar):scalar(scalar){}
188 T operator()(T, T y)
const{
196 static const bool left_zero_remains =
false;
197 static const bool right_zero_remains =
false;
198 typedef T result_type;
199 T operator()(T x, T y)
const {
205 struct multiply_scalar{
206 static const bool zero_identity =
true;
207 typedef T result_type;
208 multiply_scalar(T scalar):m_scalar(scalar){}
209 T operator()(T x)
const{
218 static const bool zero_identity =
false;
219 typedef T result_type;
220 add_scalar(T scalar):m_scalar(scalar){}
221 T operator()(T x)
const{
229 struct divide_scalar{
230 static const bool zero_identity =
true;
231 typedef T result_type;
232 divide_scalar(T scalar):m_scalar(scalar){}
233 T operator()(T x)
const{
241 struct modulo_scalar{
242 static const bool zero_identity =
true;
243 typedef T result_type;
244 modulo_scalar(T scalar):m_scalar(scalar){}
245 T operator()(T x)
const{
256 static const bool left_zero_remains =
true;
257 static const bool right_zero_remains =
false;
258 safe_divide(T defaultValue):m_defaultValue(defaultValue) {}
259 typedef T result_type;
260 T operator()(T x, T y)
const{
261 return y == T()? m_defaultValue : x/y;
269 typedef T result_type;
271 T operator()(T arg)
const{
278 typedef T result_type;
279 static const bool left_zero_remains =
true;
280 static const bool right_zero_remains =
false;
281 T operator()(T arg1, T)
const{
287 typedef T result_type;
288 static const bool left_zero_remains =
false;
289 static const bool right_zero_remains =
true;
290 T operator()(T, T arg2)
const{
296 #define REMORA_STD_UNARY_FUNCTION(func, id)\
299 static const bool zero_identity = id;\
300 typedef T result_type;\
301 T operator()(T x)const {\
302 return std::func(x);\
328#undef REMORA_STD_UNARY_FUNCTION
332 static const bool zero_identity =
false;
333 typedef T result_type;
334 T operator()(T x)
const {
336 return (tanh(x/T(2)) + T(1))/T(2);
341 static const bool zero_identity =
false;
342 typedef T result_type;
343 T operator()(T x)
const {
350 return std::log(1+std::exp(x));
356 static const bool zero_identity =
false;
357 typedef T result_type;
358 T operator()(T x)
const {
364 static const bool zero_identity =
true;
365 typedef T result_type;
366 T operator()(T x)
const {
375 static const bool left_zero_remains =
false;
376 static const bool right_zero_remains =
false;
377 typedef T result_type;
378 T operator()(T x, T y)
const{
379 return std::min(x,y);
385 static const bool left_zero_remains =
false;
386 static const bool right_zero_remains =
false;
387 typedef T result_type;
388 T operator()(T x, T y)
const{
389 return std::max(x,y);
397 static const bool left_zero_remains =
false;
398 static const bool right_zero_remains =
false;
399 typedef int result_type;
400 int operator()(T x1, T x2)
const {
406 static const bool left_zero_remains =
false;
407 static const bool right_zero_remains =
false;
408 typedef int result_type;
409 int operator()(T x1, T x2)
const {
416 static const bool left_zero_remains =
false;
417 static const bool right_zero_remains =
false;
418 typedef int result_type;
419 int operator()(T x1, T x2)
const {
425 struct greater_equal{
426 static const bool left_zero_remains =
false;
427 static const bool right_zero_remains =
false;
428 typedef int result_type;
429 int operator()(T x1, T x2)
const {
436 static const bool left_zero_remains =
false;
437 static const bool right_zero_remains =
false;
438 typedef int result_type;
439 int operator()(T x1, T x2)
const {
446 static const bool left_zero_remains =
false;
447 static const bool right_zero_remains =
false;
448 typedef int result_type;
449 int operator()(T x1, T x2)
const {
455 template<
class F,
class G>
457 typedef typename G::result_type result_type;
458 compose(F
const& f, G
const& g): m_f(f), m_g(g){ }
461 result_type operator()(Arg1
const& x)
const{
465 template<
class Arg1,
class Arg2>
466 result_type operator()(Arg1
const& x, Arg2
const& y)
const{
467 return m_g(m_f(x,y));
475 template<
class F1,
class F2,
class G>
476 struct compose_binary{
477 typedef typename G::result_type result_type;
478 compose_binary(F1
const& f1, F2
const& f2, G
const& g): m_f1(f1), m_f2(f2), m_g(g){ }
481 result_type operator()( Arg1
const& x)
const{
482 return m_g(m_f1(x), m_f2(x));
484 template<
class Arg1,
class Arg2>
485 result_type operator()( Arg1
const& x, Arg2
const& y)
const{
486 return m_g(m_f1(x,y), m_f2(x,y));
495 template<
class F1,
class F2,
class G>
496 struct transform_arguments{
497 typedef typename G::result_type result_type;
498 transform_arguments(F1
const& f1, F2
const& f2, G
const& g): m_f1(f1), m_f2(f2), m_g(g){ }
500 template<
class Arg1,
class Arg2>
501 result_type operator()( Arg1
const& x, Arg2
const& y)
const{
502 return m_g(m_f1(x),m_f2(y));
510 template<
class F,
class Arg2>
512 typedef typename F::result_type result_type;
513 bind_second(F
const& f, Arg2
const& arg2) : m_function(f), m_arg2(arg2){ }
516 result_type operator()(Arg1
const& arg1)
const{
517 return m_function(arg1, m_arg2);
526 template<
class F,
class G>
527 static compose<F,G> make_compose(F
const& f, G
const&g){
528 return compose<F,G>(f,g);
531 template<
class F1,
class F2,
class G>
532 static compose_binary<F1, F2, G> make_compose_binary(F1
const& f1, F2
const& f2, G
const&g){
533 return compose_binary<F1, F2, G>(f1, f2, g);
536 template<
class F1,
class F2,
class G>
537 static transform_arguments<F1, F2, G> make_transform_arguments(F1
const& f1, F2
const& f2, G
const& g){
538 return transform_arguments<F1, F2, G>(f1, f2, g);
541 template<
class F,
class Arg2>
542 static bind_second<F,Arg2> make_bind_second(F
const& f, Arg2
const& arg2){
543 return bind_second<F,Arg2>(f,arg2);