00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __MMX__VECTOR_SCALAR__HPP
00014 #define __MMX__VECTOR_SCALAR__HPP
00015 #include <basix/vector_naive.hpp>
00016 #include <numerix/modular.hpp>
00017 #include <algebramix/multiplier.hpp>
00018 #include <algebramix/vector_unrolled.hpp>
00019
00020 namespace mmx {
00021 #define TMPL template<typename C>
00022 #define TMPLX template<typename C, typename X>
00023
00024
00025
00026
00027
00028 template<typename V>
00029 struct vector_scalar: public V {
00030 typedef vector_scalar<typename V::Naive> Naive;
00031 typedef vector_scalar<typename V::Aligned> Aligned;
00032 typedef vector_scalar<typename V::No_simd> No_simd;
00033 typedef vector_scalar<typename V::No_thread> No_thread;
00034 };
00035
00036 template<typename F, typename V, typename W>
00037 struct implementation<F,V,vector_scalar<W> >:
00038 public implementation<F,V,W> {};
00039
00040
00041
00042
00043
00044 template<typename V, typename W>
00045 struct implementation<vector_abstractions,V,vector_scalar<W> >:
00046 public implementation<vector_abstractions,V,W>
00047 {
00048
00049
00050 typedef implementation<vector_abstractions,V,W> Vec;
00051
00052 template<typename Op, typename T, typename X>
00053 struct vec_scalar_unary_scalar_helper {
00054 static inline void op (T* dest, const X& x, nat n) {
00055 Vec::template vec_unary_scalar<Op> (dest, x, n); }
00056 };
00057
00058 template<typename T, typename X>
00059 struct vec_scalar_unary_scalar_helper<mul_op, T, X> {
00060 static inline void op (T* dest, const X& x, nat n) {
00061 multiplier<X> y (x);
00062 Vec::template vec_unary_scalar<mul_op> (dest, y, n); }
00063 };
00064
00065 template<typename Op, typename T, typename X> static inline void
00066 vec_unary_scalar (T* dest, const X& x, nat n) {
00067 vec_scalar_unary_scalar_helper<Op,T,X>::op (dest, x, n);
00068 }
00069
00070 template<typename Op, typename T, typename C, typename X>
00071 struct vec_scalar_binary_scalar_helper {
00072 static inline void op (T* dest, const C* s, const X& x, nat n) {
00073 Vec::template vec_binary_scalar<Op> (dest, s, x, n); }
00074 };
00075
00076 template<typename T, typename C, typename X>
00077 struct vec_scalar_binary_scalar_helper<mul_op, T, C, X> {
00078 static inline void op (T* dest, const C* s, const X& x, nat n) {
00079 multiplier<X> y (x);
00080 Vec::template vec_binary_scalar<mul_op> (dest, s, y, n); }
00081 };
00082
00083 template<typename T, typename C, typename X>
00084 struct vec_scalar_binary_scalar_helper<rmul_op, T, C, X> {
00085 static inline void op (T* dest, const C* s, const X& x, nat n) {
00086 multiplier<X> y (x);
00087 Vec::template vec_binary_scalar<rmul_op> (dest, s, y, n); }
00088 };
00089
00090 template<typename T, typename C, typename X>
00091 struct vec_scalar_binary_scalar_helper<lmul_op, T, C, X> {
00092 static inline void op (T* dest, const C* s, const X& x, nat n) {
00093 multiplier<X> y (x);
00094 Vec::template vec_binary_scalar<lmul_op> (dest, s, y, n); }
00095 };
00096
00097 template<typename T, typename C, typename X>
00098 struct vec_scalar_binary_scalar_helper<rmul_add_op, T, C, X> {
00099 static inline void op (T* dest, const C* s, const X& x, nat n) {
00100 multiplier<X> y (x);
00101 Vec::template vec_binary_scalar<rmul_add_op> (dest, s, y, n); }
00102 };
00103
00104 template<typename T, typename C, typename X>
00105 struct vec_scalar_binary_scalar_helper<lmul_add_op, T, C, X> {
00106 static inline void op (T* dest, const C* s, const X& x, nat n) {
00107 multiplier<X> y (x);
00108 Vec::template vec_binary_scalar<lmul_add_op> (dest, s, y, n); }
00109 };
00110
00111 template<typename Op, typename T, typename C, typename X> static inline void
00112 vec_binary_scalar (T* dest, const C* s, const X& x, nat n) {
00113 vec_scalar_binary_scalar_helper<Op,T,C,X>::op (dest, s, x, n);
00114 }
00115
00116 };
00117
00118
00119
00120
00121
00122 #define MV(C) modulus<C, modulus_int_preinverse<m> >
00123
00124 template<typename W, nat m>
00125 struct vector_variant_helper<modular<MV (char), W> > {
00126 typedef vector_scalar<vector_unrolled<16,vector_unrolled<32> > > VV; };
00127
00128 template<typename W, nat m>
00129 struct vector_variant_helper<modular<MV (signed char), W> > {
00130 typedef vector_scalar<vector_unrolled<16,vector_unrolled<32> > > VV; };
00131
00132 template<typename W, nat m>
00133 struct vector_variant_helper<modular<MV (unsigned char), W> > {
00134 typedef vector_scalar<vector_unrolled<16,vector_unrolled<32> > > VV; };
00135
00136 template<typename W, nat m>
00137 struct vector_variant_helper<modular<MV (short int), W> > {
00138 typedef vector_scalar<vector_unrolled<8> > VV; };
00139
00140 template<typename W, nat m>
00141 struct vector_variant_helper<modular<MV (short unsigned int), W> > {
00142 typedef vector_scalar<vector_unrolled<8> > VV; };
00143
00144 template<typename W, nat m>
00145 struct vector_variant_helper<modular<MV (int), W> > {
00146 typedef vector_scalar<vector_unrolled<4> > VV; };
00147
00148 template<typename W, nat m>
00149 struct vector_variant_helper<modular<MV (unsigned int), W> > {
00150 typedef vector_scalar<vector_unrolled<4> > VV; };
00151
00152 template<typename W, nat m>
00153 struct vector_variant_helper<modular<MV (long int), W> > {
00154 typedef vector_scalar<vector_unrolled<4> > VV; };
00155
00156 template<typename W, nat m>
00157 struct vector_variant_helper<modular<MV (long unsigned int), W> > {
00158 typedef vector_scalar<vector_unrolled<4> > VV; };
00159
00160 template<typename W, nat m>
00161 struct vector_variant_helper<modular<MV (long long int), W> > {
00162 typedef vector_scalar<vector_unrolled<2> > VV; };
00163
00164 template<typename W, nat m>
00165 struct vector_variant_helper<modular<MV (long long unsigned int), W> > {
00166 typedef vector_scalar<vector_unrolled<2> > VV; };
00167
00168 #undef MV
00169 #undef TMPL
00170 #undef TMPLX
00171 }
00172 #endif //__MMX__VECTOR_SCALAR__HPP