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>
66 #include <blaze/util/Types.h>
67 
68 
69 namespace blaze {
70 
71 //=================================================================================================
72 //
73 // HPX-BASED ASSIGNMENT KERNELS
74 //
75 //=================================================================================================
76 
77 //*************************************************************************************************
94 template< typename VT1 // Type of the left-hand side dense vector
95  , bool TF1 // Transpose flag of the left-hand side dense vector
96  , typename VT2 // Type of the right-hand side dense vector
97  , bool TF2 // Transpose flag of the right-hand side dense vector
98  , typename OP > // Type of the assignment operation
99 void hpxAssign( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs, OP op )
100 {
101  using hpx::parallel::for_loop;
102  using hpx::parallel::execution::par;
103 
105 
106  using ET1 = ElementType_t<VT1>;
107  using ET2 = ElementType_t<VT2>;
108 
109  constexpr bool simdEnabled( VT1::simdEnabled && VT2::simdEnabled && IsSIMDCombinable_v<ET1,ET2> );
110  constexpr size_t SIMDSIZE( SIMDTrait< ElementType_t<VT1> >::size );
111 
112  const bool lhsAligned( (~lhs).isAligned() );
113  const bool rhsAligned( (~rhs).isAligned() );
114 
115  const size_t threads ( getNumThreads() );
116  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
117  const size_t equalShare ( (~lhs).size() / threads + addon );
118  const size_t rest ( equalShare & ( SIMDSIZE - 1UL ) );
119  const size_t sizePerThread( ( simdEnabled && rest )?( equalShare - rest + SIMDSIZE ):( equalShare ) );
120 
121  for_loop( par, size_t(0), threads, [&](int i)
122  {
123  const size_t index( i*sizePerThread );
124 
125  if( index >= (~lhs).size() )
126  return;
127 
128  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
129 
130  if( simdEnabled && lhsAligned && rhsAligned ) {
131  auto target( subvector<aligned>( ~lhs, index, size, unchecked ) );
132  const auto source( subvector<aligned>( ~rhs, index, size, unchecked ) );
133  op( target, source );
134  }
135  else if( simdEnabled && lhsAligned ) {
136  auto target( subvector<aligned>( ~lhs, index, size, unchecked ) );
137  const auto source( subvector<unaligned>( ~rhs, index, size, unchecked ) );
138  op( target, source );
139  }
140  else if( simdEnabled && rhsAligned ) {
141  auto target( subvector<unaligned>( ~lhs, index, size, unchecked ) );
142  const auto source( subvector<aligned>( ~rhs, index, size, unchecked ) );
143  op( target, source );
144  }
145  else {
146  auto target( subvector<unaligned>( ~lhs, index, size, unchecked ) );
147  const auto source( subvector<unaligned>( ~rhs, index, size, unchecked ) );
148  op( target, source );
149  }
150  } );
151 }
153 //*************************************************************************************************
154 
155 
156 //*************************************************************************************************
173 template< typename VT1 // Type of the left-hand side dense vector
174  , bool TF1 // Transpose flag of the left-hand side dense vector
175  , typename VT2 // Type of the right-hand side sparse vector
176  , bool TF2 // Transpose flag of the right-hand side sparse vector
177  , typename OP > // Type of the assignment operation
178 void hpxAssign( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs, OP op )
179 {
180  using hpx::parallel::for_loop;
181  using hpx::parallel::execution::par;
182 
184 
185  const size_t threads ( getNumThreads() );
186  const size_t addon ( ( ( (~lhs).size() % threads ) != 0UL )? 1UL : 0UL );
187  const size_t sizePerThread( (~lhs).size() / threads + addon );
188 
189  for_loop( par, size_t(0), threads, [&](int i)
190  {
191  const size_t index( i*sizePerThread );
192 
193  if( index < (~lhs).size() )
194  return;
195 
196  const size_t size( min( sizePerThread, (~lhs).size() - index ) );
197  auto target( subvector<unaligned>( ~lhs, index, size, unchecked ) );
198  const auto source( subvector<unaligned>( ~rhs, index, size, unchecked ) );
199  op( target, source );
200  } );
201 }
203 //*************************************************************************************************
204 
205 
206 
207 
208 //=================================================================================================
209 //
210 // PLAIN ASSIGNMENT
211 //
212 //=================================================================================================
213 
214 //*************************************************************************************************
232 template< typename VT1 // Type of the left-hand side dense vector
233  , bool TF1 // Transpose flag of the left-hand side dense vector
234  , typename VT2 // Type of the right-hand side vector
235  , bool TF2 > // Transpose flag of the right-hand side vector
236 inline auto smpAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
237  -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
238 {
240 
241  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
242 
243  assign( ~lhs, ~rhs );
244 }
246 //*************************************************************************************************
247 
248 
249 //*************************************************************************************************
267 template< typename VT1 // Type of the left-hand side dense vector
268  , bool TF1 // Transpose flag of the left-hand side dense vector
269  , typename VT2 // Type of the right-hand side vector
270  , bool TF2 > // Transpose flag of the right-hand side vector
271 inline auto smpAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
272  -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
273 {
275 
276  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_t<VT1> );
277  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_t<VT2> );
278 
279  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
280 
281  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
282  assign( ~lhs, ~rhs );
283  }
284  else {
285  hpxAssign( ~lhs, ~rhs, Assign() );
286  }
287 }
289 //*************************************************************************************************
290 
291 
292 
293 
294 //=================================================================================================
295 //
296 // ADDITION ASSIGNMENT
297 //
298 //=================================================================================================
299 
300 //*************************************************************************************************
318 template< typename VT1 // Type of the left-hand side dense vector
319  , bool TF1 // Transpose flag of the left-hand side dense vector
320  , typename VT2 // Type of the right-hand side vector
321  , bool TF2 > // Transpose flag of the right-hand side vector
322 inline auto smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
323  -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
324 {
326 
327  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
328 
329  addAssign( ~lhs, ~rhs );
330 }
332 //*************************************************************************************************
333 
334 
335 //*************************************************************************************************
353 template< typename VT1 // Type of the left-hand side dense vector
354  , bool TF1 // Transpose flag of the left-hand side dense vector
355  , typename VT2 // Type of the right-hand side vector
356  , bool TF2 > // Transpose flag of the right-hand side vector
357 inline auto smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
358  -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
359 {
361 
362  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_t<VT1> );
363  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_t<VT2> );
364 
365  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
366 
367  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
368  addAssign( ~lhs, ~rhs );
369  }
370  else {
371  hpxAssign( ~lhs, ~rhs, AddAssign() );
372  }
373 }
375 //*************************************************************************************************
376 
377 
378 
379 
380 //=================================================================================================
381 //
382 // SUBTRACTION ASSIGNMENT
383 //
384 //=================================================================================================
385 
386 //*************************************************************************************************
404 template< typename VT1 // Type of the left-hand side dense vector
405  , bool TF1 // Transpose flag of the left-hand side dense vector
406  , typename VT2 // Type of the right-hand side vector
407  , bool TF2 > // Transpose flag of the right-hand side vector
408 inline auto smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
409  -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
410 {
412 
413  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
414 
415  subAssign( ~lhs, ~rhs );
416 }
418 //*************************************************************************************************
419 
420 
421 //*************************************************************************************************
439 template< typename VT1 // Type of the left-hand side dense vector
440  , bool TF1 // Transpose flag of the left-hand side dense vector
441  , typename VT2 // Type of the right-hand side vector
442  , bool TF2 > // Transpose flag of the right-hand side vector
443 inline auto smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
444  -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
445 {
447 
448  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_t<VT1> );
449  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_t<VT2> );
450 
451  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
452 
453  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
454  subAssign( ~lhs, ~rhs );
455  }
456  else {
457  hpxAssign( ~lhs, ~rhs, SubAssign() );
458  }
459 }
461 //*************************************************************************************************
462 
463 
464 
465 
466 //=================================================================================================
467 //
468 // MULTIPLICATION ASSIGNMENT
469 //
470 //=================================================================================================
471 
472 //*************************************************************************************************
490 template< typename VT1 // Type of the left-hand side dense vector
491  , bool TF1 // Transpose flag of the left-hand side dense vector
492  , typename VT2 // Type of the right-hand side vector
493  , bool TF2 > // Transpose flag of the right-hand side vector
494 inline auto smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
495  -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
496 {
498 
499  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
500 
501  multAssign( ~lhs, ~rhs );
502 }
504 //*************************************************************************************************
505 
506 
507 //*************************************************************************************************
525 template< typename VT1 // Type of the left-hand side dense vector
526  , bool TF1 // Transpose flag of the left-hand side dense vector
527  , typename VT2 // Type of the right-hand side vector
528  , bool TF2 > // Transpose flag of the right-hand side vector
529 inline auto smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
530  -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
531 {
533 
534  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_t<VT1> );
535  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_t<VT2> );
536 
537  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
538 
539  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
540  multAssign( ~lhs, ~rhs );
541  }
542  else {
543  hpxAssign( ~lhs, ~rhs, MultAssign() );
544  }
545 }
547 //*************************************************************************************************
548 
549 
550 
551 
552 //=================================================================================================
553 //
554 // DIVISION ASSIGNMENT
555 //
556 //=================================================================================================
557 
558 //*************************************************************************************************
576 template< typename VT1 // Type of the left-hand side dense vector
577  , bool TF1 // Transpose flag of the left-hand side dense vector
578  , typename VT2 // Type of the right-hand side vector
579  , bool TF2 > // Transpose flag of the right-hand side vector
580 inline auto smpDivAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
581  -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
582 {
584 
585  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
586 
587  divAssign( ~lhs, ~rhs );
588 }
590 //*************************************************************************************************
591 
592 
593 //*************************************************************************************************
611 template< typename VT1 // Type of the left-hand side dense vector
612  , bool TF1 // Transpose flag of the left-hand side dense vector
613  , typename VT2 // Type of the right-hand side vector
614  , bool TF2 > // Transpose flag of the right-hand side vector
615 inline auto smpDivAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
616  -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
617 {
619 
620  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_t<VT1> );
621  BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE( ElementType_t<VT2> );
622 
623  BLAZE_INTERNAL_ASSERT( (~lhs).size() == (~rhs).size(), "Invalid vector sizes" );
624 
625  if( isSerialSectionActive() || !(~rhs).canSMPAssign() ) {
626  divAssign( ~lhs, ~rhs );
627  }
628  else {
629  hpxAssign( ~lhs, ~rhs, DivAssign() );
630  }
631 }
633 //*************************************************************************************************
634 
635 
636 
637 
638 //=================================================================================================
639 //
640 // COMPILE TIME CONSTRAINTS
641 //
642 //=================================================================================================
643 
644 //*************************************************************************************************
646 namespace {
647 
649 
650 }
652 //*************************************************************************************************
653 
654 } // namespace blaze
655 
656 #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.
Header file for the Assign functor.
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
Header file for the AddAssign functor.
Header file for the DenseVector base class.
Header file for the SIMD trait.
auto smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:220
#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:96
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.
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1147
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.
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
#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
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
Header file for the IsDenseVector type trait.
Header file for the MultAssign functor.
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
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
auto smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:191
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.