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