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