15#include <sys/resource.h>
17#include <tbb/blocked_range.h>
18#include <tbb/parallel_for.h>
19#include <tbb/tick_count.h>
25#define ON_DEBUG if ( msgLevel( MSG::DEBUG ) )
26#define DEBUG_MSG ON_DEBUG debug()
28#define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) )
29#define VERBOSE_MSG ON_VERBOSE verbose()
39 CHM::accessor name_ninstances;
41 name_ninstances->second += 1;
56 fatal() <<
"unable to acquire CPUCruncSvc" <<
endmsg;
90 VERBOSE_MSG <<
"found late-attributed output: " << outputHandle->objKey() <<
endmsg;
122 auto getGausRandom = [](
double mean,
double sigma ) ->
double {
123 unsigned int seed = std::clock();
125 auto getUnifRandom = [](
unsigned int& seed ) ->
double {
127 constexpr unsigned int m = 232;
128 constexpr unsigned int a = 1664525;
129 constexpr unsigned int c = 1013904223;
130 seed = ( a * seed + c ) % m;
131 const double unif = double( seed ) / m;
137 unif1 = getUnifRandom( seed );
138 unif2 = getUnifRandom( seed );
139 }
while ( unif1 < std::numeric_limits<double>::epsilon() );
141 const double normal = sqrt( -2. * log( unif1 ) ) * cos( 2 * M_PI * unif2 );
143 return normal * sigma + mean;
151 crunchtime =
std::abs( rndmgaus() );
153 unsigned int crunchtime_ms = 1000 * crunchtime;
159 const std::chrono::duration<double> dreamtime_duration( dreamtime );
162 tbb::tick_count starttbb = tbb::tick_count::now();
164 DEBUG_MSG <<
"Crunching time will be: " << crunchtime_ms <<
" ms" <<
endmsg;
166 DEBUG_MSG <<
"Start event " << context.
evt() <<
" in slot " << context.
slot() <<
" on pthreadID " << std::hex
167 << pthread_self() << std::dec <<
endmsg;
171 if ( !inputHandle->isValid() )
continue;
175 for (
unsigned int i = 0; i <
m_rwRepetitions; ++i ) { obj = inputHandle->get(); }
176 if ( obj ==
nullptr )
error() <<
"A read object was a null pointer." <<
endmsg;
180 tbb::parallel_for( tbb::blocked_range<size_t>( 0,
m_nParallel ), [&]( tbb::blocked_range<size_t> r ) {
181 m_crunchSvc->crunch_for( std::chrono::milliseconds( crunchtime_ms ) );
182 debug() <<
"CPUCrunch complete in TBB parallel for block " << r.begin() <<
" to " << r.end() <<
endmsg;
185 m_crunchSvc->crunch_for( std::chrono::milliseconds( crunchtime_ms ) );
195 if ( !outputHandle->isValid() )
continue;
198 outputHandle->put( std::make_unique<DataObject>() );
201 tbb::tick_count endtbb = tbb::tick_count::now();
202 const double actualRuntime = ( endtbb - starttbb ).seconds();
204 DEBUG_MSG <<
"Finish event " << context.
evt() <<
" in " << int( 1000 * actualRuntime ) <<
" ms" <<
endmsg;
206 DEBUG_MSG <<
"Timing: ExpectedCrunchtime= " << crunchtime_ms <<
" ms. ExpectedDreamtime= " << int( 1000 * dreamtime )
207 <<
" ms. ActualTotalRuntime= " << int( 1000 * actualRuntime )
208 <<
" ms. Ratio= " << ( crunchtime + dreamtime ) / actualRuntime <<
endmsg;
221 unsigned int ninstances;
224 CHM::const_accessor const_name_ninstances;
226 ninstances = const_name_ninstances->second;
229 constexpr double s2ms = 1000.;
231 if ( ninstances != 0 ) {
232 info() <<
"Summary: name= " <<
name() <<
"\t avg_runtime= " <<
m_avg_runtime * s2ms <<
"\t n_clones= " << ninstances
235 CHM::accessor name_ninstances;
237 name_ninstances->second = 0;
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
#define DECLARE_COMPONENT(type)
A class that implements a search for prime numbers.
Gaudi::Property< bool > m_invertCFD
std::vector< DataObjectHandle< DataObject > * > m_outputHandles
CPUCruncher()
the default constructor is disabled
StatusCode execute() override
the execution of the algorithm
virtual ~CPUCruncher()
virtual & protected desctrustor
void declareRuntimeRequestedOutputs()
The CPU intensive function.
Gaudi::Property< std::vector< std::string > > m_outKeys
StatusCode finalize() override
the finalization of the algorithm
std::vector< DataObjectHandle< DataObject > * > m_inputHandles
tbb::concurrent_hash_map< std::string, unsigned int > CHM
static CHM m_name_ncopies_map
SmartIF< ICPUCrunchSvc > m_crunchSvc
Gaudi::Property< bool > m_local_rndm_gen
Gaudi::Property< double > m_var_runtime
Gaudi::Property< std::vector< std::string > > m_inpKeys
StatusCode initialize() override
Its initialization.
Gaudi::Property< int > m_nParallel
Gaudi::Property< double > m_avg_runtime
Gaudi::Property< bool > m_loader
Gaudi::Property< double > m_sleepFraction
Gaudi::Property< unsigned int > m_rwRepetitions
Gaudi::Property< unsigned int > m_failNEvents
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
const SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
const DataObjIDColl & outputDataObjs() const override
void initDataHandleHolder()
DataObjectHandle.h GaudiKernel/DataObjectHandle.h.
A DataObject is the base class of any identifiable object on any data store.
This class represents an entry point to all the event specific data.
Algorithm(std::string name, ISvcLocator *svcloc, std::string version=PACKAGE_VERSION)
Constructor.
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, ToolHandle< T > &hndl, const std::string &doc="none")
StatusCode initialize() override
the default (empty) implementation of IStateful::initialize() method
StatusCode finalize() override
the default (empty) implementation of IStateful::finalize() method
SmartIF< IRndmGenSvc > & randSvc() const
The standard RandomGen service, Return a pointer to the service if present.
SmartIF< ISvcLocator > & serviceLocator() const override
The standard service locator.
const std::string & name() const override
The identifying name of the algorithm object.
void setFilterPassed(bool state) const
Set the filter passed flag to the specified state.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
virtual SmartIF< IService > & service(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)=0
Returns a smart pointer to a service.
Definition of the MsgStream class used to transmit messages.
Parameters for the Gauss random number generation.
This class is used for returning status codes from appropriate routines.
constexpr static const auto SUCCESS
constexpr static const auto FAILURE
GAUDI_API const EventContext & currentContext()
Gaudi::ParticleID abs(const Gaudi::ParticleID &p)
Return the absolute value for a PID.