16 #include <sys/resource.h>
17 #include <sys/times.h>
18 #include <tbb/tick_count.h>
24 #define ON_DEBUG if ( msgLevel( MSG::DEBUG ) )
25 #define DEBUG_MSG ON_DEBUG debug()
27 #define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) )
28 #define VERBOSE_MSG ON_VERBOSE verbose()
34 : AsynchronousAlgorithm(
name, pSvc ) {
38 CHM::accessor name_ninstances;
40 name_ninstances->second += 1;
97 auto getGausRandom = [](
double mean,
double sigma ) ->
double {
100 auto getUnifRandom = [](
unsigned int&
seed ) ->
double {
102 constexpr
unsigned int m = 232;
103 constexpr
unsigned int a = 1664525;
104 constexpr
unsigned int c = 1013904223;
106 const double unif = double(
seed ) /
m;
112 unif1 = getUnifRandom(
seed );
113 unif2 = getUnifRandom(
seed );
116 const double normal =
sqrt( -2. *
log( unif1 ) ) * cos( 2 * M_PI * unif2 );
118 return normal * sigma + mean;
121 crunchtime = fabs( getGausRandom( m_avg_runtime, m_var_runtime ) );
123 input.reserve( 50000 * crunchtime );
124 for (
int i = 0; i < 50000 * crunchtime; ++i ) { input.push_back( getGausRandom( 20.0, 1.0 ) ); }
125 unsigned int crunchtime_ms = 1000 * crunchtime;
128 double lower_bound = std::ranges::min( input );
129 double upper_bound = std::ranges::max( input ) * 256;
130 DEBUG_MSG <<
"Crunching time will be: " << crunchtime_ms <<
" ms" <<
endmsg;
135 tbb::tick_count starttbb = tbb::tick_count::now();
138 for (
auto& inputHandle : m_inputHandles ) {
139 if ( !inputHandle->isValid() )
continue;
144 obj = inputHandle->get();
146 error() <<
"Caught exception with message " << e.
what() <<
" in evt " <<
ctx.evt() <<
endmsg;
149 if ( obj ==
nullptr ) error() <<
"A read object was a null pointer." <<
endmsg;
152 info() <<
"Crunching..." <<
endmsg;
155 gpuExecute( input,
out ).orThrow(
"GPU_EXECUTE" );
159 (
out.at( 0 ) == lower_bound ) && (
out.at( 1 ) == upper_bound ) && ( total_entries == 256 * input.size() );
160 info() <<
"Crunched." <<
endmsg;
161 ( match ? info() : warning() )
163 "GPU Crunch time: {} s. Input length {}, total entries {}. Pass: Lower {}, Upper {}, Entries {} ({} "
165 std::chrono::duration_cast<std::chrono::milliseconds>( endcrunch - startcrunch ).count() / 1
e3,
166 input.size(), total_entries,
out.at( 0 ) == lower_bound,
out.at( 1 ) == upper_bound,
167 total_entries == 256 * input.size(), 256 * input.size() - total_entries )
171 for (
auto& outputHandle : m_outputHandles ) {
172 if ( !outputHandle->isValid() )
continue;
176 outputHandle->put( std::make_unique<DataObject>() );
178 error() <<
"Caught exception with message " << e.
what() <<
" in evt " <<
ctx.evt() <<
endmsg;
183 tbb::tick_count endtbb = tbb::tick_count::now();
184 const double actualRuntime = ( endtbb - starttbb ).seconds();
186 DEBUG_MSG <<
"Finish event " <<
ctx.evt() <<
" in " << int( 1000 * actualRuntime ) <<
" ms" <<
endmsg;
188 DEBUG_MSG <<
"Timing: ExpectedCrunchtime= " << crunchtime_ms
189 <<
" ms. ActualTotalRuntime= " << int( 1000 * actualRuntime )
190 <<
" ms. Ratio= " << crunchtime / actualRuntime <<
endmsg;
201 unsigned int ninstances;
204 CHM::const_accessor const_name_ninstances;
206 ninstances = const_name_ninstances->second;
209 constexpr
double s2ms = 1000.;
211 if ( ninstances != 0 ) {
212 info() <<
"Summary: name= " <<
name() <<
"\t avg_runtime= " <<
m_avg_runtime * s2ms <<
"\t n_clones= " << ninstances
215 CHM::accessor name_ninstances;
217 name_ninstances->second = 0;