All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TDMatTSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_TDMATTSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_TDMATTSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
51 #include <blaze/math/Intrinsics.h>
53 #include <blaze/math/shims/Reset.h>
80 #include <blaze/util/Assert.h>
82 #include <blaze/util/DisableIf.h>
83 #include <blaze/util/EnableIf.h>
84 #include <blaze/util/InvalidType.h>
86 #include <blaze/util/SelectType.h>
87 #include <blaze/util/Types.h>
89 
90 
91 namespace blaze {
92 
93 //=================================================================================================
94 //
95 // CLASS TDMATTSMATMULTEXPR
96 //
97 //=================================================================================================
98 
99 //*************************************************************************************************
106 template< typename MT1 // Type of the left-hand side dense matrix
107  , typename MT2 > // Type of the right-hand side sparse matrix
108 class TDMatTSMatMultExpr : public DenseMatrix< TDMatTSMatMultExpr<MT1,MT2>, true >
109  , private MatMatMultExpr
110  , private Computation
111 {
112  private:
113  //**Type definitions****************************************************************************
114  typedef typename MT1::ResultType RT1;
115  typedef typename MT2::ResultType RT2;
116  typedef typename RT1::ElementType ET1;
117  typedef typename RT2::ElementType ET2;
118  typedef typename MT1::CompositeType CT1;
119  typedef typename MT2::CompositeType CT2;
120  //**********************************************************************************************
121 
122  //**********************************************************************************************
125  //**********************************************************************************************
126 
127  //**********************************************************************************************
129  enum { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
130  //**********************************************************************************************
131 
132  //**********************************************************************************************
134 
137  template< typename T1, typename T2, typename T3 >
138  struct UseSMPAssignKernel {
139  enum { value = evaluateLeft || evaluateRight };
140  };
142  //**********************************************************************************************
143 
144  //**********************************************************************************************
146 
149  template< typename T1, typename T2, typename T3 >
150  struct UseVectorizedKernel {
151  enum { value = !UseSMPAssignKernel<T1,T2,T3>::value &&
152  T1::vectorizable && T2::vectorizable &&
153  IsColumnMajorMatrix<T1>::value &&
154  IsSame<typename T1::ElementType,typename T2::ElementType>::value &&
155  IsSame<typename T1::ElementType,typename T3::ElementType>::value &&
156  IntrinsicTrait<typename T1::ElementType>::addition &&
157  IntrinsicTrait<typename T1::ElementType>::subtraction &&
158  IntrinsicTrait<typename T1::ElementType>::multiplication };
159  };
161  //**********************************************************************************************
162 
163  //**********************************************************************************************
165 
169  template< typename T1, typename T2, typename T3 >
170  struct UseOptimizedKernel {
171  enum { value = !UseSMPAssignKernel<T1,T2,T3>::value &&
172  !UseVectorizedKernel<T1,T2,T3>::value &&
173  !IsResizable<typename T1::ElementType>::value &&
174  !IsResizable<ET1>::value };
175  };
177  //**********************************************************************************************
178 
179  //**********************************************************************************************
181 
184  template< typename T1, typename T2, typename T3 >
185  struct UseDefaultKernel {
186  enum { value = !UseSMPAssignKernel<T1,T2,T3>::value &&
187  !UseVectorizedKernel<T1,T2,T3>::value &&
188  !UseOptimizedKernel<T1,T2,T3>::value };
189  };
191  //**********************************************************************************************
192 
193  public:
194  //**Type definitions****************************************************************************
201  typedef const ElementType ReturnType;
202  typedef const ResultType CompositeType;
203 
205  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
206 
208  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
209 
212 
215  //**********************************************************************************************
216 
217  //**Compilation flags***************************************************************************
219  enum { vectorizable = MT1::vectorizable &&
223 
225  enum { smpAssignable = !evaluateLeft && !evaluateRight };
226  //**********************************************************************************************
227 
228  //**Constructor*********************************************************************************
234  explicit inline TDMatTSMatMultExpr( const MT1& lhs, const MT2& rhs )
235  : lhs_( lhs ) // Left-hand side dense matrix of the multiplication expression
236  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
237  {
238  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
239  }
240  //**********************************************************************************************
241 
242  //**Access operator*****************************************************************************
249  inline ReturnType operator()( size_t i, size_t j ) const {
250  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
251  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
252 
254 
255  ElementType tmp = ElementType();
256 
257  // Early exit
258  if( lhs_.columns() == 0UL )
259  return tmp;
260 
261  // Fast computation in case the right-hand side sparse matrix directly provides iterators
263  {
264  CT2 B( rhs_ ); // Evaluation of the right-hand side sparse matrix operand
265 
266  const ConstIterator end( B.end(j) );
267  ConstIterator element( B.begin(j) );
268 
269  // Early exit in case column j is empty
270  if( element == end )
271  return tmp;
272 
273  // Calculating element (i,j)
274  tmp = lhs_(i,element->index()) * element->value();
275  ++element;
276  for( ; element!=end; ++element )
277  tmp += lhs_(i,element->index()) * element->value();
278  }
279 
280  // Default computation in case the right-hand side sparse matrix doesn't provide iterators
281  else {
282  tmp = lhs_(i,0UL) * rhs_(0UL,j);
283  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
284  tmp += lhs_(i,k) * rhs_(k,j);
285  }
286  }
287 
288  return tmp;
289  }
290  //**********************************************************************************************
291 
292  //**Rows function*******************************************************************************
297  inline size_t rows() const {
298  return lhs_.rows();
299  }
300  //**********************************************************************************************
301 
302  //**Columns function****************************************************************************
307  inline size_t columns() const {
308  return rhs_.columns();
309  }
310  //**********************************************************************************************
311 
312  //**Left operand access*************************************************************************
317  inline LeftOperand leftOperand() const {
318  return lhs_;
319  }
320  //**********************************************************************************************
321 
322  //**Right operand access************************************************************************
327  inline RightOperand rightOperand() const {
328  return rhs_;
329  }
330  //**********************************************************************************************
331 
332  //**********************************************************************************************
338  template< typename T >
339  inline bool canAlias( const T* alias ) const {
340  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
341  }
342  //**********************************************************************************************
343 
344  //**********************************************************************************************
350  template< typename T >
351  inline bool isAliased( const T* alias ) const {
352  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
353  }
354  //**********************************************************************************************
355 
356  //**********************************************************************************************
361  inline bool isAligned() const {
362  return lhs_.isAligned();
363  }
364  //**********************************************************************************************
365 
366  //**********************************************************************************************
371  inline bool canSMPAssign() const {
372  return ( columns() > SMP_TDMATTSMATMULT_THRESHOLD );
373  }
374  //**********************************************************************************************
375 
376  private:
377  //**Member variables****************************************************************************
380  //**********************************************************************************************
381 
382  //**Assignment to dense matrices****************************************************************
395  template< typename MT // Type of the target dense matrix
396  , bool SO > // Storage order of the target dense matrix
397  friend inline void assign( DenseMatrix<MT,SO>& lhs, const TDMatTSMatMultExpr& rhs )
398  {
400 
401  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
402  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
403 
404  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
405  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
406 
407  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
408  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
409  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
410  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
411  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
412  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
413 
414  TDMatTSMatMultExpr::selectAssignKernel( ~lhs, A, B );
415  }
417  //**********************************************************************************************
418 
419  //**Default assignment to row-major dense matrices**********************************************
433  template< typename MT3 // Type of the left-hand side target matrix
434  , typename MT4 // Type of the left-hand side matrix operand
435  , typename MT5 > // Type of the right-hand side matrix operand
436  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
437  selectAssignKernel( DenseMatrix<MT3,false>& C, const MT4& A, const MT5& B )
438  {
439  typedef typename MT5::ConstIterator ConstIterator;
440 
441  const size_t iend( A.rows() & size_t(-4) );
442  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == iend, "Invalid end calculation" );
443 
444  for( size_t i=0UL; i<iend; i+=4UL ) {
445  for( size_t j=0UL; j<B.columns(); ++j )
446  {
447  ConstIterator element( B.begin(j) );
448  const ConstIterator end( B.end(j) );
449 
450  if( element == end ) {
451  reset( (~C)(i ,j) );
452  reset( (~C)(i+1UL,j) );
453  reset( (~C)(i+2UL,j) );
454  reset( (~C)(i+3UL,j) );
455  continue;
456  }
457 
458  (~C)(i ,j) = A(i ,element->index()) * element->value();
459  (~C)(i+1UL,j) = A(i+1UL,element->index()) * element->value();
460  (~C)(i+2UL,j) = A(i+2UL,element->index()) * element->value();
461  (~C)(i+3UL,j) = A(i+3UL,element->index()) * element->value();
462  ++element;
463  for( ; element!=end; ++element ) {
464  (~C)(i ,j) += A(i ,element->index()) * element->value();
465  (~C)(i+1UL,j) += A(i+1UL,element->index()) * element->value();
466  (~C)(i+2UL,j) += A(i+2UL,element->index()) * element->value();
467  (~C)(i+3UL,j) += A(i+3UL,element->index()) * element->value();
468  }
469  }
470  }
471 
472  for( size_t i=iend; i<A.rows(); ++i ) {
473  for( size_t j=0UL; j<B.columns(); ++j )
474  {
475  ConstIterator element( B.begin(j) );
476  const ConstIterator end( B.end(j) );
477 
478  if( element == end ) {
479  reset( (~C)(i,j) );
480  continue;
481  }
482 
483  (~C)(i,j) = A(i,element->index()) * element->value();
484  ++element;
485  for( ; element!=end; ++element )
486  (~C)(i,j) += A(i,element->index()) * element->value();
487  }
488  }
489  }
491  //**********************************************************************************************
492 
493  //**Default assignment to column-major dense matrices*******************************************
507  template< typename MT3 // Type of the left-hand side target matrix
508  , typename MT4 // Type of the left-hand side matrix operand
509  , typename MT5 > // Type of the right-hand side matrix operand
510  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
511  selectAssignKernel( DenseMatrix<MT3,true>& C, const MT4& A, const MT5& B )
512  {
513  typedef typename MT5::ConstIterator ConstIterator;
514 
515  for( size_t j=0UL; j<B.columns(); ++j ) {
516  for( size_t i=0UL; i<(~C).rows(); ++i ) {
517  reset( (~C)(i,j) );
518  }
519  ConstIterator element( B.begin(j) );
520  const ConstIterator end( B.end(j) );
521  for( ; element!=end; ++element ) {
522  for( size_t i=0UL; i<A.rows(); ++i ) {
523  if( isDefault( (~C)(i,j) ) )
524  (~C)(i,j) = A(i,element->index()) * element->value();
525  else
526  (~C)(i,j) += A(i,element->index()) * element->value();
527  }
528  }
529  }
530  }
532  //**********************************************************************************************
533 
534  //**Optimized assignment to column-major dense matrices*****************************************
548  template< typename MT3 // Type of the left-hand side target matrix
549  , typename MT4 // Type of the left-hand side matrix operand
550  , typename MT5 > // Type of the right-hand side matrix operand
551  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
552  selectAssignKernel( DenseMatrix<MT3,true>& C, const MT4& A, const MT5& B )
553  {
554  typedef typename MT5::ConstIterator ConstIterator;
555 
556  const size_t iend( A.rows() & size_t(-4) );
557  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == iend, "Invalid end calculation" );
558 
559  reset( ~C );
560 
561  for( size_t j=0UL; j<B.columns(); ++j )
562  {
563  const ConstIterator end( B.end(j) );
564  ConstIterator element( B.begin(j) );
565 
566  const size_t kend( B.nonZeros(j) & size_t(-4) );
567 
568  for( size_t k=0UL; k<kend; k+=4UL ) {
569  const size_t j1( element->index() );
570  const ET2 v1( element->value() );
571  ++element;
572  const size_t j2( element->index() );
573  const ET2 v2( element->value() );
574  ++element;
575  const size_t j3( element->index() );
576  const ET2 v3( element->value() );
577  ++element;
578  const size_t j4( element->index() );
579  const ET2 v4( element->value() );
580  ++element;
581 
582  for( size_t i=0UL; i<iend; i+=4UL ) {
583  (~C)(i ,j) += A(i ,j1) * v1 + A(i ,j2) * v2 + A(i ,j3) * v3 + A(i ,j4) * v4;
584  (~C)(i+1UL,j) += A(i+1UL,j1) * v1 + A(i+1UL,j2) * v2 + A(i+1UL,j3) * v3 + A(i+1UL,j4) * v4;
585  (~C)(i+2UL,j) += A(i+2UL,j1) * v1 + A(i+2UL,j2) * v2 + A(i+2UL,j3) * v3 + A(i+2UL,j4) * v4;
586  (~C)(i+3UL,j) += A(i+3UL,j1) * v1 + A(i+3UL,j2) * v2 + A(i+3UL,j3) * v3 + A(i+3UL,j4) * v4;
587  }
588  for( size_t i=iend; i<A.rows(); ++i ) {
589  (~C)(i,j) += A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
590  }
591  }
592 
593  for( ; element!=end; ++element ) {
594  for( size_t i=0UL; i<iend; i+=4UL ) {
595  (~C)(i ,j) += A(i ,element->index()) * element->value();
596  (~C)(i+1UL,j) += A(i+1UL,element->index()) * element->value();
597  (~C)(i+2UL,j) += A(i+2UL,element->index()) * element->value();
598  (~C)(i+3UL,j) += A(i+3UL,element->index()) * element->value();
599  }
600  for( size_t i=iend; i<A.rows(); ++i ) {
601  (~C)(i,j) += A(i,element->index()) * element->value();
602  }
603  }
604  }
605  }
607  //**********************************************************************************************
608 
609  //**Vectorized assignment to column-major dense matrices****************************************
623  template< typename MT3 // Type of the left-hand side target matrix
624  , typename MT4 // Type of the left-hand side matrix operand
625  , typename MT5 > // Type of the right-hand side matrix operand
626  static inline typename EnableIf< UseVectorizedKernel<MT3,MT4,MT5> >::Type
627  selectAssignKernel( DenseMatrix<MT3,true>& C, const MT4& A, const MT5& B )
628  {
629  typedef IntrinsicTrait<ElementType> IT;
630  typedef typename MT5::ConstIterator ConstIterator;
631 
632  const size_t M( A.rows() );
633 
634  reset( ~C );
635 
636  for( size_t j=0UL; j<B.columns(); ++j )
637  {
638  const ConstIterator end( B.end(j) );
639  ConstIterator element( B.begin(j) );
640 
641  const size_t kend( B.nonZeros(j) & size_t(-4) );
642 
643  for( size_t k=0UL; k<kend; k+=4UL ) {
644  const size_t j1( element->index() );
645  const IntrinsicType v1( set( element->value() ) );
646  ++element;
647  const size_t j2( element->index() );
648  const IntrinsicType v2( set( element->value() ) );
649  ++element;
650  const size_t j3( element->index() );
651  const IntrinsicType v3( set( element->value() ) );
652  ++element;
653  const size_t j4( element->index() );
654  const IntrinsicType v4( set( element->value() ) );
655  ++element;
656 
657  for( size_t i=0UL; i<M; i+=IT::size ) {
658  (~C).store( i, j, (~C).load(i,j) + A.load(i,j1) * v1 + A.load(i,j2) * v2 + A.load(i,j3) * v3 + A.load(i,j4) * v4 );
659  }
660  }
661 
662  for( ; element!=end; ++element ) {
663  const size_t j1( element->index() );
664  const IntrinsicType v1( set( element->value() ) );
665 
666  for( size_t i=0UL; i<M; i+=IT::size ) {
667  (~C).store( i, j, (~C).load(i,j) + A.load(i,j1) * v1 );
668  }
669  }
670  }
671  }
673  //**********************************************************************************************
674 
675  //**SMP assignment to dense matrices************************************************************
689  template< typename MT3 // Type of the left-hand side target matrix
690  , typename MT4 // Type of the left-hand side matrix operand
691  , typename MT5 > // Type of the right-hand side matrix operand
692  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
693  selectAssignKernel( MT3& C, const MT4& A, const MT5& B )
694  {
695  smpAssign( C, A * B );
696  }
698  //**********************************************************************************************
699 
700  //**Assignment to sparse matrices***************************************************************
712  template< typename MT // Type of the target sparse matrix
713  , bool SO > // Storage order of the target sparse matrix
714  friend inline void assign( SparseMatrix<MT,SO>& lhs, const TDMatTSMatMultExpr& rhs )
715  {
717 
718  typedef typename SelectType< SO, ResultType, OppositeType >::Type TmpType;
719 
726 
727  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
728  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
729 
730  const TmpType tmp( rhs );
731  smpAssign( ~lhs, tmp );
732  }
734  //**********************************************************************************************
735 
736  //**Addition assignment to dense matrices*******************************************************
749  template< typename MT // Type of the target dense matrix
750  , bool SO > // Storage order of the target dense matrix
751  friend inline void addAssign( DenseMatrix<MT,SO>& lhs, const TDMatTSMatMultExpr& rhs )
752  {
754 
755  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
756  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
757 
758  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
759  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
760 
761  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
762  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
763  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
764  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
765  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
766  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
767 
768  TDMatTSMatMultExpr::selectAddAssignKernel( ~lhs, A, B );
769  }
771  //**********************************************************************************************
772 
773  //**Default addition assignment to row-major dense matrices*************************************
787  template< typename MT3 // Type of the left-hand side target matrix
788  , typename MT4 // Type of the left-hand side matrix operand
789  , typename MT5 > // Type of the right-hand side matrix operand
790  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
791  selectAddAssignKernel( DenseMatrix<MT3,false>& C, const MT4& A, const MT5& B )
792  {
793  typedef typename MT5::ConstIterator ConstIterator;
794 
795  const size_t iend( A.rows() & size_t(-4) );
796  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == iend, "Invalid end calculation" );
797 
798  for( size_t i=0UL; i<iend; i+=4UL ) {
799  for( size_t j=0UL; j<B.columns(); ++j )
800  {
801  ConstIterator element( B.begin(j) );
802  const ConstIterator end( B.end(j) );
803 
804  for( ; element!=end; ++element ) {
805  (~C)(i ,j) += A(i ,element->index()) * element->value();
806  (~C)(i+1UL,j) += A(i+1UL,element->index()) * element->value();
807  (~C)(i+2UL,j) += A(i+2UL,element->index()) * element->value();
808  (~C)(i+3UL,j) += A(i+3UL,element->index()) * element->value();
809  }
810  }
811  }
812 
813  for( size_t i=iend; i<A.rows(); ++i ) {
814  for( size_t j=0UL; j<B.columns(); ++j )
815  {
816  ConstIterator element( B.begin(j) );
817  const ConstIterator end( B.end(j) );
818 
819  for( ; element!=end; ++element )
820  (~C)(i,j) += A(i,element->index()) * element->value();
821  }
822  }
823  }
825  //**********************************************************************************************
826 
827  //**Default addition assignment to column-major dense matrices**********************************
841  template< typename MT3 // Type of the left-hand side target matrix
842  , typename MT4 // Type of the left-hand side matrix operand
843  , typename MT5 > // Type of the right-hand side matrix operand
844  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
845  selectAddAssignKernel( DenseMatrix<MT3,true>& C, const MT4& A, const MT5& B )
846  {
847  typedef typename MT5::ConstIterator ConstIterator;
848 
849  for( size_t j=0UL; j<B.columns(); ++j ) {
850  ConstIterator element( B.begin(j) );
851  const ConstIterator end( B.end(j) );
852  for( ; element!=end; ++element ) {
853  for( size_t i=0UL; i<A.rows(); ++i ) {
854  if( isDefault( (~C)(i,j) ) )
855  (~C)(i,j) = A(i,element->index()) * element->value();
856  else
857  (~C)(i,j) += A(i,element->index()) * element->value();
858  }
859  }
860  }
861  }
863  //**********************************************************************************************
864 
865  //**Optimized addition assignment to column-major dense matrices********************************
879  template< typename MT3 // Type of the left-hand side target matrix
880  , typename MT4 // Type of the left-hand side matrix operand
881  , typename MT5 > // Type of the right-hand side matrix operand
882  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
883  selectAddAssignKernel( DenseMatrix<MT3,true>& C, const MT4& A, const MT5& B )
884  {
885  typedef typename MT5::ConstIterator ConstIterator;
886 
887  const size_t iend( A.rows() & size_t(-4) );
888  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == iend, "Invalid end calculation" );
889 
890  for( size_t j=0UL; j<B.columns(); ++j )
891  {
892  const ConstIterator end( B.end(j) );
893  ConstIterator element( B.begin(j) );
894 
895  const size_t kend( B.nonZeros(j) & size_t(-4) );
896 
897  for( size_t k=0UL; k<kend; k+=4UL ) {
898  const size_t j1( element->index() );
899  const ET2 v1( element->value() );
900  ++element;
901  const size_t j2( element->index() );
902  const ET2 v2( element->value() );
903  ++element;
904  const size_t j3( element->index() );
905  const ET2 v3( element->value() );
906  ++element;
907  const size_t j4( element->index() );
908  const ET2 v4( element->value() );
909  ++element;
910 
911  for( size_t i=0UL; i<iend; i+=4UL ) {
912  (~C)(i ,j) += A(i ,j1) * v1 + A(i ,j2) * v2 + A(i ,j3) * v3 + A(i ,j4) * v4;
913  (~C)(i+1UL,j) += A(i+1UL,j1) * v1 + A(i+1UL,j2) * v2 + A(i+1UL,j3) * v3 + A(i+1UL,j4) * v4;
914  (~C)(i+2UL,j) += A(i+2UL,j1) * v1 + A(i+2UL,j2) * v2 + A(i+2UL,j3) * v3 + A(i+2UL,j4) * v4;
915  (~C)(i+3UL,j) += A(i+3UL,j1) * v1 + A(i+3UL,j2) * v2 + A(i+3UL,j3) * v3 + A(i+3UL,j4) * v4;
916  }
917  for( size_t i=iend; i<A.rows(); ++i ) {
918  (~C)(i,j) += A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
919  }
920  }
921 
922  for( ; element!=end; ++element ) {
923  for( size_t i=0UL; i<iend; i+=4UL ) {
924  (~C)(i ,j) += A(i ,element->index()) * element->value();
925  (~C)(i+1UL,j) += A(i+1UL,element->index()) * element->value();
926  (~C)(i+2UL,j) += A(i+2UL,element->index()) * element->value();
927  (~C)(i+3UL,j) += A(i+3UL,element->index()) * element->value();
928  }
929  for( size_t i=iend; i<A.rows(); ++i ) {
930  (~C)(i,j) += A(i,element->index()) * element->value();
931  }
932  }
933  }
934  }
936  //**********************************************************************************************
937 
938  //**Vectorized addition assignment to column-major dense matrices*******************************
952  template< typename MT3 // Type of the left-hand side target matrix
953  , typename MT4 // Type of the left-hand side matrix operand
954  , typename MT5 > // Type of the right-hand side matrix operand
955  static inline typename EnableIf< UseVectorizedKernel<MT3,MT4,MT5> >::Type
956  selectAddAssignKernel( DenseMatrix<MT3,true>& C, const MT4& A, const MT5& B )
957  {
958  typedef IntrinsicTrait<ElementType> IT;
959  typedef typename MT5::ConstIterator ConstIterator;
960 
961  const size_t M( A.rows() );
962 
963  for( size_t j=0UL; j<B.columns(); ++j )
964  {
965  const ConstIterator end( B.end(j) );
966  ConstIterator element( B.begin(j) );
967 
968  const size_t kend( B.nonZeros(j) & size_t(-4) );
969 
970  for( size_t k=0UL; k<kend; k+=4UL ) {
971  const size_t j1( element->index() );
972  const IntrinsicType v1( set( element->value() ) );
973  ++element;
974  const size_t j2( element->index() );
975  const IntrinsicType v2( set( element->value() ) );
976  ++element;
977  const size_t j3( element->index() );
978  const IntrinsicType v3( set( element->value() ) );
979  ++element;
980  const size_t j4( element->index() );
981  const IntrinsicType v4( set( element->value() ) );
982  ++element;
983 
984  for( size_t i=0UL; i<M; i+=IT::size ) {
985  (~C).store( i, j, (~C).load(i,j) + A.load(i,j1) * v1 + A.load(i,j2) * v2 + A.load(i,j3) * v3 + A.load(i,j4) * v4 );
986  }
987  }
988 
989  for( ; element!=end; ++element ) {
990  const size_t j1( element->index() );
991  const IntrinsicType v1( set( element->value() ) );
992 
993  for( size_t i=0UL; i<M; i+=IT::size ) {
994  (~C).store( i, j, (~C).load(i,j) + A.load(i,j1) * v1 );
995  }
996  }
997  }
998  }
1000  //**********************************************************************************************
1001 
1002  //**SMP addition assignment to dense matrices***************************************************
1016  template< typename MT3 // Type of the left-hand side target matrix
1017  , typename MT4 // Type of the left-hand side matrix operand
1018  , typename MT5 > // Type of the right-hand side matrix operand
1019  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
1020  selectAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
1021  {
1022  smpAddAssign( C, A * B );
1023  }
1025  //**********************************************************************************************
1026 
1027  //**Addition assignment to sparse matrices******************************************************
1028  // No special implementation for the addition assignment to sparse matrices.
1029  //**********************************************************************************************
1030 
1031  //**Subtraction assignment to dense matrices****************************************************
1044  template< typename MT // Type of the target dense matrix
1045  , bool SO > // Storage order of the target dense matrix
1046  friend inline void subAssign( DenseMatrix<MT,SO>& lhs, const TDMatTSMatMultExpr& rhs )
1047  {
1049 
1050  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1051  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1052 
1053  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1054  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1055 
1056  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1057  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1058  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1059  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1060  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1061  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1062 
1063  TDMatTSMatMultExpr::selectSubAssignKernel( ~lhs, A, B );
1064  }
1066  //**********************************************************************************************
1067 
1068  //**Default subtraction assignment to row-major dense matrices**********************************
1082  template< typename MT3 // Type of the left-hand side target matrix
1083  , typename MT4 // Type of the left-hand side matrix operand
1084  , typename MT5 > // Type of the right-hand side matrix operand
1085  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
1086  selectSubAssignKernel( DenseMatrix<MT3,false>& C, const MT4& A, const MT5& B )
1087  {
1088  typedef typename MT5::ConstIterator ConstIterator;
1089 
1090  const size_t iend( A.rows() & size_t(-4) );
1091  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == iend, "Invalid end calculation" );
1092 
1093  for( size_t i=0UL; i<iend; i+=4UL ) {
1094  for( size_t j=0UL; j<B.columns(); ++j )
1095  {
1096  ConstIterator element( B.begin(j) );
1097  const ConstIterator end( B.end(j) );
1098 
1099  for( ; element!=end; ++element ) {
1100  (~C)(i ,j) -= A(i ,element->index()) * element->value();
1101  (~C)(i+1UL,j) -= A(i+1UL,element->index()) * element->value();
1102  (~C)(i+2UL,j) -= A(i+2UL,element->index()) * element->value();
1103  (~C)(i+3UL,j) -= A(i+3UL,element->index()) * element->value();
1104  }
1105  }
1106  }
1107 
1108  for( size_t i=iend; i<A.rows(); ++i ) {
1109  for( size_t j=0UL; j<B.columns(); ++j )
1110  {
1111  ConstIterator element( B.begin(j) );
1112  const ConstIterator end( B.end(j) );
1113 
1114  for( ; element!=end; ++element )
1115  (~C)(i,j) -= A(i,element->index()) * element->value();
1116  }
1117  }
1118  }
1120  //**********************************************************************************************
1121 
1122  //**Default subtraction assignment to column-major dense matrices*******************************
1136  template< typename MT3 // Type of the left-hand side target matrix
1137  , typename MT4 // Type of the left-hand side matrix operand
1138  , typename MT5 > // Type of the right-hand side matrix operand
1139  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
1140  selectSubAssignKernel( DenseMatrix<MT3,true>& C, const MT4& A, const MT5& B )
1141  {
1142  typedef typename MT5::ConstIterator ConstIterator;
1143 
1144  for( size_t j=0UL; j<B.columns(); ++j ) {
1145  ConstIterator element( B.begin(j) );
1146  const ConstIterator end( B.end(j) );
1147  for( ; element!=end; ++element ) {
1148  for( size_t i=0UL; i<A.rows(); ++i ) {
1149  if( isDefault( (~C)(i,j) ) )
1150  (~C)(i,j) = -A(i,element->index()) * element->value();
1151  else
1152  (~C)(i,j) -= A(i,element->index()) * element->value();
1153  }
1154  }
1155  }
1156  }
1158  //**********************************************************************************************
1159 
1160  //**Optimized subtraction assignment to column-major dense matrices*****************************
1174  template< typename MT3 // Type of the left-hand side target matrix
1175  , typename MT4 // Type of the left-hand side matrix operand
1176  , typename MT5 > // Type of the right-hand side matrix operand
1177  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
1178  selectSubAssignKernel( DenseMatrix<MT3,true>& C, const MT4& A, const MT5& B )
1179  {
1180  typedef typename MT5::ConstIterator ConstIterator;
1181 
1182  const size_t iend( A.rows() & size_t(-4) );
1183  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == iend, "Invalid end calculation" );
1184 
1185  for( size_t j=0UL; j<B.columns(); ++j )
1186  {
1187  const ConstIterator end( B.end(j) );
1188  ConstIterator element( B.begin(j) );
1189 
1190  const size_t kend( B.nonZeros(j) & size_t(-4) );
1191 
1192  for( size_t k=0UL; k<kend; k+=4UL ) {
1193  const size_t j1( element->index() );
1194  const ET2 v1( element->value() );
1195  ++element;
1196  const size_t j2( element->index() );
1197  const ET2 v2( element->value() );
1198  ++element;
1199  const size_t j3( element->index() );
1200  const ET2 v3( element->value() );
1201  ++element;
1202  const size_t j4( element->index() );
1203  const ET2 v4( element->value() );
1204  ++element;
1205 
1206  for( size_t i=0UL; i<iend; i+=4UL ) {
1207  (~C)(i ,j) -= A(i ,j1) * v1 + A(i ,j2) * v2 + A(i ,j3) * v3 + A(i ,j4) * v4;
1208  (~C)(i+1UL,j) -= A(i+1UL,j1) * v1 + A(i+1UL,j2) * v2 + A(i+1UL,j3) * v3 + A(i+1UL,j4) * v4;
1209  (~C)(i+2UL,j) -= A(i+2UL,j1) * v1 + A(i+2UL,j2) * v2 + A(i+2UL,j3) * v3 + A(i+2UL,j4) * v4;
1210  (~C)(i+3UL,j) -= A(i+3UL,j1) * v1 + A(i+3UL,j2) * v2 + A(i+3UL,j3) * v3 + A(i+3UL,j4) * v4;
1211  }
1212  for( size_t i=iend; i<A.rows(); ++i ) {
1213  (~C)(i,j) -= A(i,j1) * v1 + A(i,j2) * v2 + A(i,j3) * v3 + A(i,j4) * v4;
1214  }
1215  }
1216 
1217  for( ; element!=end; ++element ) {
1218  for( size_t i=0UL; i<iend; i+=4UL ) {
1219  (~C)(i ,j) -= A(i ,element->index()) * element->value();
1220  (~C)(i+1UL,j) -= A(i+1UL,element->index()) * element->value();
1221  (~C)(i+2UL,j) -= A(i+2UL,element->index()) * element->value();
1222  (~C)(i+3UL,j) -= A(i+3UL,element->index()) * element->value();
1223  }
1224  for( size_t i=iend; i<A.rows(); ++i ) {
1225  (~C)(i,j) -= A(i,element->index()) * element->value();
1226  }
1227  }
1228  }
1229  }
1231  //**********************************************************************************************
1232 
1233  //**Vectorized subtraction assignment to column-major dense matrices****************************
1247  template< typename MT3 // Type of the left-hand side target matrix
1248  , typename MT4 // Type of the left-hand side matrix operand
1249  , typename MT5 > // Type of the right-hand side matrix operand
1250  static inline typename EnableIf< UseVectorizedKernel<MT3,MT4,MT5> >::Type
1251  selectSubAssignKernel( DenseMatrix<MT3,true>& C, const MT4& A, const MT5& B )
1252  {
1253  typedef IntrinsicTrait<ElementType> IT;
1254  typedef typename MT5::ConstIterator ConstIterator;
1255 
1256  const size_t M( A.rows() );
1257 
1258  for( size_t j=0UL; j<B.columns(); ++j )
1259  {
1260  const ConstIterator end( B.end(j) );
1261  ConstIterator element( B.begin(j) );
1262 
1263  const size_t kend( B.nonZeros(j) & size_t(-4) );
1264 
1265  for( size_t k=0UL; k<kend; k+=4UL ) {
1266  const size_t j1( element->index() );
1267  const IntrinsicType v1( set( element->value() ) );
1268  ++element;
1269  const size_t j2( element->index() );
1270  const IntrinsicType v2( set( element->value() ) );
1271  ++element;
1272  const size_t j3( element->index() );
1273  const IntrinsicType v3( set( element->value() ) );
1274  ++element;
1275  const size_t j4( element->index() );
1276  const IntrinsicType v4( set( element->value() ) );
1277  ++element;
1278 
1279  for( size_t i=0UL; i<M; i+=IT::size ) {
1280  (~C).store( i, j, (~C).load(i,j) - A.load(i,j1) * v1 - A.load(i,j2) * v2 - A.load(i,j3) * v3 - A.load(i,j4) * v4 );
1281  }
1282  }
1283 
1284  for( ; element!=end; ++element ) {
1285  const size_t j1( element->index() );
1286  const IntrinsicType v1( set( element->value() ) );
1287 
1288  for( size_t i=0UL; i<M; i+=IT::size ) {
1289  (~C).store( i, j, (~C).load(i,j) - A.load(i,j1) * v1 );
1290  }
1291  }
1292  }
1293  }
1295  //**********************************************************************************************
1296 
1297  //**SMP subtraction assignment to dense matrices************************************************
1311  template< typename MT3 // Type of the left-hand side target matrix
1312  , typename MT4 // Type of the left-hand side matrix operand
1313  , typename MT5 > // Type of the right-hand side matrix operand
1314  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
1315  selectSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1316  {
1317  smpSubAssign( C, A * B );
1318  }
1320  //**********************************************************************************************
1321 
1322  //**Subtraction assignment to sparse matrices***************************************************
1323  // No special implementation for the subtraction assignment to sparse matrices.
1324  //**********************************************************************************************
1325 
1326  //**Multiplication assignment to dense matrices*************************************************
1327  // No special implementation for the multiplication assignment to dense matrices.
1328  //**********************************************************************************************
1329 
1330  //**Multiplication assignment to sparse matrices************************************************
1331  // No special implementation for the multiplication assignment to sparse matrices.
1332  //**********************************************************************************************
1333 
1334  //**Compile time checks*************************************************************************
1341  //**********************************************************************************************
1342 };
1343 //*************************************************************************************************
1344 
1345 
1346 
1347 
1348 //=================================================================================================
1349 //
1350 // GLOBAL BINARY ARITHMETIC OPERATORS
1351 //
1352 //=================================================================================================
1353 
1354 //*************************************************************************************************
1383 template< typename T1 // Type of the left-hand side dense matrix
1384  , typename T2 > // Type of the right-hand side sparse matrix
1385 inline const TDMatTSMatMultExpr<T1,T2>
1387 {
1389 
1390  if( (~lhs).columns() != (~rhs).rows() )
1391  throw std::invalid_argument( "Matrix sizes do not match" );
1392 
1393  return TDMatTSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1394 }
1395 //*************************************************************************************************
1396 
1397 
1398 
1399 
1400 //=================================================================================================
1401 //
1402 // EXPRESSION TRAIT SPECIALIZATIONS
1403 //
1404 //=================================================================================================
1405 
1406 //*************************************************************************************************
1408 template< typename MT1, typename MT2, typename VT >
1409 struct TDMatDVecMultExprTrait< TDMatTSMatMultExpr<MT1,MT2>, VT >
1410 {
1411  public:
1412  //**********************************************************************************************
1413  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1414  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1415  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1416  , typename TDMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
1417  , INVALID_TYPE >::Type Type;
1418  //**********************************************************************************************
1419 };
1421 //*************************************************************************************************
1422 
1423 
1424 //*************************************************************************************************
1426 template< typename MT1, typename MT2, typename VT >
1427 struct TDMatSVecMultExprTrait< TDMatTSMatMultExpr<MT1,MT2>, VT >
1428 {
1429  public:
1430  //**********************************************************************************************
1431  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1432  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value &&
1433  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1434  , typename TDMatDVecMultExprTrait< MT1, typename TSMatDVecMultExprTrait<MT2,VT>::Type >::Type
1435  , INVALID_TYPE >::Type Type;
1436  //**********************************************************************************************
1437 };
1439 //*************************************************************************************************
1440 
1441 
1442 //*************************************************************************************************
1444 template< typename VT, typename MT1, typename MT2 >
1445 struct TDVecTDMatMultExprTrait< VT, TDMatTSMatMultExpr<MT1,MT2> >
1446 {
1447  public:
1448  //**********************************************************************************************
1449  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1450  IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1451  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1452  , typename TDVecTSMatMultExprTrait< typename TDVecTDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1453  , INVALID_TYPE >::Type Type;
1454  //**********************************************************************************************
1455 };
1457 //*************************************************************************************************
1458 
1459 
1460 //*************************************************************************************************
1462 template< typename VT, typename MT1, typename MT2 >
1463 struct TSVecTDMatMultExprTrait< VT, TDMatTSMatMultExpr<MT1,MT2> >
1464 {
1465  public:
1466  //**********************************************************************************************
1467  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1468  IsDenseMatrix<MT1>::value && IsColumnMajorMatrix<MT1>::value &&
1469  IsSparseMatrix<MT2>::value && IsColumnMajorMatrix<MT2>::value
1470  , typename TDVecTSMatMultExprTrait< typename TSVecTDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1471  , INVALID_TYPE >::Type Type;
1472  //**********************************************************************************************
1473 };
1475 //*************************************************************************************************
1476 
1477 
1478 //*************************************************************************************************
1480 template< typename MT1, typename MT2, bool AF >
1481 struct SubmatrixExprTrait< TDMatTSMatMultExpr<MT1,MT2>, AF >
1482 {
1483  public:
1484  //**********************************************************************************************
1485  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1486  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1487  //**********************************************************************************************
1488 };
1490 //*************************************************************************************************
1491 
1492 
1493 //*************************************************************************************************
1495 template< typename MT1, typename MT2 >
1496 struct RowExprTrait< TDMatTSMatMultExpr<MT1,MT2> >
1497 {
1498  public:
1499  //**********************************************************************************************
1500  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1501  //**********************************************************************************************
1502 };
1504 //*************************************************************************************************
1505 
1506 
1507 //*************************************************************************************************
1509 template< typename MT1, typename MT2 >
1510 struct ColumnExprTrait< TDMatTSMatMultExpr<MT1,MT2> >
1511 {
1512  public:
1513  //**********************************************************************************************
1514  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1515  //**********************************************************************************************
1516 };
1518 //*************************************************************************************************
1519 
1520 } // namespace blaze
1521 
1522 #endif
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: TDMatTSMatMultExpr.h:116
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4579
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:4075
void smpSubAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:151
Expression object for transpose dense matrix-transpose sparse matrix multiplications.The TDMatTSMatMultExpr class represents the compile time expression for multiplications between a column-major dense matrix and a column-major sparse matrix.
Definition: Forward.h:128
Header file for the IsSparseMatrix type trait.
bool isDefault(const DynamicMatrix< Type, SO > &m)
Returns whether the given dense matrix is in default state.
Definition: DynamicMatrix.h:4622
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:197
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:79
Header file for the ColumnExprTrait class template.
Header file for the IsColumnMajorMatrix type trait.
const ResultType CompositeType
Data type for composite expression templates.
Definition: TDMatTSMatMultExpr.h:202
Header file for the sparse matrix SMP implementation.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2384
Header file for the IsRowVector type trait.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:249
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member enumeration is set to 1, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to 0, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:158
Header file for the RequiresEvaluation type trait.
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: TDMatTSMatMultExpr.h:205
const size_t SMP_TDMATTSMATMULT_THRESHOLD
SMP column-major dense matrix/column-major sparse matrix multiplication threshold.This threshold represents the system-specific threshold for a parallel column-major dense matrix/column-major sparse matrix multiplication. In case the number of rows/columns of the target matrix is larger or equal to this threshold, the operation is executed in parallel. If the number of rows/columns is below this threshold the operation is executed single-threaded.
Definition: Thresholds.h:524
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:104
size_t rows() const
Returns the current number of rows of the matrix.
Definition: TDMatTSMatMultExpr.h:297
Constraint on the data type.
TDMatTSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the TDMatTSMatMultExpr class.
Definition: TDMatTSMatMultExpr.h:234
Constraint on the data type.
Constraint on the data type.
Header file for the MultExprTrait class template.
void smpAddAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:121
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
IntrinsicTrait< ElementType >::Type IntrinsicType
Resulting intrinsic element type.
Definition: TDMatTSMatMultExpr.h:200
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: TDMatTSMatMultExpr.h:119
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the DisableIf class template.
MT1::CompositeType CT1
Composite type of the left-hand side dense matrix expression.
Definition: TDMatTSMatMultExpr.h:118
Header file for the multiplication trait.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: StorageOrder.h:161
Header file for the TSVecTDMatMultExprTrait class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2388
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: TDMatTSMatMultExpr.h:249
Header file for the TDMatSVecMultExprTrait class template.
Header file for the TDVecTSMatMultExprTrait class template.
Header file for the dense matrix SMP implementation.
Header file for the DenseMatrix base class.
Header file for the TSMatDVecMultExprTrait class template.
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: TDMatTSMatMultExpr.h:371
void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:179
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: TDMatTSMatMultExpr.h:361
LeftOperand leftOperand() const
Returns the left-hand side transpose dense matrix operand.
Definition: TDMatTSMatMultExpr.h:317
#define BLAZE_CONSTRAINT_MUST_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:78
RightOperand rightOperand() const
Returns the right-hand side transpose sparse matrix operand.
Definition: TDMatTSMatMultExpr.h:327
Constraints on the storage order of matrix types.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2382
Header file for the SelectType class template.
Header file for the RowExprTrait class template.
Header file for all forward declarations for expression class templates.
Header file for the IsDenseMatrix type trait.
ResultType::ElementType ElementType
Resulting element type.
Definition: TDMatTSMatMultExpr.h:199
Header file for the EnableIf class template.
LeftOperand lhs_
Left-hand side dense matrix of the multiplication expression.
Definition: TDMatTSMatMultExpr.h:378
void smpAssign(DenseMatrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:91
Header file for the IsSparseVector type trait.
Header file for the SubmatrixExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:748
Header file for run time assertion macros.
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:141
const ElementType ReturnType
Return type for expression template evaluations.
Definition: TDMatTSMatMultExpr.h:201
void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:209
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: TDMatTSMatMultExpr.h:198
Header file for the reset shim.
void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:239
Header file for the isDefault shim.
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: TDMatTSMatMultExpr.h:339
MT1::ResultType RT1
Result type of the left-hand side dense matrix expression.
Definition: TDMatTSMatMultExpr.h:114
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: TDMatTSMatMultExpr.h:117
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: TDMatTSMatMultExpr.h:197
Header file for the RemoveReference type trait.
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
#define BLAZE_CONSTRAINT_MATRICES_MUST_HAVE_SAME_STORAGE_ORDER(T1, T2)
Constraint on the data type.In case either of the two given data types T1 or T2 is not a matrix type ...
Definition: StorageOrder.h:283
Header file for the IsDenseVector type trait.
Header file for all intrinsic functionality.
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side sparse matrix operand.
Definition: TDMatTSMatMultExpr.h:214
TDMatTSMatMultExpr< MT1, MT2 > This
Type of this TDMatTSMatMultExpr instance.
Definition: TDMatTSMatMultExpr.h:195
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: TDMatTSMatMultExpr.h:115
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side dense matrix operand.
Definition: TDMatTSMatMultExpr.h:211
Header file for the IsComputation type trait class.
Header file for the TDMatDVecMultExprTrait class template.
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: TDMatTSMatMultExpr.h:351
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2379
size_t columns(const Matrix< MT, SO > &m)
Returns the current number of columns of the matrix.
Definition: Matrix.h:154
Header file for basic type definitions.
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: TDMatTSMatMultExpr.h:208
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: TDMatTSMatMultExpr.h:379
Header file for the IsColumnVector type trait.
Header file for the IsResizable type trait.
Size type of the Blaze library.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
size_t rows(const Matrix< MT, SO > &m)
Returns the current number of rows of the matrix.
Definition: Matrix.h:138
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the TDVecTDMatMultExprTrait class template.
EnableIf< IsIntegral< T >, Set< T, sizeof(T)> >::Type::Type set(T value)
Sets all values in the vector to the given integral value.
Definition: Set.h:209
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
void store(float *address, const sse_float_t &value)
Aligned store of a vector of &#39;float&#39; values.
Definition: Store.h:242
Header file for the IsExpression type trait class.
Header file for the TSMatSVecMultExprTrait class template.
Header file for the FunctionTrace class.
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: TDMatTSMatMultExpr.h:196
size_t columns() const
Returns the current number of columns of the matrix.
Definition: TDMatTSMatMultExpr.h:307