ThreadBackend.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_SMP_THREADS_THREADBACKEND_H_
36 #define _BLAZE_MATH_SMP_THREADS_THREADBACKEND_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #if BLAZE_CPP_THREADS_PARALLEL_MODE
44 # include <condition_variable>
45 # include <mutex>
46 # include <thread>
47 #elif BLAZE_BOOST_THREADS_PARALLEL_MODE
48 # include <boost/thread/condition.hpp>
49 # include <boost/thread/mutex.hpp>
50 # include <boost/thread/thread.hpp>
51 #endif
52 
53 #include <cstdlib>
55 #include <blaze/math/Functions.h>
56 #include <blaze/system/SMP.h>
59 #include <blaze/util/ThreadPool.h>
60 #include <blaze/util/Types.h>
61 
62 
63 namespace blaze {
64 
65 //=================================================================================================
66 //
67 // CLASS DEFINITION
68 //
69 //=================================================================================================
70 
71 //*************************************************************************************************
82 template< typename TT // Type of the encapsulated thread
83  , typename MT // Type of the synchronization mutex
84  , typename LT // Type of the mutex lock
85  , typename CT > // Type of the condition variable
86 class ThreadBackend
87 {
88  public:
89  //**Utility functions***************************************************************************
92  static inline size_t size ();
93  static inline void resize( size_t n, bool block=false );
94  static inline void wait ();
96  //**********************************************************************************************
97 
98  //**Thread execution functions******************************************************************
101  template< typename Target, typename Source >
102  static inline void scheduleAssign( Target& target, const Source& source );
103 
104  template< typename Target, typename Source >
105  static inline void scheduleAddAssign( Target& target, const Source& source );
106 
107  template< typename Target, typename Source >
108  static inline void scheduleSubAssign( Target& target, const Source& source );
109 
110  template< typename Target, typename Source >
111  static inline void scheduleMultAssign( Target& target, const Source& source );
112 
113  template< typename Target, typename Source >
114  static inline void scheduleDivAssign( Target& target, const Source& source );
116  //**********************************************************************************************
117 
118  private:
119  //**Private class Assigner**********************************************************************
122  template< typename Target // Type of the target operand
123  , typename Source > // Type of the source operand
124  struct Assigner
125  {
126  //**Constructor******************************************************************************
132  explicit inline Assigner( Target& target, const Source& source )
133  : target_( target ) // The target operand
134  , source_( source ) // The source operand
135  {}
136  //*******************************************************************************************
137 
138  //**Function call operator*******************************************************************
143  inline void operator()() {
144  assign( target_, source_ );
145  }
146  //*******************************************************************************************
147 
148  //**Member variables*************************************************************************
149  Target target_;
150  const Source source_;
151  //*******************************************************************************************
152 
153  //**Member variables*************************************************************************
156  //*******************************************************************************************
157  };
158  //**********************************************************************************************
159 
160  //**Private class AddAssigner*******************************************************************
163  template< typename Target // Type of the target operand
164  , typename Source > // Type of the source operand
165  struct AddAssigner
166  {
167  //**Constructor******************************************************************************
173  explicit inline AddAssigner( Target& target, const Source& source )
174  : target_( target ) // The target operand
175  , source_( source ) // The source operand
176  {}
177  //*******************************************************************************************
178 
179  //**Function call operator*******************************************************************
184  inline void operator()() {
185  addAssign( target_, source_ );
186  }
187  //*******************************************************************************************
188 
189  //**Member variables*************************************************************************
190  Target target_;
191  const Source source_;
192  //*******************************************************************************************
193 
194  //**Member variables*************************************************************************
197  //*******************************************************************************************
198  };
199  //**********************************************************************************************
200 
201  //**Private class SubAssigner*******************************************************************
204  template< typename Target // Type of the target operand
205  , typename Source > // Type of the source operand
206  struct SubAssigner
207  {
208  //**Constructor******************************************************************************
214  explicit inline SubAssigner( Target& target, const Source& source )
215  : target_( target ) // The target operand
216  , source_( source ) // The source operand
217  {}
218  //*******************************************************************************************
219 
220  //**Function call operator*******************************************************************
225  inline void operator()() {
226  subAssign( target_, source_ );
227  }
228  //*******************************************************************************************
229 
230  //**Member variables*************************************************************************
231  Target target_;
232  const Source source_;
233  //*******************************************************************************************
234 
235  //**Member variables*************************************************************************
238  //*******************************************************************************************
239  };
240  //**********************************************************************************************
241 
242  //**Private class MultAssigner******************************************************************
245  template< typename Target // Type of the target operand
246  , typename Source > // Type of the source operand
247  struct MultAssigner
248  {
249  //**Constructor******************************************************************************
255  explicit inline MultAssigner( Target& target, const Source& source )
256  : target_( target ) // The target operand
257  , source_( source ) // The source operand
258  {}
259  //*******************************************************************************************
260 
261  //**Function call operator*******************************************************************
266  inline void operator()() {
267  multAssign( target_, source_ );
268  }
269  //*******************************************************************************************
270 
271  //**Member variables*************************************************************************
272  Target target_;
273  const Source source_;
274  //*******************************************************************************************
275 
276  //**Member variables*************************************************************************
279  //*******************************************************************************************
280  };
281  //**********************************************************************************************
282 
283  //**Private class DivAssigner*******************************************************************
286  template< typename Target // Type of the target operand
287  , typename Source > // Type of the source operand
288  struct DivAssigner
289  {
290  //**Constructor******************************************************************************
296  explicit inline DivAssigner( Target& target, const Source& source )
297  : target_( target ) // The target operand
298  , source_( source ) // The source operand
299  {}
300  //*******************************************************************************************
301 
302  //**Function call operator*******************************************************************
307  inline void operator()() {
308  divAssign( target_, source_ );
309  }
310  //*******************************************************************************************
311 
312  //**Member variables*************************************************************************
313  Target target_;
314  const Source source_;
315  //*******************************************************************************************
316 
317  //**Member variables*************************************************************************
320  //*******************************************************************************************
321  };
322  //**********************************************************************************************
323 
324  //**Initialization functions********************************************************************
327  static inline size_t initPool();
329  //**********************************************************************************************
330 
331  //**Member variables****************************************************************************
334  static ThreadPool<TT,MT,LT,CT> threadpool_;
335 
341  //**********************************************************************************************
342 };
344 //*************************************************************************************************
345 
346 
347 
348 
349 //=================================================================================================
350 //
351 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
352 //
353 //=================================================================================================
354 
355 //*************************************************************************************************
357 template< typename TT, typename MT, typename LT, typename CT >
358 ThreadPool<TT,MT,LT,CT> ThreadBackend<TT,MT,LT,CT>::threadpool_( initPool() );
360 //*************************************************************************************************
361 
362 
363 
364 
365 //=================================================================================================
366 //
367 // UTILITY FUNCTIONS
368 //
369 //=================================================================================================
370 
371 //*************************************************************************************************
377 template< typename TT // Type of the encapsulated thread
378  , typename MT // Type of the synchronization mutex
379  , typename LT // Type of the mutex lock
380  , typename CT > // Type of the condition variable
381 inline size_t ThreadBackend<TT,MT,LT,CT>::size()
382 {
383  return threadpool_.size();
384 }
386 //*************************************************************************************************
387 
388 
389 //*************************************************************************************************
405 template< typename TT // Type of the encapsulated thread
406  , typename MT // Type of the synchronization mutex
407  , typename LT // Type of the mutex lock
408  , typename CT > // Type of the condition variable
409 inline void ThreadBackend<TT,MT,LT,CT>::resize( size_t n, bool block )
410 {
411  return threadpool_.resize( n, block );
412 }
414 //*************************************************************************************************
415 
416 
417 //*************************************************************************************************
425 template< typename TT // Type of the encapsulated thread
426  , typename MT // Type of the synchronization mutex
427  , typename LT // Type of the mutex lock
428  , typename CT > // Type of the condition variable
429 inline void ThreadBackend<TT,MT,LT,CT>::wait()
430 {
431  threadpool_.wait();
432 }
434 //*************************************************************************************************
435 
436 
437 
438 
439 //=================================================================================================
440 //
441 // THREAD EXECUTION FUNCTIONS
442 //
443 //=================================================================================================
444 
445 //*************************************************************************************************
455 template< typename TT // Type of the encapsulated thread
456  , typename MT // Type of the synchronization mutex
457  , typename LT // Type of the mutex lock
458  , typename CT > // Type of the condition variable
459 template< typename Target // Type of the target operand
460  , typename Source > // Type of the source operand
461 inline void ThreadBackend<TT,MT,LT,CT>::scheduleAssign( Target& target, const Source& source )
462 {
464  threadpool_.schedule( Assigner<Target,Source>( target, source ) );
465 }
467 //*************************************************************************************************
468 
469 
470 //*************************************************************************************************
480 template< typename TT // Type of the encapsulated thread
481  , typename MT // Type of the synchronization mutex
482  , typename LT // Type of the mutex lock
483  , typename CT > // Type of the condition variable
484 template< typename Target // Type of the target operand
485  , typename Source > // Type of the source operand
486 inline void ThreadBackend<TT,MT,LT,CT>::scheduleAddAssign( Target& target, const Source& source )
487 {
489  threadpool_.schedule( AddAssigner<Target,Source>( target, source ) );
490 }
492 //*************************************************************************************************
493 
494 
495 //*************************************************************************************************
505 template< typename TT // Type of the encapsulated thread
506  , typename MT // Type of the synchronization mutex
507  , typename LT // Type of the mutex lock
508  , typename CT > // Type of the condition variable
509 template< typename Target // Type of the target operand
510  , typename Source > // Type of the source operand
511 inline void ThreadBackend<TT,MT,LT,CT>::scheduleSubAssign( Target& target, const Source& source )
512 {
514  threadpool_.schedule( SubAssigner<Target,Source>( target, source ) );
515 }
517 //*************************************************************************************************
518 
519 
520 //*************************************************************************************************
530 template< typename TT // Type of the encapsulated thread
531  , typename MT // Type of the synchronization mutex
532  , typename LT // Type of the mutex lock
533  , typename CT > // Type of the condition variable
534 template< typename Target // Type of the target operand
535  , typename Source > // Type of the source operand
536 inline void ThreadBackend<TT,MT,LT,CT>::scheduleMultAssign( Target& target, const Source& source )
537 {
539  threadpool_.schedule( MultAssigner<Target,Source>( target, source ) );
540 }
542 //*************************************************************************************************
543 
544 
545 //*************************************************************************************************
555 template< typename TT // Type of the encapsulated thread
556  , typename MT // Type of the synchronization mutex
557  , typename LT // Type of the mutex lock
558  , typename CT > // Type of the condition variable
559 template< typename Target // Type of the target operand
560  , typename Source > // Type of the source operand
561 inline void ThreadBackend<TT,MT,LT,CT>::scheduleDivAssign( Target& target, const Source& source )
562 {
564  threadpool_.schedule( DivAssigner<Target,Source>( target, source ) );
565 }
567 //*************************************************************************************************
568 
569 
570 
571 
572 //=================================================================================================
573 //
574 // INITIALIZATION FUNCTIONS
575 //
576 //=================================================================================================
577 
578 //*************************************************************************************************
588 #if (defined _MSC_VER)
589 # pragma warning(push)
590 # pragma warning(disable:4996)
591 #endif
592 template< typename TT // Type of the encapsulated thread
593  , typename MT // Type of the synchronization mutex
594  , typename LT // Type of the mutex lock
595  , typename CT > // Type of the condition variable
596 inline size_t ThreadBackend<TT,MT,LT,CT>::initPool()
597 {
598  const char* env = std::getenv( "BLAZE_NUM_THREADS" );
599 
600  if( env == nullptr )
601  return 1UL;
602  else return max( 1, atoi( env ) );
603 }
604 #if (defined _MSC_VER)
605 # pragma warning(pop)
606 #endif
607 
608 //*************************************************************************************************
609 
610 
611 
612 
613 //=================================================================================================
614 //
615 // TYPE DEFINITIONS
616 //
617 //=================================================================================================
618 
619 //*************************************************************************************************
628 #if BLAZE_CPP_THREADS_PARALLEL_MODE
629 typedef ThreadBackend< std::thread
630  , std::mutex
631  , std::unique_lock< std::mutex >
632  , std::condition_variable
633  > TheThreadBackend;
634 #elif BLAZE_BOOST_THREADS_PARALLEL_MODE
635 typedef ThreadBackend< boost::thread
636  , boost::mutex
637  , boost::unique_lock< boost::mutex >
638  , boost::condition_variable
639  > TheThreadBackend;
640 #endif
641 
642 //*************************************************************************************************
643 
644 
645 
646 
647 //=================================================================================================
648 //
649 // COMPILE TIME CONSTRAINTS
650 //
651 //=================================================================================================
652 
653 //*************************************************************************************************
655 namespace {
656 
658 
659 }
661 //*************************************************************************************************
662 
663 } // namespace blaze
664 
665 #endif
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:79
Header file for mathematical functions.
Header file of the ThreadPool class.
Header file for basic type definitions.
#define BLAZE_CONSTRAINT_MUST_BE_EXPRESSION_TYPE(T)
Constraint on the data type.In case the given data type T is not an expression (i.e. a type derived from the Expression base class), a compilation error is created.
Definition: Expression.h:61
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:258
#define BLAZE_BOOST_THREADS_PARALLEL_MODE
Compilation switch for the Boost parallelization.This compilation switch enables/disables the paralle...
Definition: SMP.h:122
Constraint on the data type.
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1716
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Compile time assertion.
System settings for the shared-memory parallelization.
#define BLAZE_CPP_THREADS_PARALLEL_MODE
Compilation switch for the C++11 parallelization.This compilation switch enables/disables the paralle...
Definition: SMP.h:95
BLAZE_ALWAYS_INLINE void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:538
Constraint on the data type.
#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