DenseMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SMP_OPENMP_DENSEMATRIX_H_
36 #define _BLAZE_MATH_SMP_OPENMP_DENSEMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <omp.h>
44 #include <blaze/math/Aliases.h>
49 #include <blaze/math/Functions.h>
60 #include <blaze/system/SMP.h>
61 #include <blaze/util/Assert.h>
62 #include <blaze/util/EnableIf.h>
64 #include <blaze/util/mpl/And.h>
65 #include <blaze/util/mpl/Not.h>
66 #include <blaze/util/mpl/Or.h>
68 #include <blaze/util/Types.h>
70 
71 
72 namespace blaze {
73 
74 //=================================================================================================
75 //
76 // PLAIN ASSIGNMENT
77 //
78 //=================================================================================================
79 
80 //*************************************************************************************************
96 template< typename MT1 // Type of the left-hand side dense matrix
97  , bool SO1 // Storage order of the left-hand side dense matrix
98  , typename MT2 // Type of the right-hand side dense matrix
99  , bool SO2 > // Storage order of the right-hand side dense matrix
100 void smpAssign_backend( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
101 {
103 
104  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
105 
106  typedef ElementType_<MT1> ET1;
107  typedef ElementType_<MT2> ET2;
108  typedef SubmatrixExprTrait_<MT1,aligned> AlignedTarget;
109  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
110 
111  enum : size_t { SIMDSIZE = SIMDTrait< ElementType_<MT1> >::size };
112 
113  const bool simdEnabled( MT1::simdEnabled && MT2::simdEnabled && AreSIMDCombinable<ET1,ET2>::value );
114  const bool lhsAligned ( (~lhs).isAligned() );
115  const bool rhsAligned ( (~rhs).isAligned() );
116 
117  const int threads( omp_get_num_threads() );
118  const ThreadMapping threadmap( createThreadMapping( threads, ~rhs ) );
119 
120  const size_t addon1 ( ( ( (~rhs).rows() % threadmap.first ) != 0UL )? 1UL : 0UL );
121  const size_t equalShare1( (~rhs).rows() / threadmap.first + addon1 );
122  const size_t rest1 ( equalShare1 & ( SIMDSIZE - 1UL ) );
123  const size_t rowsPerThread( ( simdEnabled && rest1 )?( equalShare1 - rest1 + SIMDSIZE ):( equalShare1 ) );
124 
125  const size_t addon2 ( ( ( (~rhs).columns() % threadmap.second ) != 0UL )? 1UL : 0UL );
126  const size_t equalShare2( (~rhs).columns() / threadmap.second + addon2 );
127  const size_t rest2 ( equalShare2 & ( SIMDSIZE - 1UL ) );
128  const size_t colsPerThread( ( simdEnabled && rest2 )?( equalShare2 - rest2 + SIMDSIZE ):( equalShare2 ) );
129 
130 #pragma omp for schedule(dynamic,1) nowait
131  for( int i=0; i<threads; ++i )
132  {
133  const size_t row ( ( i / threadmap.second ) * rowsPerThread );
134  const size_t column( ( i % threadmap.second ) * colsPerThread );
135 
136  if( row >= (~rhs).rows() || column >= (~rhs).columns() )
137  continue;
138 
139  const size_t m( min( rowsPerThread, (~rhs).rows() - row ) );
140  const size_t n( min( colsPerThread, (~rhs).columns() - column ) );
141 
142  if( simdEnabled && lhsAligned && rhsAligned ) {
143  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
144  assign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
145  }
146  else if( simdEnabled && lhsAligned ) {
147  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
148  assign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
149  }
150  else if( simdEnabled && rhsAligned ) {
151  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
152  assign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
153  }
154  else {
155  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
156  assign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
157  }
158  }
159 }
161 //*************************************************************************************************
162 
163 
164 //*************************************************************************************************
180 template< typename MT1 // Type of the left-hand side dense matrix
181  , bool SO1 // Storage order of the left-hand side dense matrix
182  , typename MT2 // Type of the right-hand side sparse matrix
183  , bool SO2 > // Storage order of the right-hand side sparse matrix
184 void smpAssign_backend( DenseMatrix<MT1,SO1>& lhs, const SparseMatrix<MT2,SO2>& rhs )
185 {
187 
188  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
189 
190  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
191 
192  const size_t threads( omp_get_num_threads() );
193  const ThreadMapping threadmap( createThreadMapping( threads, ~rhs ) );
194 
195  const size_t addon1 ( ( ( (~rhs).rows() % threadmap.first ) != 0UL )? 1UL : 0UL );
196  const size_t rowsPerThread( (~rhs).rows() / threadmap.first + addon1 );
197 
198  const size_t addon2 ( ( ( (~rhs).columns() % threadmap.second ) != 0UL )? 1UL : 0UL );
199  const size_t colsPerThread( (~rhs).columns() / threadmap.second + addon2 );
200 
201 #pragma omp for schedule(dynamic,1) nowait
202  for( int i=0; i<threads; ++i )
203  {
204  const size_t row ( ( i / threadmap.second ) * rowsPerThread );
205  const size_t column( ( i % threadmap.second ) * colsPerThread );
206 
207  if( row >= (~rhs).rows() || column >= (~rhs).columns() )
208  continue;
209 
210  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
211  const size_t n( min( colsPerThread, (~lhs).columns() - column ) );
212 
213  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
214  assign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
215  }
216 }
218 //*************************************************************************************************
219 
220 
221 //*************************************************************************************************
239 template< typename MT1 // Type of the left-hand side dense matrix
240  , bool SO1 // Storage order of the left-hand side dense matrix
241  , typename MT2 // Type of the right-hand side matrix
242  , bool SO2 > // Storage order of the right-hand side matrix
243 inline EnableIf_< And< IsDenseMatrix<MT1>
244  , Or< Not< IsSMPAssignable<MT1> >
245  , Not< IsSMPAssignable<MT2> > > > >
246  smpAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
247 {
249 
250  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
251  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
252 
253  assign( ~lhs, ~rhs );
254 }
256 //*************************************************************************************************
257 
258 
259 //*************************************************************************************************
277 template< typename MT1 // Type of the left-hand side dense matrix
278  , bool SO1 // Storage order of the left-hand side dense matrix
279  , typename MT2 // Type of the right-hand side matrix
280  , bool SO2 > // Storage order of the right-hand side matrix
281 inline EnableIf_< And< IsDenseMatrix<MT1>, IsSMPAssignable<MT1>, IsSMPAssignable<MT2> > >
282  smpAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
283 {
285 
286  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT1> );
287  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT2> );
288 
289  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
290  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
291 
293  {
294  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
295  assign( ~lhs, ~rhs );
296  }
297  else {
298 #pragma omp parallel shared( lhs, rhs )
299  smpAssign_backend( ~lhs, ~rhs );
300  }
301  }
302 }
304 //*************************************************************************************************
305 
306 
307 
308 
309 //=================================================================================================
310 //
311 // ADDITION ASSIGNMENT
312 //
313 //=================================================================================================
314 
315 //*************************************************************************************************
331 template< typename MT1 // Type of the left-hand side dense matrix
332  , bool SO1 // Storage order of the left-hand side dense matrix
333  , typename MT2 // Type of the right-hand side dense matrix
334  , bool SO2 > // Storage order of the right-hand side dense matrix
335 void smpAddAssign_backend( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
336 {
338 
339  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
340 
341  typedef ElementType_<MT1> ET1;
342  typedef ElementType_<MT2> ET2;
343  typedef SubmatrixExprTrait_<MT1,aligned> AlignedTarget;
344  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
345 
346  enum : size_t { SIMDSIZE = SIMDTrait< ElementType_<MT1> >::size };
347 
348  const bool simdEnabled( MT1::simdEnabled && MT2::simdEnabled && IsSame<ET1,ET2>::value );
349  const bool lhsAligned ( (~lhs).isAligned() );
350  const bool rhsAligned ( (~rhs).isAligned() );
351 
352  const int threads( omp_get_num_threads() );
353  const ThreadMapping threadmap( createThreadMapping( threads, ~rhs ) );
354 
355  const size_t addon1 ( ( ( (~rhs).rows() % threadmap.first ) != 0UL )? 1UL : 0UL );
356  const size_t equalShare1( (~rhs).rows() / threadmap.first + addon1 );
357  const size_t rest1 ( equalShare1 & ( SIMDSIZE - 1UL ) );
358  const size_t rowsPerThread( ( simdEnabled && rest1 )?( equalShare1 - rest1 + SIMDSIZE ):( equalShare1 ) );
359 
360  const size_t addon2 ( ( ( (~rhs).columns() % threadmap.second ) != 0UL )? 1UL : 0UL );
361  const size_t equalShare2( (~rhs).columns() / threadmap.second + addon2 );
362  const size_t rest2 ( equalShare2 & ( SIMDSIZE - 1UL ) );
363  const size_t colsPerThread( ( simdEnabled && rest2 )?( equalShare2 - rest2 + SIMDSIZE ):( equalShare2 ) );
364 
365 #pragma omp for schedule(dynamic,1) nowait
366  for( int i=0; i<threads; ++i )
367  {
368  const size_t row ( ( i / threadmap.second ) * rowsPerThread );
369  const size_t column( ( i % threadmap.second ) * colsPerThread );
370 
371  if( row >= (~rhs).rows() || column >= (~rhs).columns() )
372  continue;
373 
374  const size_t m( min( rowsPerThread, (~rhs).rows() - row ) );
375  const size_t n( min( colsPerThread, (~rhs).columns() - column ) );
376 
377  if( simdEnabled && lhsAligned && rhsAligned ) {
378  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
379  addAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
380  }
381  else if( simdEnabled && lhsAligned ) {
382  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
383  addAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
384  }
385  else if( simdEnabled && rhsAligned ) {
386  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
387  addAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
388  }
389  else {
390  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
391  addAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
392  }
393  }
394 }
396 //*************************************************************************************************
397 
398 
399 //*************************************************************************************************
415 template< typename MT1 // Type of the left-hand side dense matrix
416  , bool SO1 // Storage order of the left-hand side dense matrix
417  , typename MT2 // Type of the right-hand side sparse matrix
418  , bool SO2 > // Storage order of the right-hand side sparse matrix
419 void smpAddAssign_backend( DenseMatrix<MT1,SO1>& lhs, const SparseMatrix<MT2,SO2>& rhs )
420 {
422 
423  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
424 
425  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
426 
427  const size_t threads( omp_get_num_threads() );
428  const ThreadMapping threadmap( createThreadMapping( threads, ~rhs ) );
429 
430  const size_t addon1 ( ( ( (~rhs).rows() % threadmap.first ) != 0UL )? 1UL : 0UL );
431  const size_t rowsPerThread( (~rhs).rows() / threadmap.first + addon1 );
432 
433  const size_t addon2 ( ( ( (~rhs).columns() % threadmap.second ) != 0UL )? 1UL : 0UL );
434  const size_t colsPerThread( (~rhs).columns() / threadmap.second + addon2 );
435 
436 #pragma omp for schedule(dynamic,1) nowait
437  for( int i=0; i<threads; ++i )
438  {
439  const size_t row ( ( i / threadmap.second ) * rowsPerThread );
440  const size_t column( ( i % threadmap.second ) * colsPerThread );
441 
442  if( row >= (~rhs).rows() || column >= (~rhs).columns() )
443  continue;
444 
445  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
446  const size_t n( min( colsPerThread, (~lhs).columns() - column ) );
447 
448  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
449  addAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
450  }
451 }
453 //*************************************************************************************************
454 
455 
456 //*************************************************************************************************
474 template< typename MT1 // Type of the left-hand side dense matrix
475  , bool SO1 // Storage order of the left-hand side dense matrix
476  , typename MT2 // Type of the right-hand side matrix
477  , bool SO2 > // Storage order of the right-hand side matrix
478 inline EnableIf_< And< IsDenseMatrix<MT1>
479  , Or< Not< IsSMPAssignable<MT1> >
480  , Not< IsSMPAssignable<MT2> > > > >
481  smpAddAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
482 {
484 
485  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
486  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
487 
488  addAssign( ~lhs, ~rhs );
489 }
491 //*************************************************************************************************
492 
493 
494 //*************************************************************************************************
512 template< typename MT1 // Type of the left-hand side dense matrix
513  , bool SO1 // Storage order of the left-hand side dense matrix
514  , typename MT2 // Type of the right-hand side matrix
515  , bool SO2 > // Storage order of the right-hand side matrix
516 inline EnableIf_< And< IsDenseMatrix<MT1>, IsSMPAssignable<MT1>, IsSMPAssignable<MT2> > >
517  smpAddAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
518 {
520 
521  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT1> );
522  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT2> );
523 
524  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
525  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
526 
528  {
529  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
530  addAssign( ~lhs, ~rhs );
531  }
532  else {
533 #pragma omp parallel shared( lhs, rhs )
534  smpAddAssign_backend( ~lhs, ~rhs );
535  }
536  }
537 }
539 //*************************************************************************************************
540 
541 
542 
543 
544 //=================================================================================================
545 //
546 // SUBTRACTION ASSIGNMENT
547 //
548 //=================================================================================================
549 
550 //*************************************************************************************************
566 template< typename MT1 // Type of the left-hand side dense matrix
567  , bool SO1 // Storage order of the left-hand side dense matrix
568  , typename MT2 // Type of the right-hand side dense matrix
569  , bool SO2 > // Storage order of the right-hand side dense matrix
570 void smpSubAssign_backend( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
571 {
573 
574  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
575 
576  typedef ElementType_<MT1> ET1;
577  typedef ElementType_<MT2> ET2;
578  typedef SubmatrixExprTrait_<MT1,aligned> AlignedTarget;
579  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
580 
581  enum : size_t { SIMDSIZE = SIMDTrait< ElementType_<MT1> >::size };
582 
583  const bool simdEnabled( MT1::simdEnabled && MT2::simdEnabled && IsSame<ET1,ET2>::value );
584  const bool lhsAligned ( (~lhs).isAligned() );
585  const bool rhsAligned ( (~rhs).isAligned() );
586 
587  const int threads( omp_get_num_threads() );
588  const ThreadMapping threadmap( createThreadMapping( threads, ~rhs ) );
589 
590  const size_t addon1 ( ( ( (~rhs).rows() % threadmap.first ) != 0UL )? 1UL : 0UL );
591  const size_t equalShare1( (~rhs).rows() / threadmap.first + addon1 );
592  const size_t rest1 ( equalShare1 & ( SIMDSIZE - 1UL ) );
593  const size_t rowsPerThread( ( simdEnabled && rest1 )?( equalShare1 - rest1 + SIMDSIZE ):( equalShare1 ) );
594 
595  const size_t addon2 ( ( ( (~rhs).columns() % threadmap.second ) != 0UL )? 1UL : 0UL );
596  const size_t equalShare2( (~rhs).columns() / threadmap.second + addon2 );
597  const size_t rest2 ( equalShare2 & ( SIMDSIZE - 1UL ) );
598  const size_t colsPerThread( ( simdEnabled && rest2 )?( equalShare2 - rest2 + SIMDSIZE ):( equalShare2 ) );
599 
600 #pragma omp for schedule(dynamic,1) nowait
601  for( int i=0; i<threads; ++i )
602  {
603  const size_t row ( ( i / threadmap.second ) * rowsPerThread );
604  const size_t column( ( i % threadmap.second ) * colsPerThread );
605 
606  if( row >= (~rhs).rows() || column >= (~rhs).columns() )
607  continue;
608 
609  const size_t m( min( rowsPerThread, (~rhs).rows() - row ) );
610  const size_t n( min( colsPerThread, (~rhs).columns() - column ) );
611 
612  if( simdEnabled && lhsAligned && rhsAligned ) {
613  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
614  subAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
615  }
616  else if( simdEnabled && lhsAligned ) {
617  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
618  subAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
619  }
620  else if( simdEnabled && rhsAligned ) {
621  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
622  subAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
623  }
624  else {
625  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
626  subAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
627  }
628  }
629 }
631 //*************************************************************************************************
632 
633 
634 //*************************************************************************************************
651 template< typename MT1 // Type of the left-hand side dense matrix
652  , bool SO1 // Storage order of the left-hand side dense matrix
653  , typename MT2 // Type of the right-hand side sparse matrix
654  , bool SO2 > // Storage order of the right-hand side sparse matrix
655 void smpSubAssign_backend( DenseMatrix<MT1,SO1>& lhs, const SparseMatrix<MT2,SO2>& rhs )
656 {
658 
659  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
660 
661  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
662 
663  const size_t threads( omp_get_num_threads() );
664  const ThreadMapping threadmap( createThreadMapping( threads, ~rhs ) );
665 
666  const size_t addon1 ( ( ( (~rhs).rows() % threadmap.first ) != 0UL )? 1UL : 0UL );
667  const size_t rowsPerThread( (~rhs).rows() / threadmap.first + addon1 );
668 
669  const size_t addon2 ( ( ( (~rhs).columns() % threadmap.second ) != 0UL )? 1UL : 0UL );
670  const size_t colsPerThread( (~rhs).columns() / threadmap.second + addon2 );
671 
672 #pragma omp for schedule(dynamic,1) nowait
673  for( int i=0; i<threads; ++i )
674  {
675  const size_t row ( ( i / threadmap.second ) * rowsPerThread );
676  const size_t column( ( i % threadmap.second ) * colsPerThread );
677 
678  if( row >= (~rhs).rows() || column >= (~rhs).columns() )
679  continue;
680 
681  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
682  const size_t n( min( colsPerThread, (~lhs).columns() - column ) );
683 
684  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
685  subAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
686  }
687 }
689 //*************************************************************************************************
690 
691 
692 //*************************************************************************************************
710 template< typename MT1 // Type of the left-hand side dense matrix
711  , bool SO1 // Storage order of the left-hand side dense matrix
712  , typename MT2 // Type of the right-hand side matrix
713  , bool SO2 > // Storage order of the right-hand side matrix
714 inline EnableIf_< And< IsDenseMatrix<MT1>
715  , Or< Not< IsSMPAssignable<MT1> >
716  , Not< IsSMPAssignable<MT2> > > > >
717  smpSubAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
718 {
720 
721  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
722  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
723 
724  subAssign( ~lhs, ~rhs );
725 }
727 //*************************************************************************************************
728 
729 
730 //*************************************************************************************************
748 template< typename MT1 // Type of the left-hand side dense matrix
749  , bool SO1 // Storage order of the left-hand side dense matrix
750  , typename MT2 // Type of the right-hand side matrix
751  , bool SO2 > // Storage order of the right-hand side matrix
752 inline EnableIf_< And< IsDenseMatrix<MT1>, IsSMPAssignable<MT1>, IsSMPAssignable<MT2> > >
753  smpSubAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
754 {
756 
757  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT1> );
758  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT2> );
759 
760  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
761  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
762 
764  {
765  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
766  subAssign( ~lhs, ~rhs );
767  }
768  else {
769 #pragma omp parallel shared( lhs, rhs )
770  smpSubAssign_backend( ~lhs, ~rhs );
771  }
772  }
773 }
775 //*************************************************************************************************
776 
777 
778 
779 
780 //=================================================================================================
781 //
782 // MULTIPLICATION ASSIGNMENT
783 //
784 //=================================================================================================
785 
786 //*************************************************************************************************
802 template< typename MT1 // Type of the left-hand side dense matrix
803  , bool SO1 // Storage order of the left-hand side matrix
804  , typename MT2 // Type of the right-hand side matrix
805  , bool SO2 > // Storage order of the right-hand side matrix
806 inline EnableIf_< IsDenseMatrix<MT1> >
807  smpMultAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
808 {
810 
811  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
812  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
813 
814  multAssign( ~lhs, ~rhs );
815 }
817 //*************************************************************************************************
818 
819 
820 
821 
822 //=================================================================================================
823 //
824 // COMPILE TIME CONSTRAINT
825 //
826 //=================================================================================================
827 
828 //*************************************************************************************************
830 namespace {
831 
833 
834 }
836 //*************************************************************************************************
837 
838 } // namespace blaze
839 
840 #endif
Header file for the implementation of the Submatrix view.
Header file for auxiliary alias declarations.
Header file for mathematical functions.
Header file for the alignment flag values.
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
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.
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_OPENMP_PARALLEL_MODE
Compilation switch for the OpenMP parallelization.This compilation switch enables/disables the OpenMP...
Definition: SMP.h:67
#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
#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.