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 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 };
00224
00225 #undef TMPL
00226 }
00227 #endif //__MMX__VECTOR_UNROLLED__HPP