00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX__VECTOR_NAIVE__HPP
00014 #define __MMX__VECTOR_NAIVE__HPP
00015 #include <basix/operators.hpp>
00016
00018
00019 namespace mmx {
00020 #define TMPL template<typename C>
00021 #define TMPLX template<typename C, typename X>
00022
00023
00024
00025
00026
00027 struct vector_naive {
00028 typedef vector_naive Naive;
00029 typedef vector_naive Aligned;
00030 typedef vector_naive No_simd;
00031 typedef vector_naive No_thread;
00032 };
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 struct vector_defaults {};
00046
00047 template<typename V>
00048 struct implementation<vector_defaults,V,vector_naive> {
00049 static const nat def_len = 0;
00050 static const nat init_len= 1;
00051 };
00052
00053
00054
00055
00056
00057 struct vector_allocate {};
00058
00059 template<typename V>
00060 struct implementation<vector_allocate,V,vector_naive>:
00061 public implementation<vector_defaults,V>
00062 {
00063 TMPL static inline nat
00064 vec_aligned_size (nat n) {
00065 return n;
00066 }
00067 };
00068
00069 template<typename C, typename V> inline nat
00070 aligned_size (nat n) {
00071 typedef implementation<vector_allocate,V> Vec;
00072 return Vec::template vec_aligned_size<C> (n);
00073 }
00074
00075 template<typename C> inline nat
00076 default_aligned_size (nat n) {
00077 typedef typename vector_variant_helper<C>::VV V;
00078 typedef implementation<vector_allocate,V> Vec;
00079 return aligned_size<C,V> (n);
00080 }
00081
00082
00083
00084
00085
00086 struct vector_abstractions {};
00087
00088 template<typename V>
00089 struct implementation<vector_abstractions,V,vector_naive>:
00090 public implementation<vector_allocate,V>
00091 {
00092
00093 template<typename Op, typename T> static inline void
00094 vec_nullary (T* dest, nat n) {
00095 for (; n != 0; dest++, n--)
00096 Op::set_op (*dest);
00097 }
00098
00099 template<typename Op, typename T, typename C> static inline void
00100 vec_unary (T* dest, const C* s, nat n) {
00101 for (; n != 0; dest++, s++, n--)
00102 Op::set_op (*dest, *s);
00103 }
00104
00105 template<typename Op, typename T, typename C1, typename C2> static inline void
00106 vec_binary (T* dest, const C1* s1, const C2* s2, nat n) {
00107 for (; n != 0; dest++, s1++, s2++, n--)
00108 Op::set_op (*dest, *s1, *s2);
00109 }
00110
00111 template<typename Op, typename T, typename X> static inline void
00112 vec_unary_scalar (T* dest, const X& x, nat n) {
00113 for (; n != 0; dest++, n--)
00114 Op::set_op (*dest, x);
00115 }
00116
00117 template<typename Op, typename T, typename C, typename X> static inline void
00118 vec_binary_scalar (T* dest, const C* s, const X& x, nat n) {
00119 for (; n != 0; dest++, s++, n--)
00120 Op::set_op (*dest, *s, x);
00121 }
00122
00123 template<typename Op, typename T, typename C1, typename C2, typename X>
00124 static inline void
00125 vec_ternary_scalar (T* dest, const C1* s1, const C1* s2, const X& x, nat n) {
00126 for (; n != 0; dest++, s1++, s2++, n--)
00127 Op::set_op (*dest, *s1, *s2, x);
00128 }
00129
00130 template<typename Op, typename C> static inline bool
00131 vec_unary_test (const C* s, nat n) {
00132 for (; n != 0; s++, n--)
00133 if (Op::not_op (*s)) return false;
00134 return true;
00135 }
00136
00137 template<typename Op, typename C1, typename C2> static inline bool
00138 vec_binary_test (const C1* s1, const C2* s2, nat n) {
00139 for (; n != 0; s1++, s2++, n--)
00140 if (Op::not_op (*s1, *s2)) return false;
00141 return true;
00142 }
00143
00144 template<typename Op, typename C, typename X> static inline bool
00145 vec_binary_test_scalar (const C* s, const X& x, nat n) {
00146 for (; n != 0; s++, n--)
00147 if (Op::not_op (*s, x)) return false;
00148 return true;
00149 }
00150
00151 template<typename Op, typename C> static inline Unary_return_type(Op,C)
00152 vec_unary_big (const C* s, nat n) {
00153 typedef Unary_return_type(Op,C) R;
00154 R r= Op::template neutral<R> ();
00155 for (; n != 0; s++, n--)
00156 Op::set_op (r, *s);
00157 return r;
00158 }
00159
00160 template<typename Op, typename C> static inline Unary_return_type(Op,C)
00161 vec_unary_big (const C* s, nat n, const format<C>& fm) {
00162 typedef Unary_return_type(Op,C) R;
00163 R r= get_sample (unary_map<Op> (fm));
00164 Op::set_neutral (r);
00165 for (; n != 0; s++, n--)
00166 Op::set_op (r, *s);
00167 return r;
00168 }
00169
00170 template<typename Op, typename C1, typename C2> static inline C1
00171 vec_binary_big (const C1* s1, const C2* s2, nat n) {
00172 C1 r= Op::template neutral<C1> ();
00173 for (; n != 0; s1++, s2++, n--)
00174 Op::set_op (r, *s1, *s2);
00175 return r;
00176 }
00177
00178 template<typename Op, typename C1, typename C2> static inline C1
00179 vec_binary_big (const C1* s1, const C2* s2, nat n,
00180 const format<C1>& fm1, const format<C2>& fm2) {
00181 C1 r= get_sample (binary_map<Op> (fm1, fm2));
00182 Op::set_neutral (r);
00183 for (; n != 0; s1++, s2++, n--)
00184 Op::set_op (r, *s1, *s2);
00185 return r;
00186 }
00187
00188 template<typename Op, typename C> static C
00189 vec_unary_big_dicho (const C* s, nat n) {
00190 switch (n) {
00191 case 0: return Op::template neutral<C> ();
00192 case 1: return s[0];
00193 case 2: return Op::op (s[0], s[1]);
00194 case 3: return Op::op (s[0], Op::op (s[1], s[2]));
00195 case 4: return Op::op (Op::op (s[0], s[1]), Op::op (s[2], s[3]));
00196 default: return Op::op (vec_unary_big_dicho<Op> (s, n>>1),
00197 vec_unary_big_dicho<Op> (s + (n>>1), n - (n>>1)));
00198 }
00199 }
00200
00201 template<typename Op, typename C> static inline C
00202 vec_unary_big_dicho (const C* s, nat n, const format<C>& fm) {
00203 if (n != 0) return vec_unary_big_dicho (s, n);
00204 else {
00205 C r= get_sample (unary_map<Op> (fm));
00206 Op::set_neutral (r);
00207 return r;
00208 }
00209 }
00210
00211 };
00212
00213
00214
00215
00216
00217 struct vector_abstractions_stride {};
00218
00219 template<typename V>
00220 struct implementation<vector_abstractions_stride,V,vector_naive>:
00221 public implementation<vector_abstractions,V>
00222 {
00223
00224 template<typename Op, typename T> static inline void
00225 vec_nullary_stride (T* dest, nat dest_stride, nat n) {
00226 for (; n != 0; dest += dest_stride, n--)
00227 Op::set_op (*dest);
00228 }
00229
00230 template<typename Op, typename T, typename C> static inline void
00231 vec_unary_stride (T* dest, nat dest_stride, const C* s, nat s_stride, nat n) {
00232 for (; n != 0; dest += dest_stride, s += s_stride, n--)
00233 Op::set_op (*dest, *s);
00234 }
00235
00236 template<typename Op, typename T, typename C1, typename C2> static inline void
00237 vec_binary_stride (T* dest, nat dest_stride, const C1* s1, nat s1_stride,
00238 const C2* s2, nat s2_stride, nat n) {
00239 for (; n != 0; dest += dest_stride, s1 += s1_stride, s2 += s2_stride, n--)
00240 Op::set_op (*dest, *s1, *s2);
00241 }
00242
00243 template<typename Op, typename T, typename X> static inline void
00244 vec_unary_scalar_stride (T* dest, nat dest_stride, const X& x, nat n) {
00245 for (; n != 0; dest += dest_stride, n--)
00246 Op::set_op (*dest, x);
00247 }
00248
00249 template<typename Op, typename T, typename C, typename X> static inline void
00250 vec_binary_scalar_stride (T* dest, nat dest_stride, const C* s, nat s_stride,
00251 const X& x, nat n) {
00252 for (; n != 0; dest += dest_stride, s += s_stride, n--)
00253 Op::set_op (*dest, *s, x);
00254 }
00255
00256 template<typename Op, typename C1, typename C2> static inline void
00257 vec_binary_combine_stride (C1* d1, nat d1_stride,
00258 C2* d2, nat d2_stride, nat n) {
00259 for (; n != 0; d1 += d1_stride, d2 += d2_stride, n--)
00260 Op::set_op (*d1, *d2);
00261 }
00262
00263 template<typename Op, typename C> static inline bool
00264 vec_unary_test_stride (const C* s, nat s_stride, nat n) {
00265 for (; n != 0; s += s_stride, n--)
00266 if (Op::not_op (*s)) return false;
00267 return true;
00268 }
00269
00270 template<typename Op, typename C1, typename C2> static inline bool
00271 vec_binary_test_stride (const C1* s1, nat s1_stride,
00272 const C2* s2, nat s2_stride, nat n) {
00273 for (; n != 0; s1 += s1_stride, s2 += s2_stride, n--)
00274 if (Op::not_op (*s1, *s2)) return false;
00275 return true;
00276 }
00277
00278 template<typename Op, typename C, typename X> static inline bool
00279 vec_binary_test_scalar_stride (const C* s, nat s_stride, const X& x, nat n) {
00280 for (; n != 0; s += s_stride, n--)
00281 if (Op::not_op (*s, x)) return false;
00282 return true;
00283 }
00284
00285 template<typename Op, typename C> static inline C
00286 vec_unary_big_stride (const C* s, nat s_stride, nat n) {
00287 if (n == 0) return Op::template neutral<C> ();
00288 C r= *s;
00289 for (s += s_stride, n--; n != 0; s += s_stride, n--)
00290 Op::set_op (r, *s);
00291 return r;
00292 }
00293
00294 template<typename Op, typename C1, typename C2> static inline C1
00295 vec_binary_big_stride (const C1* s1, nat p1, const C2* s2, nat p2, nat n) {
00296 C1 r; Op::set_neutral (r);
00297 for (; n != 0; s1 += p1, s2 += p2, n--)
00298 Op::set_op (r, *s1, *s2);
00299 return r;
00300 }
00301
00302 template<typename Op, typename C> static C
00303 vec_unary_big_dicho_stride (const C* s, nat p, nat n) {
00304 switch (n) {
00305 case 0: return Op::template neutral<C> ();
00306 case 1: return s[0];
00307 case 2: return Op::op (s[0], s[p]);
00308 case 3: return Op::op (s[0], Op::op (s[p], s[p+p]));
00309 case 4: return Op::op (Op::op (s[0], s[p]), Op::op (s[p+p], s[p+p+p]));
00310 default:
00311 return Op::op (vec_unary_big_dicho_stride<Op> (s, p, n>>1),
00312 vec_unary_big_dicho_stride<Op> (s + (n>>1), p, n - (n>>1)));
00313 }
00314 }
00315
00316 };
00317
00318
00319
00320
00321
00322 struct vector_linear {};
00323
00324 template<typename V>
00325 struct implementation<vector_linear,V,vector_naive>:
00326 public implementation<vector_abstractions_stride,V>
00327 {
00328 typedef implementation<vector_abstractions_stride,V> Vec;
00329
00330 TMPLX static inline void set (C* dest, const X& c, nat n) {
00331 Vec::template vec_unary_scalar<id_op> (dest, c, n); }
00332 TMPLX static inline void set_as (C* dest, const X& c, nat n) {
00333 Vec::template vec_unary_scalar<as_op> (dest, c, n); }
00334 TMPL static inline void clear (C* dest, nat n) {
00335 set_as (dest, (int) 0, n); }
00336 TMPL static inline void copy (C* dest, const C* s, nat n) {
00337 Vec::template vec_unary<id_op> (dest, s, n); }
00338 TMPLX static inline void cast (C* dest, const X* s, nat n) {
00339 Vec::template vec_unary<as_op> (dest, s, n); }
00340 TMPL static inline void neg (C* dest, const C* s, nat n) {
00341 Vec::template vec_unary<neg_op> (dest, s, n); }
00342 TMPL static inline void neg (C* dest, nat n) {
00343 Vec::template vec_nullary<neg_op> (dest, n); }
00344 TMPL static inline void add (C* dest, const C* s1, const C* s2, nat n) {
00345 Vec::template vec_binary<add_op> (dest, s1, s2, n); }
00346 TMPL static inline void sub (C* dest, const C* s1, const C* s2, nat n) {
00347 Vec::template vec_binary<sub_op> (dest, s1, s2, n); }
00348 TMPL static inline void mul (C* dest, const C* s1, const C* s2, nat n) {
00349 Vec::template vec_binary<mul_op> (dest, s1, s2, n); }
00350 TMPL static inline void div (C* dest, const C* s1, const C* s2, nat n) {
00351 Vec::template vec_binary<div_op> (dest, s1, s2, n); }
00352 TMPL static inline void mul (C* dest, const C* s, const C& c, nat n) {
00353 Vec::template vec_binary_scalar<mul_op> (dest, s, c, n); }
00354 TMPL static inline void div (C* dest, const C* s, const C& c, nat n) {
00355 Vec::template vec_binary_scalar<div_op> (dest, s, c, n); }
00356 TMPL static inline void quo (C* dest, const C* s, const C& c, nat n) {
00357 Vec::template vec_binary_scalar<quo_op> (dest, s, c, n); }
00358 TMPL static inline void rem (C* dest, const C* s, const C& c, nat n) {
00359 Vec::template vec_binary_scalar<rem_op> (dest, s, c, n); }
00360 TMPL static inline void add (C* dest, const C* s, nat n) {
00361 Vec::template vec_unary<add_op> (dest, s, n); }
00362 TMPL static inline void sub (C* dest, const C* s, nat n) {
00363 Vec::template vec_unary<sub_op> (dest, s, n); }
00364 TMPL static inline void mul (C* dest, const C* s, nat n) {
00365 Vec::template vec_unary<mul_op> (dest, s, n); }
00366 TMPL static inline void div (C* dest, const C* s, nat n) {
00367 Vec::template vec_unary<div_op> (dest, s, n); }
00368 TMPL static inline void mul (C* dest, const C& c, nat n) {
00369 Vec::template vec_unary_scalar<mul_op> (dest, c, n); }
00370 TMPL static inline void div (C* dest, const C& c, nat n) {
00371 Vec::template vec_unary_scalar<div_op> (dest, c, n); }
00372 TMPL static inline void quo (C* dest, const C& c, nat n) {
00373 Vec::template vec_unary_scalar<quo_op> (dest, c, n); }
00374 TMPL static inline void rem (C* dest, const C& c, nat n) {
00375 Vec::template vec_unary_scalar<rem_op> (dest, c, n); }
00376 TMPL static inline void mul_add (C* dest, const C* s1, const C* s2, nat n) {
00377 Vec::template vec_binary<mul_add_op> (dest, s1, s2, n); }
00378 TMPLX static inline void mul_add (C* dest, const C* s, const X& c, nat n) {
00379 Vec::template vec_binary_scalar<rmul_add_op> (dest, s, c, n); }
00380 TMPLX static inline void mul_add (C* dest, const X& c, const C* s, nat n) {
00381 Vec::template vec_binary_scalar<lmul_add_op> (dest, s, c, n); }
00382 TMPL static inline C inn_prod (const C* s1, const C* s2, nat n) {
00383 return Vec::template vec_binary_big<mul_add_op> (s1, s2, n); }
00384 TMPL static inline C inn_prod (const C* s1, const C* s2, nat n,
00385 const format<C>& fm) {
00386 return Vec::template vec_binary_big<mul_add_op> (s1, s2, n, fm, fm); }
00387 TMPL static inline bool equal (const C* s1, const C* s2, nat n) {
00388 return Vec::template vec_binary_test<equal_op> (s1, s2, n); }
00389 TMPL static inline bool lesseq (const C* s1, const C* s2, nat n) {
00390 return Vec::template vec_binary_test<lesseq_op> (s1, s2, n); }
00391 TMPL static inline bool gtreq (const C* s1, const C* s2, nat n) {
00392 return Vec::template vec_binary_test<gtreq_op> (s1, s2, n); }
00393 TMPL static inline bool equal (const C* s, const C& c, nat n) {
00394 return Vec::template vec_binary_test_scalar<equal_op> (s, c, n); }
00395 TMPL static inline bool lesseq (const C* s, const C& c, nat n) {
00396 return Vec::template vec_binary_test_scalar<lesseq_op> (s, c, n); }
00397 TMPL static inline bool gtreq (const C* s, const C& c, nat n) {
00398 return Vec::template vec_binary_test_scalar<gtreq_op> (s, c, n); }
00399 TMPL static inline bool exact_eq (const C* s1, const C* s2, nat n) {
00400 return Vec::template vec_binary_test<exact_eq_op> (s1, s2, n); }
00401 TMPL static inline bool exact_eq (const C* s, const C& c, nat n) {
00402 return Vec::template vec_binary_test_scalar<exact_eq_op> (s, c, n); }
00403
00404 TMPL static inline void half_copy (C* dest, const C* s, nat l) {
00405 Vec::template vec_unary_stride<id_op> (dest, 1, s, 2, l); }
00406 TMPL static inline void double_copy (C* dest, const C* s, nat l) {
00407 Vec::template vec_unary_stride<id_op> (dest, 2, s, 1, l); }
00408 TMPL static inline void double_add (C* dest, const C* s, nat l) {
00409 Vec::template vec_unary_stride<add_op> (dest, 2, s, 1, l); }
00410 TMPL static inline void triple_copy (C* dest, const C* s, nat l) {
00411 Vec::template vec_unary_stride<id_op> (dest, 3, s, 1, l); }
00412
00413 TMPL static inline void
00414 vec_reverse (C* dest, const C* src, nat n) {
00415 dest += n-1;
00416 for (; n != 0; dest--, src++, n--) *dest= *src;
00417 }
00418
00419 TMPL static inline void
00420 vec_reverse (C* dest, nat ds, const C* src, nat ss, nat n) {
00421 dest += (n-1) * ds;
00422 for (; n != 0; dest -= ds, src += ss, n--) *dest= *src;
00423 }
00424
00425 TMPL static inline void
00426 vec_reverse (C* dest, nat n) {
00427 nat h= n >> 1;
00428 C* rev= dest + n - 1;
00429 C tmp;
00430 for (; h != 0; dest++, rev--, h--) {
00431 tmp = *dest;
00432 *dest= *rev;
00433 *rev = tmp;
00434 }
00435 }
00436
00437 TMPL static inline void
00438 vec_reverse (C* dest, nat stride, nat n) {
00439 nat h= n >> 1;
00440 C* rev= dest + (n - 1) * stride;
00441 C tmp;
00442 for (; h != 0; dest += stride, rev -= stride, h--) {
00443 tmp = *dest;
00444 *dest= *rev;
00445 *rev = tmp;
00446 }
00447 }
00448
00449 TMPL static inline void
00450 print (const port& out, const C* s, nat n) {
00451 if (n == 0) out << "[]";
00452 else {
00453 out << "[ " << s[0];
00454 for (nat i=1; i<n; i++)
00455 out << ", " << s[i];
00456 out << " ]";
00457 }
00458 }
00459
00460 };
00461
00462 #undef TMPL
00463 #undef TMPLX
00464 }
00465 #endif //__MMX__VECTOR_NAIVE__HPP