forked from demianmnave/CML1
-
Notifications
You must be signed in to change notification settings - Fork 0
/
extra.txt
206 lines (154 loc) · 5.79 KB
/
extra.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#if 0
/** Simple type deduction for binary ops. */
template<class LeftT, class RightT> struct DeduceBinaryOpTag;
/** The simple case of (Scalar,Vector)->Vector. */
template<> struct DeduceBinaryOpTag<scalar_result,vector_result> {
typedef vector_op tag;
};
/** The simple case of (Vector,Scalar)->Vector. */
template<> struct DeduceBinaryOpTag<vector_result,scalar_result> {
typedef vector_op tag;
};
/** The simple case of (Vector,Vector)->Vector. */
template<> struct DeduceBinaryOpTag<vector_result,vector_result> {
typedef vector_op tag;
};
/** The simple case of (Scalar,Matrix)->Matrix. */
template<> struct DeduceBinaryOpTag<scalar_result,matrix_result> {
typedef matrix_op tag;
};
/** The simple case of (Matrix,Scalar)->Matrix. */
template<> struct DeduceBinaryOpTag<matrix_result,scalar_result> {
typedef matrix_op tag;
};
/** The simple case of (Matrix,Matrix)->Matrix. */
template<> struct DeduceBinaryOpTag<matrix_result,matrix_result> {
typedef matrix_op tag;
};
struct true_type {};
struct false_type {};
template<bool T> struct STATIC_ASSERTION_FAILURE;
template<> struct STATIC_ASSERTION_FAILURE<false> {
typedef true_type result;
enum { value = true };
};
#define CML_JOIN(X,Y) CML_DO_JOIN(X,Y)
#define CML_DO_JOIN(X,Y) CML_DO_JOIN2(X,Y)
#define CML_DO_JOIN2(X,Y) X##Y
#define CML_STATIC_REQUIRE(_E_) \
typedef typename STATIC_ASSERTION_FAILURE<!(_E_)>::result \
CML_JOIN(__cml_assert_test_typedef_, __LINE__)
template<typename T1, typename T2> struct same_type_t {
typedef false_type result;
enum { value = false };
};
template<typename T> struct same_type_t<T,T> {
typedef true_type result;
enum { value = true };
};
#define CML_SAME_TYPE(_T1,_T2) same_type_t<_T1,_T2>::value
#endif
/** A binary vector reduction expression.
*
* Both operators must take two arguments.
*
* @internal The result of a reduction operation should be stored as a
* temporary in the expression tree, otherwise it will be recomputed on
* each call.
*/
template<class LeftT, class RightT, class OpT, class ReduceT>
class BinaryVectorReductionOp
{
public:
typedef BinaryVectorReductionOp<LeftT,RightT,OpT,ReduceT> expr_type;
/* Record ary-ness of the expression: */
typedef binary_expression expr_ary;
#if defined(CML_USE_VEC_BINOP_REF)
/* Use a reference to the compiler's BinaryVectorOp temporary in
* expressions:
*/
typedef const expr_type& expr_const_reference;
#else
/* Copy the expression by value into higher-up expressions: */
typedef expr_type expr_const_reference;
#endif // CML_USE_VEC_BINOP_REF
typedef typename ReduceT::value_type value_type;
typedef typename ReduceT::result_tag result_tag;
/* Store the expression traits types for the two subexpressions: */
typedef ExprTraits<LeftT> left_traits;
typedef ExprTraits<RightT> right_traits;
/* Reference types for the two subexpressions: */
typedef typename left_traits::const_reference left_reference;
typedef typename right_traits::const_reference right_reference;
/* A checker to verify the argument sizes at compile- or run-time. This
* automatically checks fixed-size vectors at compile time:
*/
typedef CheckVectorSizes<LeftT,RightT> check_size;
/* Figure out the number of elements to reduce: */
typedef DeduceVectorExprSize<LeftT,RightT> deduce_size;
/* Always unit size: */
typedef unit_size_tag size_tag;
/* The expression's resulting (vector) type: */
typedef typename ReduceT::value_type result_type;
public:
/** Record result size. */
enum { array_size = 1 };
public:
/** Return the size of the vector result. */
size_t size() const {
return 1;
}
/** Compute value of the reduction operator.
*
* @internal Should the loop be unrolled automatically?
*/
value_type operator()() const {
/* Figure out the result size and type based on the subexpressions.
* This automatically verifies at run-time that dynamic-size
* vectors have the same length:
*/
size_t sz = deduce_size()(m_left,m_right);
/* Initialize by computing the first value: */
value_type result(
OpT().apply(
left_traits().get(m_left,0),
right_traits().get(m_right,0))
);
/* Loop through and compute the reduction: */
for(size_t i = 1; i < sz; ++i) {
result = ReduceT().apply(
result,
OpT().apply(
left_traits().get(m_left,i),
right_traits().get(m_right,i))
);
}
return result;
}
public:
/** Construct from the two subexpressions. */
BinaryVectorReductionOp(const LeftT& left, const RightT& right)
: m_left(left), m_right(right) {}
/** Copy constructor. */
BinaryVectorReductionOp(const expr_type& e)
: m_left(e.m_left), m_right(e.m_right) {}
protected:
left_reference m_left;
right_reference m_right;
private:
/* Cannot be assigned to: */
expr_type& operator=(const expr_type&);
};
/** Expression traits class for BinaryVectorOp<>. */
template<class LeftT, class RightT, class OpT, class ReduceT>
struct ExprTraits< BinaryVectorReductionOp<LeftT,RightT,OpT,ReduceT> >
{
typedef BinaryVectorReductionOp<LeftT,RightT,OpT,ReduceT> expr_type;
typedef typename expr_type::value_type value_type;
typedef typename expr_type::expr_const_reference const_reference;
typedef typename expr_type::result_tag result_tag;
typedef typename expr_type::size_tag size_tag;
typedef typename expr_type::result_type result_type;
value_type get(const expr_type& v, size_t) const { return v(); }
size_t size(const expr_type& e) const { return e.size(); }
};