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 
43 #include <blaze/math/Aliases.h>
60 #include <blaze/system/SMP.h>
62 #include <blaze/util/Assert.h>
63 #include <blaze/util/EnableIf.h>
65 #include <blaze/util/mpl/And.h>
66 #include <blaze/util/mpl/Not.h>
67 #include <blaze/util/mpl/Or.h>
69 #include <blaze/util/Types.h>
70 
71 
72 namespace blaze {
73 
74 //=================================================================================================
75 //
76 // THREAD-BASED ASSIGNMENT KERNELS
77 //
78 //=================================================================================================
79 
80 //*************************************************************************************************
98 template< typename VT1 // Type of the left-hand side dense vector
99  , bool TF1 // Transpose flag of the left-hand side dense vector
100  , typename VT2 // Type of the right-hand side dense vector
101  , bool TF2 // Transpose flag of the right-hand side dense vector
102  , typename OP > // Type of the assignment operation
103 void threadAssign( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs, OP op )
104 {
106 
107  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
108 
109  using ET1 = ElementType_<VT1>;
110  using ET2 = ElementType_<VT2>;
111 
112  constexpr bool simdEnabled( VT1::simdEnabled && VT2::simdEnabled && IsSIMDCombinable<ET1,ET2>::value );
113  constexpr size_t SIMDSIZE( SIMDTrait< ElementType_<VT1> >::size );
114 
115  const bool lhsAligned( (~lhs).isAligned() );
116  const bool rhsAligned( (~rhs).isAligned() );
117 
118  const size_t threads ( TheThreadBackend::size() );
119  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
120  const size_t equalShare ( (~lhs).size() / threads + addon );
121  const size_t rest ( equalShare & ( SIMDSIZE - 1UL ) );
122  const size_t sizePerThread( ( simdEnabled && rest )?( equalShare - rest + SIMDSIZE ):( equalShare ) );
123 
124  for( size_t i=0UL; i<threads; ++i )
125  {
126  const size_t index( i*sizePerThread );
127 
128  if( index >= (~lhs).size() )
129  continue;
130 
131  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
132 
133  if( simdEnabled && lhsAligned && rhsAligned ) {
134  auto target( subvector<aligned>( ~lhs, index, size, unchecked ) );
135  const auto source( subvector<aligned>( ~rhs, index, size, unchecked ) );
136  TheThreadBackend::schedule( target, source, op );
137  }
138  else if( simdEnabled && lhsAligned ) {
139  auto target( subvector<aligned>( ~lhs, index, size, unchecked ) );
140  const auto source( subvector<unaligned>( ~rhs, index, size, unchecked ) );
141  TheThreadBackend::schedule( target, source, op );
142  }
143  else if( simdEnabled && rhsAligned ) {
144  auto target( subvector<unaligned>( ~lhs, index, size, unchecked ) );
145  const auto source( subvector<aligned>( ~rhs, index, size, unchecked ) );
146  TheThreadBackend::schedule( target, source, op );
147  }
148  else {
149  auto target( subvector<unaligned>( ~lhs, index, size, unchecked ) );
150  const auto source( subvector<unaligned>( ~rhs, index, size, unchecked ) );
151  TheThreadBackend::schedule( target, source, op );
152  }
153  }
154 
155  TheThreadBackend::wait();
156 }
158 //*************************************************************************************************
159 
160 
161 //*************************************************************************************************
179 template< typename VT1 // Type of the left-hand side dense vector
180  , bool TF1 // Transpose flag of the left-hand side dense vector
181  , typename VT2 // Type of the right-hand side sparse vector
182  , bool TF2 // Transpose flag of the right-hand side sparse vector
183  , typename OP > // Type of the assignment operation
184 void threadAssign( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs, OP op )
185 {
187 
188  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
189 
190  const size_t threads ( TheThreadBackend::size() );
191  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
192  const size_t sizePerThread( (~lhs).size() / threads + addon );
193 
194  for( size_t i=0UL; i<threads; ++i )
195  {
196  const size_t index( i*sizePerThread );
197 
198  if( index >= (~lhs).size() )
199  continue;
200 
201  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
202  auto target( subvector<unaligned>( ~lhs, index, size, unchecked ) );
203  const auto source( subvector<unaligned>( ~rhs, index, size, unchecked ) );
204  TheThreadBackend::schedule( target, source, op );
205  }
206 
207  TheThreadBackend::wait();
208 }
210 //*************************************************************************************************
211 
212 
213 
214 
215 //=================================================================================================
216 //
217 // PLAIN ASSIGNMENT
218 //
219 //=================================================================================================
220 
221 //*************************************************************************************************
239 template< typename VT1 // Type of the left-hand side dense vector
240  , bool TF1 // Transpose flag of the left-hand side dense vector
241  , typename VT2 // Type of the right-hand side vector
242  , bool TF2 > // Transpose flag of the right-hand side vector
243 inline EnableIf_< And< IsDenseVector<VT1>
244  , Or< Not< IsSMPAssignable<VT1> >
245  , Not< IsSMPAssignable<VT2> > > > >
246  smpAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
247 {
249 
250  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
251 
252  assign( ~lhs, ~rhs );
253 }
255 //*************************************************************************************************
256 
257 
258 //*************************************************************************************************
276 template< typename VT1 // Type of the left-hand side dense vector
277  , bool TF1 // Transpose flag of the left-hand side dense vector
278  , typename VT2 // Type of the right-hand side vector
279  , bool TF2 > // Transpose flag of the right-hand side vector
280 inline EnableIf_< And< IsDenseVector<VT1>, IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >
281  smpAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
282 {
284 
285  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT1> );
286  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT2> );
287 
288  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
289 
291  {
292  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
293  assign( ~lhs, ~rhs );
294  }
295  else {
296  threadAssign( ~lhs, ~rhs, Assign() );
297  }
298  }
299 }
301 //*************************************************************************************************
302 
303 
304 
305 
306 //=================================================================================================
307 //
308 // ADDITION ASSIGNMENT
309 //
310 //=================================================================================================
311 
312 //*************************************************************************************************
331 template< typename VT1 // Type of the left-hand side dense vector
332  , bool TF1 // Transpose flag of the left-hand side dense vector
333  , typename VT2 // Type of the right-hand side vector
334  , bool TF2 > // Transpose flag of the right-hand side vector
335 inline EnableIf_< And< IsDenseVector<VT1>
336  , Or< Not< IsSMPAssignable<VT1> >
337  , Not< IsSMPAssignable<VT2> > > > >
338  smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
339 {
341 
342  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
343 
344  addAssign( ~lhs, ~rhs );
345 }
347 //*************************************************************************************************
348 
349 
350 //*************************************************************************************************
368 template< typename VT1 // Type of the left-hand side dense vector
369  , bool TF1 // Transpose flag of the left-hand side dense vector
370  , typename VT2 // Type of the right-hand side vector
371  , bool TF2 > // Transpose flag of the right-hand side vector
372 inline EnableIf_< And< IsDenseVector<VT1>, IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >
373  smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
374 {
376 
377  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT1> );
378  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT2> );
379 
380  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
381 
383  {
384  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
385  addAssign( ~lhs, ~rhs );
386  }
387  else {
388  threadAssign( ~lhs, ~rhs, AddAssign() );
389  }
390  }
391 }
393 //*************************************************************************************************
394 
395 
396 
397 
398 //=================================================================================================
399 //
400 // SUBTRACTION ASSIGNMENT
401 //
402 //=================================================================================================
403 
404 //*************************************************************************************************
423 template< typename VT1 // Type of the left-hand side dense vector
424  , bool TF1 // Transpose flag of the left-hand side dense vector
425  , typename VT2 // Type of the right-hand side vector
426  , bool TF2 > // Transpose flag of the right-hand side vector
427 inline EnableIf_< And< IsDenseVector<VT1>
428  , Or< Not< IsSMPAssignable<VT1> >
429  , Not< IsSMPAssignable<VT2> > > > >
430  smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
431 {
433 
434  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
435 
436  subAssign( ~lhs, ~rhs );
437 }
439 //*************************************************************************************************
440 
441 
442 //*************************************************************************************************
461 template< typename VT1 // Type of the left-hand side dense vector
462  , bool TF1 // Transpose flag of the left-hand side dense vector
463  , typename VT2 // Type of the right-hand side vector
464  , bool TF2 > // Transpose flag of the right-hand side vector
465 inline EnableIf_< And< IsDenseVector<VT1>, IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >
466  smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
467 {
469 
470  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT1> );
471  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT2> );
472 
473  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
474 
476  {
477  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
478  subAssign( ~lhs, ~rhs );
479  }
480  else {
481  threadAssign( ~lhs, ~rhs, SubAssign() );
482  }
483  }
484 }
486 //*************************************************************************************************
487 
488 
489 
490 
491 //=================================================================================================
492 //
493 // MULTIPLICATION ASSIGNMENT
494 //
495 //=================================================================================================
496 
497 //*************************************************************************************************
516 template< typename VT1 // Type of the left-hand side dense vector
517  , bool TF1 // Transpose flag of the left-hand side dense vector
518  , typename VT2 // Type of the right-hand side vector
519  , bool TF2 > // Transpose flag of the right-hand side vector
520 inline EnableIf_< And< IsDenseVector<VT1>
521  , Or< Not< IsSMPAssignable<VT1> >
522  , Not< IsSMPAssignable<VT2> > > > >
523  smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
524 {
526 
527  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
528 
529  multAssign( ~lhs, ~rhs );
530 }
532 //*************************************************************************************************
533 
534 
535 //*************************************************************************************************
554 template< typename VT1 // Type of the left-hand side dense vector
555  , bool TF1 // Transpose flag of the left-hand side dense vector
556  , typename VT2 // Type of the right-hand side vector
557  , bool TF2 > // Transpose flag of the right-hand side vector
558 inline EnableIf_< And< IsDenseVector<VT1>, IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >
559  smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
560 {
562 
563  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT1> );
564  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT2> );
565 
566  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
567 
569  {
570  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
571  multAssign( ~lhs, ~rhs );
572  }
573  else {
574  threadAssign( ~lhs, ~rhs, MultAssign() );
575  }
576  }
577 }
579 //*************************************************************************************************
580 
581 
582 
583 
584 //=================================================================================================
585 //
586 // DIVISION ASSIGNMENT
587 //
588 //=================================================================================================
589 
590 //*************************************************************************************************
609 template< typename VT1 // Type of the left-hand side dense vector
610  , bool TF1 // Transpose flag of the left-hand side dense vector
611  , typename VT2 // Type of the right-hand side vector
612  , bool TF2 > // Transpose flag of the right-hand side vector
613 inline EnableIf_< And< IsDenseVector<VT1>
614  , Or< Not< IsSMPAssignable<VT1> >
615  , Not< IsSMPAssignable<VT2> > > > >
616  smpDivAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
617 {
619 
620  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
621 
622  divAssign( ~lhs, ~rhs );
623 }
625 //*************************************************************************************************
626 
627 
628 //*************************************************************************************************
646 template< typename VT1 // Type of the left-hand side dense vector
647  , bool TF1 // Transpose flag of the left-hand side dense vector
648  , typename VT2 // Type of the right-hand side vector
649  , bool TF2 > // Transpose flag of the right-hand side vector
650 inline EnableIf_< And< IsDenseVector<VT1>, IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >
651  smpDivAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
652 {
654 
655  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT1> );
656  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT2> );
657 
658  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
659 
661  {
662  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
663  divAssign( ~lhs, ~rhs );
664  }
665  else {
666  threadAssign( ~lhs, ~rhs, DivAssign() );
667  }
668  }
669 }
671 //*************************************************************************************************
672 
673 
674 
675 
676 //=================================================================================================
677 //
678 // COMPILE TIME CONSTRAINTS
679 //
680 //=================================================================================================
681 
682 //*************************************************************************************************
684 namespace {
685 
687 
688 }
690 //*************************************************************************************************
691 
692 } // namespace blaze
693 
694 #endif
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
Header file for basic type definitions.
Header file for the SparseVector base class.
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
Header file for the Assign functor.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
#define BLAZE_BOOST_THREADS_PARALLEL_MODE
Compilation switch for the Boost parallelization.This compilation switch enables/disables the paralle...
Definition: SMP.h:122
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
EnableIf_< IsDenseVector< VT1 > > smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:193
Header file for the AddAssign functor.
Header file for the And class template.
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1903
Header file for the DenseVector base class.
Header file for the SIMD trait.
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE(T)
Constraint on the data type.In case the given data type T is SMP-assignable (can be assigned by multi...
Definition: SMPAssignable.h:81
Header file for the implementation of the Subvector view.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the SubAssign functor.
Compile time assertion.
System settings for the shared-memory parallelization.
Header file for the IsSMPAssignable type trait.
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
Header file for the Or class template.
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.
Header file for the EnableIf class template.
#define BLAZE_PARALLEL_SECTION
Section for the debugging of the shared-memory parallelization.During the shared-memory parallel (SMP...
Definition: ParallelSection.h:246
bool isSerialSectionActive()
Returns whether a serial section is active or not.
Definition: SerialSection.h:213
Header file for the IsSIMDCombinable type trait.
Header file for run time assertion macros.
EnableIf_< IsDenseVector< VT1 > > smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:222
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
Header file for the IsDenseVector type trait.
bool isParallelSectionActive()
Returns whether a parallel section is active or not.
Definition: ParallelSection.h:213
Header file for the MultAssign functor.
Header file for the C++11 and Boost thread backend.
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:112
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the DivAssign functor.
Constraint on the data type.
Header file for the function trace functionality.