basix_doc 0.1
|
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