All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TDVecDVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_TDVECDVECMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TDVECDVECMULTEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <stdexcept>
32 #include <blaze/math/Intrinsics.h>
34 #include <blaze/util/DisableIf.h>
35 #include <blaze/util/EnableIf.h>
37 #include <blaze/util/Types.h>
40 
41 
42 namespace blaze {
43 
44 //=================================================================================================
45 //
46 // CLASS DEFINITION
47 //
48 //=================================================================================================
49 
50 //*************************************************************************************************
55 template< typename T1 // Type of the left-hand side dense vector
56  , typename T2 > // Type of the right-hand side dense vector
57 struct TDVecDVecMultExprHelper
58 {
59  //**Type definitions****************************************************************************
61  typedef typename RemoveReference< typename T1::CompositeType >::Type CT1;
62 
64  typedef typename RemoveReference< typename T2::CompositeType >::Type CT2;
65  //**********************************************************************************************
66 
67  //**********************************************************************************************
68  enum { value = CT1::vectorizable &&
69  CT2::vectorizable &&
70  IsSame< typename CT1::ElementType, typename CT2::ElementType>::value &&
71  IntrinsicTrait< typename CT1::ElementType >::addition &&
72  IntrinsicTrait< typename CT2::ElementType >::multiplication };
73  //**********************************************************************************************
74 };
76 //*************************************************************************************************
77 
78 
79 
80 
81 //=================================================================================================
82 //
83 // GLOBAL BINARY ARITHMETIC OPERATORS
84 //
85 //=================================================================================================
86 
87 //*************************************************************************************************
113 template< typename T1 // Type of the left-hand side dense vector
114  , typename T2 > // Type of the right-hand side dense vector
115 inline typename DisableIf< TDVecDVecMultExprHelper<T1,T2>,
116  const typename MultTrait<typename T1::ElementType,typename T2::ElementType>::Type >::Type
118 {
120 
121  if( (~lhs).size() != (~rhs).size() )
122  throw std::invalid_argument( "Vector sizes do not match" );
123 
124  typedef typename T1::CompositeType Lhs;
125  typedef typename T2::CompositeType Rhs;
126  typedef typename T1::ElementType ET1;
127  typedef typename T2::ElementType ET2;
128  typedef typename MultTrait<ET1,ET2>::Type MultType;
129 
130  if( (~lhs).size() == 0UL ) return MultType();
131 
132  Lhs left ( ~lhs );
133  Rhs right( ~rhs );
134 
135  MultType sp( left[0UL] * right[0UL] );
136 
137  for( size_t i=1UL; i<left.size(); ++i )
138  sp += left[i] * right[i];
139 
140  return sp;
141 }
142 //*************************************************************************************************
143 
144 
145 //*************************************************************************************************
173 template< typename T1 // Type of the left-hand side dense vector
174  , typename T2 > // Type of the right-hand side dense vector
175 inline typename EnableIf< TDVecDVecMultExprHelper<T1,T2>,
176  const typename MultTrait<typename T1::ElementType,typename T2::ElementType>::Type >::Type
178 {
180 
181  if( (~lhs).size() != (~rhs).size() )
182  throw std::invalid_argument( "Vector sizes do not match" );
183 
184  typedef typename T1::CompositeType Lhs;
185  typedef typename T2::CompositeType Rhs;
186  typedef typename T1::ElementType ET1;
187  typedef typename T2::ElementType ET2;
188  typedef typename MultTrait<ET1,ET2>::Type MultType;
189  typedef IntrinsicTrait<MultType> IT;
190 
191  if( (~lhs).size() == 0UL ) return MultType();
192 
193  Lhs left ( ~lhs );
194  Rhs right( ~rhs );
195 
196  typename IT::Type xmm1, xmm2, xmm3, xmm4;
197  MultType sp( 0 );
198 
199  const size_t N ( left.size() );
200  const size_t end( N - N % (IT::size*4UL) );
201 
202  for( size_t i=0UL; i<end; i+=IT::size*4UL ) {
203  xmm1 = xmm1 + ( left.get(i ) * right.get(i ) );
204  xmm2 = xmm2 + ( left.get(i+IT::size ) * right.get(i+IT::size ) );
205  xmm3 = xmm3 + ( left.get(i+IT::size*2UL) * right.get(i+IT::size*2UL) );
206  xmm4 = xmm4 + ( left.get(i+IT::size*3UL) * right.get(i+IT::size*3UL) );
207  }
208 
209  MultType array[IT::size];
210  store( array, xmm1 + xmm2 + xmm3 + xmm4 );
211 
212  for( size_t i=0UL; i<IT::size; ++i )
213  sp += array[i];
214  for( size_t i=end; i<N; ++i )
215  sp += left[i] * right[i];
216 
217  return sp;
218 }
219 //*************************************************************************************************
220 
221 } // namespace blaze
222 
223 #endif