basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/include/basix/vector_naive.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : vector_naive.hpp
00004 * DESCRIPTION: header for low level vectorial computations
00005 * COPYRIGHT  : (C) 2003  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license and comes WITHOUT
00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
00009 * If you don't have this file, write to the Free Software Foundation, Inc.,
00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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 * Naive variant for vectors
00025 ******************************************************************************/
00026 
00027 struct vector_naive {
00028   typedef vector_naive Naive;      // Naive variant
00029   typedef vector_naive Aligned;    // Vectors which are assumed to be aligned
00030   typedef vector_naive No_simd;    // Variant without SIMD instructions
00031   typedef vector_naive No_thread;  // Variant without threads
00032 };
00033 
00034 /* NOTE: defined in basix.hpp
00035 template<typename C>
00036 struct vector_variant_helper {
00037   typedef vector_naive VV;
00038 };
00039 */
00040 
00041 /******************************************************************************
00042 * Vector defaults
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 }; // implementation<vector_defaults,V,vector_naive>
00052 
00053 /******************************************************************************
00054 * Memory allocation
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 }; // implementation<vector_allocate,V,vector_naive>
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 * Abstract low level vector routines on vectors in memory
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 C> static inline bool
00124 vec_unary_test (const C* s, nat n) {
00125   for (; n != 0; s++, n--)
00126     if (Op::not_op (*s)) return false;
00127   return true;
00128 }
00129 
00130 template<typename Op, typename C1, typename C2> static inline bool
00131 vec_binary_test (const C1* s1, const C2* s2, nat n) {
00132   for (; n != 0; s1++, s2++, n--)
00133     if (Op::not_op (*s1, *s2)) return false;
00134   return true;
00135 }
00136 
00137 template<typename Op, typename C, typename X> static inline bool
00138 vec_binary_test_scalar (const C* s, const X& x, nat n) {
00139   for (; n != 0; s++, n--)
00140     if (Op::not_op (*s, x)) return false;
00141   return true;
00142 }
00143 
00144 template<typename Op, typename C> static inline Unary_return_type(Op,C)
00145 vec_unary_big (const C* s, nat n) {
00146   typedef Unary_return_type(Op,C) R;
00147   R r= Op::template neutral<R> ();
00148   for (; n != 0; s++, n--)
00149     Op::set_op (r, *s);
00150   return r;
00151 }
00152 
00153 template<typename Op, typename C> static inline Unary_return_type(Op,C)
00154   vec_unary_big (const C* s, nat n, const format<C>& fm) {
00155   typedef Unary_return_type(Op,C) R;
00156   R r= get_sample (unary_map<Op> (fm));
00157   Op::set_neutral (r);
00158   for (; n != 0; s++, n--)
00159     Op::set_op (r, *s);
00160   return r;
00161 }
00162 
00163 template<typename Op, typename C1, typename C2> static inline C1
00164 vec_binary_big (const C1* s1, const C2* s2, nat n) {
00165   C1 r= Op::template neutral<C1> ();
00166   for (; n != 0; s1++, s2++, n--)
00167     Op::set_op (r, *s1, *s2);
00168   return r;
00169 }
00170 
00171 template<typename Op, typename C1, typename C2> static inline C1
00172 vec_binary_big (const C1* s1, const C2* s2, nat n,
00173                 const format<C1>& fm1, const format<C2>& fm2) {
00174   C1 r= get_sample (binary_map<Op> (fm1, fm2));
00175   Op::set_neutral (r);
00176   for (; n != 0; s1++, s2++, n--)
00177     Op::set_op (r, *s1, *s2);
00178   return r;
00179 }
00180 
00181 template<typename Op, typename C> static C
00182 vec_unary_big_dicho (const C* s, nat n) {
00183   switch (n) {
00184   case 0: return Op::template neutral<C> ();
00185   case 1: return s[0];
00186   case 2: return Op::op (s[0], s[1]);
00187   case 3: return Op::op (s[0], Op::op (s[1], s[2]));
00188   case 4: return Op::op (Op::op (s[0], s[1]), Op::op (s[2], s[3]));
00189   default: return Op::op (vec_unary_big_dicho<Op> (s, n>>1),
00190                           vec_unary_big_dicho<Op> (s + (n>>1), n - (n>>1)));
00191   }
00192 }
00193 
00194 template<typename Op, typename C> static inline C
00195 vec_unary_big_dicho (const C* s, nat n, const format<C>& fm) {
00196   if (n != 0) return vec_unary_big_dicho (s, n);
00197   else {
00198     C r= get_sample (unary_map<Op> (fm));
00199     Op::set_neutral (r);
00200     return r;
00201   }
00202 }
00203 
00204 }; // implementation<vector_abstractions,V,vector_naive>
00205 
00206 /******************************************************************************
00207 * Abstract low level vector routines on vectors with stride
00208 ******************************************************************************/
00209 
00210 struct vector_abstractions_stride {};
00211 
00212 template<typename V>
00213 struct implementation<vector_abstractions_stride,V,vector_naive>:
00214   public implementation<vector_abstractions,V>
00215 {
00216 
00217 template<typename Op, typename T> static inline void
00218 vec_nullary_stride (T* dest, nat dest_stride, nat n) {
00219   for (; n != 0; dest += dest_stride, n--)
00220     Op::set_op (*dest);
00221 }
00222 
00223 template<typename Op, typename T, typename C> static inline void
00224 vec_unary_stride (T* dest, nat dest_stride, const C* s, nat s_stride, nat n) {
00225   for (; n != 0; dest += dest_stride, s += s_stride, n--)
00226     Op::set_op (*dest, *s);
00227 }
00228 
00229 template<typename Op, typename T, typename C1, typename C2> static inline void
00230 vec_binary_stride (T* dest, nat dest_stride, const C1* s1, nat s1_stride,
00231                    const C2* s2, nat s2_stride, nat n) {
00232   for (; n != 0; dest += dest_stride, s1 += s1_stride, s2 += s2_stride, n--)
00233     Op::set_op (*dest, *s1, *s2);
00234 }
00235 
00236 template<typename Op, typename T, typename X> static inline void
00237 vec_unary_scalar_stride (T* dest, nat dest_stride, const X& x, nat n) {
00238   for (; n != 0; dest += dest_stride, n--)
00239     Op::set_op (*dest, x);
00240 }
00241 
00242 template<typename Op, typename T, typename C, typename X> static inline void
00243 vec_binary_scalar_stride (T* dest, nat dest_stride, const C* s, nat s_stride,
00244                           const X& x, nat n) {
00245   for (; n != 0; dest += dest_stride, s += s_stride, n--)
00246     Op::set_op (*dest, *s, x);
00247 }
00248 
00249 template<typename Op, typename C1, typename C2> static inline void
00250 vec_binary_combine_stride (C1* d1, nat d1_stride,
00251                            C2* d2, nat d2_stride, nat n) {
00252   for (; n != 0; d1 += d1_stride, d2 += d2_stride, n--)
00253     Op::set_op (*d1, *d2);
00254 }
00255 
00256 template<typename Op, typename C> static inline bool
00257 vec_unary_test_stride (const C* s, nat s_stride, nat n) {
00258   for (; n != 0; s += s_stride, n--)
00259     if (Op::not_op (*s)) return false;
00260   return true;
00261 }
00262 
00263 template<typename Op, typename C1, typename C2> static inline bool
00264 vec_binary_test_stride (const C1* s1, nat s1_stride,
00265                         const C2* s2, nat s2_stride, nat n) {
00266   for (; n != 0; s1 += s1_stride, s2 += s2_stride, n--)
00267     if (Op::not_op (*s1, *s2)) return false;
00268   return true;
00269 }
00270 
00271 template<typename Op, typename C, typename X> static inline bool
00272 vec_binary_test_scalar_stride (const C* s, nat s_stride, const X& x, nat n) {
00273   for (; n != 0; s += s_stride, n--)
00274     if (Op::not_op (*s, x)) return false;
00275   return true;
00276 }
00277 
00278 template<typename Op, typename C> static inline C
00279 vec_unary_big_stride (const C* s, nat s_stride, nat n) {
00280   if (n == 0) return Op::template neutral<C> ();
00281   C r= *s;
00282   for (s += s_stride, n--; n != 0; s += s_stride, n--)
00283     Op::set_op (r, *s);
00284   return r;
00285 }
00286 
00287 template<typename Op, typename C1, typename C2> static inline C1
00288 vec_binary_big_stride (const C1* s1, nat p1, const C2* s2, nat p2, nat n) {
00289   C1 r= Op::template neutral<C1> ();
00290   for (; n != 0; s1 += p1, s2 += p2, n--)
00291     Op::set_op (r, *s1, *s2);
00292   return r;
00293 }
00294 
00295 template<typename Op, typename C> static C
00296 vec_unary_big_dicho_stride (const C* s, nat p, nat n) {
00297   switch (n) {
00298   case 0: return Op::template neutral<C> ();
00299   case 1: return s[0];
00300   case 2: return Op::op (s[0], s[p]);
00301   case 3: return Op::op (s[0], Op::op (s[p], s[p+p]));
00302   case 4: return Op::op (Op::op (s[0], s[p]), Op::op (s[p+p], s[p+p+p]));
00303   default:
00304     return Op::op (vec_unary_big_dicho_stride<Op> (s, p, n>>1),
00305                    vec_unary_big_dicho_stride<Op> (s + (n>>1), p, n - (n>>1)));
00306   }
00307 }
00308 
00309 }; // implementation<vector_abstractions_stride,V,vector_naive>
00310 
00311 /******************************************************************************
00312 * Instantiations
00313 ******************************************************************************/
00314 
00315 struct vector_linear {};
00316 
00317 template<typename V>
00318 struct implementation<vector_linear,V,vector_naive>:
00319   public implementation<vector_abstractions_stride,V>
00320 {
00321   typedef implementation<vector_abstractions_stride,V> Vec;
00322 
00323 TMPLX static inline void set (C* dest, const X& c, nat n) {
00324   Vec::template vec_unary_scalar<id_op> (dest, c, n); }
00325 TMPLX static inline void set_as (C* dest, const X& c, nat n) {
00326   Vec::template vec_unary_scalar<as_op> (dest, c, n); }
00327 TMPL static inline void clear (C* dest, nat n) {
00328   set_as (dest, (int) 0, n); }
00329 TMPL static inline void copy (C* dest, const C* s, nat n) {
00330   Vec::template vec_unary<id_op> (dest, s, n); }
00331 TMPLX static inline void cast (C* dest, const X* s, nat n) {
00332   Vec::template vec_unary<as_op> (dest, s, n); }
00333 TMPL static inline void neg (C* dest, const C* s, nat n) {
00334   Vec::template vec_unary<neg_op> (dest, s, n); }
00335 TMPL static inline void neg (C* dest, nat n) {
00336   Vec::template vec_nullary<neg_op> (dest, n); }
00337 TMPL static inline void add (C* dest, const C* s1, const C* s2, nat n) {
00338   Vec::template vec_binary<add_op> (dest, s1, s2, n); }
00339 TMPL static inline void sub (C* dest, const C* s1, const C* s2, nat n) {
00340   Vec::template vec_binary<sub_op> (dest, s1, s2, n); }
00341 TMPL static inline void mul (C* dest, const C* s1, const C* s2, nat n) {
00342   Vec::template vec_binary<mul_op> (dest, s1, s2, n); }
00343 TMPL static inline void div (C* dest, const C* s1, const C* s2, nat n) {
00344   Vec::template vec_binary<div_op> (dest, s1, s2, n); }
00345 TMPL static inline void mul (C* dest, const C* s, const C& c, nat n) {
00346   Vec::template vec_binary_scalar<mul_op> (dest, s, c, n); }
00347 TMPL static inline void div (C* dest, const C* s, const C& c, nat n) {
00348   Vec::template vec_binary_scalar<div_op> (dest, s, c, n); }
00349 TMPL static inline void quo (C* dest, const C* s, const C& c, nat n) {
00350   Vec::template vec_binary_scalar<quo_op> (dest, s, c, n); }
00351 TMPL static inline void rem (C* dest, const C* s, const C& c, nat n) {
00352   Vec::template vec_binary_scalar<rem_op> (dest, s, c, n); }
00353 TMPL static inline void add (C* dest, const C* s, nat n) {
00354   Vec::template vec_unary<add_op> (dest, s, n); }
00355 TMPL static inline void sub (C* dest, const C* s, nat n) {
00356   Vec::template vec_unary<sub_op> (dest, s, n); }
00357 TMPL static inline void mul (C* dest, const C* s, nat n) {
00358   Vec::template vec_unary<mul_op> (dest, s, n); }
00359 TMPL static inline void div (C* dest, const C* s, nat n) {
00360   Vec::template vec_unary<div_op> (dest, s, n); }
00361 TMPL static inline void mul (C* dest, const C& c, nat n) {
00362   Vec::template vec_unary_scalar<mul_op> (dest, c, n); }
00363 TMPL static inline void div (C* dest, const C& c, nat n) {
00364   Vec::template vec_unary_scalar<div_op> (dest, c, n); }
00365 TMPL static inline void quo (C* dest, const C& c, nat n) {
00366   Vec::template vec_unary_scalar<quo_op> (dest, c, n); }
00367 TMPL static inline void rem (C* dest, const C& c, nat n) {
00368   Vec::template vec_unary_scalar<rem_op> (dest, c, n); }
00369 TMPL static inline void mul_add (C* dest, const C* s1, const C* s2, nat n) {
00370   Vec::template vec_binary<mul_add_op> (dest, s1, s2, n); }
00371 TMPLX static inline void mul_add (C* dest, const C* s, const X& c, nat n) {
00372   Vec::template vec_binary_scalar<rmul_add_op> (dest, s, c, n); }
00373 TMPLX static inline void mul_add (C* dest, const X& c, const C* s, nat n) {
00374   Vec::template vec_binary_scalar<lmul_add_op> (dest, s, c, n); }
00375 TMPL static inline C inn_prod (const C* s1, const C* s2, nat n) {
00376   return Vec::template vec_binary_big<mul_add_op> (s1, s2, n); }
00377 TMPL static inline C inn_prod (const C* s1, const C* s2, nat n,
00378                                const format<C>& fm) {
00379   return Vec::template vec_binary_big<mul_add_op> (s1, s2, n, fm, fm); }
00380 TMPL static inline bool equal (const C* s1, const C* s2, nat n) {
00381   return Vec::template vec_binary_test<equal_op> (s1, s2, n); }
00382 TMPL static inline bool lesseq (const C* s1, const C* s2, nat n) {
00383   return Vec::template vec_binary_test<lesseq_op> (s1, s2, n); }
00384 TMPL static inline bool gtreq (const C* s1, const C* s2, nat n) {
00385   return Vec::template vec_binary_test<gtreq_op> (s1, s2, n); }
00386 TMPL static inline bool equal (const C* s, const C& c, nat n) {
00387   return Vec::template vec_binary_test_scalar<equal_op> (s, c, n); }
00388 TMPL static inline bool lesseq (const C* s, const C& c, nat n) {
00389   return Vec::template vec_binary_test_scalar<lesseq_op> (s, c, n); }
00390 TMPL static inline bool gtreq (const C* s, const C& c, nat n) {
00391   return Vec::template vec_binary_test_scalar<gtreq_op> (s, c, n); }
00392 TMPL static inline bool exact_eq (const C* s1, const C* s2, nat n) {
00393   return Vec::template vec_binary_test<exact_eq_op> (s1, s2, n); }
00394 TMPL static inline bool exact_eq (const C* s, const C& c, nat n) {
00395   return Vec::template vec_binary_test_scalar<exact_eq_op> (s, c, n); }
00396 
00397 TMPL static inline void half_copy (C* dest, const C* s, nat l) {
00398   Vec::template vec_unary_stride<id_op> (dest, 1, s, 2, l); }
00399 TMPL static inline void double_copy (C* dest, const C* s, nat l) {
00400   Vec::template vec_unary_stride<id_op> (dest, 2, s, 1, l); }
00401 TMPL static inline void double_add (C* dest, const C* s, nat l) {
00402   Vec::template vec_unary_stride<add_op> (dest, 2, s, 1, l); }
00403 TMPL static inline void triple_copy (C* dest, const C* s, nat l) {
00404   Vec::template vec_unary_stride<id_op> (dest, 3, s, 1, l); }
00405 
00406 TMPL static inline void
00407 vec_reverse (C* dest, const C* src, nat n) {
00408   dest += n-1;
00409   for (; n != 0; dest--, src++, n--) *dest= *src;
00410 }
00411 
00412 TMPL static inline void
00413 vec_reverse (C* dest, nat ds, const C* src, nat ss, nat n) {
00414   dest += (n-1) * ds;
00415   for (; n != 0; dest -= ds, src += ss, n--) *dest= *src;
00416 }
00417 
00418 TMPL static inline void
00419 vec_reverse (C* dest, nat n) {
00420   nat h= n >> 1;
00421   C* rev= dest + n - 1;
00422   C tmp;
00423   for (; h != 0; dest++, rev--, h--) {
00424     tmp  = *dest;
00425     *dest= *rev;
00426     *rev = tmp;
00427   }
00428 }
00429 
00430 TMPL static inline void
00431 vec_reverse (C* dest, nat stride, nat n) {
00432   nat h= n >> 1;
00433   C* rev= dest + (n - 1) * stride;
00434   C tmp;
00435   for (; h != 0; dest += stride, rev -= stride, h--) {
00436     tmp  = *dest;
00437     *dest= *rev;
00438     *rev = tmp;
00439   }
00440 }
00441 
00442 TMPL static inline void
00443 print (const port& out, const C* s, nat n) {
00444   if (n == 0) out << "[]";
00445   else {
00446     out << "[ " << s[0];
00447     for (nat i=1; i<n; i++)
00448       out << ", " << s[i];
00449     out << " ]";
00450   }
00451 }
00452 
00453 }; // implementation<vector_linear,V,vector_naive>
00454 
00455 #undef TMPL
00456 #undef TMPLX
00457 } // namespace mmx
00458 #endif //__MMX__VECTOR_NAIVE__HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines