DenseMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SMP_THREADS_DENSEMATRIX_H_
36 #define _BLAZE_MATH_SMP_THREADS_DENSEMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
47 #include <blaze/math/Functions.h>
59 #include <blaze/system/SMP.h>
60 #include <blaze/util/Assert.h>
61 #include <blaze/util/EnableIf.h>
63 #include <blaze/util/mpl/And.h>
64 #include <blaze/util/mpl/Not.h>
65 #include <blaze/util/mpl/Or.h>
67 #include <blaze/util/Types.h>
69 
70 
71 namespace blaze {
72 
73 //=================================================================================================
74 //
75 // PLAIN ASSIGNMENT
76 //
77 //=================================================================================================
78 
79 //*************************************************************************************************
95 template< typename MT1 // Type of the left-hand side dense matrix
96  , bool SO1 // Storage order of the left-hand side dense matrix
97  , typename MT2 // Type of the right-hand side dense matrix
98  , bool SO2 > // Storage order of the right-hand side dense matrix
99 void smpAssign_backend( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
100 {
102 
103  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
104 
105  typedef ElementType_<MT1> ET1;
106  typedef ElementType_<MT2> ET2;
107  typedef SubmatrixExprTrait_<MT1,aligned> AlignedTarget;
108  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
109 
110  enum : size_t { SIMDSIZE = SIMDTrait< ElementType_<MT1> >::size };
111 
112  const bool simdEnabled( MT1::simdEnabled && MT2::simdEnabled && IsSame<ET1,ET2>::value );
113  const bool lhsAligned ( (~lhs).isAligned() );
114  const bool rhsAligned ( (~rhs).isAligned() );
115 
116  const ThreadMapping threads( createThreadMapping( TheThreadBackend::size(), ~rhs ) );
117 
118  const size_t addon1 ( ( ( (~rhs).rows() % threads.first ) != 0UL )? 1UL : 0UL );
119  const size_t equalShare1( (~rhs).rows() / threads.first + addon1 );
120  const size_t rest1 ( equalShare1 & ( SIMDSIZE - 1UL ) );
121  const size_t rowsPerThread( ( simdEnabled && rest1 )?( equalShare1 - rest1 + SIMDSIZE ):( equalShare1 ) );
122 
123  const size_t addon2 ( ( ( (~rhs).columns() % threads.second ) != 0UL )? 1UL : 0UL );
124  const size_t equalShare2( (~rhs).columns() / threads.second + addon2 );
125  const size_t rest2 ( equalShare2 & ( SIMDSIZE - 1UL ) );
126  const size_t colsPerThread( ( simdEnabled && rest2 )?( equalShare2 - rest2 + SIMDSIZE ):( equalShare2 ) );
127 
128  for( size_t i=0UL; i<threads.first; ++i )
129  {
130  const size_t row( i*rowsPerThread );
131 
132  if( row >= (~lhs).rows() )
133  continue;
134 
135  for( size_t j=0UL; j<threads.second; ++j )
136  {
137  const size_t column( j*colsPerThread );
138 
139  if( column >= (~rhs).columns() )
140  continue;
141 
142  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
143  const size_t n( min( colsPerThread, (~rhs).columns() - column ) );
144 
145  if( simdEnabled && lhsAligned && rhsAligned ) {
146  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
147  TheThreadBackend::scheduleAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
148  }
149  else if( simdEnabled && lhsAligned ) {
150  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
151  TheThreadBackend::scheduleAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
152  }
153  else if( simdEnabled && rhsAligned ) {
154  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
155  TheThreadBackend::scheduleAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
156  }
157  else {
158  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
159  TheThreadBackend::scheduleAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
160  }
161  }
162  }
163 
164  TheThreadBackend::wait();
165 }
167 //*************************************************************************************************
168 
169 
170 //*************************************************************************************************
187 template< typename MT1 // Type of the left-hand side dense matrix
188  , bool SO1 // Storage order of the left-hand side dense matrix
189  , typename MT2 // Type of the right-hand side sparse matrix
190  , bool SO2 > // Storage order of the right-hand side sparse matrix
191 void smpAssign_backend( DenseMatrix<MT1,SO1>& lhs, const SparseMatrix<MT2,SO2>& rhs )
192 {
194 
195  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
196 
197  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
198 
199  const ThreadMapping threads( createThreadMapping( TheThreadBackend::size(), ~rhs ) );
200 
201  const size_t addon1 ( ( ( (~rhs).rows() % threads.first ) != 0UL )? 1UL : 0UL );
202  const size_t rowsPerThread( (~rhs).rows() / threads.first + addon1 );
203 
204  const size_t addon2 ( ( ( (~rhs).columns() % threads.second ) != 0UL )? 1UL : 0UL );
205  const size_t colsPerThread( (~rhs).columns() / threads.second + addon2 );
206 
207  for( size_t i=0UL; i<threads.first; ++i )
208  {
209  const size_t row( i*rowsPerThread );
210 
211  if( row >= (~lhs).rows() )
212  continue;
213 
214  for( size_t j=0UL; j<threads.second; ++j )
215  {
216  const size_t column( j*colsPerThread );
217 
218  if( column >= (~lhs).columns() )
219  continue;
220 
221  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
222  const size_t n( min( colsPerThread, (~lhs).columns() - column ) );
223 
224  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
225  TheThreadBackend::scheduleAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
226  }
227  }
228 
229  TheThreadBackend::wait();
230 }
232 //*************************************************************************************************
233 
234 
235 //*************************************************************************************************
253 template< typename MT1 // Type of the left-hand side dense matrix
254  , bool SO1 // Storage order of the left-hand side dense matrix
255  , typename MT2 // Type of the right-hand side matrix
256  , bool SO2 > // Storage order of the right-hand side matrix
257 inline EnableIf_< And< IsDenseMatrix<MT1>
258  , Or< Not< IsSMPAssignable<MT1> >
259  , Not< IsSMPAssignable<MT2> > > > >
260  smpAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
261 {
263 
264  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
265  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
266 
267  assign( ~lhs, ~rhs );
268 }
270 //*************************************************************************************************
271 
272 
273 //*************************************************************************************************
291 template< typename MT1 // Type of the left-hand side dense matrix
292  , bool SO1 // Storage order of the left-hand side dense matrix
293  , typename MT2 // Type of the right-hand side matrix
294  , bool SO2 > // Storage order of the right-hand side matrix
295 inline EnableIf_< And< IsDenseMatrix<MT1>, IsSMPAssignable<MT1>, IsSMPAssignable<MT2> > >
296  smpAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
297 {
299 
300  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT1> );
301  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT2> );
302 
303  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
304  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
305 
307  {
308  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
309  assign( ~lhs, ~rhs );
310  }
311  else {
312  smpAssign_backend( ~lhs, ~rhs );
313  }
314  }
315 }
317 //*************************************************************************************************
318 
319 
320 
321 
322 //=================================================================================================
323 //
324 // ADDITION ASSIGNMENT
325 //
326 //=================================================================================================
327 
328 //*************************************************************************************************
345 template< typename MT1 // Type of the left-hand side dense matrix
346  , bool SO1 // Storage order of the left-hand side dense matrix
347  , typename MT2 // Type of the right-hand side dense matrix
348  , bool SO2 > // Storage order fo the right-hand side dense matrix
349 void smpAddAssign_backend( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
350 {
352 
353  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
354 
355  typedef ElementType_<MT1> ET1;
356  typedef ElementType_<MT2> ET2;
357  typedef SubmatrixExprTrait_<MT1,aligned> AlignedTarget;
358  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
359 
360  enum : size_t { SIMDSIZE = SIMDTrait< ElementType_<MT1> >::size };
361 
362  const bool simdEnabled( MT1::simdEnabled && MT2::simdEnabled && IsSame<ET1,ET2>::value );
363  const bool lhsAligned ( (~lhs).isAligned() );
364  const bool rhsAligned ( (~rhs).isAligned() );
365 
366  const ThreadMapping threads( createThreadMapping( TheThreadBackend::size(), ~rhs ) );
367 
368  const size_t addon1 ( ( ( (~rhs).rows() % threads.first ) != 0UL )? 1UL : 0UL );
369  const size_t equalShare1( (~rhs).rows() / threads.first + addon1 );
370  const size_t rest1 ( equalShare1 & ( SIMDSIZE - 1UL ) );
371  const size_t rowsPerThread( ( simdEnabled && rest1 )?( equalShare1 - rest1 + SIMDSIZE ):( equalShare1 ) );
372 
373  const size_t addon2 ( ( ( (~rhs).columns() % threads.second ) != 0UL )? 1UL : 0UL );
374  const size_t equalShare2( (~rhs).columns() / threads.second + addon2 );
375  const size_t rest2 ( equalShare2 & ( SIMDSIZE - 1UL ) );
376  const size_t colsPerThread( ( simdEnabled && rest2 )?( equalShare2 - rest2 + SIMDSIZE ):( equalShare2 ) );
377 
378  for( size_t i=0UL; i<threads.first; ++i )
379  {
380  const size_t row( i*rowsPerThread );
381 
382  if( row >= (~lhs).rows() )
383  continue;
384 
385  for( size_t j=0UL; j<threads.second; ++j )
386  {
387  const size_t column( j*colsPerThread );
388 
389  if( column >= (~rhs).columns() )
390  continue;
391 
392  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
393  const size_t n( min( colsPerThread, (~rhs).columns() - column ) );
394 
395  if( simdEnabled && lhsAligned && rhsAligned ) {
396  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
397  TheThreadBackend::scheduleAddAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
398  }
399  else if( simdEnabled && lhsAligned ) {
400  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
401  TheThreadBackend::scheduleAddAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
402  }
403  else if( simdEnabled && rhsAligned ) {
404  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
405  TheThreadBackend::scheduleAddAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
406  }
407  else {
408  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
409  TheThreadBackend::scheduleAddAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
410  }
411  }
412  }
413 
414  TheThreadBackend::wait();
415 }
417 //*************************************************************************************************
418 
419 
420 //*************************************************************************************************
437 template< typename MT1 // Type of the left-hand side dense matrix
438  , bool SO1 // Storage order of the left-hand side dense matrix
439  , typename MT2 // Type of the right-hand side sparse matrix
440  , bool SO2 > // Storage order of the right-hand side sparse matrix
441 void smpAddAssign_backend( DenseMatrix<MT1,SO1>& lhs, const SparseMatrix<MT2,SO2>& rhs )
442 {
444 
445  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
446 
447  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
448 
449  const ThreadMapping threads( createThreadMapping( TheThreadBackend::size(), ~rhs ) );
450 
451  const size_t addon1 ( ( ( (~rhs).rows() % threads.first ) != 0UL )? 1UL : 0UL );
452  const size_t rowsPerThread( (~rhs).rows() / threads.first + addon1 );
453 
454  const size_t addon2 ( ( ( (~rhs).columns() % threads.second ) != 0UL )? 1UL : 0UL );
455  const size_t colsPerThread( (~rhs).columns() / threads.second + addon2 );
456 
457  for( size_t i=0UL; i<threads.first; ++i )
458  {
459  const size_t row( i*rowsPerThread );
460 
461  if( row >= (~lhs).rows() )
462  continue;
463 
464  for( size_t j=0UL; j<threads.second; ++j )
465  {
466  const size_t column( j*colsPerThread );
467 
468  if( column >= (~lhs).columns() )
469  continue;
470 
471  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
472  const size_t n( min( colsPerThread, (~lhs).columns() - column ) );
473 
474  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
475  TheThreadBackend::scheduleAddAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
476  }
477  }
478 
479  TheThreadBackend::wait();
480 }
482 //*************************************************************************************************
483 
484 
485 //*************************************************************************************************
504 template< typename MT1 // Type of the left-hand side dense matrix
505  , bool SO1 // Storage order of the left-hand side dense matrix
506  , typename MT2 // Type of the right-hand side matrix
507  , bool SO2 > // Storage order of the right-hand side matrix
508 inline EnableIf_< And< IsDenseMatrix<MT1>
509  , Or< Not< IsSMPAssignable<MT1> >
510  , Not< IsSMPAssignable<MT2> > > > >
511  smpAddAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
512 {
514 
515  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
516  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
517 
518  addAssign( ~lhs, ~rhs );
519 }
521 //*************************************************************************************************
522 
523 
524 //*************************************************************************************************
542 template< typename MT1 // Type of the left-hand side dense matrix
543  , bool SO1 // Storage order of the left-hand side dense matrix
544  , typename MT2 // Type of the right-hand side matrix
545  , bool SO2 > // Storage order of the right-hand side matrix
546 inline EnableIf_< And< IsDenseMatrix<MT1>, IsSMPAssignable<MT1>, IsSMPAssignable<MT2> > >
547  smpAddAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
548 {
550 
551  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT1> );
552  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT2> );
553 
554  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
555  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
556 
558  {
559  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
560  addAssign( ~lhs, ~rhs );
561  }
562  else {
563  smpAddAssign_backend( ~lhs, ~rhs );
564  }
565  }
566 }
568 //*************************************************************************************************
569 
570 
571 
572 
573 //=================================================================================================
574 //
575 // SUBTRACTION ASSIGNMENT
576 //
577 //=================================================================================================
578 
579 //*************************************************************************************************
596 template< typename MT1 // Type of the left-hand side dense matrix
597  , bool SO1 // Storage order of the left-hand side dense matrix
598  , typename MT2 // Type of the right-hand side dense matrix
599  , bool SO2 > // Storage order of the right-hand side dense matrix
600 void smpSubAssign_backend( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
601 {
603 
604  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
605 
606  typedef ElementType_<MT1> ET1;
607  typedef ElementType_<MT2> ET2;
608  typedef SubmatrixExprTrait_<MT1,aligned> AlignedTarget;
609  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
610 
611  enum : size_t { SIMDSIZE = SIMDTrait< ElementType_<MT1> >::size };
612 
613  const bool simdEnabled( MT1::simdEnabled && MT2::simdEnabled && IsSame<ET1,ET2>::value );
614  const bool lhsAligned ( (~lhs).isAligned() );
615  const bool rhsAligned ( (~rhs).isAligned() );
616 
617  const ThreadMapping threads( createThreadMapping( TheThreadBackend::size(), ~rhs ) );
618 
619  const size_t addon1 ( ( ( (~rhs).rows() % threads.first ) != 0UL )? 1UL : 0UL );
620  const size_t equalShare1( (~rhs).rows() / threads.first + addon1 );
621  const size_t rest1 ( equalShare1 & ( SIMDSIZE - 1UL ) );
622  const size_t rowsPerThread( ( simdEnabled && rest1 )?( equalShare1 - rest1 + SIMDSIZE ):( equalShare1 ) );
623 
624  const size_t addon2 ( ( ( (~rhs).columns() % threads.second ) != 0UL )? 1UL : 0UL );
625  const size_t equalShare2( (~rhs).columns() / threads.second + addon2 );
626  const size_t rest2 ( equalShare2 & ( SIMDSIZE - 1UL ) );
627  const size_t colsPerThread( ( simdEnabled && rest2 )?( equalShare2 - rest2 + SIMDSIZE ):( equalShare2 ) );
628 
629  for( size_t i=0UL; i<threads.first; ++i )
630  {
631  const size_t row( i*rowsPerThread );
632 
633  if( row >= (~lhs).rows() )
634  continue;
635 
636  for( size_t j=0UL; j<threads.second; ++j )
637  {
638  const size_t column( j*colsPerThread );
639 
640  if( column >= (~rhs).columns() )
641  continue;
642 
643  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
644  const size_t n( min( colsPerThread, (~rhs).columns() - column ) );
645 
646  if( simdEnabled && lhsAligned && rhsAligned ) {
647  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
648  TheThreadBackend::scheduleSubAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
649  }
650  else if( simdEnabled && lhsAligned ) {
651  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
652  TheThreadBackend::scheduleSubAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
653  }
654  else if( simdEnabled && rhsAligned ) {
655  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
656  TheThreadBackend::scheduleSubAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
657  }
658  else {
659  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
660  TheThreadBackend::scheduleSubAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
661  }
662  }
663  }
664 
665  TheThreadBackend::wait();
666 }
668 //*************************************************************************************************
669 
670 
671 //*************************************************************************************************
688 template< typename MT1 // Type of the left-hand side dense matrix
689  , bool SO1 // Storage order of the left-hand side dense matrix
690  , typename MT2 // Type of the right-hand side sparse matrix
691  , bool SO2 > // Storage order of the right-hand side sparse matrix
692 void smpSubAssign_backend( DenseMatrix<MT1,SO1>& lhs, const SparseMatrix<MT2,SO2>& rhs )
693 {
695 
696  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
697 
698  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
699 
700  const ThreadMapping threads( createThreadMapping( TheThreadBackend::size(), ~rhs ) );
701 
702  const size_t addon1 ( ( ( (~rhs).rows() % threads.first ) != 0UL )? 1UL : 0UL );
703  const size_t rowsPerThread( (~rhs).rows() / threads.first + addon1 );
704 
705  const size_t addon2 ( ( ( (~rhs).columns() % threads.second ) != 0UL )? 1UL : 0UL );
706  const size_t colsPerThread( (~rhs).columns() / threads.second + addon2 );
707 
708  for( size_t i=0UL; i<threads.first; ++i )
709  {
710  const size_t row( i*rowsPerThread );
711 
712  if( row >= (~lhs).rows() )
713  continue;
714 
715  for( size_t j=0UL; j<threads.second; ++j )
716  {
717  const size_t column( j*colsPerThread );
718 
719  if( column >= (~lhs).columns() )
720  continue;
721 
722  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
723  const size_t n( min( colsPerThread, (~lhs).columns() - column ) );
724 
725  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
726  TheThreadBackend::scheduleSubAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
727  }
728  }
729 
730  TheThreadBackend::wait();
731 }
733 //*************************************************************************************************
734 
735 
736 //*************************************************************************************************
755 template< typename MT1 // Type of the left-hand side dense matrix
756  , bool SO1 // Storage order of the left-hand side dense matrix
757  , typename MT2 // Type of the right-hand side matrix
758  , bool SO2 > // Storage order of the right-hand side matrix
759 inline EnableIf_< And< IsDenseMatrix<MT1>
760  , Or< Not< IsSMPAssignable<MT1> >
761  , Not< IsSMPAssignable<MT2> > > > >
762  smpSubAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
763 {
765 
766  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
767  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
768 
769  subAssign( ~lhs, ~rhs );
770 }
772 //*************************************************************************************************
773 
774 
775 //*************************************************************************************************
794 template< typename MT1 // Type of the left-hand side dense matrix
795  , bool SO1 // Storage order of the left-hand side dense matrix
796  , typename MT2 // Type of the right-hand side matrix
797  , bool SO2 > // Storage order of the right-hand side matrix
798 inline EnableIf_< And< IsDenseMatrix<MT1>, IsSMPAssignable<MT1>, IsSMPAssignable<MT2> > >
799  smpSubAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
800 {
802 
803  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT1> );
804  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT2> );
805 
806  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
807  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
808 
810  {
811  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
812  subAssign( ~lhs, ~rhs );
813  }
814  else {
815  smpSubAssign_backend( ~lhs, ~rhs );
816  }
817  }
818 }
820 //*************************************************************************************************
821 
822 
823 
824 
825 //=================================================================================================
826 //
827 // MULTIPLICATION ASSIGNMENT
828 //
829 //=================================================================================================
830 
831 //*************************************************************************************************
848 template< typename MT1 // Type of the left-hand side dense matrix
849  , bool SO1 // Storage order of the left-hand side matrix
850  , typename MT2 // Type of the right-hand side matrix
851  , bool SO2 > // Storage order of the right-hand side matrix
852 inline EnableIf_< IsDenseMatrix<MT1> >
853  smpMultAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
854 {
856 
857  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
858  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
859 
860  multAssign( ~lhs, ~rhs );
861 }
863 //*************************************************************************************************
864 
865 
866 
867 
868 //=================================================================================================
869 //
870 // COMPILE TIME CONSTRAINT
871 //
872 //=================================================================================================
873 
874 //*************************************************************************************************
876 namespace {
877 
879 
880 }
882 //*************************************************************************************************
883 
884 } // namespace blaze
885 
886 #endif
Header file for the implementation of the Submatrix view.
Header file for auxiliary alias declarations.
Header file for mathematical functions.
Header file for basic type definitions.
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:258
#define BLAZE_BOOST_THREADS_PARALLEL_MODE
Compilation switch for the Boost parallelization.This compilation switch enables/disables the paralle...
Definition: SMP.h:122
Header file for the IsSame and IsStrictlySame type traits.
EnableIf_< IsDenseVector< VT1 > > smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:193
Header file for the And class template.
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1669
Header file for the SIMD trait.
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< 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:129
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT > >, ColumnExprTrait_< MT > > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:126
Header file for the SparseMatrix base class.
Header file for the SMP thread mapping functionality.
Header file for the matrix storage order types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE(T)
Constraint on the data type.In case the given data type T is SMP-assignable (can be assigned by multi...
Definition: SMPAssignable.h:81
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Compile time assertion.
System settings for the shared-memory parallelization.
Header file for the IsSMPAssignable type trait.
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
Header file for the Or class template.
Header file for the DenseMatrix base class.
Header file for the Not class template.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:330
Header file for the serial section implementation.
#define BLAZE_CPP_THREADS_PARALLEL_MODE
Compilation switch for the C++11 parallelization.This compilation switch enables/disables the paralle...
Definition: SMP.h:95
Header file for the parallel section implementation.
Header file for the IsDenseMatrix type trait.
Header file for the EnableIf class template.
#define BLAZE_PARALLEL_SECTION
Section for the debugging of the shared-memory parallelization.During the shared-memory parallel (SMP...
Definition: ParallelSection.h:246
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT > >, RowExprTrait_< MT > > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:126
bool isSerialSectionActive()
Returns whether a serial section is active or not.
Definition: SerialSection.h:213
Header file for the SubmatrixExprTrait class template.
Header file for run time assertion macros.
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:314
Header file for the AreSIMDCombinable type trait.
bool isParallelSectionActive()
Returns whether a parallel section is active or not.
Definition: ParallelSection.h:213
#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
Header file for the C++11 and Boost thread backend.
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:112
#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
Constraint on the data type.
Header file for the FunctionTrace class.