DenseVector.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SMP_HPX_DENSEVECTOR_H_
36 #define _BLAZE_MATH_SMP_HPX_DENSEVECTOR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <hpx/include/parallel_for_loop.hpp>
44 #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 // HPX-BASED ASSIGNMENT KERNELS
77 //
78 //=================================================================================================
79 
80 //*************************************************************************************************
97 template< typename VT1 // Type of the left-hand side dense vector
98  , bool TF1 // Transpose flag of the left-hand side dense vector
99  , typename VT2 // Type of the right-hand side dense vector
100  , bool TF2 // Transpose flag of the right-hand side dense vector
101  , typename OP > // Type of the assignment operation
102 void hpxAssign( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs, OP op )
103 {
104  using hpx::parallel::for_loop;
105  using hpx::parallel::execution::par;
106 
108 
109  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
110 
111  using ET1 = ElementType_<VT1>;
112  using ET2 = ElementType_<VT2>;
113 
114  constexpr bool simdEnabled( VT1::simdEnabled && VT2::simdEnabled && IsSIMDCombinable<ET1,ET2>::value );
115  constexpr size_t SIMDSIZE( SIMDTrait< ElementType_<VT1> >::size );
116 
117  const bool lhsAligned( (~lhs).isAligned() );
118  const bool rhsAligned( (~rhs).isAligned() );
119 
120  const size_t threads ( getNumThreads() );
121  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
122  const size_t equalShare ( (~lhs).size() / threads + addon );
123  const size_t rest ( equalShare & ( SIMDSIZE - 1UL ) );
124  const size_t sizePerThread( ( simdEnabled && rest )?( equalShare - rest + SIMDSIZE ):( equalShare ) );
125 
126  for_loop( par, size_t(0), threads, [&](int i)
127  {
128  const size_t index( i*sizePerThread );
129 
130  if( index >= (~lhs).size() )
131  return;
132 
133  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
134 
135  if( simdEnabled && lhsAligned && rhsAligned ) {
136  auto target( subvector<aligned>( ~lhs, index, size, unchecked ) );
137  const auto source( subvector<aligned>( ~rhs, index, size, unchecked ) );
138  op( target, source );
139  }
140  else if( simdEnabled && lhsAligned ) {
141  auto target( subvector<aligned>( ~lhs, index, size, unchecked ) );
142  const auto source( subvector<unaligned>( ~rhs, index, size, unchecked ) );
143  op( target, source );
144  }
145  else if( simdEnabled && rhsAligned ) {
146  auto target( subvector<unaligned>( ~lhs, index, size, unchecked ) );
147  const auto source( subvector<aligned>( ~rhs, index, size, unchecked ) );
148  op( target, source );
149  }
150  else {
151  auto target( subvector<unaligned>( ~lhs, index, size, unchecked ) );
152  const auto source( subvector<unaligned>( ~rhs, index, size, unchecked ) );
153  op( target, source );
154  }
155  } );
156 }
158 //*************************************************************************************************
159 
160 
161 //*************************************************************************************************
178 template< typename VT1 // Type of the left-hand side dense vector
179  , bool TF1 // Transpose flag of the left-hand side dense vector
180  , typename VT2 // Type of the right-hand side sparse vector
181  , bool TF2 // Transpose flag of the right-hand side sparse vector
182  , typename OP > // Type of the assignment operation
183 void hpxAssign( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs, OP op )
184 {
185  using hpx::parallel::for_loop;
186  using hpx::parallel::execution::par;
187 
189 
190  BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
191 
192  const size_t threads ( getNumThreads() );
193  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
194  const size_t sizePerThread( (~lhs).size() / threads + addon );
195 
196  for_loop( par, size_t(0), threads, [&](int i)
197  {
198  const size_t index( i*sizePerThread );
199 
200  if( index < (~lhs).size() )
201  return;
202 
203  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
204  auto target( subvector<unaligned>( ~lhs, index, size, unchecked ) );
205  const auto source( subvector<unaligned>( ~rhs, index, size, unchecked ) );
206  op( target, source );
207  } );
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 
290  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
291  assign( ~lhs, ~rhs );
292  }
293  else {
294  hpxAssign( ~lhs, ~rhs, Assign() );
295  }
296 }
298 //*************************************************************************************************
299 
300 
301 
302 
303 //=================================================================================================
304 //
305 // ADDITION ASSIGNMENT
306 //
307 //=================================================================================================
308 
309 //*************************************************************************************************
327 template< typename VT1 // Type of the left-hand side dense vector
328  , bool TF1 // Transpose flag of the left-hand side dense vector
329  , typename VT2 // Type of the right-hand side vector
330  , bool TF2 > // Transpose flag of the right-hand side vector
331 inline EnableIf_< And< IsDenseVector<VT1>
332  , Or< Not< IsSMPAssignable<VT1> >
333  , Not< IsSMPAssignable<VT2> > > > >
334  smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
335 {
337 
338  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
339 
340  addAssign( ~lhs, ~rhs );
341 }
343 //*************************************************************************************************
344 
345 
346 //*************************************************************************************************
364 template< typename VT1 // Type of the left-hand side dense vector
365  , bool TF1 // Transpose flag of the left-hand side dense vector
366  , typename VT2 // Type of the right-hand side vector
367  , bool TF2 > // Transpose flag of the right-hand side vector
368 inline EnableIf_< And< IsDenseVector<VT1>, IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >
369  smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
370 {
372 
373  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT1> );
374  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT2> );
375 
376  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
377 
378  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
379  addAssign( ~lhs, ~rhs );
380  }
381  else {
382  hpxAssign( ~lhs, ~rhs, AddAssign() );
383  }
384 }
386 //*************************************************************************************************
387 
388 
389 
390 
391 //=================================================================================================
392 //
393 // SUBTRACTION ASSIGNMENT
394 //
395 //=================================================================================================
396 
397 //*************************************************************************************************
415 template< typename VT1 // Type of the left-hand side dense vector
416  , bool TF1 // Transpose flag of the left-hand side dense vector
417  , typename VT2 // Type of the right-hand side vector
418  , bool TF2 > // Transpose flag of the right-hand side vector
419 inline EnableIf_< And< IsDenseVector<VT1>
420  , Or< Not< IsSMPAssignable<VT1> >
421  , Not< IsSMPAssignable<VT2> > > > >
422  smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
423 {
425 
426  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
427 
428  subAssign( ~lhs, ~rhs );
429 }
431 //*************************************************************************************************
432 
433 
434 //*************************************************************************************************
452 template< typename VT1 // Type of the left-hand side dense vector
453  , bool TF1 // Transpose flag of the left-hand side dense vector
454  , typename VT2 // Type of the right-hand side vector
455  , bool TF2 > // Transpose flag of the right-hand side vector
456 inline EnableIf_< And< IsDenseVector<VT1>, IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >
457  smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
458 {
460 
461  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT1> );
462  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT2> );
463 
464  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
465 
466  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
467  subAssign( ~lhs, ~rhs );
468  }
469  else {
470  hpxAssign( ~lhs, ~rhs, SubAssign() );
471  }
472 }
474 //*************************************************************************************************
475 
476 
477 
478 
479 //=================================================================================================
480 //
481 // MULTIPLICATION ASSIGNMENT
482 //
483 //=================================================================================================
484 
485 //*************************************************************************************************
503 template< typename VT1 // Type of the left-hand side dense vector
504  , bool TF1 // Transpose flag of the left-hand side dense vector
505  , typename VT2 // Type of the right-hand side vector
506  , bool TF2 > // Transpose flag of the right-hand side vector
507 inline EnableIf_< And< IsDenseVector<VT1>
508  , Or< Not< IsSMPAssignable<VT1> >
509  , Not< IsSMPAssignable<VT2> > > > >
510  smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
511 {
513 
514  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
515 
516  multAssign( ~lhs, ~rhs );
517 }
519 //*************************************************************************************************
520 
521 
522 //*************************************************************************************************
540 template< typename VT1 // Type of the left-hand side dense vector
541  , bool TF1 // Transpose flag of the left-hand side dense vector
542  , typename VT2 // Type of the right-hand side vector
543  , bool TF2 > // Transpose flag of the right-hand side vector
544 inline EnableIf_< And< IsDenseVector<VT1>, IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >
545  smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
546 {
548 
549  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT1> );
550  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT2> );
551 
552  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
553 
554  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
555  multAssign( ~lhs, ~rhs );
556  }
557  else {
558  hpxAssign( ~lhs, ~rhs, MultAssign() );
559  }
560 }
562 //*************************************************************************************************
563 
564 
565 
566 
567 //=================================================================================================
568 //
569 // DIVISION ASSIGNMENT
570 //
571 //=================================================================================================
572 
573 //*************************************************************************************************
591 template< typename VT1 // Type of the left-hand side dense vector
592  , bool TF1 // Transpose flag of the left-hand side dense vector
593  , typename VT2 // Type of the right-hand side vector
594  , bool TF2 > // Transpose flag of the right-hand side vector
595 inline EnableIf_< And< IsDenseVector<VT1>
596  , Or< Not< IsSMPAssignable<VT1> >
597  , Not< IsSMPAssignable<VT2> > > > >
598  smpDivAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
599 {
601 
602  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
603 
604  divAssign( ~lhs, ~rhs );
605 }
607 //*************************************************************************************************
608 
609 
610 //*************************************************************************************************
628 template< typename VT1 // Type of the left-hand side dense vector
629  , bool TF1 // Transpose flag of the left-hand side dense vector
630  , typename VT2 // Type of the right-hand side vector
631  , bool TF2 > // Transpose flag of the right-hand side vector
632 inline EnableIf_< And< IsDenseVector<VT1>, IsSMPAssignable<VT1>, IsSMPAssignable<VT2> > >
633  smpDivAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
634 {
636 
637  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT1> );
638  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_<VT2> );
639 
640  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
641 
642  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
643  divAssign( ~lhs, ~rhs );
644  }
645  else {
646  hpxAssign( ~lhs, ~rhs, DivAssign() );
647  }
648 }
650 //*************************************************************************************************
651 
652 
653 
654 
655 //=================================================================================================
656 //
657 // COMPILE TIME CONSTRAINTS
658 //
659 //=================================================================================================
660 
661 //*************************************************************************************************
663 namespace {
664 
666 
667 }
669 //*************************************************************************************************
670 
671 } // namespace blaze
672 
673 #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
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
#define BLAZE_HPX_PARALLEL_MODE
Compilation switch for the HPX parallelization.This compilation switch enables/disables the paralleli...
Definition: SMP.h:148
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.
Header file for the EnableIf class template.
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 SMP utility functions.
#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
BLAZE_ALWAYS_INLINE size_t getNumThreads()
Returns the number of threads used for thread parallel operations.
Definition: Functions.h:77
Header file for the DivAssign functor.
Constraint on the data type.
Header file for the function trace functionality.