Blaze 3.9
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>
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// THREAD-BASED ASSIGNMENT KERNELS
70//
71//=================================================================================================
72
73//*************************************************************************************************
91template< typename VT1 // Type of the left-hand side dense vector
92 , bool TF1 // Transpose flag of the left-hand side dense vector
93 , typename VT2 // Type of the right-hand side dense vector
94 , bool TF2 // Transpose flag of the right-hand side dense vector
95 , typename OP > // Type of the assignment operation
96void threadAssign( DenseVector<VT1,TF1>& lhs, const DenseVector<VT2,TF2>& rhs, OP op )
97{
99
100 BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
101
102 using ET1 = ElementType_t<VT1>;
103 using ET2 = ElementType_t<VT2>;
104
105 constexpr bool simdEnabled( VT1::simdEnabled && VT2::simdEnabled && IsSIMDCombinable_v<ET1,ET2> );
106 constexpr size_t SIMDSIZE( SIMDTrait< ElementType_t<VT1> >::size );
107
108 const bool lhsAligned( (*lhs).isAligned() );
109 const bool rhsAligned( (*rhs).isAligned() );
110
111 const size_t threads ( TheThreadBackend::size() );
112 const size_t addon ( ( ( (*lhs).size() % threads ) != 0UL )? 1UL : 0UL );
113 const size_t equalShare ( (*lhs).size() / threads + addon );
114 const size_t rest ( equalShare & ( SIMDSIZE - 1UL ) );
115 const size_t sizePerThread( ( simdEnabled && rest )?( equalShare - rest + SIMDSIZE ):( equalShare ) );
116
117 for( size_t i=0UL; i<threads; ++i )
118 {
119 const size_t index( i*sizePerThread );
120
121 if( index >= (*lhs).size() )
122 continue;
123
124 const size_t size( min( sizePerThread, (*lhs).size() - index ) );
125
126 if( simdEnabled && lhsAligned && rhsAligned ) {
127 auto target( subvector<aligned>( *lhs, index, size, unchecked ) );
128 const auto source( subvector<aligned>( *rhs, index, size, unchecked ) );
129 TheThreadBackend::schedule( target, source, op );
130 }
131 else if( simdEnabled && lhsAligned ) {
132 auto target( subvector<aligned>( *lhs, index, size, unchecked ) );
133 const auto source( subvector<unaligned>( *rhs, index, size, unchecked ) );
134 TheThreadBackend::schedule( target, source, op );
135 }
136 else if( simdEnabled && rhsAligned ) {
137 auto target( subvector<unaligned>( *lhs, index, size, unchecked ) );
138 const auto source( subvector<aligned>( *rhs, index, size, unchecked ) );
139 TheThreadBackend::schedule( target, source, op );
140 }
141 else {
142 auto target( subvector<unaligned>( *lhs, index, size, unchecked ) );
143 const auto source( subvector<unaligned>( *rhs, index, size, unchecked ) );
144 TheThreadBackend::schedule( target, source, op );
145 }
146 }
147
148 TheThreadBackend::wait();
149}
151//*************************************************************************************************
152
153
154//*************************************************************************************************
172template< typename VT1 // Type of the left-hand side dense vector
173 , bool TF1 // Transpose flag of the left-hand side dense vector
174 , typename VT2 // Type of the right-hand side sparse vector
175 , bool TF2 // Transpose flag of the right-hand side sparse vector
176 , typename OP > // Type of the assignment operation
177void threadAssign( DenseVector<VT1,TF1>& lhs, const SparseVector<VT2,TF2>& rhs, OP op )
178{
180
181 BLAZE_INTERNAL_ASSERT( isParallelSectionActive(), "Invalid call outside a parallel section" );
182
183 const size_t threads ( TheThreadBackend::size() );
184 const size_t addon ( ( ( (*lhs).size() % threads ) != 0UL )? 1UL : 0UL );
185 const size_t sizePerThread( (*lhs).size() / threads + addon );
186
187 for( size_t i=0UL; i<threads; ++i )
188 {
189 const size_t index( i*sizePerThread );
190
191 if( index >= (*lhs).size() )
192 continue;
193
194 const size_t size( min( sizePerThread, (*lhs).size() - index ) );
195 auto target( subvector<unaligned>( *lhs, index, size, unchecked ) );
196 const auto source( subvector<unaligned>( *rhs, index, size, unchecked ) );
197 TheThreadBackend::schedule( target, source, op );
198 }
199
200 TheThreadBackend::wait();
201}
203//*************************************************************************************************
204
205
206
207
208//=================================================================================================
209//
210// PLAIN ASSIGNMENT
211//
212//=================================================================================================
213
214//*************************************************************************************************
232template< 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
236inline 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//*************************************************************************************************
267template< 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
271inline 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
278
279 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
280
282 {
283 if( isSerialSectionActive() || !(*rhs).canSMPAssign() ) {
284 assign( *lhs, *rhs );
285 }
286 else {
287 threadAssign( *lhs, *rhs, []( auto& a, const auto& b ){ assign( a, b ); } );
288 }
289 }
290}
292//*************************************************************************************************
293
294
295
296
297//=================================================================================================
298//
299// ADDITION ASSIGNMENT
300//
301//=================================================================================================
302
303//*************************************************************************************************
322template< typename VT1 // Type of the left-hand side dense vector
323 , bool TF1 // Transpose flag of the left-hand side dense vector
324 , typename VT2 // Type of the right-hand side vector
325 , bool TF2 > // Transpose flag of the right-hand side vector
326inline auto smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
327 -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
328{
330
331 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
332
333 addAssign( *lhs, *rhs );
334}
336//*************************************************************************************************
337
338
339//*************************************************************************************************
357template< typename VT1 // Type of the left-hand side dense vector
358 , bool TF1 // Transpose flag of the left-hand side dense vector
359 , typename VT2 // Type of the right-hand side vector
360 , bool TF2 > // Transpose flag of the right-hand side vector
361inline auto smpAddAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
362 -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
363{
365
368
369 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
370
372 {
373 if( isSerialSectionActive() || !(*rhs).canSMPAssign() ) {
374 addAssign( *lhs, *rhs );
375 }
376 else {
377 threadAssign( *lhs, *rhs, []( auto& a, const auto& b ){ addAssign( a, b ); } );
378 }
379 }
380}
382//*************************************************************************************************
383
384
385
386
387//=================================================================================================
388//
389// SUBTRACTION ASSIGNMENT
390//
391//=================================================================================================
392
393//*************************************************************************************************
412template< typename VT1 // Type of the left-hand side dense vector
413 , bool TF1 // Transpose flag of the left-hand side dense vector
414 , typename VT2 // Type of the right-hand side vector
415 , bool TF2 > // Transpose flag of the right-hand side vector
416inline auto smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
417 -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
418{
420
421 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
422
423 subAssign( *lhs, *rhs );
424}
426//*************************************************************************************************
427
428
429//*************************************************************************************************
448template< typename VT1 // Type of the left-hand side dense vector
449 , bool TF1 // Transpose flag of the left-hand side dense vector
450 , typename VT2 // Type of the right-hand side vector
451 , bool TF2 > // Transpose flag of the right-hand side vector
452inline auto smpSubAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
453 -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
454{
456
459
460 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
461
463 {
464 if( isSerialSectionActive() || !(*rhs).canSMPAssign() ) {
465 subAssign( *lhs, *rhs );
466 }
467 else {
468 threadAssign( *lhs, *rhs, []( auto& a, const auto& b ){ subAssign( a, b ); } );
469 }
470 }
471}
473//*************************************************************************************************
474
475
476
477
478//=================================================================================================
479//
480// MULTIPLICATION ASSIGNMENT
481//
482//=================================================================================================
483
484//*************************************************************************************************
503template< 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
507inline auto smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
508 -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
509{
511
512 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
513
514 multAssign( *lhs, *rhs );
515}
517//*************************************************************************************************
518
519
520//*************************************************************************************************
539template< typename VT1 // Type of the left-hand side dense vector
540 , bool TF1 // Transpose flag of the left-hand side dense vector
541 , typename VT2 // Type of the right-hand side vector
542 , bool TF2 > // Transpose flag of the right-hand side vector
543inline auto smpMultAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
544 -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
545{
547
550
551 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
552
554 {
555 if( isSerialSectionActive() || !(*rhs).canSMPAssign() ) {
556 multAssign( *lhs, *rhs );
557 }
558 else {
559 threadAssign( *lhs, *rhs, []( auto& a, const auto& b ){ multAssign( a, b ); } );
560 }
561 }
562}
564//*************************************************************************************************
565
566
567
568
569//=================================================================================================
570//
571// DIVISION ASSIGNMENT
572//
573//=================================================================================================
574
575//*************************************************************************************************
594template< typename VT1 // Type of the left-hand side dense vector
595 , bool TF1 // Transpose flag of the left-hand side dense vector
596 , typename VT2 // Type of the right-hand side vector
597 , bool TF2 > // Transpose flag of the right-hand side vector
598inline auto smpDivAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
599 -> EnableIf_t< IsDenseVector_v<VT1> && ( !IsSMPAssignable_v<VT1> || !IsSMPAssignable_v<VT2> ) >
600{
602
603 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
604
605 divAssign( *lhs, *rhs );
606}
608//*************************************************************************************************
609
610
611//*************************************************************************************************
629template< typename VT1 // Type of the left-hand side dense vector
630 , bool TF1 // Transpose flag of the left-hand side dense vector
631 , typename VT2 // Type of the right-hand side vector
632 , bool TF2 > // Transpose flag of the right-hand side vector
633inline auto smpDivAssign( Vector<VT1,TF1>& lhs, const Vector<VT2,TF2>& rhs )
634 -> EnableIf_t< IsDenseVector_v<VT1> && IsSMPAssignable_v<VT1> && IsSMPAssignable_v<VT2> >
635{
637
640
641 BLAZE_INTERNAL_ASSERT( (*lhs).size() == (*rhs).size(), "Invalid vector sizes" );
642
644 {
645 if( isSerialSectionActive() || !(*rhs).canSMPAssign() ) {
646 divAssign( *lhs, *rhs );
647 }
648 else {
649 threadAssign( *lhs, *rhs, []( auto& a, const auto& b ){ divAssign( a, b ); } );
650 }
651 }
652}
654//*************************************************************************************************
655
656
657
658
659//=================================================================================================
660//
661// COMPILE TIME CONSTRAINTS
662//
663//=================================================================================================
664
665//*************************************************************************************************
667namespace {
668
670
671}
673//*************************************************************************************************
674
675} // namespace blaze
676
677#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 parallel section implementation.
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 C++11 and Boost thread backend.
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
bool isParallelSectionActive()
Returns whether a parallel section is active or not.
Definition: ParallelSection.h:221
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
#define BLAZE_PARALLEL_SECTION
Section for the debugging of the shared-memory parallelization.
Definition: ParallelSection.h:254
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_CPP_THREADS_PARALLEL_MODE
Compilation switch for the C++11 parallelization.
Definition: SMP.h:124
#define BLAZE_BOOST_THREADS_PARALLEL_MODE
Compilation switch for the Boost parallelization.
Definition: SMP.h:152
#define BLAZE_FUNCTION_TRACE
Function trace macro.
Definition: FunctionTrace.h:94
constexpr Unchecked unchecked
Global Unchecked instance.
Definition: Check.h:146
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.