1 // -*- C++ -*-
2 /** @file */
3 #pragma once
4
5 /** \addtogroup ARCHALG Architecture specific algorithm
6 * \ingroup DSPPP
7 * \addtogroup SCALARALG Scalar algorithm
8 * \ingroup ARCHALG
9 * @{
10 */
11
12
13 #define SCALAR_UNROLL 2
14
15 /**
16 * @brief Fill evaluator for scalar architecture
17 *
18 * @param v Destination vector
19 * @param[in] val Initialization value
20 * @param[in] l Length of vector
21 *
22 * @tparam T Scalar datatype
23 * @tparam DST VEctor / Matrix datatype
24 * @tparam <unnamed> Test to restrict to vector addressing
25 * and compatible datatype
26 *
27 */
28 template<typename T,typename DST,
29 typename std::enable_if<IsVector<DST>::value &&
30 SameElementType<DST,T>::value,bool>::type = true>
_Fill(DST & v,const T val,vector_length_t l,const Scalar * =nullptr)31 inline void _Fill(DST &v,
32 const T val,
33 vector_length_t l,
34 const Scalar* = nullptr)
35 {
36 constexpr unsigned int U = SCALAR_UNROLL;
37 index_t i;
38
39 UNROLL_LOOP
40 for(i=0 ; i <= l-(1<<U); i += (1<<U))
41 {
42 for(int k=0;k < (1<<U);k++)
43 {
44 v[i+k] = val;
45 }
46 }
47
48 for(; i < l ; i++)
49 {
50 v[i] = val;
51 }
52 }
53
54 /**
55 * @brief Fill2D evaluator for scalar architecture
56 *
57 * @param v Matrix value
58 * @param[in] val Initialization value
59 * @param[in] rows Number of rows
60 * @param[in] cols Number of columns
61 *
62 * @tparam T Scalar datatype
63 * @tparam DST Matrix datatype
64 * @tparam <unnamed> Check DST has matrix indexing only
65 */
66 template<typename T,typename DST,
67 typename std::enable_if<must_use_matrix_idx<DST>() &&
68 SameElementType<DST,T>::value,bool>::type = true>
_Fill2D(DST & v,const T val,const vector_length_t rows,const vector_length_t cols,const Scalar * =nullptr)69 inline void _Fill2D(DST &v,
70 const T val,
71 const vector_length_t rows,
72 const vector_length_t cols,
73 const Scalar* = nullptr)
74 {
75 constexpr unsigned int U = SCALAR_UNROLL;
76 index_t row=0;
77
78
79 for(; row <= rows-(1<<U);row += (1<<U))
80 {
81
82 for(index_t col=0; col < cols;col ++)
83 {
84 for(int k=0;k<(1<<U);k++)
85 {
86 v(row+k,col) = val;
87 }
88 }
89
90 }
91
92 for(; row < rows;row ++)
93 {
94 for(index_t col=0; col < cols;col ++)
95 {
96 v(row,col) = val;
97 }
98 }
99 }
100
101
102 /**
103 * @brief Expression evaluator for vector in scalar mode
104 *
105 * @param v Vector
106 * @param[in] other Expression
107 * @param[in] l Length of expression (number of samples)
108 *
109 * @tparam DA Destination datatype
110 * @tparam DB Source datatype
111 * @tparam <unnamed> Check vectors are compatible
112 */
113 template<typename DA,typename DB,
114 typename std::enable_if<vector_idx_pair<DA,DB>(),bool>::type = true>
eval(DA & v,const DB & other,const vector_length_t l,const Scalar * =nullptr)115 inline void eval(DA &v,
116 const DB& other,
117 const vector_length_t l,
118 const Scalar* = nullptr)
119 {
120 constexpr unsigned int U = SCALAR_UNROLL;
121 index_t i=0;
122
123 for(i=0 ; i <= l-(1<<U); i += (1<<U))
124 {
125 for(int k=0;k < (1<<U);k++)
126 {
127 v[i+k] = other[i+k];
128 }
129 }
130
131 for(; i < l ; i++)
132 {
133 v[i] = other[i];
134 }
135 }
136
137 /**
138 * @brief 2D expression evaluator for scalar archiecture
139 *
140 * @param v Destination value
141 * @param[in] other The expression
142 * @param[in] rows Number of rows
143 * @param[in] cols Number of columns
144 *
145 * @tparam DA Destination datatype
146 * @tparam DB Source datatype
147 * @tparam <unnamed> Check only support matrix indexing
148 */
149 template<typename DA,typename DB,
150 typename std::enable_if<must_use_matrix_idx_pair<DA,DB>(),bool>::type = true>
eval2D(DA & v,const DB & other,const vector_length_t rows,const vector_length_t cols,const Scalar * =nullptr)151 inline void eval2D(DA &v,
152 const DB& other,
153 const vector_length_t rows,
154 const vector_length_t cols,
155 const Scalar* = nullptr)
156 {
157 constexpr unsigned int U = SCALAR_UNROLL;
158 index_t row=0;
159
160
161 for(; row <= rows-(1<<U);row += (1<<U))
162 {
163 for(index_t col=0; col < cols;col ++)
164 {
165 for(int k=0;k<(1<<U);k++)
166 {
167 v(row+k,col) = other(row+k,col);
168 }
169 }
170
171 }
172
173
174 for(; row < rows;row ++)
175 {
176
177 for(index_t col=0; col < cols;col ++)
178 {
179 v(row,col) = other(row,col);
180 }
181 }
182 }
183
184 /**
185 * @brief Dot product evaluator for scalar architectuire
186 *
187 * @param[in] a Left hand side
188 * @param[in] b Right hand side
189 * @param[in] l Vector lenght
190 *
191 * @tparam DA Left hand side datatype (may be expression)
192 * @tparam DB Right hand side datatype (may be expression)
193 * @tparam <unnamed> Check vector expressions are compatible
194 *
195 * @return Dot product result
196 */
197 template<typename DA,typename DB,
198 typename std::enable_if<vector_idx_pair<DA,DB>(),bool>::type = true>
_dot(const DA & a,const DB & b,const vector_length_t l,const Scalar * =nullptr)199 inline DotResult<DA> _dot(const DA& a,
200 const DB& b,
201 const vector_length_t l,
202 const Scalar* = nullptr)
203 {
204 using Acc = DotResult<DA>;
205 constexpr unsigned int U = SCALAR_UNROLL;
206 index_t i;
207
208 Acc acc = Acc{};
209
210 for(i=0 ; i <= l-(1<<U); i += (1<<U))
211 {
212 for(int k=0;k < (1<<U);k++)
213 {
214 acc = inner::mac(acc , a[i+k] , b[i+k]);
215 }
216 }
217
218 for(; i < l ; i++)
219 {
220 acc = inner::mac(acc , a[i] , b[i]);
221 }
222
223 return(acc);
224 }
225
226 /**
227 * @brief Swap evaluator for scalar architecture
228 *
229 * @param a Left hand side
230 * @param b Right hand side
231 * @param[in] l Vector length
232 *
233 * @tparam DA Left hand side datatype
234 * @tparam DB Right hand side datatype
235 * @tparam <unnamed> Check vectors are compatible
236 */
237 template<typename DA,typename DB,
238 typename std::enable_if<vector_idx_pair<DA,DB>(),bool>::type = true>
_swap(DA && a,DB && b,const vector_length_t l,const Scalar * =nullptr)239 inline void _swap(DA&& a,
240 DB&& b,
241 const vector_length_t l,
242 const Scalar* = nullptr)
243 {
244 for(index_t i=0;i<l;i++)
245 {
246 const auto tmp = a[i];
247 a[i] = b[i];
248 b[i] = tmp;
249 }
250
251 }
252
253 #undef SCALAR_UNROLL
254
255 /*! @} */
256