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>
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 size_t threads ( TheThreadBackend::size() );
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  for( size_t i=0UL; i<threads; ++i )
119  {
120  const size_t index( i*sizePerThread );
121 
122  if( index >= (~lhs).size() )
123  continue;
124 
125  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
126 
127  if( vectorizable && lhsAligned && rhsAligned ) {
128  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
129  TheThreadBackend::scheduleAssign( target, subvector<aligned>( ~rhs, index, size ) );
130  }
131  else if( vectorizable && lhsAligned ) {
132  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
133  TheThreadBackend::scheduleAssign( target, subvector<unaligned>( ~rhs, index, size ) );
134  }
135  else if( vectorizable && rhsAligned ) {
136  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
137  TheThreadBackend::scheduleAssign( target, subvector<aligned>( ~rhs, index, size ) );
138  }
139  else {
140  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
141  TheThreadBackend::scheduleAssign( target, subvector<unaligned>( ~rhs, index, size ) );
142  }
143  }
144 
145  TheThreadBackend::wait();
146 }
148 //*************************************************************************************************
149 
150 
151 //*************************************************************************************************
168 template< typename VT1 // Type of the left-hand side dense vector
169  , bool TF1 // Transpose flag of the left-hand side dense vector
170  , typename VT2 // Type of the right-hand side sparse vector
171  , bool TF2 > // Transpose flag of the right-hand side sparse vector
172 void smpAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
173 {
175 
176  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
177 
178  typedef typename VT1::ElementType ET1;
179  typedef typename VT2::ElementType ET2;
180  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
181 
182  const size_t threads ( TheThreadBackend::size() );
183  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
184  const size_t sizePerThread( (~lhs).size() / threads + addon );
185 
186  for( size_t i=0UL; i<threads; ++i )
187  {
188  const size_t index( i*sizePerThread );
189 
190  if( index >= (~lhs).size() )
191  continue;
192 
193  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
194  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
195  TheThreadBackend::scheduleAssign( target, subvector<unaligned>( ~rhs, index, size ) );
196  }
197 
198  TheThreadBackend::wait();
199 }
201 //*************************************************************************************************
202 
203 
204 //*************************************************************************************************
222 template< typename VT1 // Type of the left-hand side dense vector
223  , bool TF1 // Transpose flag of the left-hand side dense vector
224  , typename VT2 // Type of the right-hand side vector
225  , bool TF2 > // Transpose flag of the right-hand side vector
226 inline typename EnableIf< And< IsDenseVector<VT1>
227  , Or< Not< IsSMPAssignable<VT1> >
228  , Not< IsSMPAssignable<VT2> > > > >::Type
229  smpAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
230 {
232 
233  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
234 
235  assign( ~lhs, ~rhs );
236 }
238 //*************************************************************************************************
239 
240 
241 //*************************************************************************************************
259 template< typename VT1 // Type of the left-hand side dense vector
260  , bool TF1 // Transpose flag of the left-hand side dense vector
261  , typename VT2 // Type of the right-hand side vector
262  , bool TF2 > // Transpose flag of the right-hand side vector
263 inline typename EnableIf< And< IsDenseVector<VT1>
264  , IsSMPAssignable<VT1>
265  , IsSMPAssignable<VT2> > >::Type
266  smpAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
267 {
269 
272 
273  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
274 
276  {
277  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
278  assign( ~lhs, ~rhs );
279  }
280  else {
281  smpAssign_backend( ~lhs, ~rhs );
282  }
283  }
284 }
286 //*************************************************************************************************
287 
288 
289 
290 
291 //=================================================================================================
292 //
293 // ADDITION ASSIGNMENT
294 //
295 //=================================================================================================
296 
297 //*************************************************************************************************
314 template< typename VT1 // Type of the left-hand side dense vector
315  , bool TF1 // Transpose flag of the left-hand side dense vector
316  , typename VT2 // Type of the right-hand side dense vector
317  , bool TF2 > // Transpose flag of the right-hand side dense vector
318 void smpAddAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
319 {
321 
322  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
323 
324  typedef typename VT1::ElementType ET1;
325  typedef typename VT2::ElementType ET2;
326  typedef IntrinsicTrait<typename VT1::ElementType> IT;
327  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
328  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
329 
330  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
331  const bool lhsAligned ( (~lhs).isAligned() );
332  const bool rhsAligned ( (~rhs).isAligned() );
333 
334  const size_t threads ( TheThreadBackend::size() );
335  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
336  const size_t equalShare ( (~lhs).size() / threads + addon );
337  const size_t rest ( equalShare & ( IT::size - 1UL ) );
338  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
339 
340  for( size_t i=0UL; i<threads; ++i )
341  {
342  const size_t index( i*sizePerThread );
343 
344  if( index >= (~lhs).size() )
345  continue;
346 
347  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
348 
349  if( vectorizable && lhsAligned && rhsAligned ) {
350  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
351  TheThreadBackend::scheduleAddAssign( target, subvector<aligned>( ~rhs, index, size ) );
352  }
353  else if( vectorizable && lhsAligned ) {
354  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
355  TheThreadBackend::scheduleAddAssign( target, subvector<unaligned>( ~rhs, index, size ) );
356  }
357  else if( vectorizable && rhsAligned ) {
358  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
359  TheThreadBackend::scheduleAddAssign( target, subvector<aligned>( ~rhs, index, size ) );
360  }
361  else {
362  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
363  TheThreadBackend::scheduleAddAssign( target, subvector<unaligned>( ~rhs, index, size ) );
364  }
365  }
366 
367  TheThreadBackend::wait();
368 }
370 //*************************************************************************************************
371 
372 
373 //*************************************************************************************************
390 template< typename VT1 // Type of the left-hand side dense vector
391  , bool TF1 // Transpose flag of the left-hand side dense vector
392  , typename VT2 // Type of the right-hand side sparse vector
393  , bool TF2 > // Transpose flag of the right-hand side sparse vector
394 void smpAddAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
395 {
397 
398  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
399 
400  typedef typename VT1::ElementType ET1;
401  typedef typename VT2::ElementType ET2;
402  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
403 
404  const size_t threads ( TheThreadBackend::size() );
405  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
406  const size_t sizePerThread( (~lhs).size() / threads + addon );
407 
408  for( size_t i=0UL; i<threads; ++i )
409  {
410  const size_t index( i*sizePerThread );
411 
412  if( index >= (~lhs).size() )
413  continue;
414 
415  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
416  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
417  TheThreadBackend::scheduleAddAssign( target, subvector<unaligned>( ~rhs, index, size ) );
418  }
419 
420  TheThreadBackend::wait();
421 }
423 //*************************************************************************************************
424 
425 
426 //*************************************************************************************************
445 template< typename VT1 // Type of the left-hand side dense vector
446  , bool TF1 // Transpose flag of the left-hand side dense vector
447  , typename VT2 // Type of the right-hand side vector
448  , bool TF2 > // Transpose flag of the right-hand side vector
449 inline typename EnableIf< And< IsDenseVector<VT1>
450  , Or< Not< IsSMPAssignable<VT1> >
451  , Not< IsSMPAssignable<VT2> > > > >::Type
452  smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
453 {
455 
456  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
457 
458  addAssign( ~lhs, ~rhs );
459 }
461 //*************************************************************************************************
462 
463 
464 //*************************************************************************************************
482 template< typename VT1 // Type of the left-hand side dense vector
483  , bool TF1 // Transpose flag of the left-hand side dense vector
484  , typename VT2 // Type of the right-hand side vector
485  , bool TF2 > // Transpose flag of the right-hand side vector
486 inline typename EnableIf< And< IsDenseVector<VT1>
487  , IsSMPAssignable<VT1>
488  , IsSMPAssignable<VT2> > >::Type
489  smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
490 {
492 
495 
496  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
497 
499  {
500  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
501  addAssign( ~lhs, ~rhs );
502  }
503  else {
504  smpAddAssign_backend( ~lhs, ~rhs );
505  }
506  }
507 }
509 //*************************************************************************************************
510 
511 
512 
513 
514 //=================================================================================================
515 //
516 // SUBTRACTION ASSIGNMENT
517 //
518 //=================================================================================================
519 
520 //*************************************************************************************************
537 template< typename VT1 // Type of the left-hand side dense vector
538  , bool TF1 // Transpose flag of the left-hand side dense vector
539  , typename VT2 // Type of the right-hand side dense vector
540  , bool TF2 > // Transpose flag of the right-hand side dense vector
541 void smpSubAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
542 {
544 
545  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
546 
547  typedef typename VT1::ElementType ET1;
548  typedef typename VT2::ElementType ET2;
549  typedef IntrinsicTrait<typename VT1::ElementType> IT;
550  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
551  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
552 
553  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
554  const bool lhsAligned ( (~lhs).isAligned() );
555  const bool rhsAligned ( (~rhs).isAligned() );
556 
557  const size_t threads ( TheThreadBackend::size() );
558  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
559  const size_t equalShare ( (~lhs).size() / threads + addon );
560  const size_t rest ( equalShare & ( IT::size - 1UL ) );
561  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
562 
563  for( size_t i=0UL; i<threads; ++i )
564  {
565  const size_t index( i*sizePerThread );
566 
567  if( index >= (~lhs).size() )
568  continue;
569 
570  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
571 
572  if( vectorizable && lhsAligned && rhsAligned ) {
573  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
574  TheThreadBackend::scheduleSubAssign( target, subvector<aligned>( ~rhs, index, size ) );
575  }
576  else if( vectorizable && lhsAligned ) {
577  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
578  TheThreadBackend::scheduleSubAssign( target, subvector<unaligned>( ~rhs, index, size ) );
579  }
580  else if( vectorizable && rhsAligned ) {
581  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
582  TheThreadBackend::scheduleSubAssign( target, subvector<aligned>( ~rhs, index, size ) );
583  }
584  else {
585  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
586  TheThreadBackend::scheduleSubAssign( target, subvector<unaligned>( ~rhs, index, size ) );
587  }
588  }
589 
590  TheThreadBackend::wait();
591 }
593 //*************************************************************************************************
594 
595 
596 //*************************************************************************************************
613 template< typename VT1 // Type of the left-hand side dense vector
614  , bool TF1 // Transpose flag of the left-hand side dense vector
615  , typename VT2 // Type of the right-hand side sparse vector
616  , bool TF2 > // Transpose flag of the right-hand side sparse vector
617 void smpSubAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
618 {
620 
621  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
622 
623  typedef typename VT1::ElementType ET1;
624  typedef typename VT2::ElementType ET2;
625  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
626 
627  const size_t threads ( TheThreadBackend::size() );
628  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
629  const size_t sizePerThread( (~lhs).size() / threads + addon );
630 
631  for( size_t i=0UL; i<threads; ++i )
632  {
633  const size_t index( i*sizePerThread );
634 
635  if( index >= (~lhs).size() )
636  continue;
637 
638  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
639  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
640  TheThreadBackend::scheduleSubAssign( target, subvector<unaligned>( ~rhs, index, size ) );
641  }
642 
643  TheThreadBackend::wait();
644 }
646 //*************************************************************************************************
647 
648 
649 //*************************************************************************************************
668 template< typename VT1 // Type of the left-hand side dense vector
669  , bool TF1 // Transpose flag of the left-hand side dense vector
670  , typename VT2 // Type of the right-hand side vector
671  , bool TF2 > // Transpose flag of the right-hand side vector
672 inline typename EnableIf< And< IsDenseVector<VT1>
673  , Or< Not< IsSMPAssignable<VT1> >
674  , Not< IsSMPAssignable<VT2> > > > >::Type
675  smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
676 {
678 
679  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
680 
681  subAssign( ~lhs, ~rhs );
682 }
684 //*************************************************************************************************
685 
686 
687 //*************************************************************************************************
706 template< typename VT1 // Type of the left-hand side dense vector
707  , bool TF1 // Transpose flag of the left-hand side dense vector
708  , typename VT2 // Type of the right-hand side vector
709  , bool TF2 > // Transpose flag of the right-hand side vector
710 inline typename EnableIf< And< IsDenseVector<VT1>
711  , IsSMPAssignable<VT1>
712  , IsSMPAssignable<VT2> > >::Type
713  smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
714 {
716 
719 
720  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
721 
723  {
724  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
725  subAssign( ~lhs, ~rhs );
726  }
727  else {
728  smpSubAssign_backend( ~lhs, ~rhs );
729  }
730  }
731 }
733 //*************************************************************************************************
734 
735 
736 
737 
738 //=================================================================================================
739 //
740 // MULTIPLICATION ASSIGNMENT
741 //
742 //=================================================================================================
743 
744 //*************************************************************************************************
761 template< typename VT1 // Type of the left-hand side dense vector
762  , bool TF1 // Transpose flag of the left-hand side dense vector
763  , typename VT2 // Type of the right-hand side dense vector
764  , bool TF2 > // Transpose flag of the right-hand side dense vector
765 void smpMultAssign_backend( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs )
766 {
768 
769  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
770 
771  typedef typename VT1::ElementType ET1;
772  typedef typename VT2::ElementType ET2;
773  typedef IntrinsicTrait<typename VT1::ElementType> IT;
774  typedef typename SubvectorExprTrait<VT1,aligned>::Type AlignedTarget;
775  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
776 
777  const bool vectorizable( VT1::vectorizable && VT2::vectorizable && IsSame<ET1,ET2>::value );
778  const bool lhsAligned ( (~lhs).isAligned() );
779  const bool rhsAligned ( (~rhs).isAligned() );
780 
781  const size_t threads ( TheThreadBackend::size() );
782  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
783  const size_t equalShare ( (~lhs).size() / threads + addon );
784  const size_t rest ( equalShare & ( IT::size - 1UL ) );
785  const size_t sizePerThread( ( vectorizable && rest )?( equalShare - rest + IT::size ):( equalShare ) );
786 
787  for( size_t i=0UL; i<threads; ++i )
788  {
789  const size_t index( i*sizePerThread );
790 
791  if( index >= (~lhs).size() )
792  continue;
793 
794  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
795 
796  if( vectorizable && lhsAligned && rhsAligned ) {
797  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
798  TheThreadBackend::scheduleMultAssign( target, subvector<aligned>( ~rhs, index, size ) );
799  }
800  else if( vectorizable && lhsAligned ) {
801  AlignedTarget target( subvector<aligned>( ~lhs, index, size ) );
802  TheThreadBackend::scheduleMultAssign( target, subvector<unaligned>( ~rhs, index, size ) );
803  }
804  else if( vectorizable && rhsAligned ) {
805  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
806  TheThreadBackend::scheduleMultAssign( target, subvector<aligned>( ~rhs, index, size ) );
807  }
808  else {
809  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
810  TheThreadBackend::scheduleMultAssign( target, subvector<unaligned>( ~rhs, index, size ) );
811  }
812  }
813 
814  TheThreadBackend::wait();
815 }
817 //*************************************************************************************************
818 
819 
820 //*************************************************************************************************
837 template< typename VT1 // Type of the left-hand side dense vector
838  , bool TF1 // Transpose flag of the left-hand side dense vector
839  , typename VT2 // Type of the right-hand side sparse vector
840  , bool TF2 > // Transpose flag of the right-hand side sparse vector
841 void smpMultAssign_backend( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs )
842 {
844 
845  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
846 
847  typedef typename VT1::ElementType ET1;
848  typedef typename VT2::ElementType ET2;
849  typedef typename SubvectorExprTrait<VT1,unaligned>::Type UnalignedTarget;
850 
851  const size_t threads ( TheThreadBackend::size() );
852  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
853  const size_t sizePerThread( (~lhs).size() / threads + addon );
854 
855  for( size_t i=0UL; i<threads; ++i )
856  {
857  const size_t index( i*sizePerThread );
858 
859  if( index >= (~lhs).size() )
860  continue;
861 
862  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
863  UnalignedTarget target( subvector<unaligned>( ~lhs, index, size ) );
864  TheThreadBackend::scheduleMultAssign( target, subvector<unaligned>( ~rhs, index, size ) );
865  }
866 
867  TheThreadBackend::wait();
868 }
870 //*************************************************************************************************
871 
872 
873 //*************************************************************************************************
892 template< typename VT1 // Type of the left-hand side dense vector
893  , bool TF1 // Transpose flag of the left-hand side dense vector
894  , typename VT2 // Type of the right-hand side vector
895  , bool TF2 > // Transpose flag of the right-hand side vector
896 inline typename EnableIf< And< IsDenseVector<VT1>
897  , Or< Not< IsSMPAssignable<VT1> >
898  , Not< IsSMPAssignable<VT2> > > > >::Type
899  smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
900 {
902 
903  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
904 
905  multAssign( ~lhs, ~rhs );
906 }
908 //*************************************************************************************************
909 
910 
911 //*************************************************************************************************
930 template< typename VT1 // Type of the left-hand side dense vector
931  , bool TF1 // Transpose flag of the left-hand side dense vector
932  , typename VT2 // Type of the right-hand side vector
933  , bool TF2 > // Transpose flag of the right-hand side vector
934 inline typename EnableIf< And< IsDenseVector<VT1>
935  , IsSMPAssignable<VT1>
936  , IsSMPAssignable<VT2> > >::Type
937  smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
938 {
940 
943 
944  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
945 
947  {
948  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
949  multAssign( ~lhs, ~rhs );
950  }
951  else {
952  smpMultAssign_backend( ~lhs, ~rhs );
953  }
954  }
955 }
957 //*************************************************************************************************
958 
959 
960 
961 
962 //=================================================================================================
963 //
964 // COMPILE TIME CONSTRAINTS
965 //
966 //=================================================================================================
967 
968 //*************************************************************************************************
970 namespace {
971 
973 
974 }
976 //*************************************************************************************************
977 
978 } // namespace blaze
979 
980 #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 basic type definitions.
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:264
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
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.
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.
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:1602
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.
#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:2505
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
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 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
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