Program Listing for File OpenMPExecutor.h
↰ Return to documentation for file (ADS/parallel/OpenMPExecutor.h)
/*--------------------------------------------------------------------------*/
/*------------------------- File OpenMPExecutor.h --------------------------*/
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/*----------------------------- DEFINITIONS --------------------------------*/
/*--------------------------------------------------------------------------*/
#ifndef __ADS_OpenMPExecutor
#define __ADS_OpenMPExecutor
/* self-identification: #endif constant */
#if defined( _OPENMP )
/*--------------------------------------------------------------------------*/
/*------------------------------ INCLUDES ----------------------------------*/
/*--------------------------------------------------------------------------*/
#include "ADS/Contract.h"
#include "ADS/parallel/Executor.h"
#include <omp.h>
#include <algorithm>
#include <cstddef>
/*--------------------------------------------------------------------------*/
/*--------------------------- NAMESPACE ------------------------------------*/
/*--------------------------------------------------------------------------*/
namespace ADS {
/*--------------------------------------------------------------------------*/
/*-------------------------- CLASS OpenMPExecutor --------------------------*/
/*--------------------------------------------------------------------------*/
class OpenMPExecutor {
/*--------------------------------------------------------------------------*/
public:
explicit OpenMPExecutor( std::size_t p = 0 )
: f_p( p ? p : std::size_t( omp_get_max_threads() ) ) {
ADS_PRE( f_p >= 1 );
}
[[nodiscard]] std::size_t concurrency( void ) const { return( f_p ); }
template< class F >
void bulk( std::size_t n , F && f ) {
if( ( n <= 1 ) || ( f_p == 1 ) ) {
for( std::size_t i = 0 ; i < n ; ++i )
f( i );
return;
}
detail::FirstError error;
const long m = long( n );
#pragma omp parallel for schedule( dynamic , 1 ) \
num_threads( int( std::min( f_p , n ) ) )
for( long i = 0 ; i < m ; ++i ) {
if( error.failed() )
continue;
try {
f( std::size_t( i ) );
}
catch( ... ) {
error.keep();
}
}
error.rethrow();
}
template< class F , class G >
void invoke( F && f , G && g ) {
bulk( 2 , [ & ]( std::size_t i ) { if( i == 0 ) f(); else g(); } );
}
/*--------------------------------------------------------------------------*/
private:
std::size_t f_p;
}; // end( class OpenMPExecutor )
/*--------------------------------------------------------------------------*/
} // end( namespace ADS )
#endif /* _OPENMP */
/*--------------------------------------------------------------------------*/
#endif /* OpenMPExecutor.h included */
/*--------------------------------------------------------------------------*/
/*----------------------- End File OpenMPExecutor.h ------------------------*/
/*--------------------------------------------------------------------------*/