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_THREADS_DENSEVECTOR_H_
36 #define _BLAZE_MATH_SMP_THREADS_DENSEVECTOR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
47 #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 size_t threads ( TheThreadBackend::size() );
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  for( size_t i=0UL; i<threads; ++i )
116  {
117  const size_t index( i*sizePerThread );
118 
119  if( index >= (~lhs).size() )
120  continue;
121 
122  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
123 
124  if( vectorizable && lhsAligned && rhsAligned ) {
125  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
126  TheThreadBackend::scheduleAssign( target, subvector<aligned>( ~rhs, index, size ) );
127  }
128  else if( vectorizable && lhsAligned ) {
129  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
130  TheThreadBackend::scheduleAssign( target, subvector<unaligned>( ~rhs, index, size ) );
131  }
132  else if( vectorizable && rhsAligned ) {
133  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
134  TheThreadBackend::scheduleAssign( target, subvector<aligned>( ~rhs, index, size ) );
135  }
136  else {
137  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
138  TheThreadBackend::scheduleAssign( target, subvector<unaligned>( ~rhs, index, size ) );
139  }
140  }
141 
142  TheThreadBackend::wait();
143 }
145 //*************************************************************************************************
146 
147 
148 //*************************************************************************************************
165 template< typename VT1 // Type of the left-hand side dense vector
166  , bool TF1 // Transpose flag of the left-hand side dense vector
167  , typename VT2 // Type of the right-hand side dense vector
168  , bool TF2 > // Transpose flag of the right-hand side dense vector
169 void smpAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
170 {
172 
173  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
174 
175  typedef typename VT1::ElementType ET1;
176  typedef typename VT2::ElementType ET2;
177  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
178 
179  const size_t threads ( TheThreadBackend::size() );
180  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
181  const size_t sizePerThread( (~lhs).size() / threads + addon );
182 
183  for( size_t i=0UL; i<threads; ++i )
184  {
185  const size_t index( i*sizePerThread );
186 
187  if( index >= (~lhs).size() )
188  continue;
189 
190  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
191  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
192  TheThreadBackend::scheduleAssign( target, subvector<unaligned>( ~rhs, index, size ) );
193  }
194 
195  TheThreadBackend::wait();
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 DisableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
224  smpAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
225 {
227 
228  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
229 
230  assign( ~lhs, ~rhs );
231 }
233 //*************************************************************************************************
234 
235 
236 //*************************************************************************************************
254 template< typename VT1 // Type of the left-hand side dense vector
255  , bool TF1 // Transpose flag of the left-hand side dense vector
256  , typename VT2 // Type of the right-hand side dense vector
257  , bool TF2 > // Transpose flag of the right-hand side dense vector
258 inline typename EnableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
259  smpAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
260 {
262 
265 
266  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
267 
269  {
270  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
271  assign( ~lhs, ~rhs );
272  }
273  else {
274  smpAssign_backend( ~lhs, ~rhs );
275  }
276  }
277 }
279 //*************************************************************************************************
280 
281 
282 
283 
284 //=================================================================================================
285 //
286 // ADDITION ASSIGNMENT
287 //
288 //=================================================================================================
289 
290 //*************************************************************************************************
307 template< typename VT1 // Type of the left-hand side dense vector
308  , bool TF1 // Transpose flag of the left-hand side dense vector
309  , typename VT2 // Type of the right-hand side dense vector
310  , bool TF2 > // Transpose flag of the right-hand side dense vector
311 void smpAddAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
312 {
314 
315  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
316 
317  typedef typename VT1::ElementType ET1;
318  typedef typename VT2::ElementType ET2;
319  typedef IntrinsicTrait<typename VT1::ElementType> IT;
320  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
321  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
322 
323  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
324  const bool lhsAligned ( (~lhs).isAligned() );
325  const bool rhsAligned ( (~rhs).isAligned() );
326 
327  const size_t threads ( TheThreadBackend::size() );
328  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
329  const size_t equalShare ( (~lhs).size() / threads + addon );
330  const size_t rest ( equalShare & ( IT::size - 1UL ) );
331  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
332 
333  for( size_t i=0UL; i<threads; ++i )
334  {
335  const size_t index( i*sizePerThread );
336 
337  if( index >= (~lhs).size() )
338  continue;
339 
340  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
341 
342  if( vectorizable && lhsAligned && rhsAligned ) {
343  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
344  TheThreadBackend::scheduleAddAssign( target, subvector<aligned>( ~rhs, index, size ) );
345  }
346  else if( vectorizable && lhsAligned ) {
347  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
348  TheThreadBackend::scheduleAddAssign( target, subvector<unaligned>( ~rhs, index, size ) );
349  }
350  else if( vectorizable && rhsAligned ) {
351  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
352  TheThreadBackend::scheduleAddAssign( target, subvector<aligned>( ~rhs, index, size ) );
353  }
354  else {
355  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
356  TheThreadBackend::scheduleAddAssign( target, subvector<unaligned>( ~rhs, index, size ) );
357  }
358  }
359 
360  TheThreadBackend::wait();
361 }
363 //*************************************************************************************************
364 
365 
366 //*************************************************************************************************
383 template< typename VT1 // Type of the left-hand side dense vector
384  , bool TF1 // Transpose flag of the left-hand side dense vector
385  , typename VT2 // Type of the right-hand side dense vector
386  , bool TF2 > // Transpose flag of the right-hand side dense vector
387 void smpAddAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
388 {
390 
391  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
392 
393  typedef typename VT1::ElementType ET1;
394  typedef typename VT2::ElementType ET2;
395  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
396 
397  const size_t threads ( TheThreadBackend::size() );
398  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
399  const size_t sizePerThread( (~lhs).size() / threads + addon );
400 
401  for( size_t i=0UL; i<threads; ++i )
402  {
403  const size_t index( i*sizePerThread );
404 
405  if( index >= (~lhs).size() )
406  continue;
407 
408  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
409  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
410  TheThreadBackend::scheduleAddAssign( target, subvector<unaligned>( ~rhs, index, size ) );
411  }
412 
413  TheThreadBackend::wait();
414 }
416 //*************************************************************************************************
417 
418 
419 //*************************************************************************************************
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 DisableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
443  smpAddAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
444 {
446 
447  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
448 
449  addAssign( ~lhs, ~rhs );
450 }
452 //*************************************************************************************************
453 
454 
455 //*************************************************************************************************
473 template< typename VT1 // Type of the left-hand side dense vector
474  , bool TF1 // Transpose flag of the left-hand side dense vector
475  , typename VT2 // Type of the right-hand side dense vector
476  , bool TF2 > // Transpose flag of the right-hand side dense vector
477 inline typename EnableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
478  smpAddAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
479 {
481 
484 
485  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
486 
488  {
489  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
490  addAssign( ~lhs, ~rhs );
491  }
492  else {
493  smpAddAssign_backend( ~lhs, ~rhs );
494  }
495  }
496 }
498 //*************************************************************************************************
499 
500 
501 
502 
503 //=================================================================================================
504 //
505 // SUBTRACTION ASSIGNMENT
506 //
507 //=================================================================================================
508 
509 //*************************************************************************************************
526 template< typename VT1 // Type of the left-hand side dense vector
527  , bool TF1 // Transpose flag of the left-hand side dense vector
528  , typename VT2 // Type of the right-hand side dense vector
529  , bool TF2 > // Transpose flag of the right-hand side dense vector
530 void smpSubAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
531 {
533 
534  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
535 
536  typedef typename VT1::ElementType ET1;
537  typedef typename VT2::ElementType ET2;
538  typedef IntrinsicTrait<typename VT1::ElementType> IT;
539  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
540  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
541 
542  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
543  const bool lhsAligned ( (~lhs).isAligned() );
544  const bool rhsAligned ( (~rhs).isAligned() );
545 
546  const size_t threads ( TheThreadBackend::size() );
547  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
548  const size_t equalShare ( (~lhs).size() / threads + addon );
549  const size_t rest ( equalShare & ( IT::size - 1UL ) );
550  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
551 
552  for( size_t i=0UL; i<threads; ++i )
553  {
554  const size_t index( i*sizePerThread );
555 
556  if( index >= (~lhs).size() )
557  continue;
558 
559  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
560 
561  if( vectorizable && lhsAligned && rhsAligned ) {
562  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
563  TheThreadBackend::scheduleSubAssign( target, subvector<aligned>( ~rhs, index, size ) );
564  }
565  else if( vectorizable && lhsAligned ) {
566  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
567  TheThreadBackend::scheduleSubAssign( target, subvector<unaligned>( ~rhs, index, size ) );
568  }
569  else if( vectorizable && rhsAligned ) {
570  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
571  TheThreadBackend::scheduleSubAssign( target, subvector<aligned>( ~rhs, index, size ) );
572  }
573  else {
574  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
575  TheThreadBackend::scheduleSubAssign( target, subvector<unaligned>( ~rhs, index, size ) );
576  }
577  }
578 
579  TheThreadBackend::wait();
580 }
582 //*************************************************************************************************
583 
584 
585 //*************************************************************************************************
602 template< typename VT1 // Type of the left-hand side dense vector
603  , bool TF1 // Transpose flag of the left-hand side dense vector
604  , typename VT2 // Type of the right-hand side dense vector
605  , bool TF2 > // Transpose flag of the right-hand side dense vector
606 void smpSubAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
607 {
609 
610  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
611 
612  typedef typename VT1::ElementType ET1;
613  typedef typename VT2::ElementType ET2;
614  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
615 
616  const size_t threads ( TheThreadBackend::size() );
617  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
618  const size_t sizePerThread( (~lhs).size() / threads + addon );
619 
620  for( size_t i=0UL; i<threads; ++i )
621  {
622  const size_t index( i*sizePerThread );
623 
624  if( index >= (~lhs).size() )
625  continue;
626 
627  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
628  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
629  TheThreadBackend::scheduleSubAssign( target, subvector<unaligned>( ~rhs, index, size ) );
630  }
631 
632  TheThreadBackend::wait();
633 }
635 //*************************************************************************************************
636 
637 
638 //*************************************************************************************************
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 DisableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
662  smpSubAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
663 {
665 
666  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
667 
668  subAssign( ~lhs, ~rhs );
669 }
671 //*************************************************************************************************
672 
673 
674 //*************************************************************************************************
693 template< typename VT1 // Type of the left-hand side dense vector
694  , bool TF1 // Transpose flag of the left-hand side dense vector
695  , typename VT2 // Type of the right-hand side dense vector
696  , bool TF2 > // Transpose flag of the right-hand side dense vector
697 inline typename EnableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
698  smpSubAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
699 {
701 
704 
705  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
706 
708  {
709  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
710  subAssign( ~lhs, ~rhs );
711  }
712  else {
713  smpSubAssign_backend( ~lhs, ~rhs );
714  }
715  }
716 }
718 //*************************************************************************************************
719 
720 
721 
722 
723 //=================================================================================================
724 //
725 // MULTIPLICATION ASSIGNMENT
726 //
727 //=================================================================================================
728 
729 //*************************************************************************************************
746 template< typename VT1 // Type of the left-hand side dense vector
747  , bool TF1 // Transpose flag of the left-hand side dense vector
748  , typename VT2 // Type of the right-hand side dense vector
749  , bool TF2 > // Transpose flag of the right-hand side dense vector
750 void smpMultAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
751 {
753 
754  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
755 
756  typedef typename VT1::ElementType ET1;
757  typedef typename VT2::ElementType ET2;
758  typedef IntrinsicTrait<typename VT1::ElementType> IT;
759  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
760  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
761 
762  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
763  const bool lhsAligned ( (~lhs).isAligned() );
764  const bool rhsAligned ( (~rhs).isAligned() );
765 
766  const size_t threads ( TheThreadBackend::size() );
767  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
768  const size_t equalShare ( (~lhs).size() / threads + addon );
769  const size_t rest ( equalShare & ( IT::size - 1UL ) );
770  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
771 
772  for( size_t i=0UL; i<threads; ++i )
773  {
774  const size_t index( i*sizePerThread );
775 
776  if( index >= (~lhs).size() )
777  continue;
778 
779  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
780 
781  if( vectorizable && lhsAligned && rhsAligned ) {
782  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
783  TheThreadBackend::scheduleMultAssign( target, subvector<aligned>( ~rhs, index, size ) );
784  }
785  else if( vectorizable && lhsAligned ) {
786  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
787  TheThreadBackend::scheduleMultAssign( target, subvector<unaligned>( ~rhs, index, size ) );
788  }
789  else if( vectorizable && rhsAligned ) {
790  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
791  TheThreadBackend::scheduleMultAssign( target, subvector<aligned>( ~rhs, index, size ) );
792  }
793  else {
794  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
795  TheThreadBackend::scheduleMultAssign( target, subvector<unaligned>( ~rhs, index, size ) );
796  }
797  }
798 
799  TheThreadBackend::wait();
800 }
802 //*************************************************************************************************
803 
804 
805 //*************************************************************************************************
822 template< typename VT1 // Type of the left-hand side dense vector
823  , bool TF1 // Transpose flag of the left-hand side dense vector
824  , typename VT2 // Type of the right-hand side dense vector
825  , bool TF2 > // Transpose flag of the right-hand side dense vector
826 void smpMultAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
827 {
829 
830  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
831 
832  typedef typename VT1::ElementType ET1;
833  typedef typename VT2::ElementType ET2;
834  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
835 
836  const size_t threads ( TheThreadBackend::size() );
837  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
838  const size_t sizePerThread( (~lhs).size() / threads + addon );
839 
840  for( size_t i=0UL; i<threads; ++i )
841  {
842  const size_t index( i*sizePerThread );
843 
844  if( index >= (~lhs).size() )
845  continue;
846 
847  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
848  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
849  TheThreadBackend::scheduleMultAssign( target, subvector<unaligned>( ~rhs, index, size ) );
850  }
851 
852  TheThreadBackend::wait();
853 }
855 //*************************************************************************************************
856 
857 
858 //*************************************************************************************************
877 template< typename VT1 // Type of the left-hand side dense vector
878  , bool TF1 // Transpose flag of the left-hand side dense vector
879  , typename VT2 // Type of the right-hand side vector
880  , bool TF2 > // Transpose flag of the right-hand side vector
881 inline typename DisableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
882  smpMultAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
883 {
885 
886  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
887 
888  multAssign( ~lhs, ~rhs );
889 }
891 //*************************************************************************************************
892 
893 
894 //*************************************************************************************************
913 template< typename VT1 // Type of the left-hand side dense vector
914  , bool TF1 // Transpose flag of the left-hand side dense vector
915  , typename VT2 // Type of the right-hand side dense vector
916  , bool TF2 > // Transpose flag of the right-hand side dense vector
917 inline typename EnableIf< And< IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >::Type
918  smpMultAssign( DenseVector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
919 {
921 
924 
925  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
926 
928  {
929  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
930  multAssign( ~lhs, ~rhs );
931  }
932  else {
933  smpMultAssign_backend( ~lhs, ~rhs );
934  }
935  }
936 }
938 //*************************************************************************************************
939 
940 
941 
942 
943 //=================================================================================================
944 //
945 // COMPILE TIME CONSTRAINTS
946 //
947 //=================================================================================================
948 
949 //*************************************************************************************************
951 namespace {
952 
954 
955 }
957 //*************************************************************************************************
958 
959 } // namespace blaze
960 
961 #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.
#define BLAZE_BOOST_THREADS_PARALLEL_MODE
Compilation switch for the Boost parallelization.This compilation switch enables/disables the paralle...
Definition: SMP.h:122
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.
#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.
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_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
Header file for the C++11 and Boost thread backend.
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.