All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DMatSMatMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATSMATMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DMATSMATMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
52 #include <blaze/math/shims/Reset.h>
78 #include <blaze/util/Assert.h>
80 #include <blaze/util/DisableIf.h>
81 #include <blaze/util/EnableIf.h>
82 #include <blaze/util/InvalidType.h>
84 #include <blaze/util/SelectType.h>
85 #include <blaze/util/Types.h>
86 
87 
88 namespace blaze {
89 
90 //=================================================================================================
91 //
92 // CLASS DMATSMATMULTEXPR
93 //
94 //=================================================================================================
95 
96 //*************************************************************************************************
103 template< typename MT1 // Type of the left-hand side dense matrix
104  , typename MT2 > // Type of the right-hand side sparse matrix
105 class DMatSMatMultExpr : public DenseMatrix< DMatSMatMultExpr<MT1,MT2>, false >
106  , private MatMatMultExpr
107  , private Computation
108 {
109  private:
110  //**Type definitions****************************************************************************
111  typedef typename MT1::ResultType RT1;
112  typedef typename MT2::ResultType RT2;
113  typedef typename RT1::ElementType ET1;
114  typedef typename RT2::ElementType ET2;
115  typedef typename MT1::CompositeType CT1;
116  typedef typename MT2::CompositeType CT2;
117  //**********************************************************************************************
118 
119  //**********************************************************************************************
122  //**********************************************************************************************
123 
124  //**********************************************************************************************
126  enum { evaluateRight = IsComputation<MT2>::value || RequiresEvaluation<MT2>::value };
127  //**********************************************************************************************
128 
129  //**********************************************************************************************
131 
134  template< typename T1, typename T2, typename T3 >
135  struct UseSMPAssignKernel {
136  enum { value = evaluateLeft || evaluateRight };
137  };
139  //**********************************************************************************************
140 
141  //**********************************************************************************************
143 
147  template< typename T1, typename T2, typename T3 >
148  struct UseOptimizedKernel {
149  enum { value = !UseSMPAssignKernel<T1,T2,T3>::value &&
150  !IsResizable<typename T1::ElementType>::value };
151  };
153  //**********************************************************************************************
154 
155  //**********************************************************************************************
157 
160  template< typename T1, typename T2, typename T3 >
161  struct UseDefaultKernel {
162  enum { value = !UseSMPAssignKernel<T1,T2,T3>::value &&
163  !UseOptimizedKernel<T1,T2,T3>::value };
164  };
166  //**********************************************************************************************
167 
168  public:
169  //**Type definitions****************************************************************************
175  typedef const ElementType ReturnType;
176  typedef const ResultType CompositeType;
177 
179  typedef typename SelectType< IsExpression<MT1>::value, const MT1, const MT1& >::Type LeftOperand;
180 
182  typedef typename SelectType< IsExpression<MT2>::value, const MT2, const MT2& >::Type RightOperand;
183 
186 
189  //**********************************************************************************************
190 
191  //**Compilation flags***************************************************************************
193  enum { vectorizable = 0 };
194 
196  enum { smpAssignable = !evaluateLeft && !evaluateRight };
197  //**********************************************************************************************
198 
199  //**Constructor*********************************************************************************
205  explicit inline DMatSMatMultExpr( const MT1& lhs, const MT2& rhs )
206  : lhs_( lhs ) // Left-hand side dense matrix of the multiplication expression
207  , rhs_( rhs ) // Right-hand side sparse matrix of the multiplication expression
208  {
209  BLAZE_INTERNAL_ASSERT( lhs.columns() == rhs.rows(), "Invalid matrix sizes" );
210  }
211  //**********************************************************************************************
212 
213  //**Access operator*****************************************************************************
220  inline ReturnType operator()( size_t i, size_t j ) const {
221  BLAZE_INTERNAL_ASSERT( i < lhs_.rows() , "Invalid row access index" );
222  BLAZE_INTERNAL_ASSERT( j < rhs_.columns(), "Invalid column access index" );
223 
224  ElementType tmp;
225 
226  if( lhs_.columns() != 0UL ) {
227  tmp = lhs_(i,0UL) * rhs_(0UL,j);
228  for( size_t k=1UL; k<lhs_.columns(); ++k ) {
229  tmp += lhs_(i,k) * rhs_(k,j);
230  }
231  }
232  else {
233  reset( tmp );
234  }
235 
236  return tmp;
237  }
238  //**********************************************************************************************
239 
240  //**Rows function*******************************************************************************
245  inline size_t rows() const {
246  return lhs_.rows();
247  }
248  //**********************************************************************************************
249 
250  //**Columns function****************************************************************************
255  inline size_t columns() const {
256  return rhs_.columns();
257  }
258  //**********************************************************************************************
259 
260  //**Left operand access*************************************************************************
265  inline LeftOperand leftOperand() const {
266  return lhs_;
267  }
268  //**********************************************************************************************
269 
270  //**Right operand access************************************************************************
275  inline RightOperand rightOperand() const {
276  return rhs_;
277  }
278  //**********************************************************************************************
279 
280  //**********************************************************************************************
286  template< typename T >
287  inline bool canAlias( const T* alias ) const {
288  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
289  }
290  //**********************************************************************************************
291 
292  //**********************************************************************************************
298  template< typename T >
299  inline bool isAliased( const T* alias ) const {
300  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
301  }
302  //**********************************************************************************************
303 
304  //**********************************************************************************************
309  inline bool isAligned() const {
310  return lhs_.isAligned();
311  }
312  //**********************************************************************************************
313 
314  //**********************************************************************************************
319  inline bool canSMPAssign() const {
320  return ( rows() > SMP_DMATSMATMULT_THRESHOLD );
321  }
322  //**********************************************************************************************
323 
324  private:
325  //**Member variables****************************************************************************
328  //**********************************************************************************************
329 
330  //**Assignment to row-major dense matrices******************************************************
343  template< typename MT > // Type of the target dense matrix
344  friend inline void assign( DenseMatrix<MT,false>& lhs, const DMatSMatMultExpr& rhs )
345  {
347 
348  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
349  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
350 
351  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
352  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
353 
354  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
355  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
356  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
357  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
358  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
359  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
360 
361  DMatSMatMultExpr::selectRowMajorAssignKernel( ~lhs, A, B );
362  }
364  //**********************************************************************************************
365 
366  //**Default assignment to row-major dense matrices**********************************************
380  template< typename MT3 // Type of the left-hand side target matrix
381  , typename MT4 // Type of the left-hand side matrix operand
382  , typename MT5 > // Type of the right-hand side matrix operand
383  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
384  selectRowMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
385  {
386  typedef typename MT5::ConstIterator ConstIterator;
387 
388  for( size_t i=0UL; i<A.rows(); ++i ) {
389  for( size_t j=0UL; j<C.columns(); ++j ) {
390  reset( C(i,j) );
391  }
392  for( size_t j=0UL; j<B.rows(); ++j ) {
393  ConstIterator element( B.begin(j) );
394  const ConstIterator end( B.end(j) );
395  for( ; element!=end; ++element ) {
396  if( isDefault( C(i,element->index()) ) )
397  C(i,element->index()) = A(i,j) * element->value();
398  else
399  C(i,element->index()) += A(i,j) * element->value();
400  }
401  }
402  }
403  }
405  //**********************************************************************************************
406 
407  //**Optimized assignment to row-major dense matrices********************************************
421  template< typename MT3 // Type of the left-hand side target matrix
422  , typename MT4 // Type of the left-hand side matrix operand
423  , typename MT5 > // Type of the right-hand side matrix operand
424  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
425  selectRowMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
426  {
427  typedef typename MT5::ConstIterator ConstIterator;
428 
429  BLAZE_INTERNAL_ASSERT( ( A.rows() - ( A.rows() % 4UL ) ) == ( A.rows() & size_t(-4) ), "Invalid end calculation" );
430  const size_t last( A.rows() & size_t(-4) );
431 
432  for( size_t i=0UL; i<last; i+=4UL ) {
433  for( size_t j=0UL; j<C.columns(); ++j ) {
434  reset( C(i ,j) );
435  reset( C(i+1UL,j) );
436  reset( C(i+2UL,j) );
437  reset( C(i+3UL,j) );
438  }
439  for( size_t j=0UL; j<B.rows(); ++j ) {
440  ConstIterator element( B.begin(j) );
441  const ConstIterator end( B.end(j) );
442  for( ; element!=end; ++element ) {
443  C(i ,element->index()) += A(i ,j) * element->value();
444  C(i+1UL,element->index()) += A(i+1UL,j) * element->value();
445  C(i+2UL,element->index()) += A(i+2UL,j) * element->value();
446  C(i+3UL,element->index()) += A(i+3UL,j) * element->value();
447  }
448  }
449  }
450 
451  for( size_t i=last; i<A.rows(); ++i ) {
452  for( size_t j=0UL; j<C.columns(); ++j ) {
453  reset( C(i,j) );
454  }
455  for( size_t j=0UL; j<B.rows(); ++j ) {
456  ConstIterator element( B.begin(j) );
457  const ConstIterator end( B.end(j) );
458  for( ; element!=end; ++element ) {
459  C(i,element->index()) += A(i,j) * element->value();
460  }
461  }
462  }
463  }
465  //**********************************************************************************************
466 
467  //**SMP assignment to row-major dense matrices**************************************************
480  template< typename MT3 // Type of the left-hand side target matrix
481  , typename MT4 // Type of the left-hand side matrix operand
482  , typename MT5 > // Type of the right-hand side matrix operand
483  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
484  selectRowMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
485  {
486  smpAssign( C, A * B );
487  }
489  //**********************************************************************************************
490 
491  //**Assignment to column-major dense matrices***************************************************
504  template< typename MT > // Type of the target dense matrix
505  friend inline void assign( DenseMatrix<MT,true>& lhs, const DMatSMatMultExpr& rhs )
506  {
508 
509  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
510  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
511 
512  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
513  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
514 
515  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
516  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
517  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
518  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
519  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
520  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
521 
522  DMatSMatMultExpr::selectColumnMajorAssignKernel( ~lhs, A, B );
523  }
525  //**********************************************************************************************
526 
527  //**Default assignment to column-major dense matrices*******************************************
541  template< typename MT3 // Type of the left-hand side target matrix
542  , typename MT4 // Type of the left-hand side matrix operand
543  , typename MT5 > // Type of the right-hand side matrix operand
544  static inline typename EnableIf< UseDefaultKernel<MT3,MT4,MT5> >::Type
545  selectColumnMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
546  {
547  typedef typename MT5::ConstIterator ConstIterator;
548 
549  reset( C );
550 
551  for( size_t i=0UL; i<B.rows(); ++i ) {
552  for( size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
553  const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
554  ConstIterator element( B.begin(i) );
555  const ConstIterator end( B.end(i) );
556  for( ; element!=end; ++element ) {
557  for( size_t j=jj; j<jend; ++j ) {
558  if( isDefault( C(j,element->index()) ) )
559  C(j,element->index()) = A(j,i) * element->value();
560  else
561  C(j,element->index()) += A(j,i) * element->value();
562  }
563  }
564  }
565  }
566  }
568  //**********************************************************************************************
569 
570  //**Optimized assignment to column-major dense matrices*****************************************
584  template< typename MT3 // Type of the left-hand side target matrix
585  , typename MT4 // Type of the left-hand side matrix operand
586  , typename MT5 > // Type of the right-hand side matrix operand
587  static inline typename EnableIf< UseOptimizedKernel<MT3,MT4,MT5> >::Type
588  selectColumnMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
589  {
590  typedef typename MT5::ConstIterator ConstIterator;
591 
592  reset( C );
593 
594  for( size_t i=0UL; i<B.rows(); ++i ) {
595  for( size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
596  const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
597  ConstIterator element( B.begin(i) );
598  const ConstIterator end( B.end(i) );
599  for( ; element!=end; ++element ) {
600  for( size_t j=jj; j<jend; ++j ) {
601  C(j,element->index()) += A(j,i) * element->value();
602  }
603  }
604  }
605  }
606  }
608  //**********************************************************************************************
609 
610  //**SMP 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< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
627  selectColumnMajorAssignKernel( MT3& C, const MT4& A, const MT5& B )
628  {
629  smpAssign( C, A * B );
630  }
632  //**********************************************************************************************
633 
634  //**Assignment to sparse matrices***************************************************************
647  template< typename MT // Type of the target sparse matrix
648  , bool SO > // Storage order of the target sparse matrix
649  friend inline void assign( SparseMatrix<MT,SO>& lhs, const DMatSMatMultExpr& rhs )
650  {
652 
653  typedef typename SelectType< SO, OppositeType, ResultType >::Type TmpType;
654 
661 
662  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
663  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
664 
665  const TmpType tmp( rhs );
666  smpAssign( ~lhs, tmp );
667  }
669  //**********************************************************************************************
670 
671  //**Addition assignment to row-major dense matrices*********************************************
684  template< typename MT > // Type of the target dense matrix
685  friend inline void addAssign( DenseMatrix<MT,false>& lhs, const DMatSMatMultExpr& rhs )
686  {
688 
689  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
690  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
691 
692  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
693  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
694 
695  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
696  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
697  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
698  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
699  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
700  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
701 
702  DMatSMatMultExpr::selectRowMajorAddAssignKernel( ~lhs, A, B );
703  }
705  //**********************************************************************************************
706 
707  //**Optimized addition assignment to row-major dense matrices***********************************
721  template< typename MT3 // Type of the left-hand side target matrix
722  , typename MT4 // Type of the left-hand side matrix operand
723  , typename MT5 > // Type of the right-hand side matrix operand
724  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
725  selectRowMajorAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
726  {
727  typedef typename MT5::ConstIterator ConstIterator;
728 
729  const size_t last( A.rows() & size_t(-4) );
730 
731  for( size_t i=0UL; i<last; i+=4UL ) {
732  for( size_t j=0UL; j<B.rows(); ++j ) {
733  ConstIterator element( B.begin(j) );
734  const ConstIterator end( B.end(j) );
735  for( ; element!=end; ++element ) {
736  C(i ,element->index()) += A(i ,j) * element->value();
737  C(i+1UL,element->index()) += A(i+1UL,j) * element->value();
738  C(i+2UL,element->index()) += A(i+2UL,j) * element->value();
739  C(i+3UL,element->index()) += A(i+3UL,j) * element->value();
740  }
741  }
742  }
743 
744  for( size_t i=last; i<A.rows(); ++i ) {
745  for( size_t j=0UL; j<B.rows(); ++j ) {
746  ConstIterator element( B.begin(j) );
747  const ConstIterator end( B.end(j) );
748  for( ; element!=end; ++element ) {
749  C(i,element->index()) += A(i,j) * element->value();
750  }
751  }
752  }
753  }
755  //**********************************************************************************************
756 
757  //**SMP addition assignment to row-major dense matrices*****************************************
771  template< typename MT3 // Type of the left-hand side target matrix
772  , typename MT4 // Type of the left-hand side matrix operand
773  , typename MT5 > // Type of the right-hand side matrix operand
774  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
775  selectRowMajorAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
776  {
777  smpAddAssign( C, A * B );
778  }
780  //**********************************************************************************************
781 
782  //**Addition assignment to column-major dense matrices******************************************
795  template< typename MT > // Type of the target dense matrix
796  friend inline void addAssign( DenseMatrix<MT,true>& lhs, const DMatSMatMultExpr& rhs )
797  {
799 
800  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
801  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
802 
803  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
804  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
805 
806  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
807  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
808  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
809  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
810  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
811  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
812 
813  DMatSMatMultExpr::selectColumnMajorAddAssignKernel( ~lhs, A, B );
814  }
816  //**********************************************************************************************
817 
818  //**Optimized addition assignment to column-major dense matrices********************************
832  template< typename MT3 // Type of the left-hand side target matrix
833  , typename MT4 // Type of the left-hand side matrix operand
834  , typename MT5 > // Type of the right-hand side matrix operand
835  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
836  selectColumnMajorAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
837  {
838  typedef typename MT5::ConstIterator ConstIterator;
839 
840  for( size_t i=0UL; i<B.rows(); ++i ) {
841  for( size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
842  const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
843  ConstIterator element( B.begin(i) );
844  const ConstIterator end( B.end(i) );
845  for( ; element!=end; ++element ) {
846  for( size_t j=jj; j<jend; ++j ) {
847  C(j,element->index()) += A(j,i) * element->value();
848  }
849  }
850  }
851  }
852  }
854  //**********************************************************************************************
855 
856  //**SMP addition assignment to column-major dense matrices**************************************
870  template< typename MT3 // Type of the left-hand side target matrix
871  , typename MT4 // Type of the left-hand side matrix operand
872  , typename MT5 > // Type of the right-hand side matrix operand
873  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
874  selectColumnMajorAddAssignKernel( MT3& C, const MT4& A, const MT5& B )
875  {
876  smpAddAssign( C, A * B );
877  }
879  //**********************************************************************************************
880 
881  //**Addition assignment to sparse matrices******************************************************
882  // No special implementation for the addition assignment to sparse matrices.
883  //**********************************************************************************************
884 
885  //**Subtraction assignment to row-major dense matrices******************************************
898  template< typename MT > // Type of the target dense matrix
899  friend inline void subAssign( DenseMatrix<MT,false>& lhs, const DMatSMatMultExpr& rhs )
900  {
902 
903  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
904  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
905 
906  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
907  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
908 
909  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
910  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
911  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
912  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
913  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
914  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
915 
916  DMatSMatMultExpr::selectRowMajorSubAssignKernel( ~lhs, A, B );
917  }
919  //**********************************************************************************************
920 
921  //**Optimized subtraction assignment to row-major dense matrices********************************
935  template< typename MT3 // Type of the left-hand side target matrix
936  , typename MT4 // Type of the left-hand side matrix operand
937  , typename MT5 > // Type of the right-hand side matrix operand
938  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
939  selectRowMajorSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
940  {
941  typedef typename MT5::ConstIterator ConstIterator;
942 
943  const size_t last( A.rows() & size_t(-4) );
944 
945  for( size_t i=0UL; i<last; i+=4UL ) {
946  for( size_t j=0UL; j<B.rows(); ++j ) {
947  ConstIterator element( B.begin(j) );
948  const ConstIterator end( B.end(j) );
949  for( ; element!=end; ++element ) {
950  C(i ,element->index()) -= A(i ,j) * element->value();
951  C(i+1UL,element->index()) -= A(i+1UL,j) * element->value();
952  C(i+2UL,element->index()) -= A(i+2UL,j) * element->value();
953  C(i+3UL,element->index()) -= A(i+3UL,j) * element->value();
954  }
955  }
956  }
957 
958  for( size_t i=last; i<A.rows(); ++i ) {
959  for( size_t j=0UL; j<B.rows(); ++j ) {
960  ConstIterator element( B.begin(j) );
961  const ConstIterator end( B.end(j) );
962  for( ; element!=end; ++element ) {
963  C(i,element->index()) -= A(i,j) * element->value();
964  }
965  }
966  }
967  }
969  //**********************************************************************************************
970 
971  //**SMP subtraction assignment to row-major dense matrices**************************************
985  template< typename MT3 // Type of the left-hand side target matrix
986  , typename MT4 // Type of the left-hand side matrix operand
987  , typename MT5 > // Type of the right-hand side matrix operand
988  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
989  selectRowMajorSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
990  {
991  smpSubAssign( C, A * B );
992  }
994  //**********************************************************************************************
995 
996  //**Subtraction assignment to column-major dense matrices***************************************
1009  template< typename MT > // Type of the target dense matrix
1010  friend inline void subAssign( DenseMatrix<MT,true>& lhs, const DMatSMatMultExpr& rhs )
1011  {
1013 
1014  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == rhs.rows() , "Invalid number of rows" );
1015  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == rhs.columns(), "Invalid number of columns" );
1016 
1017  LT A( rhs.lhs_ ); // Evaluation of the left-hand side dense matrix operand
1018  RT B( rhs.rhs_ ); // Evaluation of the right-hand side sparse matrix operand
1019 
1020  BLAZE_INTERNAL_ASSERT( A.rows() == rhs.lhs_.rows() , "Invalid number of rows" );
1021  BLAZE_INTERNAL_ASSERT( A.columns() == rhs.lhs_.columns(), "Invalid number of columns" );
1022  BLAZE_INTERNAL_ASSERT( B.rows() == rhs.rhs_.rows() , "Invalid number of rows" );
1023  BLAZE_INTERNAL_ASSERT( B.columns() == rhs.rhs_.columns(), "Invalid number of columns" );
1024  BLAZE_INTERNAL_ASSERT( A.rows() == (~lhs).rows() , "Invalid number of rows" );
1025  BLAZE_INTERNAL_ASSERT( B.columns() == (~lhs).columns() , "Invalid number of columns" );
1026 
1027  DMatSMatMultExpr::selectColumnMajorSubAssignKernel( ~lhs, A, B );
1028  }
1030  //**********************************************************************************************
1031 
1032  //**Optimized subtraction assignment to column-major dense matrices*****************************
1046  template< typename MT3 // Type of the left-hand side target matrix
1047  , typename MT4 // Type of the left-hand side matrix operand
1048  , typename MT5 > // Type of the right-hand side matrix operand
1049  static inline typename DisableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
1050  selectColumnMajorSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1051  {
1052  typedef typename MT5::ConstIterator ConstIterator;
1053 
1054  for( size_t i=0UL; i<B.rows(); ++i ) {
1055  for( size_t jj=0UL; jj<A.rows(); jj+=8UL ) {
1056  const size_t jend( ( jj+8UL > A.rows() )?( A.rows() ):( jj+8UL ) );
1057  ConstIterator element( B.begin(i) );
1058  const ConstIterator end( B.end(i) );
1059  for( ; element!=end; ++element ) {
1060  for( size_t j=jj; j<jend; ++j ) {
1061  C(j,element->index()) -= A(j,i) * element->value();
1062  }
1063  }
1064  }
1065  }
1066  }
1068  //**********************************************************************************************
1069 
1070  //**SMP subtraction assignment to column-major dense matrices***********************************
1084  template< typename MT3 // Type of the left-hand side target matrix
1085  , typename MT4 // Type of the left-hand side matrix operand
1086  , typename MT5 > // Type of the right-hand side matrix operand
1087  static inline typename EnableIf< UseSMPAssignKernel<MT3,MT4,MT5> >::Type
1088  selectColumnMajorSubAssignKernel( MT3& C, const MT4& A, const MT5& B )
1089  {
1090  smpSubAssign( C, A * B );
1091  }
1093  //**********************************************************************************************
1094 
1095  //**Subtraction assignment to sparse matrices***************************************************
1096  // No special implementation for the subtraction assignment to sparse matrices.
1097  //**********************************************************************************************
1098 
1099  //**Multiplication assignment to dense matrices*************************************************
1100  // No special implementation for the multiplication assignment to dense matrices.
1101  //**********************************************************************************************
1102 
1103  //**Multiplication assignment to sparse matrices************************************************
1104  // No special implementation for the multiplication assignment to sparse matrices.
1105  //**********************************************************************************************
1106 
1107  //**Compile time checks*************************************************************************
1114  //**********************************************************************************************
1115 };
1116 //*************************************************************************************************
1117 
1118 
1119 
1120 
1121 //=================================================================================================
1122 //
1123 // GLOBAL BINARY ARITHMETIC OPERATORS
1124 //
1125 //=================================================================================================
1126 
1127 //*************************************************************************************************
1156 template< typename T1 // Type of the left-hand side dense matrix
1157  , typename T2 > // Type of the right-hand side sparse matrix
1158 inline const DMatSMatMultExpr<T1,T2>
1160 {
1162 
1163  if( (~lhs).columns() != (~rhs).rows() )
1164  throw std::invalid_argument( "Matrix sizes do not match" );
1165 
1166  return DMatSMatMultExpr<T1,T2>( ~lhs, ~rhs );
1167 }
1168 //*************************************************************************************************
1169 
1170 
1171 
1172 
1173 //=================================================================================================
1174 //
1175 // EXPRESSION TRAIT SPECIALIZATIONS
1176 //
1177 //=================================================================================================
1178 
1179 //*************************************************************************************************
1181 template< typename MT1, typename MT2, typename VT >
1182 struct DMatDVecMultExprTrait< DMatSMatMultExpr<MT1,MT2>, VT >
1183 {
1184  public:
1185  //**********************************************************************************************
1186  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1187  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1188  IsDenseVector<VT>::value && IsColumnVector<VT>::value
1189  , typename DMatDVecMultExprTrait< MT1, typename SMatDVecMultExprTrait<MT2,VT>::Type >::Type
1190  , INVALID_TYPE >::Type Type;
1191  //**********************************************************************************************
1192 };
1194 //*************************************************************************************************
1195 
1196 
1197 //*************************************************************************************************
1199 template< typename MT1, typename MT2, typename VT >
1200 struct DMatSVecMultExprTrait< DMatSMatMultExpr<MT1,MT2>, VT >
1201 {
1202  public:
1203  //**********************************************************************************************
1204  typedef typename SelectType< IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1205  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value &&
1206  IsSparseVector<VT>::value && IsColumnVector<VT>::value
1207  , typename DMatSVecMultExprTrait< MT1, typename SMatSVecMultExprTrait<MT2,VT>::Type >::Type
1208  , INVALID_TYPE >::Type Type;
1209  //**********************************************************************************************
1210 };
1212 //*************************************************************************************************
1213 
1214 
1215 //*************************************************************************************************
1217 template< typename VT, typename MT1, typename MT2 >
1218 struct TDVecDMatMultExprTrait< VT, DMatSMatMultExpr<MT1,MT2> >
1219 {
1220  public:
1221  //**********************************************************************************************
1222  typedef typename SelectType< IsDenseVector<VT>::value && IsRowVector<VT>::value &&
1223  IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1224  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1225  , typename TDVecSMatMultExprTrait< typename TDVecDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1226  , INVALID_TYPE >::Type Type;
1227  //**********************************************************************************************
1228 };
1230 //*************************************************************************************************
1231 
1232 
1233 //*************************************************************************************************
1235 template< typename VT, typename MT1, typename MT2 >
1236 struct TSVecDMatMultExprTrait< VT, DMatSMatMultExpr<MT1,MT2> >
1237 {
1238  public:
1239  //**********************************************************************************************
1240  typedef typename SelectType< IsSparseVector<VT>::value && IsRowVector<VT>::value &&
1241  IsDenseMatrix<MT1>::value && IsRowMajorMatrix<MT1>::value &&
1242  IsSparseMatrix<MT2>::value && IsRowMajorMatrix<MT2>::value
1243  , typename TDVecSMatMultExprTrait< typename TDVecDMatMultExprTrait<VT,MT1>::Type, MT2 >::Type
1244  , INVALID_TYPE >::Type Type;
1245  //**********************************************************************************************
1246 };
1248 //*************************************************************************************************
1249 
1250 
1251 //*************************************************************************************************
1253 template< typename MT1, typename MT2, bool AF >
1254 struct SubmatrixExprTrait< DMatSMatMultExpr<MT1,MT2>, AF >
1255 {
1256  public:
1257  //**********************************************************************************************
1258  typedef typename MultExprTrait< typename SubmatrixExprTrait<const MT1,AF>::Type
1259  , typename SubmatrixExprTrait<const MT2,AF>::Type >::Type Type;
1260  //**********************************************************************************************
1261 };
1263 //*************************************************************************************************
1264 
1265 
1266 //*************************************************************************************************
1268 template< typename MT1, typename MT2 >
1269 struct RowExprTrait< DMatSMatMultExpr<MT1,MT2> >
1270 {
1271  public:
1272  //**********************************************************************************************
1273  typedef typename MultExprTrait< typename RowExprTrait<const MT1>::Type, MT2 >::Type Type;
1274  //**********************************************************************************************
1275 };
1277 //*************************************************************************************************
1278 
1279 
1280 //*************************************************************************************************
1282 template< typename MT1, typename MT2 >
1283 struct ColumnExprTrait< DMatSMatMultExpr<MT1,MT2> >
1284 {
1285  public:
1286  //**********************************************************************************************
1287  typedef typename MultExprTrait< MT1, typename ColumnExprTrait<const MT2>::Type >::Type Type;
1288  //**********************************************************************************************
1289 };
1291 //*************************************************************************************************
1292 
1293 } // namespace blaze
1294 
1295 #endif
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: DMatSMatMultExpr.h:173
Compile time check whether the given type is a computational expression template.This type trait clas...
Definition: IsComputation.h:89
const size_t SMP_DMATSMATMULT_THRESHOLD
SMP row-major dense matrix/row-major sparse matrix multiplication threshold.This threshold represents...
Definition: Thresholds.h:485
RightOperand rhs_
Right-hand side sparse matrix of the multiplication expression.
Definition: DMatSMatMultExpr.h:327
Header file for the SMatDVecMultExprTrait class template.
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
const ResultType CompositeType
Data type for composite expression templates.
Definition: DMatSMatMultExpr.h:176
ReturnType operator()(size_t i, size_t j) const
2D-access to the matrix elements.
Definition: DMatSMatMultExpr.h:220
const ElementType ReturnType
Return type for expression template evaluations.
Definition: DMatSMatMultExpr.h:175
SelectType< evaluateRight, const RT2, CT2 >::Type RT
Type for the assignment of the right-hand side sparse matrix operand.
Definition: DMatSMatMultExpr.h:188
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
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 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
size_t columns() const
Returns the current number of columns of the matrix.
Definition: DMatSMatMultExpr.h:255
bool isAligned() const
Returns whether the operands of the expression are properly aligned in memory.
Definition: DMatSMatMultExpr.h:309
MT2::ResultType RT2
Result type of the right-hand side sparse matrix expression.
Definition: DMatSMatMultExpr.h:112
Header file for the TDVecSMatMultExprTrait class template.
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: DMatSMatMultExpr.h:171
Header file for the Computation base class.
Header file for the MatMatMultExpr base class.
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
Constraint on the data type.
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
SelectType< IsExpression< MT2 >::value, const MT2, const MT2 & >::Type RightOperand
Composite type of the right-hand side sparse matrix expression.
Definition: DMatSMatMultExpr.h:182
LeftOperand lhs_
Left-hand side dense matrix of the multiplication expression.
Definition: DMatSMatMultExpr.h:326
size_t rows() const
Returns the current number of rows of the matrix.
Definition: DMatSMatMultExpr.h:245
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.
Header file for the multiplication trait.
MT1::ResultType RT1
Result type of the left-hand side dense matrix expression.
Definition: DMatSMatMultExpr.h:111
#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
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2388
LeftOperand leftOperand() const
Returns the left-hand side dense matrix operand.
Definition: DMatSMatMultExpr.h:265
Header file for the dense matrix SMP implementation.
Header file for the DenseMatrix base class.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DMatSMatMultExpr.h:172
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
Header file for the DMatDVecMultExprTrait class template.
RT2::ElementType ET2
Element type of the right-hand side sparse matrix expression.
Definition: DMatSMatMultExpr.h:114
Header file for the SMatSVecMultExprTrait class template.
#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
bool canSMPAssign() const
Returns whether the expression can be used in SMP assignments.
Definition: DMatSMatMultExpr.h:319
Constraints on the storage order of matrix types.
SelectType< evaluateLeft, const RT1, CT1 >::Type LT
Type for the assignment of the left-hand side dense matrix operand.
Definition: DMatSMatMultExpr.h:185
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.
Header file for the EnableIf class template.
ResultType::ElementType ElementType
Resulting element type.
Definition: DMatSMatMultExpr.h:174
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
MT1::CompositeType CT1
Composite type of the left-hand side dense matrix expression.
Definition: DMatSMatMultExpr.h:115
RT1::ElementType ET1
Element type of the left-hand side dense matrix expression.
Definition: DMatSMatMultExpr.h:113
Base class for all matrix/matrix multiplication expression templates.The MatMatMultExpr class serves ...
Definition: MatMatMultExpr.h:65
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
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: DMatSMatMultExpr.h:287
Header file for run time assertion macros.
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: DMatSMatMultExpr.h:299
Utility type for generic codes.
Base template for the MultTrait class.
Definition: MultTrait.h:141
Expression object for dense matrix-sparse matrix multiplications.The DMatSMatMultExpr class represent...
Definition: DMatSMatMultExpr.h:105
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
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
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.
#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
MT2::CompositeType CT2
Composite type of the right-hand side sparse matrix expression.
Definition: DMatSMatMultExpr.h:116
Header file for the IsDenseVector type trait.
SelectType< IsExpression< MT1 >::value, const MT1, const MT1 & >::Type LeftOperand
Composite type of the left-hand side dense matrix expression.
Definition: DMatSMatMultExpr.h:179
Header file for the IsRowMajorMatrix type trait.
Header file for the IsComputation type trait class.
Base class for all compute expression templates.The Computation class serves as a tag for all computa...
Definition: Computation.h:59
Header file for the TDVecDMatMultExprTrait 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
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
DMatSMatMultExpr(const MT1 &lhs, const MT2 &rhs)
Constructor for the DMatSMatMultExpr class.
Definition: DMatSMatMultExpr.h:205
Header file for basic type definitions.
Header file for the TSVecDMatMultExprTrait class template.
DMatSMatMultExpr< MT1, MT2 > This
Type of this DMatSMatMultExpr instance.
Definition: DMatSMatMultExpr.h:170
Header file for the DMatSVecMultExprTrait class template.
Header file for the IsColumnVector type trait.
Header file for the IsResizable type trait.
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
#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
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
RightOperand rightOperand() const
Returns the right-hand side sparse matrix operand.
Definition: DMatSMatMultExpr.h:275