Blaze 3.9
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>
56#include <blaze/system/SMP.h>
58#include <blaze/util/Assert.h>
59#include <blaze/util/EnableIf.h>
62#include <blaze/util/Types.h>
63
64
65namespace blaze {
66
67//=================================================================================================
68//
69// HPX-BASED ASSIGNMENT KERNELS
70//
71//=================================================================================================
72
73//*************************************************************************************************
90template< typename VT1 // Type of the left-hand side dense vector
91 , bool TF1 // Transpose flag of the left-hand side dense vector
92 , typename VT2 // Type of the right-hand side dense vector
93 , bool TF2 // Transpose flag of the right-hand side dense vector
94 , typename OP > // Type of the assignment operation
95void hpxAssign( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs, OP op )
96{
97#if HPX_VERSION_FULL >= 0x010500
98 using hpx::for_loop;
99 using hpx::execution::par;
100#else
101 using hpx::parallel::for_loop;
102 using hpx::parallel::execution::par;
103#endif
104
106
107 using ET1 = ElementType_t<VT1>;
108 using ET2 = ElementType_t<VT2>;
109
110 constexpr bool simdEnabled( VT1::simdEnabled && VT2::simdEnabled && IsSIMDCombinable_v<ET1,ET2> );
111 constexpr size_t SIMDSIZE( SIMDTrait< ElementType_t<VT1> >::size );
112
113 const bool lhsAligned( (*lhs).isAligned() );
114 const bool rhsAligned( (*rhs).isAligned() );
115
116 const size_t threads ( getNumThreads() );
117 const size_t addon ( ( ( (*lhs).size() % threads ) != 0UL )? 1UL : 0UL );
118 const size_t equalShare ( (*lhs).size() / threads + addon );
119 const size_t rest ( equalShare & ( SIMDSIZE - 1UL ) );
120 const size_t sizePerThread( ( simdEnabled && rest )?( equalShare - rest + SIMDSIZE ):( equalShare ) );
121
122 for_loop( par, size_t(0), threads, [&](int i)
123 {
124 const size_t index( i*sizePerThread );
125
126 if( index >= (*lhs).size() )
127 return;
128
129 const size_t size( min( sizePerThread, (*lhs).size() - index ) );
130
131 if( simdEnabled && lhsAligned && rhsAligned ) {
132 auto target( subvector<aligned>( *lhs, index, size, unchecked ) );
133 const auto source( subvector<aligned>( *rhs, index, size, unchecked ) );
134 op( target, source );
135 }
136 else if( simdEnabled && lhsAligned ) {
137 auto target( subvector<aligned>( *lhs, index, size, unchecked ) );
138 const auto source( subvector<unaligned>( *rhs, index, size, unchecked ) );
139 op( target, source );
140 }
141 else if( simdEnabled && rhsAligned ) {
142 auto target( subvector<unaligned>( *lhs, index, size, unchecked ) );
143 const auto source( subvector<aligned>( *rhs, index, size, unchecked ) );
144 op( target, source );
145 }
146 else {
147 auto target( subvector<unaligned>( *lhs, index, size, unchecked ) );
148 const auto source( subvector<unaligned>( *rhs, index, size, unchecked ) );
149 op( target, source );
150 }
151 } );
152}
154//*************************************************************************************************
155
156
157//*************************************************************************************************
174template< typename VT1 // Type of the left-hand side dense vector
175 , bool TF1 // Transpose flag of the left-hand side dense vector
176 , typename VT2 // Type of the right-hand side sparse vector
177 , bool TF2 // Transpose flag of the right-hand side sparse vector
178 , typename OP > // Type of the assignment operation
179void hpxAssign( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs, OP op )
180{
181#if HPX_VERSION_FULL >= 0x010500
182 using hpx::for_loop;
183 using hpx::execution::par;
184#else
185 using hpx::parallel::for_loop;
186 using hpx::parallel::execution::par;
187#endif
188
190
191 const size_t threads ( getNumThreads() );
192 const size_t addon ( ( ( (*lhs).size() % threads ) != 0UL )? 1UL : 0UL );
193 const size_t sizePerThread( (*lhs).size() / threads + addon );
194
195 for_loop( par, size_t(0), threads, [&](int i)
196 {
197 const size_t index( i*sizePerThread );
198
199 if( index < (*lhs).size() )
200 return;
201
202 const size_t size( min( sizePerThread, (*lhs).size() - index ) );
203 auto target( subvector<unaligned>( *lhs, index, size, unchecked ) );
204 const auto source( subvector<unaligned>( *rhs, index, size, unchecked ) );
205 op( target, source );
206 } );
207}
209//*************************************************************************************************
210
211
212
213
214//=================================================================================================
215//
216// PLAIN ASSIGNMENT
217//
218//=================================================================================================
219
220//*************************************************************************************************
238template< typename VT1 // Type of the left-hand side dense vector
239 , bool TF1 // Transpose flag of the left-hand side dense vector
240 , typename VT2 // Type of the right-hand side vector
241 , bool TF2 > // Transpose flag of the right-hand side vector
242inline auto smpAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
243 -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
244{
246
247 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
248
249 assign( *lhs, *rhs );
250}
252//*************************************************************************************************
253
254
255//*************************************************************************************************
273template< typename VT1 // Type of the left-hand side dense vector
274 , bool TF1 // Transpose flag of the left-hand side dense vector
275 , typename VT2 // Type of the right-hand side vector
276 , bool TF2 > // Transpose flag of the right-hand side vector
277inline auto smpAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
278 -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
279{
281
284
285 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
286
287 if( isSerialSectionActive() || !(*rhs).canSMPAssign() ) {
288 assign( *lhs, *rhs );
289 }
290 else {
291 hpxAssign( *lhs, *rhs, []( auto& a, const auto& b ){ assign( a, b ); } );
292 }
293}
295//*************************************************************************************************
296
297
298
299
300//=================================================================================================
301//
302// ADDITION ASSIGNMENT
303//
304//=================================================================================================
305
306//*************************************************************************************************
324template< typename VT1 // Type of the left-hand side dense vector
325 , bool TF1 // Transpose flag of the left-hand side dense vector
326 , typename VT2 // Type of the right-hand side vector
327 , bool TF2 > // Transpose flag of the right-hand side vector
328inline auto smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
329 -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
330{
332
333 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
334
335 addAssign( *lhs, *rhs );
336}
338//*************************************************************************************************
339
340
341//*************************************************************************************************
359template< typename VT1 // Type of the left-hand side dense vector
360 , bool TF1 // Transpose flag of the left-hand side dense vector
361 , typename VT2 // Type of the right-hand side vector
362 , bool TF2 > // Transpose flag of the right-hand side vector
363inline auto smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
364 -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
365{
367
370
371 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
372
373 if( isSerialSectionActive() || !(*rhs).canSMPAssign() ) {
374 addAssign( *lhs, *rhs );
375 }
376 else {
377 hpxAssign( *lhs, *rhs, []( auto& a, const auto& b ){ addAssign( a, b ); } );
378 }
379}
381//*************************************************************************************************
382
383
384
385
386//=================================================================================================
387//
388// SUBTRACTION ASSIGNMENT
389//
390//=================================================================================================
391
392//*************************************************************************************************
410template< typename VT1 // Type of the left-hand side dense vector
411 , bool TF1 // Transpose flag of the left-hand side dense vector
412 , typename VT2 // Type of the right-hand side vector
413 , bool TF2 > // Transpose flag of the right-hand side vector
414inline auto smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
415 -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
416{
418
419 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
420
421 subAssign( *lhs, *rhs );
422}
424//*************************************************************************************************
425
426
427//*************************************************************************************************
445template< 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
449inline auto smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
450 -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
451{
453
456
457 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
458
459 if( isSerialSectionActive() || !(*rhs).canSMPAssign() ) {
460 subAssign( *lhs, *rhs );
461 }
462 else {
463 hpxAssign( *lhs, *rhs, []( auto& a, const auto& b ){ subAssign( a, b ); } );
464 }
465}
467//*************************************************************************************************
468
469
470
471
472//=================================================================================================
473//
474// MULTIPLICATION ASSIGNMENT
475//
476//=================================================================================================
477
478//*************************************************************************************************
496template< typename VT1 // Type of the left-hand side dense vector
497 , bool TF1 // Transpose flag of the left-hand side dense vector
498 , typename VT2 // Type of the right-hand side vector
499 , bool TF2 > // Transpose flag of the right-hand side vector
500inline auto smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
501 -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
502{
504
505 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
506
507 multAssign( *lhs, *rhs );
508}
510//*************************************************************************************************
511
512
513//*************************************************************************************************
531template< typename VT1 // Type of the left-hand side dense vector
532 , bool TF1 // Transpose flag of the left-hand side dense vector
533 , typename VT2 // Type of the right-hand side vector
534 , bool TF2 > // Transpose flag of the right-hand side vector
535inline auto smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
536 -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
537{
539
542
543 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
544
545 if( isSerialSectionActive() || !(*rhs).canSMPAssign() ) {
546 multAssign( *lhs, *rhs );
547 }
548 else {
549 hpxAssign( *lhs, *rhs, []( auto& a, const auto& b ){ multAssign( a, b ); } );
550 }
551}
553//*************************************************************************************************
554
555
556
557
558//=================================================================================================
559//
560// DIVISION ASSIGNMENT
561//
562//=================================================================================================
563
564//*************************************************************************************************
582template< typename VT1 // Type of the left-hand side dense vector
583 , bool TF1 // Transpose flag of the left-hand side dense vector
584 , typename VT2 // Type of the right-hand side vector
585 , bool TF2 > // Transpose flag of the right-hand side vector
586inline auto smpDivAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
587 -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
588{
590
591 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
592
593 divAssign( *lhs, *rhs );
594}
596//*************************************************************************************************
597
598
599//*************************************************************************************************
617template< typename VT1 // Type of the left-hand side dense vector
618 , bool TF1 // Transpose flag of the left-hand side dense vector
619 , typename VT2 // Type of the right-hand side vector
620 , bool TF2 > // Transpose flag of the right-hand side vector
621inline auto smpDivAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
622 -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
623{
625
628
629 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
630
631 if( isSerialSectionActive() || !(*rhs).canSMPAssign() ) {
632 divAssign( *lhs, *rhs );
633 }
634 else {
635 hpxAssign( *lhs, *rhs, []( auto& a, const auto& b ){ divAssign( a, b ); } );
636 }
637}
639//*************************************************************************************************
640
641
642
643
644//=================================================================================================
645//
646// COMPILE TIME CONSTRAINTS
647//
648//=================================================================================================
649
650//*************************************************************************************************
652namespace {
653
655
656}
658//*************************************************************************************************
659
660} // namespace blaze
661
662#endif
Header file for auxiliary alias declarations.
Header file for run time assertion macros.
Header file for the EnableIf class template.
Header file for the function trace functionality.
Header file for the IsDenseVector type trait.
Header file for the IsSIMDCombinable type trait.
Header file for the IsSMPAssignable type trait.
Deactivation of problematic macros.
Header file for the SIMD trait.
Constraint on the data type.
Header file for the serial section implementation.
Compile time assertion.
Header file for the DenseVector base class.
Header file for the SparseVector base class.
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:1339
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SMP_ASSIGNABLE(T)
Constraint on the data type.
Definition: SMPAssignable.h:81
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:676
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
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:221
BLAZE_ALWAYS_INLINE size_t getNumThreads()
Returns the number of threads used for thread parallel operations.
Definition: Functions.h:77
auto smpAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP assignment of a vector to a dense vector.
Definition: DenseVector.h:105
auto smpAddAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP addition assignment of a vector to a dense vector.
Definition: DenseVector.h:134
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:192
bool isSerialSectionActive()
Returns whether a serial section is active or not.
Definition: SerialSection.h:213
auto smpSubAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP subtraction assignment of a vector to a dense vector.
Definition: DenseVector.h:163
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.
Definition: StaticAssert.h:112
#define BLAZE_HPX_PARALLEL_MODE
Compilation switch for the HPX parallelization.
Definition: SMP.h:96
#define BLAZE_FUNCTION_TRACE
Function trace macro.
Definition: FunctionTrace.h:94
constexpr Unchecked unchecked
Global Unchecked instance.
Definition: Check.h:146
Header file for SMP utility functions.
System settings for the shared-memory parallelization.
Header file for basic type definitions.
Header file for the generic min algorithm.
Header file for the implementation of the Subvector view.