00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
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 T, typename C1, typename C2, typename X>
00103 static inline void
00104 vec_ternary_scalar (T* dest, const C1* s1, const C2* s2, const X& x, nat n) {
00105 _loop:
00106 if (n<len)
00107 Vec::template vec_ternary_scalar<Op, T, C1, C2, X> (dest, s1, s2, x, n);
00108 else {
00109 vec_ternary_scalar_helper<Op, T, C1, C2, X, len>::op (dest, s1, s2, x);
00110 dest += len; s1 += len; s2 += len; n -= len;
00111 goto _loop;
00112 }
00113 }
00114
00115 template<typename Op, typename T, typename C, typename X1, typename X2>
00116 static inline void
00117 vec_ternary_scalar_scalar (T* dest, const C* s,
00118 const X1& x1, const X2& x2, nat n) {
00119 _loop:
00120 if (n<len)
00121 Vec::template vec_ternary_scalar_scalar<Op, T, C, X1, X2>
00122 (dest, s, x1, x2, n);
00123 else {
00124 vec_ternary_scalar_scalar_helper<Op, T, C, X1, X2, len>::op
00125 (dest, s, x1, x2);
00126 dest += len; s += len; n -= len;
00127 goto _loop;
00128 }
00129 }
00130
00131 template<typename Op, typename C> static inline bool
00132 vec_unary_test (const C* s, nat n) {
00133 _loop:
00134 if (n<len)
00135 return Vec::template vec_unary_test<Op, C> (s, n);
00136 else {
00137 if (! vec_unary_test_helper<Op, C, len>::op (s))
00138 return false;
00139 s += len; n -= len;
00140 goto _loop;
00141 }
00142 return true;
00143 }
00144
00145 template<typename Op, typename C1, typename C2> static inline bool
00146 vec_binary_test (const C1* s1, const C2* s2, nat n) {
00147 _loop:
00148 if (n<len)
00149 return Vec::template vec_binary_test<Op, C1, C2> (s1, s2, n);
00150 else {
00151 if (! vec_binary_test_helper<Op, C1, C2, len>::op (s1, s2))
00152 return false;
00153 s1 += len; s2 += len; n -= len;
00154 goto _loop;
00155 }
00156 return true;
00157 }
00158
00159 template<typename Op, typename C, typename X> static inline bool
00160 vec_binary_test_scalar (const C* s, const X& x, nat n) {
00161 _loop:
00162 if (n<len)
00163 return Vec::template vec_binary_test_scalar<Op, C, X> (s, x, n);
00164 else {
00165 if (! vec_binary_test_scalar_helper<Op, C, X, len>::op (s, x))
00166 return false;
00167 s += len; n -= len;
00168 goto _loop;
00169 }
00170 return true;
00171 }
00172
00173 template<typename Op, typename C> static inline Unary_return_type(Op,C)
00174 vec_unary_big (const C* s, nat n) {
00175 typedef Unary_return_type(Op,C) R;
00176 if (n == 0) return Op::template neutral<C> ();
00177 R r= Op::template neutral<R> ();
00178 Op::set_op (r, Vec::template vec_unary_big<Op, C> (s, n));
00179 s++; n--;
00180 _loop:
00181 if (n < len)
00182 Op::set_op (r, Vec::template vec_unary_big<Op, C> (s, n));
00183 else {
00184 vec_unary_big_helper<Op, R, C, len>::set_op (r, s);
00185 s += len; n -= len;
00186 goto _loop;
00187 }
00188 return r;
00189 }
00190
00191 template<typename Op, typename C> static inline Unary_return_type(Op,C)
00192 vec_unary_big (const C* s, nat n, const format<C>& fm) {
00193 typedef Unary_return_type(Op,C) R;
00194 R r= get_sample (unary_map<Op> (fm));
00195 Op::set_neutral (r);
00196 if (n == 0) return r;
00197 Op::set_op (r, Vec::template vec_unary_big<Op, C> (s, n, fm));
00198 s++; n--;
00199 _loop:
00200 if (n < len)
00201 Op::set_op (r, Vec::template vec_unary_big<Op, C> (s, n, fm));
00202 else {
00203 vec_unary_big_helper<Op, R, C, len>::set_op (r, s, fm);
00204 s += len; n -= len;
00205 goto _loop;
00206 }
00207 return r;
00208 }
00209
00210 template<typename Op, typename C> static inline C
00211 vec_unary_big_dicho (const C* s, nat n) {
00212 return vec_unary_big<Op, C> (s, n);
00213 }
00214
00215 template<typename Op, typename C> static inline C
00216 vec_unary_big_dicho (const C* s, nat n, const format<C>& fm) {
00217 return vec_unary_big<Op, C> (s, n, fm);
00218 }
00219
00220 template<typename Op, typename C1, typename C2> static inline C1
00221 vec_binary_big (const C1* s1, const C2* s2, nat n) {
00222 C1 r= Op::template neutral<C1> ();
00223 _loop:
00224 if (n<len)
00225 for (; n != 0; s1++, s2++, n--)
00226 Op::set_op (r, *s1, *s2);
00227 else {
00228 vec_binary_big_helper<Op, C1, C2, len>::_op (r, s1, s2);
00229 s1 += len; s2 += len; n -= len;
00230 goto _loop;
00231 }
00232 return r;
00233 }
00234
00235 template<typename Op, typename C1, typename C2> static inline C1
00236 vec_binary_big (const C1* s1, const C2* s2, nat n,
00237 const format<C1>& fm1, const format<C2>& fm2) {
00238 C1 r= get_sample (binary_map<Op> (fm1, fm2));
00239 Op::set_neutral (r);
00240 _loop:
00241 if (n<len)
00242 for (; n != 0; s1++, s2++, n--)
00243 Op::set_op (r, *s1, *s2);
00244 else {
00245 vec_binary_big_helper<Op, C1, C2, len>::_op (r, s1, s2, fm1, fm2);
00246 s1 += len; s2 += len; n -= len;
00247 goto _loop;
00248 }
00249 return r;
00250 }
00251
00252 };
00253
00254 #undef TMPL
00255 }
00256 #endif //__MMX__VECTOR_UNROLLED__HPP