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>
56 #include <blaze/system/SMP.h>
57 #include <blaze/util/Assert.h>
58 #include <blaze/util/EnableIf.h>
60 #include <blaze/util/mpl/And.h>
61 #include <blaze/util/mpl/Not.h>
62 #include <blaze/util/mpl/Or.h>
64 #include <blaze/util/Types.h>
66 
67 
68 namespace blaze {
69 
70 //=================================================================================================
71 //
72 // PLAIN ASSIGNMENT
73 //
74 //=================================================================================================
75 
76 //*************************************************************************************************
92 template< typename VT1 // Type of the left-hand side dense vector
93  , bool TF1 // Transpose flag of the left-hand side dense vector
94  , typename VT2 // Type of the right-hand side dense vector
95  , bool TF2 > // Transpose flag of the right-hand side dense vector
96 void smpAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
97 {
99 
100  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
101 
102  typedef typename VT1::ElementType ET1;
103  typedef typename VT2::ElementType ET2;
104  typedef IntrinsicTrait<typename VT1::ElementType> IT;
105  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
106  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
107 
108  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
109  const bool lhsAligned ( (~lhs).isAligned() );
110  const bool rhsAligned ( (~rhs).isAligned() );
111 
112  const int threads ( omp_get_num_threads() );
113  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
114  const size_t equalShare ( (~lhs).size() / threads + addon );
115  const size_t rest ( equalShare & ( IT::size - 1UL ) );
116  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
117 
118 #pragma omp for schedule(dynamic,1) nowait
119  for( int i=0UL; i<threads; ++i )
120  {
121  const size_t index( i*sizePerThread );
122 
123  if( index >= (~lhs).size() )
124  continue;
125 
126  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
127 
128  if( vectorizable && lhsAligned && rhsAligned ) {
129  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
130  assign( target, subvector<aligned>( ~rhs, index, size ) );
131  }
132  else if( vectorizable && lhsAligned ) {
133  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
134  assign( target, subvector<unaligned>( ~rhs, index, size ) );
135  }
136  else if( vectorizable && rhsAligned ) {
137  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
138  assign( target, subvector<aligned>( ~rhs, index, size ) );
139  }
140  else {
141  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
142  assign( target, subvector<unaligned>( ~rhs, index, size ) );
143  }
144  }
145 }
147 //*************************************************************************************************
148 
149 
150 //*************************************************************************************************
166 template< typename VT1 // Type of the left-hand side dense vector
167  , bool TF1 // Transpose flag of the left-hand side dense vector
168  , typename VT2 // Type of the right-hand side sparse vector
169  , bool TF2 > // Transpose flag of the right-hand side sparse vector
170 void smpAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
171 {
173 
174  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
175 
176  typedef typename VT1::ElementType ET1;
177  typedef typename VT2::ElementType ET2;
178  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
179 
180  const int threads ( omp_get_num_threads() );
181  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
182  const size_t sizePerThread( (~lhs).size() / threads + addon );
183 
184 #pragma omp for schedule(dynamic,1) nowait
185  for( int i=0UL; i<threads; ++i )
186  {
187  const size_t index( i*sizePerThread );
188 
189  if( index >= (~lhs).size() )
190  continue;
191 
192  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
193  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
194  assign( target, subvector<unaligned>( ~rhs, index, size ) );
195  }
196 }
198 //*************************************************************************************************
199 
200 
201 //*************************************************************************************************
219 template< typename VT1 // Type of the left-hand side dense vector
220  , bool TF1 // Transpose flag of the left-hand side dense vector
221  , typename VT2 // Type of the right-hand side vector
222  , bool TF2 > // Transpose flag of the right-hand side vector
223 inline typename EnableIf< And< IsDenseVector<VT1>
224  , Or< Not< IsSMPAssignable<VT1> >
225  , Not< IsSMPAssignable<VT2> > > > >::Type
226  smpAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
227 {
229 
230  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
231 
232  assign( ~lhs, ~rhs );
233 }
235 //*************************************************************************************************
236 
237 
238 //*************************************************************************************************
256 template< typename VT1 // Type of the left-hand side dense vector
257  , bool TF1 // Transpose flag of the left-hand side dense vector
258  , typename VT2 // Type of the right-hand side vector
259  , bool TF2 > // Transpose flag of the right-hand side vector
260 inline typename EnableIf< And< IsDenseVector<VT1>
261  , IsSMPAssignable<VT1>
262  , IsSMPAssignable<VT2> > >::Type
263  smpAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
264 {
266 
269 
270  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
271 
273  {
274  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
275  assign( ~lhs, ~rhs );
276  }
277  else {
278 #pragma omp parallel shared( lhs, rhs )
279  smpAssign_backend( ~lhs, ~rhs );
280  }
281  }
282 }
284 //*************************************************************************************************
285 
286 
287 
288 
289 //=================================================================================================
290 //
291 // ADDITION ASSIGNMENT
292 //
293 //=================================================================================================
294 
295 //*************************************************************************************************
311 template< typename VT1 // Type of the left-hand side dense vector
312  , bool TF1 // Transpose flag of the left-hand side dense vector
313  , typename VT2 // Type of the right-hand side dense vector
314  , bool TF2 > // Transpose flag of the right-hand side dense vector
315 void smpAddAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
316 {
318 
319  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
320 
321  typedef typename VT1::ElementType ET1;
322  typedef typename VT2::ElementType ET2;
323  typedef IntrinsicTrait<typename VT1::ElementType> IT;
324  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
325  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
326 
327  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
328  const bool lhsAligned ( (~lhs).isAligned() );
329  const bool rhsAligned ( (~rhs).isAligned() );
330 
331  const int threads ( omp_get_num_threads() );
332  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
333  const size_t equalShare ( (~lhs).size() / threads + addon );
334  const size_t rest ( equalShare & ( IT::size - 1UL ) );
335  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
336 
337 #pragma omp for schedule(dynamic,1) nowait
338  for( int i=0UL; i<threads; ++i )
339  {
340  const size_t index( i*sizePerThread );
341 
342  if( index >= (~lhs).size() )
343  continue;
344 
345  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
346 
347  if( vectorizable && lhsAligned && rhsAligned ) {
348  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
349  addAssign( target, subvector<aligned>( ~rhs, index, size ) );
350  }
351  else if( vectorizable && lhsAligned ) {
352  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
353  addAssign( target, subvector<unaligned>( ~rhs, index, size ) );
354  }
355  else if( vectorizable && rhsAligned ) {
356  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
357  addAssign( target, subvector<aligned>( ~rhs, index, size ) );
358  }
359  else {
360  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
361  addAssign( target, subvector<unaligned>( ~rhs, index, size ) );
362  }
363  }
364 }
366 //*************************************************************************************************
367 
368 
369 //*************************************************************************************************
385 template< typename VT1 // Type of the left-hand side dense vector
386  , bool TF1 // Transpose flag of the left-hand side dense vector
387  , typename VT2 // Type of the right-hand side sparse vector
388  , bool TF2 > // Transpose flag of the right-hand side sparse vector
389 void smpAddAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
390 {
392 
393  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
394 
395  typedef typename VT1::ElementType ET1;
396  typedef typename VT2::ElementType ET2;
397  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
398 
399  const int threads ( omp_get_num_threads() );
400  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
401  const size_t sizePerThread( (~lhs).size() / threads + addon );
402 
403 #pragma omp for schedule(dynamic,1) nowait
404  for( int i=0UL; i<threads; ++i )
405  {
406  const size_t index( i*sizePerThread );
407 
408  if( index >= (~lhs).size() )
409  continue;
410 
411  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
412  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
413  addAssign( target, subvector<unaligned>( ~rhs, index, size ) );
414  }
415 }
417 //*************************************************************************************************
418 
419 
420 //*************************************************************************************************
438 template< typename VT1 // Type of the left-hand side dense vector
439  , bool TF1 // Transpose flag of the left-hand side dense vector
440  , typename VT2 // Type of the right-hand side vector
441  , bool TF2 > // Transpose flag of the right-hand side vector
442 inline typename EnableIf< And< IsDenseVector<VT1>
443  , Or< Not< IsSMPAssignable<VT1> >
444  , Not< IsSMPAssignable<VT2> > > > >::Type
445  smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
446 {
448 
449  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
450 
451  addAssign( ~lhs, ~rhs );
452 }
454 //*************************************************************************************************
455 
456 
457 //*************************************************************************************************
475 template< typename VT1 // Type of the left-hand side dense vector
476  , bool TF1 // Transpose flag of the left-hand side dense vector
477  , typename VT2 // Type of the right-hand side vector
478  , bool TF2 > // Transpose flag of the right-hand side vector
479 inline typename EnableIf< And< IsDenseVector<VT1>
480  , IsSMPAssignable<VT1>
481  , IsSMPAssignable<VT2> > >::Type
482  smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
483 {
485 
488 
489  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
490 
492  {
493  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
494  addAssign( ~lhs, ~rhs );
495  }
496  else {
497 #pragma omp parallel shared( lhs, rhs )
498  smpAddAssign_backend( ~lhs, ~rhs );
499  }
500  }
501 }
503 //*************************************************************************************************
504 
505 
506 
507 
508 //=================================================================================================
509 //
510 // SUBTRACTION ASSIGNMENT
511 //
512 //=================================================================================================
513 
514 //*************************************************************************************************
530 template< typename VT1 // Type of the left-hand side dense vector
531  , bool TF1 // Transpose flag of the left-hand side dense vector
532  , typename VT2 // Type of the right-hand side dense vector
533  , bool TF2 > // Transpose flag of the right-hand side dense vector
534 void smpSubAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
535 {
537 
538  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
539 
540  typedef typename VT1::ElementType ET1;
541  typedef typename VT2::ElementType ET2;
542  typedef IntrinsicTrait<typename VT1::ElementType> IT;
543  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
544  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
545 
546  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
547  const bool lhsAligned ( (~lhs).isAligned() );
548  const bool rhsAligned ( (~rhs).isAligned() );
549 
550  const int threads ( omp_get_num_threads() );
551  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
552  const size_t equalShare ( (~lhs).size() / threads + addon );
553  const size_t rest ( equalShare & ( IT::size - 1UL ) );
554  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
555 
556 #pragma omp for schedule(dynamic,1) nowait
557  for( int i=0UL; i<threads; ++i )
558  {
559  const size_t index( i*sizePerThread );
560 
561  if( index >= (~lhs).size() )
562  continue;
563 
564  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
565 
566  if( vectorizable && lhsAligned && rhsAligned ) {
567  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
568  subAssign( target, subvector<aligned>( ~rhs, index, size ) );
569  }
570  else if( vectorizable && lhsAligned ) {
571  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
572  subAssign( target, subvector<unaligned>( ~rhs, index, size ) );
573  }
574  else if( vectorizable && rhsAligned ) {
575  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
576  subAssign( target, subvector<aligned>( ~rhs, index, size ) );
577  }
578  else {
579  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
580  subAssign( target, subvector<unaligned>( ~rhs, index, size ) );
581  }
582  }
583 }
585 //*************************************************************************************************
586 
587 
588 //*************************************************************************************************
604 template< typename VT1 // Type of the left-hand side dense vector
605  , bool TF1 // Transpose flag of the left-hand side dense vector
606  , typename VT2 // Type of the right-hand side sparse vector
607  , bool TF2 > // Transpose flag of the right-hand side sparse vector
608 void smpSubAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
609 {
611 
612  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
613 
614  typedef typename VT1::ElementType ET1;
615  typedef typename VT2::ElementType ET2;
616  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
617 
618  const int threads ( omp_get_num_threads() );
619  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
620  const size_t sizePerThread( (~lhs).size() / threads + addon );
621 
622 #pragma omp for schedule(dynamic,1) nowait
623  for( int i=0UL; i<threads; ++i )
624  {
625  const size_t index( i*sizePerThread );
626 
627  if( index >= (~lhs).size() )
628  continue;
629 
630  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
631  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
632  subAssign( target, subvector<unaligned>( ~rhs, index, size ) );
633  }
634 }
636 //*************************************************************************************************
637 
638 
639 //*************************************************************************************************
657 template< typename VT1 // Type of the left-hand side dense vector
658  , bool TF1 // Transpose flag of the left-hand side dense vector
659  , typename VT2 // Type of the right-hand side vector
660  , bool TF2 > // Transpose flag of the right-hand side vector
661 inline typename EnableIf< And< IsDenseVector<VT1>
662  , Or< Not< IsSMPAssignable<VT1> >
663  , Not< IsSMPAssignable<VT2> > > > >::Type
664  smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
665 {
667 
668  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
669 
670  subAssign( ~lhs, ~rhs );
671 }
673 //*************************************************************************************************
674 
675 
676 //*************************************************************************************************
694 template< typename VT1 // Type of the left-hand side dense vector
695  , bool TF1 // Transpose flag of the left-hand side dense vector
696  , typename VT2 // Type of the right-hand side vector
697  , bool TF2 > // Transpose flag of the right-hand side vector
698 inline typename EnableIf< And< IsDenseVector<VT1>
699  , IsSMPAssignable<VT1>
700  , IsSMPAssignable<VT2> > >::Type
701  smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
702 {
704 
707 
708  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
709 
711  {
712  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
713  subAssign( ~lhs, ~rhs );
714  }
715  else {
716 #pragma omp parallel shared( lhs, rhs )
717  smpSubAssign_backend( ~lhs, ~rhs );
718  }
719  }
720 }
722 //*************************************************************************************************
723 
724 
725 
726 
727 //=================================================================================================
728 //
729 // MULTIPLICATION ASSIGNMENT
730 //
731 //=================================================================================================
732 
733 //*************************************************************************************************
750 template< typename VT1 // Type of the left-hand side dense vector
751  , bool TF1 // Transpose flag of the left-hand side dense vector
752  , typename VT2 // Type of the right-hand side dense vector
753  , bool TF2 > // Transpose flag of the right-hand side dense vector
754 void smpMultAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
755 {
757 
758  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
759 
760  typedef typename VT1::ElementType ET1;
761  typedef typename VT2::ElementType ET2;
762  typedef IntrinsicTrait<typename VT1::ElementType> IT;
763  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
764  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
765 
766  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
767  const bool lhsAligned ( (~lhs).isAligned() );
768  const bool rhsAligned ( (~rhs).isAligned() );
769 
770  const int threads ( omp_get_num_threads() );
771  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
772  const size_t equalShare ( (~lhs).size() / threads + addon );
773  const size_t rest ( equalShare & ( IT::size - 1UL ) );
774  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
775 
776 #pragma omp for schedule(dynamic,1) nowait
777  for( int i=0UL; i<threads; ++i )
778  {
779  const size_t index( i*sizePerThread );
780 
781  if( index >= (~lhs).size() )
782  continue;
783 
784  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
785 
786  if( vectorizable && lhsAligned && rhsAligned ) {
787  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
788  multAssign( target, subvector<aligned>( ~rhs, index, size ) );
789  }
790  else if( vectorizable && lhsAligned ) {
791  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
792  multAssign( target, subvector<unaligned>( ~rhs, index, size ) );
793  }
794  else if( vectorizable && rhsAligned ) {
795  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
796  multAssign( target, subvector<aligned>( ~rhs, index, size ) );
797  }
798  else {
799  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
800  multAssign( target, subvector<unaligned>( ~rhs, index, size ) );
801  }
802  }
803 }
805 //*************************************************************************************************
806 
807 
808 //*************************************************************************************************
825 template< typename VT1 // Type of the left-hand side dense vector
826  , bool TF1 // Transpose flag of the left-hand side dense vector
827  , typename VT2 // Type of the right-hand side sparse vector
828  , bool TF2 > // Transpose flag of the right-hand side sparse vector
829 void smpMultAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
830 {
832 
833  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
834 
835  typedef typename VT1::ElementType ET1;
836  typedef typename VT2::ElementType ET2;
837  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
838 
839  const int threads ( omp_get_num_threads() );
840  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
841  const size_t sizePerThread( (~lhs).size() / threads + addon );
842 
843 #pragma omp for schedule(dynamic,1) nowait
844  for( int i=0UL; i<threads; ++i )
845  {
846  const size_t index( i*sizePerThread );
847 
848  if( index >= (~lhs).size() )
849  continue;
850 
851  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
852  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
853  multAssign( target, subvector<unaligned>( ~rhs, index, size ) );
854  }
855 }
857 //*************************************************************************************************
858 
859 
860 //*************************************************************************************************
878 template< typename VT1 // Type of the left-hand side dense vector
879  , bool TF1 // Transpose flag of the left-hand side dense vector
880  , typename VT2 // Type of the right-hand side vector
881  , bool TF2 > // Transpose flag of the right-hand side vector
882 inline typename EnableIf< And< IsDenseVector<VT1>
883  , Or< Not< IsSMPAssignable<VT1> >
884  , Not< IsSMPAssignable<VT2> > > > >::Type
885  smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
886 {
888 
889  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
890 
891  multAssign( ~lhs, ~rhs );
892 }
894 //*************************************************************************************************
895 
896 
897 //*************************************************************************************************
915 template< typename VT1 // Type of the left-hand side dense vector
916  , bool TF1 // Transpose flag of the left-hand side dense vector
917  , typename VT2 // Type of the right-hand side vector
918  , bool TF2 > // Transpose flag of the right-hand side vector
919 inline typename EnableIf< And< IsDenseVector<VT1>
920  , IsSMPAssignable<VT1>
921  , IsSMPAssignable<VT2> > >::Type
922  smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
923 {
925 
928 
929  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
930 
932  {
933  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
934  multAssign( ~lhs, ~rhs );
935  }
936  else {
937 #pragma omp parallel shared( lhs, rhs )
938  smpMultAssign_backend( ~lhs, ~rhs );
939  }
940  }
941 }
943 //*************************************************************************************************
944 
945 
946 
947 
948 //=================================================================================================
949 //
950 // COMPILE TIME CONSTRAINTS
951 //
952 //=================================================================================================
953 
954 //*************************************************************************************************
956 namespace {
957 
959 
960 }
962 //*************************************************************************************************
963 
964 } // namespace blaze
965 
966 #endif
Header file for mathematical functions.
BLAZE_ALWAYS_INLINE 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:879
Header file for the SparseVector base class.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:258
Header file for the complete DenseSubvector implementation.
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.
Compile time assertion.
System settings for the shared-memory parallelization.
Header file for the IsSMPAssignable type trait.
Header file for the Or class template.
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:947
BLAZE_ALWAYS_INLINE 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:635
Header file for the Not class template.
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:2476
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
bool isSerialSectionActive()
Returns whether a serial section is active or not.
Definition: SerialSection.h:212
EnableIf< IsDenseMatrix< MT1 > >::Type 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
Header file for run time assertion macros.
EnableIf< IsDenseMatrix< MT1 > >::Type 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
BLAZE_ALWAYS_INLINE 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:742
Header file for the IsDenseVector type trait.
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
EnableIf< IsDenseMatrix< MT1 > >::Type 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
#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 basic type definitions.
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
EnableIf< IsDenseVector< VT1 > >::Type 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:189
#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.
BLAZE_ALWAYS_INLINE 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:849