algebramix_doc 0.3
|
00001 00002 /****************************************************************************** 00003 * MODULE : vector_scalar.hpp 00004 * DESCRIPTION: support for multiplier within vector variants 00005 * COPYRIGHT : (C) 2008 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_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 * Variant for customized scalar multiplications 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 * Abstract low level vector routines for products 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 // V is expected to be a complete vector variant abstraction. 00049 // Here we simply override routines involving products. 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 }; // implementation<vector_abstractions,V,vector_scalar<W> > 00117 00118 /****************************************************************************** 00119 * Use vector_scalar operations by default 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 } // namespace mmx 00172 #endif //__MMX__VECTOR_SCALAR__HPP