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/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 scheduleSchurAssign( Target& target, const Source& source );
112 
113  template< typename Target, typename Source >
114  static inline void scheduleMultAssign( Target& target, const Source& source );
115 
116  template< typename Target, typename Source >
117  static inline void scheduleDivAssign( Target& target, const Source& source );
119  //**********************************************************************************************
120 
121  private:
122  //**Private class Assigner**********************************************************************
125  template< typename Target // Type of the target operand
126  , typename Source > // Type of the source operand
127  struct Assigner
128  {
129  //**Constructor******************************************************************************
135  explicit inline Assigner( Target& target, const Source& source )
136  : target_( target ) // The target operand
137  , source_( source ) // The source operand
138  {}
139  //*******************************************************************************************
140 
141  //**Function call operator*******************************************************************
146  inline void operator()() {
147  assign( target_, source_ );
148  }
149  //*******************************************************************************************
150 
151  //**Member variables*************************************************************************
152  Target target_;
153  const Source source_;
154  //*******************************************************************************************
155 
156  //**Member variables*************************************************************************
159  //*******************************************************************************************
160  };
161  //**********************************************************************************************
162 
163  //**Private class AddAssigner*******************************************************************
166  template< typename Target // Type of the target operand
167  , typename Source > // Type of the source operand
168  struct AddAssigner
169  {
170  //**Constructor******************************************************************************
176  explicit inline AddAssigner( Target& target, const Source& source )
177  : target_( target ) // The target operand
178  , source_( source ) // The source operand
179  {}
180  //*******************************************************************************************
181 
182  //**Function call operator*******************************************************************
187  inline void operator()() {
188  addAssign( target_, source_ );
189  }
190  //*******************************************************************************************
191 
192  //**Member variables*************************************************************************
193  Target target_;
194  const Source source_;
195  //*******************************************************************************************
196 
197  //**Member variables*************************************************************************
200  //*******************************************************************************************
201  };
202  //**********************************************************************************************
203 
204  //**Private class SubAssigner*******************************************************************
207  template< typename Target // Type of the target operand
208  , typename Source > // Type of the source operand
209  struct SubAssigner
210  {
211  //**Constructor******************************************************************************
217  explicit inline SubAssigner( Target& target, const Source& source )
218  : target_( target ) // The target operand
219  , source_( source ) // The source operand
220  {}
221  //*******************************************************************************************
222 
223  //**Function call operator*******************************************************************
228  inline void operator()() {
229  subAssign( target_, source_ );
230  }
231  //*******************************************************************************************
232 
233  //**Member variables*************************************************************************
234  Target target_;
235  const Source source_;
236  //*******************************************************************************************
237 
238  //**Member variables*************************************************************************
241  //*******************************************************************************************
242  };
243  //**********************************************************************************************
244 
245  //**Private class SchurAssigner*****************************************************************
248  template< typename Target // Type of the target operand
249  , typename Source > // Type of the source operand
250  struct SchurAssigner
251  {
252  //**Constructor******************************************************************************
258  explicit inline SchurAssigner( Target& target, const Source& source )
259  : target_( target ) // The target operand
260  , source_( source ) // The source operand
261  {}
262  //*******************************************************************************************
263 
264  //**Function call operator*******************************************************************
269  inline void operator()() {
270  schurAssign( target_, source_ );
271  }
272  //*******************************************************************************************
273 
274  //**Member variables*************************************************************************
275  Target target_;
276  const Source source_;
277  //*******************************************************************************************
278 
279  //**Member variables*************************************************************************
282  //*******************************************************************************************
283  };
284  //**********************************************************************************************
285 
286  //**Private class MultAssigner******************************************************************
289  template< typename Target // Type of the target operand
290  , typename Source > // Type of the source operand
291  struct MultAssigner
292  {
293  //**Constructor******************************************************************************
299  explicit inline MultAssigner( Target& target, const Source& source )
300  : target_( target ) // The target operand
301  , source_( source ) // The source operand
302  {}
303  //*******************************************************************************************
304 
305  //**Function call operator*******************************************************************
310  inline void operator()() {
311  multAssign( target_, source_ );
312  }
313  //*******************************************************************************************
314 
315  //**Member variables*************************************************************************
316  Target target_;
317  const Source source_;
318  //*******************************************************************************************
319 
320  //**Member variables*************************************************************************
323  //*******************************************************************************************
324  };
325  //**********************************************************************************************
326 
327  //**Private class DivAssigner*******************************************************************
330  template< typename Target // Type of the target operand
331  , typename Source > // Type of the source operand
332  struct DivAssigner
333  {
334  //**Constructor******************************************************************************
340  explicit inline DivAssigner( Target& target, const Source& source )
341  : target_( target ) // The target operand
342  , source_( source ) // The source operand
343  {}
344  //*******************************************************************************************
345 
346  //**Function call operator*******************************************************************
351  inline void operator()() {
352  divAssign( target_, source_ );
353  }
354  //*******************************************************************************************
355 
356  //**Member variables*************************************************************************
357  Target target_;
358  const Source source_;
359  //*******************************************************************************************
360 
361  //**Member variables*************************************************************************
364  //*******************************************************************************************
365  };
366  //**********************************************************************************************
367 
368  //**Initialization functions********************************************************************
371  static inline size_t initPool();
373  //**********************************************************************************************
374 
375  //**Member variables****************************************************************************
378  static ThreadPool<TT,MT,LT,CT> threadpool_;
379 
385  //**********************************************************************************************
386 };
388 //*************************************************************************************************
389 
390 
391 
392 
393 //=================================================================================================
394 //
395 // DEFINITION AND INITIALIZATION OF THE STATIC MEMBER VARIABLES
396 //
397 //=================================================================================================
398 
399 //*************************************************************************************************
401 template< typename TT, typename MT, typename LT, typename CT >
402 ThreadPool<TT,MT,LT,CT> ThreadBackend<TT,MT,LT,CT>::threadpool_( initPool() );
404 //*************************************************************************************************
405 
406 
407 
408 
409 //=================================================================================================
410 //
411 // UTILITY FUNCTIONS
412 //
413 //=================================================================================================
414 
415 //*************************************************************************************************
421 template< typename TT // Type of the encapsulated thread
422  , typename MT // Type of the synchronization mutex
423  , typename LT // Type of the mutex lock
424  , typename CT > // Type of the condition variable
425 inline size_t ThreadBackend<TT,MT,LT,CT>::size()
426 {
427  return threadpool_.size();
428 }
430 //*************************************************************************************************
431 
432 
433 //*************************************************************************************************
449 template< typename TT // Type of the encapsulated thread
450  , typename MT // Type of the synchronization mutex
451  , typename LT // Type of the mutex lock
452  , typename CT > // Type of the condition variable
453 inline void ThreadBackend<TT,MT,LT,CT>::resize( size_t n, bool block )
454 {
455  return threadpool_.resize( n, block );
456 }
458 //*************************************************************************************************
459 
460 
461 //*************************************************************************************************
469 template< typename TT // Type of the encapsulated thread
470  , typename MT // Type of the synchronization mutex
471  , typename LT // Type of the mutex lock
472  , typename CT > // Type of the condition variable
473 inline void ThreadBackend<TT,MT,LT,CT>::wait()
474 {
475  threadpool_.wait();
476 }
478 //*************************************************************************************************
479 
480 
481 
482 
483 //=================================================================================================
484 //
485 // THREAD EXECUTION FUNCTIONS
486 //
487 //=================================================================================================
488 
489 //*************************************************************************************************
499 template< typename TT // Type of the encapsulated thread
500  , typename MT // Type of the synchronization mutex
501  , typename LT // Type of the mutex lock
502  , typename CT > // Type of the condition variable
503 template< typename Target // Type of the target operand
504  , typename Source > // Type of the source operand
505 inline void ThreadBackend<TT,MT,LT,CT>::scheduleAssign( Target& target, const Source& source )
506 {
508  threadpool_.schedule( Assigner<Target,Source>( target, source ) );
509 }
511 //*************************************************************************************************
512 
513 
514 //*************************************************************************************************
524 template< typename TT // Type of the encapsulated thread
525  , typename MT // Type of the synchronization mutex
526  , typename LT // Type of the mutex lock
527  , typename CT > // Type of the condition variable
528 template< typename Target // Type of the target operand
529  , typename Source > // Type of the source operand
530 inline void ThreadBackend<TT,MT,LT,CT>::scheduleAddAssign( Target& target, const Source& source )
531 {
533  threadpool_.schedule( AddAssigner<Target,Source>( target, source ) );
534 }
536 //*************************************************************************************************
537 
538 
539 //*************************************************************************************************
549 template< typename TT // Type of the encapsulated thread
550  , typename MT // Type of the synchronization mutex
551  , typename LT // Type of the mutex lock
552  , typename CT > // Type of the condition variable
553 template< typename Target // Type of the target operand
554  , typename Source > // Type of the source operand
555 inline void ThreadBackend<TT,MT,LT,CT>::scheduleSubAssign( Target& target, const Source& source )
556 {
558  threadpool_.schedule( SubAssigner<Target,Source>( target, source ) );
559 }
561 //*************************************************************************************************
562 
563 
564 //*************************************************************************************************
574 template< typename TT // Type of the encapsulated thread
575  , typename MT // Type of the synchronization mutex
576  , typename LT // Type of the mutex lock
577  , typename CT > // Type of the condition variable
578 template< typename Target // Type of the target operand
579  , typename Source > // Type of the source operand
580 inline void ThreadBackend<TT,MT,LT,CT>::scheduleSchurAssign( Target& target, const Source& source )
581 {
583  threadpool_.schedule( SchurAssigner<Target,Source>( target, source ) );
584 }
586 //*************************************************************************************************
587 
588 
589 //*************************************************************************************************
599 template< typename TT // Type of the encapsulated thread
600  , typename MT // Type of the synchronization mutex
601  , typename LT // Type of the mutex lock
602  , typename CT > // Type of the condition variable
603 template< typename Target // Type of the target operand
604  , typename Source > // Type of the source operand
605 inline void ThreadBackend<TT,MT,LT,CT>::scheduleMultAssign( Target& target, const Source& source )
606 {
608  threadpool_.schedule( MultAssigner<Target,Source>( target, source ) );
609 }
611 //*************************************************************************************************
612 
613 
614 //*************************************************************************************************
624 template< typename TT // Type of the encapsulated thread
625  , typename MT // Type of the synchronization mutex
626  , typename LT // Type of the mutex lock
627  , typename CT > // Type of the condition variable
628 template< typename Target // Type of the target operand
629  , typename Source > // Type of the source operand
630 inline void ThreadBackend<TT,MT,LT,CT>::scheduleDivAssign( Target& target, const Source& source )
631 {
633  threadpool_.schedule( DivAssigner<Target,Source>( target, source ) );
634 }
636 //*************************************************************************************************
637 
638 
639 
640 
641 //=================================================================================================
642 //
643 // INITIALIZATION FUNCTIONS
644 //
645 //=================================================================================================
646 
647 //*************************************************************************************************
657 #if (defined _MSC_VER)
658 # pragma warning(push)
659 # pragma warning(disable:4996)
660 #endif
661 template< typename TT // Type of the encapsulated thread
662  , typename MT // Type of the synchronization mutex
663  , typename LT // Type of the mutex lock
664  , typename CT > // Type of the condition variable
665 inline size_t ThreadBackend<TT,MT,LT,CT>::initPool()
666 {
667  const char* env = std::getenv( "BLAZE_NUM_THREADS" );
668 
669  if( env == nullptr )
670  return 1UL;
671  else return max( 1, atoi( env ) );
672 }
673 #if (defined _MSC_VER)
674 # pragma warning(pop)
675 #endif
676 
677 //*************************************************************************************************
678 
679 
680 
681 
682 //=================================================================================================
683 //
684 // TYPE DEFINITIONS
685 //
686 //=================================================================================================
687 
688 //*************************************************************************************************
697 #if BLAZE_CPP_THREADS_PARALLEL_MODE
698 using TheThreadBackend = ThreadBackend< std::thread
699  , std::mutex
700  , std::unique_lock< std::mutex >
701  , std::condition_variable
702  >;
703 #elif BLAZE_BOOST_THREADS_PARALLEL_MODE
704 using TheThreadBackend = ThreadBackend< boost::thread
705  , boost::mutex
706  , boost::unique_lock< boost::mutex >
707  , boost::condition_variable
708  >;
709 #endif
710 
711 //*************************************************************************************************
712 
713 
714 
715 
716 //=================================================================================================
717 //
718 // COMPILE TIME CONSTRAINTS
719 //
720 //=================================================================================================
721 
722 //*************************************************************************************************
724 namespace {
725 
727 
728 }
730 //*************************************************************************************************
731 
732 } // namespace blaze
733 
734 #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 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:265
#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:1809
Headerfile for the generic max algorithm.
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:548
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