All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DenseVector.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SMP_OPENMP_DENSEVECTOR_H_
36 #define _BLAZE_MATH_SMP_OPENMP_DENSEVECTOR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <omp.h>
48 #include <blaze/math/Functions.h>
55 #include <blaze/system/SMP.h>
56 #include <blaze/util/Assert.h>
57 #include <blaze/util/DisableIf.h>
58 #include <blaze/util/EnableIf.h>
60 #include <blaze/util/mpl/And.h>
63 
64 
65 namespace blaze {
66 
67 //=================================================================================================
68 //
69 // PLAIN ASSIGNMENT
70 //
71 //=================================================================================================
72 
73 //*************************************************************************************************
89 template< typename VT1 // Type of the left-hand side dense vector
90  , bool TF1 // Transpose flag of the left-hand side dense vector
91  , typename VT2 // Type of the right-hand side dense vector
92  , bool TF2 > // Transpose flag of the right-hand side dense vector
93 void smpAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
94 {
96 
97  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
98 
99  typedef typename VT1::ElementType ET1;
100  typedef typename VT2::ElementType ET2;
101  typedef IntrinsicTrait<typename VT1::ElementType> IT;
102  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
103  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
104 
105  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
106  const bool lhsAligned ( (~lhs).isAligned() );
107  const bool rhsAligned ( (~rhs).isAligned() );
108 
109  const int threads ( omp_get_num_threads() );
110  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
111  const size_t equalShare ( (~lhs).size() / threads + addon );
112  const size_t rest ( equalShare & ( IT::size - 1UL ) );
113  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
114 
115 #pragma omp for schedule(dynamic,1) nowait
116  for( int i=0UL; i<threads; ++i )
117  {
118  const size_t index( i*sizePerThread );
119 
120  if( index >= (~lhs).size() )
121  continue;
122 
123  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
124 
125  if( vectorizable && lhsAligned && rhsAligned ) {
126  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
127  assign( target, subvector<aligned>( ~rhs, index, size ) );
128  }
129  else if( vectorizable && lhsAligned ) {
130  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
131  assign( target, subvector<unaligned>( ~rhs, index, size ) );
132  }
133  else if( vectorizable && rhsAligned ) {
134  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
135  assign( target, subvector<aligned>( ~rhs, index, size ) );
136  }
137  else {
138  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
139  assign( target, subvector<unaligned>( ~rhs, index, size ) );
140  }
141  }
142 }
144 //*************************************************************************************************
145 
146 
147 //*************************************************************************************************
163 template< typename VT1 // Type of the left-hand side dense vector
164  , bool TF1 // Transpose flag of the left-hand side dense vector
165  , typename VT2 // Type of the right-hand side dense vector
166  , bool TF2 > // Transpose flag of the right-hand side dense vector
167 void smpAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
168 {
170 
171  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
172 
173  typedef typename VT1::ElementType ET1;
174  typedef typename VT2::ElementType ET2;
175  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
176 
177  const int threads ( omp_get_num_threads() );
178  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
179  const size_t sizePerThread( (~lhs).size() / threads + addon );
180 
181 #pragma omp for schedule(dynamic,1) nowait
182  for( int i=0UL; i<threads; ++i )
183  {
184  const size_t index( i*sizePerThread );
185 
186  if( index >= (~lhs).size() )
187  continue;
188 
189  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
190  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
191  assign( target, subvector<unaligned>( ~rhs, index, size ) );
192  }
193 }
195 //*************************************************************************************************
196 
197 
198 //*************************************************************************************************
216 template< typename VT1 // Type of the left-hand side dense vector
217  , bool TF1 // Transpose flag of the left-hand side dense vector
218  , typename VT2 // Type of the right-hand side vector
219  , bool TF2 > // Transpose flag of the right-hand side vector
220 inline typename DisableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
221  smpAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
222 {
224 
225  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
226 
227  assign( ~lhs, ~rhs );
228 }
230 //*************************************************************************************************
231 
232 
233 //*************************************************************************************************
251 template< typename VT1 // Type of the left-hand side dense vector
252  , bool TF1 // Transpose flag of the left-hand side dense vector
253  , typename VT2 // Type of the right-hand side dense vector
254  , bool TF2 > // Transpose flag of the right-hand side dense vector
255 inline typename EnableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
256  smpAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
257 {
259 
262 
263  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
264 
266  {
267  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
268  assign( ~lhs, ~rhs );
269  }
270  else {
271 #pragma omp parallel shared( lhs, rhs )
272  smpAssign_backend( ~lhs, ~rhs );
273  }
274  }
275 }
277 //*************************************************************************************************
278 
279 
280 
281 
282 //=================================================================================================
283 //
284 // ADDITION ASSIGNMENT
285 //
286 //=================================================================================================
287 
288 //*************************************************************************************************
304 template< typename VT1 // Type of the left-hand side dense vector
305  , bool TF1 // Transpose flag of the left-hand side dense vector
306  , typename VT2 // Type of the right-hand side dense vector
307  , bool TF2 > // Transpose flag of the right-hand side dense vector
308 void smpAddAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
309 {
311 
312  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
313 
314  typedef typename VT1::ElementType ET1;
315  typedef typename VT2::ElementType ET2;
316  typedef IntrinsicTrait<typename VT1::ElementType> IT;
317  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
318  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
319 
320  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
321  const bool lhsAligned ( (~lhs).isAligned() );
322  const bool rhsAligned ( (~rhs).isAligned() );
323 
324  const int threads ( omp_get_num_threads() );
325  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
326  const size_t equalShare ( (~lhs).size() / threads + addon );
327  const size_t rest ( equalShare & ( IT::size - 1UL ) );
328  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
329 
330 #pragma omp for schedule(dynamic,1) nowait
331  for( int i=0UL; i<threads; ++i )
332  {
333  const size_t index( i*sizePerThread );
334 
335  if( index >= (~lhs).size() )
336  continue;
337 
338  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
339 
340  if( vectorizable && lhsAligned && rhsAligned ) {
341  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
342  addAssign( target, subvector<aligned>( ~rhs, index, size ) );
343  }
344  else if( vectorizable && lhsAligned ) {
345  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
346  addAssign( target, subvector<unaligned>( ~rhs, index, size ) );
347  }
348  else if( vectorizable && rhsAligned ) {
349  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
350  addAssign( target, subvector<aligned>( ~rhs, index, size ) );
351  }
352  else {
353  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
354  addAssign( target, subvector<unaligned>( ~rhs, index, size ) );
355  }
356  }
357 }
359 //*************************************************************************************************
360 
361 
362 //*************************************************************************************************
378 template< typename VT1 // Type of the left-hand side dense vector
379  , bool TF1 // Transpose flag of the left-hand side dense vector
380  , typename VT2 // Type of the right-hand side dense vector
381  , bool TF2 > // Transpose flag of the right-hand side dense vector
382 void smpAddAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
383 {
385 
386  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
387 
388  typedef typename VT1::ElementType ET1;
389  typedef typename VT2::ElementType ET2;
390  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
391 
392  const int threads ( omp_get_num_threads() );
393  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
394  const size_t sizePerThread( (~lhs).size() / threads + addon );
395 
396 #pragma omp for schedule(dynamic,1) nowait
397  for( int i=0UL; i<threads; ++i )
398  {
399  const size_t index( i*sizePerThread );
400 
401  if( index >= (~lhs).size() )
402  continue;
403 
404  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
405  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
406  addAssign( target, subvector<unaligned>( ~rhs, index, size ) );
407  }
408 }
410 //*************************************************************************************************
411 
412 
413 //*************************************************************************************************
431 template< typename VT1 // Type of the left-hand side dense vector
432  , bool TF1 // Transpose flag of the left-hand side dense vector
433  , typename VT2 // Type of the right-hand side vector
434  , bool TF2 > // Transpose flag of the right-hand side vector
435 inline typename DisableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
436  smpAddAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
437 {
439 
440  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
441 
442  addAssign( ~lhs, ~rhs );
443 }
445 //*************************************************************************************************
446 
447 
448 //*************************************************************************************************
466 template< typename VT1 // Type of the left-hand side dense vector
467  , bool TF1 // Transpose flag of the left-hand side dense vector
468  , typename VT2 // Type of the right-hand side dense vector
469  , bool TF2 > // Transpose flag of the right-hand side dense vector
470 inline typename EnableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
471  smpAddAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
472 {
474 
477 
478  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
479 
481  {
482  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
483  addAssign( ~lhs, ~rhs );
484  }
485  else {
486 #pragma omp parallel shared( lhs, rhs )
487  smpAddAssign_backend( ~lhs, ~rhs );
488  }
489  }
490 }
492 //*************************************************************************************************
493 
494 
495 
496 
497 //=================================================================================================
498 //
499 // SUBTRACTION ASSIGNMENT
500 //
501 //=================================================================================================
502 
503 //*************************************************************************************************
519 template< typename VT1 // Type of the left-hand side dense vector
520  , bool TF1 // Transpose flag of the left-hand side dense vector
521  , typename VT2 // Type of the right-hand side dense vector
522  , bool TF2 > // Transpose flag of the right-hand side dense vector
523 void smpSubAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
524 {
526 
527  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
528 
529  typedef typename VT1::ElementType ET1;
530  typedef typename VT2::ElementType ET2;
531  typedef IntrinsicTrait<typename VT1::ElementType> IT;
532  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
533  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
534 
535  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
536  const bool lhsAligned ( (~lhs).isAligned() );
537  const bool rhsAligned ( (~rhs).isAligned() );
538 
539  const int threads ( omp_get_num_threads() );
540  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
541  const size_t equalShare ( (~lhs).size() / threads + addon );
542  const size_t rest ( equalShare & ( IT::size - 1UL ) );
543  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
544 
545 #pragma omp for schedule(dynamic,1) nowait
546  for( int i=0UL; i<threads; ++i )
547  {
548  const size_t index( i*sizePerThread );
549 
550  if( index >= (~lhs).size() )
551  continue;
552 
553  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
554 
555  if( vectorizable && lhsAligned && rhsAligned ) {
556  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
557  subAssign( target, subvector<aligned>( ~rhs, index, size ) );
558  }
559  else if( vectorizable && lhsAligned ) {
560  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
561  subAssign( target, subvector<unaligned>( ~rhs, index, size ) );
562  }
563  else if( vectorizable && rhsAligned ) {
564  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
565  subAssign( target, subvector<aligned>( ~rhs, index, size ) );
566  }
567  else {
568  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
569  subAssign( target, subvector<unaligned>( ~rhs, index, size ) );
570  }
571  }
572 }
574 //*************************************************************************************************
575 
576 
577 //*************************************************************************************************
593 template< typename VT1 // Type of the left-hand side dense vector
594  , bool TF1 // Transpose flag of the left-hand side dense vector
595  , typename VT2 // Type of the right-hand side dense vector
596  , bool TF2 > // Transpose flag of the right-hand side dense vector
597 void smpSubAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
598 {
600 
601  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
602 
603  typedef typename VT1::ElementType ET1;
604  typedef typename VT2::ElementType ET2;
605  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
606 
607  const int threads ( omp_get_num_threads() );
608  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
609  const size_t sizePerThread( (~lhs).size() / threads + addon );
610 
611 #pragma omp for schedule(dynamic,1) nowait
612  for( int i=0UL; i<threads; ++i )
613  {
614  const size_t index( i*sizePerThread );
615 
616  if( index >= (~lhs).size() )
617  continue;
618 
619  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
620  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
621  subAssign( target, subvector<unaligned>( ~rhs, index, size ) );
622  }
623 }
625 //*************************************************************************************************
626 
627 
628 //*************************************************************************************************
646 template< typename VT1 // Type of the left-hand side dense vector
647  , bool TF1 // Transpose flag of the left-hand side dense vector
648  , typename VT2 // Type of the right-hand side vector
649  , bool TF2 > // Transpose flag of the right-hand side vector
650 inline typename DisableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
651  smpSubAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
652 {
654 
655  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
656 
657  subAssign( ~lhs, ~rhs );
658 }
660 //*************************************************************************************************
661 
662 
663 //*************************************************************************************************
681 template< typename VT1 // Type of the left-hand side dense vector
682  , bool TF1 // Transpose flag of the left-hand side dense vector
683  , typename VT2 // Type of the right-hand side dense vector
684  , bool TF2 > // Transpose flag of the right-hand side dense vector
685 inline typename EnableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
686  smpSubAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
687 {
689 
692 
693  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
694 
696  {
697  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
698  subAssign( ~lhs, ~rhs );
699  }
700  else {
701 #pragma omp parallel shared( lhs, rhs )
702  smpSubAssign_backend( ~lhs, ~rhs );
703  }
704  }
705 }
707 //*************************************************************************************************
708 
709 
710 
711 
712 //=================================================================================================
713 //
714 // MULTIPLICATION ASSIGNMENT
715 //
716 //=================================================================================================
717 
718 //*************************************************************************************************
735 template< typename VT1 // Type of the left-hand side dense vector
736  , bool TF1 // Transpose flag of the left-hand side dense vector
737  , typename VT2 // Type of the right-hand side dense vector
738  , bool TF2 > // Transpose flag of the right-hand side dense vector
739 void smpMultAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
740 {
742 
743  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
744 
745  typedef typename VT1::ElementType ET1;
746  typedef typename VT2::ElementType ET2;
747  typedef IntrinsicTrait<typename VT1::ElementType> IT;
748  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
749  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
750 
751  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
752  const bool lhsAligned ( (~lhs).isAligned() );
753  const bool rhsAligned ( (~rhs).isAligned() );
754 
755  const int threads ( omp_get_num_threads() );
756  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
757  const size_t equalShare ( (~lhs).size() / threads + addon );
758  const size_t rest ( equalShare & ( IT::size - 1UL ) );
759  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
760 
761 #pragma omp for schedule(dynamic,1) nowait
762  for( int i=0UL; i<threads; ++i )
763  {
764  const size_t index( i*sizePerThread );
765 
766  if( index >= (~lhs).size() )
767  continue;
768 
769  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
770 
771  if( vectorizable && lhsAligned && rhsAligned ) {
772  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
773  multAssign( target, subvector<aligned>( ~rhs, index, size ) );
774  }
775  else if( vectorizable && lhsAligned ) {
776  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
777  multAssign( target, subvector<unaligned>( ~rhs, index, size ) );
778  }
779  else if( vectorizable && rhsAligned ) {
780  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
781  multAssign( target, subvector<aligned>( ~rhs, index, size ) );
782  }
783  else {
784  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
785  multAssign( target, subvector<unaligned>( ~rhs, index, size ) );
786  }
787  }
788 }
790 //*************************************************************************************************
791 
792 
793 //*************************************************************************************************
810 template< typename VT1 // Type of the left-hand side dense vector
811  , bool TF1 // Transpose flag of the left-hand side dense vector
812  , typename VT2 // Type of the right-hand side dense vector
813  , bool TF2 > // Transpose flag of the right-hand side dense vector
814 void smpMultAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
815 {
817 
818  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
819 
820  typedef typename VT1::ElementType ET1;
821  typedef typename VT2::ElementType ET2;
822  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
823 
824  const int threads ( omp_get_num_threads() );
825  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
826  const size_t sizePerThread( (~lhs).size() / threads + addon );
827 
828 #pragma omp for schedule(dynamic,1) nowait
829  for( int i=0UL; i<threads; ++i )
830  {
831  const size_t index( i*sizePerThread );
832 
833  if( index >= (~lhs).size() )
834  continue;
835 
836  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
837  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
838  multAssign( target, subvector<unaligned>( ~rhs, index, size ) );
839  }
840 }
842 //*************************************************************************************************
843 
844 
845 //*************************************************************************************************
863 template< typename VT1 // Type of the left-hand side dense vector
864  , bool TF1 // Transpose flag of the left-hand side dense vector
865  , typename VT2 // Type of the right-hand side vector
866  , bool TF2 > // Transpose flag of the right-hand side vector
867 inline typename DisableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
868  smpMultAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
869 {
871 
872  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
873 
874  multAssign( ~lhs, ~rhs );
875 }
877 //*************************************************************************************************
878 
879 
880 //*************************************************************************************************
898 template< typename VT1 // Type of the left-hand side dense vector
899  , bool TF1 // Transpose flag of the left-hand side dense vector
900  , typename VT2 // Type of the right-hand side dense vector
901  , bool TF2 > // Transpose flag of the right-hand side dense vector
902 inline typename EnableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
903  smpMultAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
904 {
906 
909 
910  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
911 
913  {
914  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
915  multAssign( ~lhs, ~rhs );
916  }
917  else {
918 #pragma omp parallel shared( lhs, rhs )
919  smpMultAssign_backend( ~lhs, ~rhs );
920  }
921  }
922 }
924 //*************************************************************************************************
925 
926 
927 
928 
929 //=================================================================================================
930 //
931 // COMPILE TIME CONSTRAINTS
932 //
933 //=================================================================================================
934 
935 //*************************************************************************************************
937 namespace {
938 
940 
941 }
943 //*************************************************************************************************
944 
945 } // namespace blaze
946 
947 #endif
Header file for mathematical functions.
Header file for the SparseVector base class.
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:152
Header file for the complete DenseSubvector implementation.
void smpMultAssign(DenseVector< 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:179
Header file for the IsSame and IsStrictlySame type traits.
Header file for the And class template.
Header file for the DenseVector base class.
Header file for the intrinsic trait.
#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:118
Header file for the complete SparseSubvector implementation.
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:122
Header file for the DisableIf class template.
Compile time assertion.
System settings for the shared-memory parallelization.
Header file for the IsSMPAssignable type trait.
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:271
Header file for the serial section implementation.
Header file for the parallel section implementation.
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2406
void multAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the multiplication assignment of a matrix to a matrix.
Definition: Matrix.h:361
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:245
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:92
bool isSerialSectionActive()
Returns whether a serial section is active or not.
Definition: SerialSection.h:212
Header file for run time assertion macros.
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:301
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:331
bool isParallelSectionActive()
Returns whether a parallel section is active or not.
Definition: ParallelSection.h:212
#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
Header file for the SubvectorExprTrait class template.
#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:143
#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.