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>
68 
69 
70 namespace blaze {
71 
72 //=================================================================================================
73 //
74 // PLAIN ASSIGNMENT
75 //
76 //=================================================================================================
77 
78 //*************************************************************************************************
94 template< typename MT1 // Type of the left-hand side dense matrix
95  , bool SO1 // Storage order of the left-hand side dense matrix
96  , typename MT2 // Type of the right-hand side dense matrix
97  , bool SO2 > // Storage order of the right-hand side dense matrix
98 void smpAssign_backend( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
99 {
101 
102  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
103 
104  typedef ElementType_<MT1> ET1;
105  typedef ElementType_<MT2> ET2;
106  typedef SubmatrixExprTrait_<MT1,aligned> AlignedTarget;
107  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
108 
109  constexpr bool simdEnabled( MT1::simdEnabled && MT2::simdEnabled && IsSIMDCombinable<ET1,ET2>::value );
110  constexpr size_t SIMDSIZE( SIMDTrait< ElementType_<MT1> >::size );
111 
112  const bool lhsAligned( (~lhs).isAligned() );
113  const bool rhsAligned( (~rhs).isAligned() );
114 
115  const ThreadMapping threads( createThreadMapping( TheThreadBackend::size(), ~rhs ) );
116 
117  const size_t addon1 ( ( ( (~rhs).rows() % threads.first ) != 0UL )? 1UL : 0UL );
118  const size_t equalShare1( (~rhs).rows() / threads.first + addon1 );
119  const size_t rest1 ( equalShare1 & ( SIMDSIZE - 1UL ) );
120  const size_t rowsPerThread( ( simdEnabled && rest1 )?( equalShare1 - rest1 + SIMDSIZE ):( equalShare1 ) );
121 
122  const size_t addon2 ( ( ( (~rhs).columns() % threads.second ) != 0UL )? 1UL : 0UL );
123  const size_t equalShare2( (~rhs).columns() / threads.second + addon2 );
124  const size_t rest2 ( equalShare2 & ( SIMDSIZE - 1UL ) );
125  const size_t colsPerThread( ( simdEnabled && rest2 )?( equalShare2 - rest2 + SIMDSIZE ):( equalShare2 ) );
126 
127  for( size_t i=0UL; i<threads.first; ++i )
128  {
129  const size_t row( i*rowsPerThread );
130 
131  if( row >= (~lhs).rows() )
132  continue;
133 
134  for( size_t j=0UL; j<threads.second; ++j )
135  {
136  const size_t column( j*colsPerThread );
137 
138  if( column >= (~rhs).columns() )
139  continue;
140 
141  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
142  const size_t n( min( colsPerThread, (~rhs).columns() - column ) );
143 
144  if( simdEnabled && lhsAligned && rhsAligned ) {
145  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
146  TheThreadBackend::scheduleAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
147  }
148  else if( simdEnabled && lhsAligned ) {
149  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
150  TheThreadBackend::scheduleAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
151  }
152  else if( simdEnabled && rhsAligned ) {
153  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
154  TheThreadBackend::scheduleAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
155  }
156  else {
157  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
158  TheThreadBackend::scheduleAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
159  }
160  }
161  }
162 
163  TheThreadBackend::wait();
164 }
166 //*************************************************************************************************
167 
168 
169 //*************************************************************************************************
186 template< typename MT1 // Type of the left-hand side dense matrix
187  , bool SO1 // Storage order of the left-hand side dense matrix
188  , typename MT2 // Type of the right-hand side sparse matrix
189  , bool SO2 > // Storage order of the right-hand side sparse matrix
190 void smpAssign_backend( DenseMatrix<MT1,SO1>& lhs, const SparseMatrix<MT2,SO2>& rhs )
191 {
193 
194  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
195 
196  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
197 
198  const ThreadMapping threads( createThreadMapping( TheThreadBackend::size(), ~rhs ) );
199 
200  const size_t addon1 ( ( ( (~rhs).rows() % threads.first ) != 0UL )? 1UL : 0UL );
201  const size_t rowsPerThread( (~rhs).rows() / threads.first + addon1 );
202 
203  const size_t addon2 ( ( ( (~rhs).columns() % threads.second ) != 0UL )? 1UL : 0UL );
204  const size_t colsPerThread( (~rhs).columns() / threads.second + addon2 );
205 
206  for( size_t i=0UL; i<threads.first; ++i )
207  {
208  const size_t row( i*rowsPerThread );
209 
210  if( row >= (~lhs).rows() )
211  continue;
212 
213  for( size_t j=0UL; j<threads.second; ++j )
214  {
215  const size_t column( j*colsPerThread );
216 
217  if( column >= (~lhs).columns() )
218  continue;
219 
220  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
221  const size_t n( min( colsPerThread, (~lhs).columns() - column ) );
222 
223  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
224  TheThreadBackend::scheduleAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
225  }
226  }
227 
228  TheThreadBackend::wait();
229 }
231 //*************************************************************************************************
232 
233 
234 //*************************************************************************************************
252 template< typename MT1 // Type of the left-hand side dense matrix
253  , bool SO1 // Storage order of the left-hand side dense matrix
254  , typename MT2 // Type of the right-hand side matrix
255  , bool SO2 > // Storage order of the right-hand side matrix
256 inline EnableIf_< And< IsDenseMatrix<MT1>
257  , Or< Not< IsSMPAssignable<MT1> >
258  , Not< IsSMPAssignable<MT2> > > > >
259  smpAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
260 {
262 
263  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
264  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
265 
266  assign( ~lhs, ~rhs );
267 }
269 //*************************************************************************************************
270 
271 
272 //*************************************************************************************************
290 template< typename MT1 // Type of the left-hand side dense matrix
291  , bool SO1 // Storage order of the left-hand side dense matrix
292  , typename MT2 // Type of the right-hand side matrix
293  , bool SO2 > // Storage order of the right-hand side matrix
294 inline EnableIf_< And< IsDenseMatrix<MT1>, IsSMPAssignable<MT1>, IsSMPAssignable<MT2> > >
295  smpAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
296 {
298 
299  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT1> );
300  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT2> );
301 
302  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
303  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
304 
306  {
307  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
308  assign( ~lhs, ~rhs );
309  }
310  else {
311  smpAssign_backend( ~lhs, ~rhs );
312  }
313  }
314 }
316 //*************************************************************************************************
317 
318 
319 
320 
321 //=================================================================================================
322 //
323 // ADDITION ASSIGNMENT
324 //
325 //=================================================================================================
326 
327 //*************************************************************************************************
344 template< typename MT1 // Type of the left-hand side dense matrix
345  , bool SO1 // Storage order of the left-hand side dense matrix
346  , typename MT2 // Type of the right-hand side dense matrix
347  , bool SO2 > // Storage order fo the right-hand side dense matrix
348 void smpAddAssign_backend( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
349 {
351 
352  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
353 
354  typedef ElementType_<MT1> ET1;
355  typedef ElementType_<MT2> ET2;
356  typedef SubmatrixExprTrait_<MT1,aligned> AlignedTarget;
357  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
358 
359  constexpr bool simdEnabled( MT1::simdEnabled && MT2::simdEnabled && IsSIMDCombinable<ET1,ET2>::value );
360  constexpr size_t SIMDSIZE( SIMDTrait< ElementType_<MT1> >::size );
361 
362  const bool lhsAligned( (~lhs).isAligned() );
363  const bool rhsAligned( (~rhs).isAligned() );
364 
365  const ThreadMapping threads( createThreadMapping( TheThreadBackend::size(), ~rhs ) );
366 
367  const size_t addon1 ( ( ( (~rhs).rows() % threads.first ) != 0UL )? 1UL : 0UL );
368  const size_t equalShare1( (~rhs).rows() / threads.first + addon1 );
369  const size_t rest1 ( equalShare1 & ( SIMDSIZE - 1UL ) );
370  const size_t rowsPerThread( ( simdEnabled && rest1 )?( equalShare1 - rest1 + SIMDSIZE ):( equalShare1 ) );
371 
372  const size_t addon2 ( ( ( (~rhs).columns() % threads.second ) != 0UL )? 1UL : 0UL );
373  const size_t equalShare2( (~rhs).columns() / threads.second + addon2 );
374  const size_t rest2 ( equalShare2 & ( SIMDSIZE - 1UL ) );
375  const size_t colsPerThread( ( simdEnabled && rest2 )?( equalShare2 - rest2 + SIMDSIZE ):( equalShare2 ) );
376 
377  for( size_t i=0UL; i<threads.first; ++i )
378  {
379  const size_t row( i*rowsPerThread );
380 
381  if( row >= (~lhs).rows() )
382  continue;
383 
384  for( size_t j=0UL; j<threads.second; ++j )
385  {
386  const size_t column( j*colsPerThread );
387 
388  if( column >= (~rhs).columns() )
389  continue;
390 
391  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
392  const size_t n( min( colsPerThread, (~rhs).columns() - column ) );
393 
394  if( simdEnabled && lhsAligned && rhsAligned ) {
395  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
396  TheThreadBackend::scheduleAddAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
397  }
398  else if( simdEnabled && lhsAligned ) {
399  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
400  TheThreadBackend::scheduleAddAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
401  }
402  else if( simdEnabled && rhsAligned ) {
403  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
404  TheThreadBackend::scheduleAddAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
405  }
406  else {
407  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
408  TheThreadBackend::scheduleAddAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
409  }
410  }
411  }
412 
413  TheThreadBackend::wait();
414 }
416 //*************************************************************************************************
417 
418 
419 //*************************************************************************************************
436 template< typename MT1 // Type of the left-hand side dense matrix
437  , bool SO1 // Storage order of the left-hand side dense matrix
438  , typename MT2 // Type of the right-hand side sparse matrix
439  , bool SO2 > // Storage order of the right-hand side sparse matrix
440 void smpAddAssign_backend( DenseMatrix<MT1,SO1>& lhs, const SparseMatrix<MT2,SO2>& rhs )
441 {
443 
444  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
445 
446  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
447 
448  const ThreadMapping threads( createThreadMapping( TheThreadBackend::size(), ~rhs ) );
449 
450  const size_t addon1 ( ( ( (~rhs).rows() % threads.first ) != 0UL )? 1UL : 0UL );
451  const size_t rowsPerThread( (~rhs).rows() / threads.first + addon1 );
452 
453  const size_t addon2 ( ( ( (~rhs).columns() % threads.second ) != 0UL )? 1UL : 0UL );
454  const size_t colsPerThread( (~rhs).columns() / threads.second + addon2 );
455 
456  for( size_t i=0UL; i<threads.first; ++i )
457  {
458  const size_t row( i*rowsPerThread );
459 
460  if( row >= (~lhs).rows() )
461  continue;
462 
463  for( size_t j=0UL; j<threads.second; ++j )
464  {
465  const size_t column( j*colsPerThread );
466 
467  if( column >= (~lhs).columns() )
468  continue;
469 
470  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
471  const size_t n( min( colsPerThread, (~lhs).columns() - column ) );
472 
473  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
474  TheThreadBackend::scheduleAddAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
475  }
476  }
477 
478  TheThreadBackend::wait();
479 }
481 //*************************************************************************************************
482 
483 
484 //*************************************************************************************************
503 template< typename MT1 // Type of the left-hand side dense matrix
504  , bool SO1 // Storage order of the left-hand side dense matrix
505  , typename MT2 // Type of the right-hand side matrix
506  , bool SO2 > // Storage order of the right-hand side matrix
507 inline EnableIf_< And< IsDenseMatrix<MT1>
508  , Or< Not< IsSMPAssignable<MT1> >
509  , Not< IsSMPAssignable<MT2> > > > >
510  smpAddAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
511 {
513 
514  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
515  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
516 
517  addAssign( ~lhs, ~rhs );
518 }
520 //*************************************************************************************************
521 
522 
523 //*************************************************************************************************
541 template< typename MT1 // Type of the left-hand side dense matrix
542  , bool SO1 // Storage order of the left-hand side dense matrix
543  , typename MT2 // Type of the right-hand side matrix
544  , bool SO2 > // Storage order of the right-hand side matrix
545 inline EnableIf_< And< IsDenseMatrix<MT1>, IsSMPAssignable<MT1>, IsSMPAssignable<MT2> > >
546  smpAddAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
547 {
549 
550  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT1> );
551  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT2> );
552 
553  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
554  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
555 
557  {
558  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
559  addAssign( ~lhs, ~rhs );
560  }
561  else {
562  smpAddAssign_backend( ~lhs, ~rhs );
563  }
564  }
565 }
567 //*************************************************************************************************
568 
569 
570 
571 
572 //=================================================================================================
573 //
574 // SUBTRACTION ASSIGNMENT
575 //
576 //=================================================================================================
577 
578 //*************************************************************************************************
595 template< typename MT1 // Type of the left-hand side dense matrix
596  , bool SO1 // Storage order of the left-hand side dense matrix
597  , typename MT2 // Type of the right-hand side dense matrix
598  , bool SO2 > // Storage order of the right-hand side dense matrix
599 void smpSubAssign_backend( DenseMatrix<MT1,SO1>& lhs, const DenseMatrix<MT2,SO2>& rhs )
600 {
602 
603  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
604 
605  typedef ElementType_<MT1> ET1;
606  typedef ElementType_<MT2> ET2;
607  typedef SubmatrixExprTrait_<MT1,aligned> AlignedTarget;
608  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
609 
610  constexpr bool simdEnabled( MT1::simdEnabled && MT2::simdEnabled && IsSIMDCombinable<ET1,ET2>::value );
611  constexpr size_t SIMDSIZE( SIMDTrait< ElementType_<MT1> >::size );
612 
613  const bool lhsAligned( (~lhs).isAligned() );
614  const bool rhsAligned( (~rhs).isAligned() );
615 
616  const ThreadMapping threads( createThreadMapping( TheThreadBackend::size(), ~rhs ) );
617 
618  const size_t addon1 ( ( ( (~rhs).rows() % threads.first ) != 0UL )? 1UL : 0UL );
619  const size_t equalShare1( (~rhs).rows() / threads.first + addon1 );
620  const size_t rest1 ( equalShare1 & ( SIMDSIZE - 1UL ) );
621  const size_t rowsPerThread( ( simdEnabled && rest1 )?( equalShare1 - rest1 + SIMDSIZE ):( equalShare1 ) );
622 
623  const size_t addon2 ( ( ( (~rhs).columns() % threads.second ) != 0UL )? 1UL : 0UL );
624  const size_t equalShare2( (~rhs).columns() / threads.second + addon2 );
625  const size_t rest2 ( equalShare2 & ( SIMDSIZE - 1UL ) );
626  const size_t colsPerThread( ( simdEnabled && rest2 )?( equalShare2 - rest2 + SIMDSIZE ):( equalShare2 ) );
627 
628  for( size_t i=0UL; i<threads.first; ++i )
629  {
630  const size_t row( i*rowsPerThread );
631 
632  if( row >= (~lhs).rows() )
633  continue;
634 
635  for( size_t j=0UL; j<threads.second; ++j )
636  {
637  const size_t column( j*colsPerThread );
638 
639  if( column >= (~rhs).columns() )
640  continue;
641 
642  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
643  const size_t n( min( colsPerThread, (~rhs).columns() - column ) );
644 
645  if( simdEnabled && lhsAligned && rhsAligned ) {
646  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
647  TheThreadBackend::scheduleSubAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
648  }
649  else if( simdEnabled && lhsAligned ) {
650  AlignedTarget target( submatrix<aligned>( ~lhs, row, column, m, n ) );
651  TheThreadBackend::scheduleSubAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
652  }
653  else if( simdEnabled && rhsAligned ) {
654  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
655  TheThreadBackend::scheduleSubAssign( target, submatrix<aligned>( ~rhs, row, column, m, n ) );
656  }
657  else {
658  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
659  TheThreadBackend::scheduleSubAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
660  }
661  }
662  }
663 
664  TheThreadBackend::wait();
665 }
667 //*************************************************************************************************
668 
669 
670 //*************************************************************************************************
687 template< typename MT1 // Type of the left-hand side dense matrix
688  , bool SO1 // Storage order of the left-hand side dense matrix
689  , typename MT2 // Type of the right-hand side sparse matrix
690  , bool SO2 > // Storage order of the right-hand side sparse matrix
691 void smpSubAssign_backend( DenseMatrix<MT1,SO1>& lhs, const SparseMatrix<MT2,SO2>& rhs )
692 {
694 
695  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
696 
697  typedef SubmatrixExprTrait_<MT1,unaligned> UnalignedTarget;
698 
699  const ThreadMapping threads( createThreadMapping( TheThreadBackend::size(), ~rhs ) );
700 
701  const size_t addon1 ( ( ( (~rhs).rows() % threads.first ) != 0UL )? 1UL : 0UL );
702  const size_t rowsPerThread( (~rhs).rows() / threads.first + addon1 );
703 
704  const size_t addon2 ( ( ( (~rhs).columns() % threads.second ) != 0UL )? 1UL : 0UL );
705  const size_t colsPerThread( (~rhs).columns() / threads.second + addon2 );
706 
707  for( size_t i=0UL; i<threads.first; ++i )
708  {
709  const size_t row( i*rowsPerThread );
710 
711  if( row >= (~lhs).rows() )
712  continue;
713 
714  for( size_t j=0UL; j<threads.second; ++j )
715  {
716  const size_t column( j*colsPerThread );
717 
718  if( column >= (~lhs).columns() )
719  continue;
720 
721  const size_t m( min( rowsPerThread, (~lhs).rows() - row ) );
722  const size_t n( min( colsPerThread, (~lhs).columns() - column ) );
723 
724  UnalignedTarget target( submatrix<unaligned>( ~lhs, row, column, m, n ) );
725  TheThreadBackend::scheduleSubAssign( target, submatrix<unaligned>( ~rhs, row, column, m, n ) );
726  }
727  }
728 
729  TheThreadBackend::wait();
730 }
732 //*************************************************************************************************
733 
734 
735 //*************************************************************************************************
754 template< typename MT1 // Type of the left-hand side dense matrix
755  , bool SO1 // Storage order of the left-hand side dense matrix
756  , typename MT2 // Type of the right-hand side matrix
757  , bool SO2 > // Storage order of the right-hand side matrix
758 inline EnableIf_< And< IsDenseMatrix<MT1>
759  , Or< Not< IsSMPAssignable<MT1> >
760  , Not< IsSMPAssignable<MT2> > > > >
761  smpSubAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
762 {
764 
765  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
766  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
767 
768  subAssign( ~lhs, ~rhs );
769 }
771 //*************************************************************************************************
772 
773 
774 //*************************************************************************************************
793 template< typename MT1 // Type of the left-hand side dense matrix
794  , bool SO1 // Storage order of the left-hand side dense matrix
795  , typename MT2 // Type of the right-hand side matrix
796  , bool SO2 > // Storage order of the right-hand side matrix
797 inline EnableIf_< And< IsDenseMatrix<MT1>, IsSMPAssignable<MT1>, IsSMPAssignable<MT2> > >
798  smpSubAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
799 {
801 
802  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT1> );
803  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<MT2> );
804 
805  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
806  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
807 
809  {
810  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
811  subAssign( ~lhs, ~rhs );
812  }
813  else {
814  smpSubAssign_backend( ~lhs, ~rhs );
815  }
816  }
817 }
819 //*************************************************************************************************
820 
821 
822 
823 
824 //=================================================================================================
825 //
826 // MULTIPLICATION ASSIGNMENT
827 //
828 //=================================================================================================
829 
830 //*************************************************************************************************
847 template< typename MT1 // Type of the left-hand side dense matrix
848  , bool SO1 // Storage order of the left-hand side matrix
849  , typename MT2 // Type of the right-hand side matrix
850  , bool SO2 > // Storage order of the right-hand side matrix
851 inline EnableIf_< IsDenseMatrix<MT1> >
852  smpMultAssign( Matrix<MT1,SO1>& lhs, const Matrix<MT2,SO2>& rhs )
853 {
855 
856  BLAZE_INTERNAL_ASSERT( (~lhs).rows() == (~rhs).rows() , "Invalid number of rows" );
857  BLAZE_INTERNAL_ASSERT( (~lhs).columns() == (~rhs).columns(), "Invalid number of columns" );
858 
859  multAssign( ~lhs, ~rhs );
860 }
862 //*************************************************************************************************
863 
864 
865 
866 
867 //=================================================================================================
868 //
869 // COMPILE TIME CONSTRAINT
870 //
871 //=================================================================================================
872 
873 //*************************************************************************************************
875 namespace {
876 
878 
879 }
881 //*************************************************************************************************
882 
883 } // namespace blaze
884 
885 #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:261
#define BLAZE_BOOST_THREADS_PARALLEL_MODE
Compilation switch for the Boost parallelization.This compilation switch enables/disables the paralle...
Definition: SMP.h:122
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:1755
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
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:336
Header file for the serial section implementation.
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT >, IsDeclExpr< 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:128
#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.
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT >, IsDeclExpr< 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:128
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
bool isSerialSectionActive()
Returns whether a serial section is active or not.
Definition: SerialSection.h:213
Header file for the IsSIMDCombinable type trait.
Header file for the SubmatrixExprTrait class template.
Header file for run time assertion macros.
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:93
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:320
bool isParallelSectionActive()
Returns whether a parallel section is active or not.
Definition: ParallelSection.h:213
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 function trace functionality.