algebramix_doc 0.3
/Users/mourrain/Devel/mmx/algebramix/include/algebramix/vector_unrolled.hpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : vector_unrolled.hpp
00004 * DESCRIPTION: loop unrolling within vectorial operations
00005 * COPYRIGHT  : (C) 2007  Joris van der Hoeven and Gregoire Lecerf
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_UNROLLED__HPP
00014 #define __MMX__VECTOR_UNROLLED__HPP
00015 #include <basix/basix.hpp>
00016 #include <algebramix/vector_fixed.hpp>
00017 
00018 namespace mmx {
00019 #define TMPL  template<typename C>
00020 
00021 /******************************************************************************
00022 * Variant for loop unrolled routines on vectors
00023 ******************************************************************************/
00024 
00025 template<nat len, typename V= vector_naive>
00026 struct vector_unrolled: public V {
00027   typedef typename V::Naive Naive;
00028   typedef vector_unrolled<len,typename V::Aligned> Aligned;
00029   typedef vector_unrolled<len,typename V::No_simd> No_simd;
00030   typedef vector_unrolled<len,typename V::No_thread> No_thread;
00031 };
00032 
00033 template<typename F, typename V, nat len, typename W>
00034 struct implementation<F,V,vector_unrolled<len,W> >:
00035   public implementation<F,V,W> {};
00036 
00037 /******************************************************************************
00038 * Abstract low level vector routines on vectors in memory
00039 ******************************************************************************/
00040 
00041 template<typename V, nat len, typename W>
00042 struct implementation<vector_abstractions,V,vector_unrolled<len,W> >:
00043   public implementation<vector_allocate,V>
00044 {
00045   typedef implementation<vector_abstractions,W> Vec;
00046 
00047 template<typename Op, typename T> static inline void
00048 vec_nullary (T* dest, nat n) {
00049 _loop:
00050   if (n<len) Vec::template vec_nullary<Op> (dest, n);
00051   else {
00052     vec_nullary_helper<Op, T, len>::op (dest);
00053     dest += len; n -= len;
00054     goto _loop;
00055   }
00056 }
00057 
00058 template<typename Op, typename T, typename C> static inline void
00059 vec_unary (T* dest, const C* s, nat n) {
00060 _loop:
00061   if (n<len) Vec::template vec_unary<Op> (dest, s, n);
00062   else {
00063     vec_unary_helper<Op, T, C, len>::op (dest, s);
00064     dest += len; s += len; n -= len;
00065     goto _loop;
00066   }
00067 }
00068 
00069 template<typename Op, typename T, typename C1, typename C2> static inline void
00070 vec_binary (T* dest, const C1* s1, const C2* s2, nat n) {
00071 _loop:
00072   if (n<len) Vec::template vec_binary<Op, T, C1, C2> (dest, s1, s2, n);
00073   else {
00074     vec_binary_helper<Op, T, C1, C2, len>::op (dest, s1, s2);
00075     dest += len; s1 += len; s2 += len; n -= len;
00076     goto _loop;
00077   }
00078 }
00079 
00080 template<typename Op, typename T, typename X> static inline void
00081 vec_unary_scalar (T* dest, const X& x, nat n) {
00082 _loop:
00083   if (n<len) Vec::template vec_unary_scalar<Op, T, X> (dest, x, n);
00084   else {
00085     vec_unary_scalar_helper<Op, T, X, len>::op (dest, x);
00086     dest += len; n -= len;
00087     goto _loop;
00088   }
00089 }
00090 
00091 template<typename Op, typename T, typename C, typename X> static inline void
00092 vec_binary_scalar (T* dest, const C* s, const X& x, nat n) {
00093 _loop:
00094   if (n<len) Vec::template vec_binary_scalar<Op, T, C, X> (dest, s, x, n);
00095   else {
00096     vec_binary_scalar_helper<Op, T, C, X, len>::op (dest, s, x);
00097     dest += len; s += len; n -= len;
00098     goto _loop;
00099   }
00100 }
00101 
00102 template<typename Op, typename C> static inline bool
00103 vec_unary_test (const C* s, nat n) {
00104 _loop:
00105   if (n<len) 
00106     return Vec::template vec_unary_test<Op, C> (s, n);
00107   else {
00108     if (! vec_unary_test_helper<Op, C, len>::op (s))
00109       return false;
00110     s += len; n -= len;
00111     goto _loop;
00112   }
00113   return true;
00114 }
00115 
00116 template<typename Op, typename C1, typename C2> static inline bool
00117 vec_binary_test (const C1* s1, const C2* s2, nat n) {
00118 _loop:
00119   if (n<len) 
00120     return Vec::template vec_binary_test<Op, C1, C2> (s1, s2, n);
00121   else {
00122     if (! vec_binary_test_helper<Op, C1, C2, len>::op (s1, s2))
00123       return false;
00124     s1 += len; s2 += len; n -= len;
00125     goto _loop;
00126   }
00127   return true;
00128 }
00129 
00130 template<typename Op, typename C, typename X> static inline bool
00131 vec_binary_test_scalar (const C* s, const X& x, nat n) {
00132 _loop:
00133   if (n<len)
00134     return Vec::template vec_binary_test_scalar<Op, C, X> (s, x, n);
00135   else {
00136     if (! vec_binary_test_scalar_helper<Op, C, X, len>::op (s, x))
00137       return false;
00138     s += len; n -= len;
00139     goto _loop;
00140   }
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   if (n == 0) return Op::template neutral<C> ();
00148   R r= Op::template neutral<R> ();
00149   Op::set_op (r, Vec::template vec_unary_big<Op, C> (s, n));
00150   s++; n--;
00151 _loop:
00152   if (n < len)
00153     Op::set_op (r, Vec::template vec_unary_big<Op, C> (s, n));
00154   else {
00155     vec_unary_big_helper<Op, R, C, len>::set_op (r, s);
00156     s += len; n -= len;
00157     goto _loop;
00158   }
00159   return r;
00160 }
00161 
00162 template<typename Op, typename C> static inline Unary_return_type(Op,C)
00163   vec_unary_big (const C* s, nat n, const format<C>& fm) {
00164   typedef Unary_return_type(Op,C) R;
00165   R r= get_sample (unary_map<Op> (fm));
00166   Op::set_neutral (r);
00167   if (n == 0) return r;
00168   Op::set_op (r, Vec::template vec_unary_big<Op, C> (s, n, fm));
00169   s++; n--;
00170 _loop:
00171   if (n < len)
00172     Op::set_op (r, Vec::template vec_unary_big<Op, C> (s, n, fm));
00173   else {
00174     vec_unary_big_helper<Op, R, C, len>::set_op (r, s, fm);
00175     s += len; n -= len;
00176     goto _loop;
00177   }
00178   return r;
00179 }
00180 
00181 template<typename Op, typename C> static inline C
00182 vec_unary_big_dicho (const C* s, nat n) {
00183   return vec_unary_big<Op, C> (s, n);
00184 }
00185 
00186 template<typename Op, typename C> static inline C
00187 vec_unary_big_dicho (const C* s, nat n, const format<C>& fm) {
00188   return vec_unary_big<Op, C> (s, n, fm);
00189 }
00190 
00191 template<typename Op, typename C1, typename C2> static inline C1
00192 vec_binary_big (const C1* s1, const C2* s2, nat n) {
00193   C1 r= Op::template neutral<C1> ();
00194 _loop:
00195   if (n<len)
00196     for (; n != 0; s1++, s2++, n--)
00197       Op::set_op (r, *s1, *s2);
00198   else {
00199     vec_binary_big_helper<Op, C1, C2, len>::_op (r, s1, s2);
00200     s1 += len; s2 += len; n -= len;
00201     goto _loop;
00202   }
00203   return r;
00204 }
00205 
00206 template<typename Op, typename C1, typename C2> static inline C1
00207 vec_binary_big (const C1* s1, const C2* s2, nat n,
00208                 const format<C1>& fm1, const format<C2>& fm2) {
00209   C1 r= get_sample (binary_map<Op> (fm1, fm2));
00210   Op::set_neutral (r);
00211 _loop:
00212   if (n<len)
00213     for (; n != 0; s1++, s2++, n--)
00214       Op::set_op (r, *s1, *s2);
00215   else {
00216     vec_binary_big_helper<Op, C1, C2, len>::_op (r, s1, s2, fm1, fm2);
00217     s1 += len; s2 += len; n -= len;
00218     goto _loop;
00219   }
00220   return r;
00221 }
00222 
00223 }; // implementation<vector_abstractions,V,vector_unrolled<len1,W> >
00224 
00225 #undef TMPL
00226 } // namespace mmx
00227 #endif //__MMX__VECTOR_UNROLLED__HPP
 All Classes Namespaces Files Functions Variables Typedefs Friends Defines