Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • holau/Gaudi
  • dmagdali/Gaudi
  • pmunozpa/Gaudi
  • ssottoco/Gaudi
  • cvarni/Gaudi
  • mafila/Gaudi
  • admorris/Gaudi
  • staider/Gaudi
  • gunther/Gaudi
  • bstanisl/Gaudi
  • jtorasso/Gaudi
  • wochung/Gaudi
  • mveghel/Gaudi
  • averbyts/Gaudi
  • dguest/Gaudi
  • alboyer/Gaudi
  • dkonst/Gaudi
  • jcarcell/Gaudi
  • elmsheus/Gaudi
  • hpxgaudi/Gaudi
  • ganis/Gaudi
  • tadej/Gaudi
  • hahansen/Gaudi
  • juesseiv/Gaudi
  • imjelde/gaudida
  • jheuel/Gaudi
  • mimazure/Gaudi
  • masato/Gaudi
  • dcasperfaser/Gaudi
  • faser/offline/Gaudi
  • axu/Gaudi
  • sailer/Gaudi
  • amete/Gaudi
  • ponyisi/Gaudi
  • vavolkl/Gaudi
  • mstahl/Gaudi
  • wlampl/Gaudi
  • kreczko/Gaudi
  • emoyse/Gaudi
  • dhynds/Gaudi
  • sstahl/Gaudi
  • rcurrie/Gaudi
  • smh/Gaudi
  • valassi/Gaudi
  • bwynne/Gaudi_gaudi
  • abarton/Gaudi
  • tsulaia/gaudigaudi
  • mnowak/Gaudi
  • roiser/Gaudi
  • merrenst/Gaudi
  • mato/Gaudi
  • christos/Gaudi
  • goetz/Gaudi
  • goetz/AtlasGaudi
  • tsulaia/atlasgaudi
  • olupton/Gaudi
  • pseyfert/Gaudi
  • graemes/Gaudi
  • gianelle/Gaudi
  • akraszna/AtlasGaudi
  • cattanem/Gaudi
  • skluth/Gaudi
  • will/Gaudi
  • ssnyder/Gaudi
  • agonzale/Gaudi
  • leggett/AtlasGaudi
  • apearce/Gaudi
  • mnowak/Gaudi-ORIG
  • fwinkl/AtlasGaudi
  • bwynne/Gaudi_atlas
  • chamont/Gaudi
  • rmatev/Gaudi
  • lhcb/Gaudi
  • atlas/Gaudi
  • akraszna/GaudiGaudi
  • fwinkl/Gaudi
  • jonrob/Gaudi
  • azaborow/Gaudi
  • clemenci/Gaudi
  • hgraslan/Gaudi
  • srimanob/Gaudi
  • graven/Gaudi
  • hegner/Gaudi
  • gaudi/Gaudi
84 results
Show changes
Commits on Source (8)
Showing
with 404 additions and 1437 deletions
// Include files
#include "ApplicationMgr.h"
#include "AlgorithmManager.h"
#include "DLLClassManager.h"
#include "ServiceManager.h"
......@@ -15,7 +16,6 @@
#include "GaudiKernel/SmartIF.h"
#include "GaudiKernel/GaudiException.h"
#include "GaudiKernel/ThreadGaudi.h"
#include "GaudiKernel/StatusCode.h"
#include "GaudiKernel/System.h"
......@@ -262,20 +262,23 @@ StatusCode ApplicationMgr::configure()
return sc;
}
MsgStream log( m_messageSvc, name() );
// Get my own options using the Job options service
if ( log.level() <= MSG::DEBUG ) log << MSG::DEBUG << "Getting my own properties" << endmsg;
sc = m_jobOptionsSvc->setMyProperties( name(), this );
if ( !sc.isSuccess() ) {
log << MSG::WARNING << "Problems getting my properties from JobOptionsSvc" << endmsg;
return sc;
{
MsgStream log( m_messageSvc, name() );
// Get my own options using the Job options service
if ( log.level() <= MSG::DEBUG ) log << MSG::DEBUG << "Getting my own properties" << endmsg;
sc = m_jobOptionsSvc->setMyProperties( name(), this );
if ( !sc.isSuccess() ) {
log << MSG::WARNING << "Problems getting my properties from JobOptionsSvc" << endmsg;
return sc;
}
}
// Make sure that the OutputLevel is in sync
if ( m_outputLevel != MSG::NIL && m_messageSvc ) m_messageSvc->setOutputLevel( name(), m_outputLevel );
MsgStream log( m_messageSvc, name() );
// Check current outputLevel to eventually inform the MessageSvc
if ( m_outputLevel != MSG::NIL && !m_appName.empty() ) {
assert( m_messageSvc );
m_messageSvc->setOutputLevel( name(), m_outputLevel );
// Print a welcome message
log << MSG::ALWAYS << std::endl
<< "=================================================================="
......@@ -315,10 +318,13 @@ StatusCode ApplicationMgr::configure()
// Check if StatusCode need to be checked
if ( m_codeCheck ) {
StatusCode::enableChecking();
sc = addMultiSvc( "StatusCodeSvc", -9999 );
sc = svcManager()->addService( "StatusCodeSvc", -9999 );
if ( sc.isFailure() ) {
log << MSG::FATAL << "Error adding StatusCodeSvc for multiple threads" << endmsg;
log << MSG::FATAL << "Error adding StatusCodeSvc" << endmsg;
return StatusCode::FAILURE;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "added service StatusCodeSvc" << endmsg;
}
} else {
StatusCode::disableChecking();
......@@ -337,15 +343,18 @@ StatusCode ApplicationMgr::configure()
// Declare Service Types
for ( auto& j : m_svcMapping ) {
Gaudi::Utils::TypeNameString itm( j );
if ( declareMultiSvcType( itm.name(), itm.type() ).isFailure() ) {
if ( svcManager()->declareSvcType( itm.name(), itm.type() ).isFailure() ) {
log << MSG::ERROR << "configure: declaring svc type:'" << j << "' failed." << endmsg;
return StatusCode::FAILURE;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "declared service " << j << endmsg;
}
}
for ( auto& j : m_svcOptMapping ) {
Gaudi::Utils::TypeNameString itm( j );
if ( declareMultiSvcType( itm.name(), itm.type() ).isFailure() ) {
log << MSG::ERROR << "configure: declaring svc type:'" << j << "' failed." << endmsg;
if ( svcManager()->declareSvcType( itm.name(), itm.type() ).isFailure() ) {
log << MSG::ERROR << "declaring svc type:'" << j << "' failed." << endmsg;
return StatusCode::FAILURE;
}
}
......@@ -366,12 +375,6 @@ StatusCode ApplicationMgr::configure()
return sc;
}
sc = decodeMultiThreadSvcNameList();
if ( sc.isFailure() ) {
log << MSG::ERROR << "Failure during multi thread service creation" << endmsg;
return sc;
}
sc = decodeCreateSvcNameList();
if ( sc.isFailure() ) {
log << MSG::ERROR << "Failure during external service creation" << endmsg;
......@@ -382,31 +385,31 @@ StatusCode ApplicationMgr::configure()
// Retrieve intrinsic services. If needed configure them.
//--------------------------------------------------------------------------
const Gaudi::Utils::TypeNameString evtloop_item( m_eventLoopMgr );
sc = addMultiSvc( evtloop_item, ServiceManager::DEFAULT_SVC_PRIORITY * 10 );
sc = svcManager()->addService( evtloop_item, ServiceManager::DEFAULT_SVC_PRIORITY * 10 );
if ( !sc.isSuccess() ) {
log << MSG::FATAL << "Error adding :" << m_eventLoopMgr << endmsg;
return sc;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "added service " << evtloop_item << endmsg;
}
if ( m_noOfEvtThreads == 0 ) {
m_runable = m_svcLocator->service( m_runableType );
if ( !m_runable ) {
log << MSG::FATAL << "Error retrieving Runable: " << m_runableType.value() << "\n Check option ApplicationMgr."
<< m_runableType.name() << endmsg;
return sc;
}
m_processingMgr = m_svcLocator->service( evtloop_item );
if ( !m_processingMgr ) {
log << MSG::FATAL << "Error retrieving Processing manager: " << m_eventLoopMgr.value()
<< "\n Check option ApplicationMgr." << m_eventLoopMgr.name() << "\n No events will be processed." << endmsg;
return sc;
}
m_runable = m_svcLocator->service( m_runableType );
if ( !m_runable ) {
log << MSG::FATAL << "Error retrieving Runable: " << m_runableType.value() << "\n Check option ApplicationMgr."
<< m_runableType.name() << endmsg;
return sc;
}
m_processingMgr = m_svcLocator->service( evtloop_item );
if ( !m_processingMgr ) {
log << MSG::FATAL << "Error retrieving Processing manager: " << m_eventLoopMgr.value()
<< "\n Check option ApplicationMgr." << m_eventLoopMgr.name() << "\n No events will be processed." << endmsg;
return sc;
}
// Establish Update Handlers for ExtSvc and DLLs Properties
m_extSvcNameList.declareUpdateHandler( &ApplicationMgr::extSvcNameListHandler, this );
m_createSvcNameList.declareUpdateHandler( &ApplicationMgr::createSvcNameListHandler, this );
m_multiThreadSvcNameList.declareUpdateHandler( &ApplicationMgr::multiThreadSvcNameListHandler, this );
m_dllNameList.declareUpdateHandler( &ApplicationMgr::dllNameListHandler, this );
if ( m_actHistory ) {
......@@ -416,14 +419,6 @@ StatusCode ApplicationMgr::configure()
log << MSG::FATAL << "Error adding HistorySvc" << endmsg;
return StatusCode::FAILURE;
}
if ( m_noOfEvtThreads > 0 ) {
sc = addMultiSvc( "HistorySvc", std::numeric_limits<int>::max() );
if ( sc.isFailure() ) {
log << MSG::FATAL << "Error adding HistorySvc for multiple threads" << endmsg;
return StatusCode::FAILURE;
}
}
}
log << MSG::INFO << "Application Manager Configured successfully" << endmsg;
......@@ -1023,107 +1018,6 @@ StatusCode ApplicationMgr::decodeExtSvcNameList()
return result;
}
//============================================================================
// External Service List handler
//============================================================================
void ApplicationMgr::multiThreadSvcNameListHandler( Gaudi::Details::PropertyBase& /* theProp */ )
{
if ( !( decodeMultiThreadSvcNameList() ).isSuccess() ) {
throw GaudiException( "Failed to create copies of mt services",
"MinimalEventLoopMgr::multiThreadSvcNameListHandler", StatusCode::FAILURE );
}
}
//============================================================================
// decodeMultiExtSvcNameList
//============================================================================
StatusCode ApplicationMgr::decodeMultiThreadSvcNameList()
{
StatusCode result = StatusCode::SUCCESS;
const auto& theNames = m_multiThreadSvcNameList.value();
for ( int iCopy = 0; iCopy < m_noOfEvtThreads; ++iCopy ) {
for ( const auto& it : theNames ) {
Gaudi::Utils::TypeNameString item( it );
result = addMultiSvc( item, ServiceManager::DEFAULT_SVC_PRIORITY );
// FIXME SHOULD CLONE?
if ( result.isFailure() ) {
MsgStream log( m_messageSvc, m_name );
log << MSG::ERROR << "decodeMultiThreadSvcNameList: Cannot create service " << item.type() << "/" << item.name()
<< endmsg;
} else {
ON_VERBOSE
{
MsgStream log( m_messageSvc, m_name );
log << MSG::VERBOSE << "decodeMultiThreadSvcNameList: created service " << item.type() << "/" << item.name()
<< endmsg;
}
}
}
}
return result;
}
//=============================================================================
// declareMultiSvcType
//=============================================================================
StatusCode ApplicationMgr::declareMultiSvcType( const std::string& name, const std::string& type )
{
StatusCode result = StatusCode::SUCCESS;
MsgStream log( m_messageSvc, m_name );
if ( 0 == m_noOfEvtThreads ) {
result = svcManager()->declareSvcType( name, type );
if ( result.isFailure() ) {
log << MSG::ERROR << "declareMultiSvcType: Cannot declare service " << type << "/" << name << endmsg;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "declareMultiSvcType: declared service " << type << "/" << name << endmsg;
}
} else {
for ( int iCopy = 0; iCopy < m_noOfEvtThreads; ++iCopy ) {
std::string thrName( name + getGaudiThreadIDfromID( iCopy ) );
result = svcManager()->declareSvcType( thrName, type );
if ( result.isFailure() ) {
log << MSG::ERROR << "declareMultiSvcType: Cannot declare service " << type << "/" << thrName << endmsg;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "declareMultiSvcType: declared service " << type << "/" << thrName << endmsg;
}
}
}
return result;
}
//=============================================================================
// addMultiSvc
//=============================================================================
StatusCode ApplicationMgr::addMultiSvc( const Gaudi::Utils::TypeNameString& typeName, int prio )
{
using Gaudi::Utils::TypeNameString;
StatusCode result = StatusCode::SUCCESS;
MsgStream log( m_messageSvc, m_name );
if ( 0 == m_noOfEvtThreads ) {
result = svcManager()->addService( typeName, prio );
// result = svcManager()->addService(name, type, prio); // CHECKME???
if ( result.isFailure() ) {
log << MSG::ERROR << "addMultiSvc: Cannot add service " << typeName.type() << "/" << typeName.name() << endmsg;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "addMultiSvc: added service " << typeName.type() << "/" << typeName.name() << endmsg;
}
} else {
for ( int iCopy = 0; iCopy < m_noOfEvtThreads; ++iCopy ) {
const std::string& type = typeName.type();
std::string thrName( typeName.name() + getGaudiThreadIDfromID( iCopy ) );
result = svcManager()->addService( TypeNameString( thrName, type ), prio );
if ( result.isFailure() ) {
log << MSG::ERROR << "addMultiSvc: Cannot add service " << type << "/" << thrName << endmsg;
} else {
ON_VERBOSE
log << MSG::VERBOSE << "addMultiSvc: added service " << type << "/" << thrName << endmsg;
}
}
}
return result;
}
//============================================================================
// Dll List handler
//============================================================================
......
......@@ -113,8 +113,6 @@ public:
StatusCode decodeCreateSvcNameList();
void createSvcNameListHandler( Gaudi::Details::PropertyBase& );
void extSvcNameListHandler( Gaudi::Details::PropertyBase& theProp );
StatusCode decodeMultiThreadSvcNameList();
void multiThreadSvcNameListHandler( Gaudi::Details::PropertyBase& theProp );
StatusCode decodeDllNameList();
void dllNameListHandler( Gaudi::Details::PropertyBase& theProp );
void pluginDebugPropertyHandler( Gaudi::Details::PropertyBase& theProp );
......@@ -152,11 +150,6 @@ public:
void outputLevelUpdate() override;
protected:
/// declare one or more copies of svc type/name as determined by NoOfThreads
StatusCode declareMultiSvcType( const std::string& name, const std::string& type );
/// add one or more copies of svc type/name as determined by NoOfThreads
StatusCode addMultiSvc( const Gaudi::Utils::TypeNameString& typeName, int prio );
// implementation of IService::setServiceManager
void setServiceManager( ISvcManager* ) override {}
......@@ -221,10 +214,6 @@ protected:
Gaudi::Property<bool> m_extSvcCreates{this, "ExtSvcCreates", true,
"LHCb (default) or ATLAS definition of \"ExtSvc\""};
/// List of external services names for which we want a copy per evt thread
Gaudi::Property<std::vector<std::string>> m_multiThreadSvcNameList{this, "MultiThreadExtSvc"};
Gaudi::Property<int> m_noOfEvtThreads{this, "NoOfThreads", 0, "MultiThreadSvc copies"};
Gaudi::Property<std::vector<std::string>> m_dllNameList{this, "Dlls", {}, "List of DDL's names"};
Gaudi::Property<std::string> m_jobOptionsType{this, "JobOptionsType", "FILE", "Source type (e.g. dbase, file...)"};
Gaudi::Property<std::string> m_jobOptionsPath{this, "JobOptionsPath", {}, "The \"file\" to look for properties"};
......
//##############################################################
// Job options file
//==============================================================
//AuditorSvc.Auditors = { "ChronoAuditor" };
ApplicationMgr.EventLoop = "MTEventLoopMgr";
ApplicationMgr.ExtSvc += { "NTupleSvc" };
ApplicationMgr.MultiThreadExtSvc += { "RndmGenSvc", "ParticlePropertySvc" };
ApplicationMgr.OutputLevel = 1;
//--------------------------------------------------------------
//--------------------------------------------------------------
// Private Application Configuration options
//--------------------------------------------------------------
ApplicationMgr.TopAlg = { "MTHelloWorld" };
// Set output level threshold (2=DEBUG, 3=INFO, 4=WARNING, 5=ERROR, 6=FATAL )
MessageSvc.OutputLevel = 1;
//--------------------------------------------------------------
// Event related parameters
//--------------------------------------------------------------
ApplicationMgr.EvtMax = 2;
ApplicationMgr.EvtSel = "NONE";
//--------------------------------------------------------------
// Algorithms Private Options
//--------------------------------------------------------------
// For the genuine HelloWorld algorithm
MTHelloWorld.MyInt = 42;
MTHelloWorld.MyBool = true;
MTHelloWorld.MyDouble = 3.14159;
MTHelloWorld.MyStringVec = { "Welcome", "to", "MT", "Gaudi" };
// For a special HelloWorld algorithm
MTHelloWorld__1.MyInt = 21;
MTHelloWorld__1.MyBool = false;
MTHelloWorld__1.MyDouble = 6.28;
MTHelloWorld__1.MyStringVec = { "Welcome", "to", "Thread", "1" };
// Include Files
#include "GaudiKernel/LoadFactoryEntries.h"
LOAD_FACTORY_ENTRIES( GaudiMTExample )
// Dear emacs, this is -*- c++ -*-
const int MAX_THREADS( 1023 ); // to check command line parameter
// Include files
#include "GaudiKernel/Bootstrap.h"
#include "GaudiKernel/IAppMgrUI.h"
#include "GaudiKernel/IClassManager.h"
#include "GaudiKernel/IProperty.h"
#include "GaudiKernel/SmartIF.h"
#include "GaudiKernel/IEventProcessor.h"
#include "GaudiKernel/IInterface.h"
#include "GaudiKernel/ISvcLocator.h"
#include "GaudiKernel/ThreadGaudi.h"
#include "boost/algorithm/string/predicate.hpp"
#include <cassert>
#include <iostream>
#include <pthread.h>
/**
* Defines a global locking mechanism so we can see when all worker threads
* are finished.
*/
int worker_done;
pthread_mutex_t mutex;
pthread_cond_t condition;
pthread_mutex_t coutmutex;
#include <sstream>
#define COUTTHREAD( _message_ ) \
{ \
pthread_mutex_lock( &coutmutex ); \
std::ostringstream _oss_; \
_oss_ << _message_; \
std::cout << _oss_.str() << std::endl; \
pthread_mutex_unlock( &coutmutex ); \
}
/**
* Defines the work that has to be done in each thread
*
* @param counter The number of times the same work has to be done.
*/
void* work( void* counter )
{
int id_thread = *( static_cast<int*>( counter ) );
assert( id_thread >= 0 );
std::string threadStrID( getGaudiThreadIDfromID( id_thread ) );
COUTTHREAD( "++++ Thread : " << id_thread << " string = " << threadStrID );
int m_evtMax = 0;
// Get an instance of the Pesa application manager
IInterface* m_pesaAppMgr = Gaudi::createApplicationMgr();
// Get the EventLoopMgr name from the Application Manager
std::string nameEventLoopMgr = "EventLoopMgr";
std::string value;
SmartIF<IProperty> propMgr( m_pesaAppMgr );
if ( !propMgr ) {
COUTTHREAD( " Fatal error while retrieving Gaudi PropertyHolder " )
} else {
StatusCode sc = propMgr->getProperty( "EventLoop", value );
if ( sc.isFailure() ) {
COUTTHREAD( " Fatal error while retrieving Property EventLoop " )
} else {
nameEventLoopMgr.assign( value, value.find_first_of( "\"" ) + 1,
value.find_last_of( "\"" ) - value.find_first_of( "\"" ) - 1 );
}
sc = propMgr->getProperty( "EvtMax", value );
if ( sc.isFailure() ) {
COUTTHREAD( " Fatal error while retrieving Property EvtMax " )
} else {
m_evtMax = std::stoi( value );
}
}
nameEventLoopMgr = nameEventLoopMgr + threadStrID;
COUTTHREAD( "---> Thread : " << id_thread << " - Name for EventLoopManager : " + nameEventLoopMgr )
StatusCode sc;
IEventProcessor* m_processingMgr = 0;
SmartIF<ISvcLocator> svcLoc( m_pesaAppMgr );
if ( svcLoc ) {
sc = svcLoc->service( nameEventLoopMgr, m_processingMgr );
if ( !sc.isSuccess() ) {
COUTTHREAD( "FATAL Error retrieving Processing manager:" )
m_processingMgr = 0;
}
}
for ( int i = 0; i < m_evtMax; i++ ) {
// ExecuteEvent from the application manager
if ( 0 != m_processingMgr ) {
SmartIF<IEventProcessor> processor( m_processingMgr );
if ( processor ) {
COUTTHREAD( " ---> Executing WorkerThread---> " << id_thread )
sc = processor->executeEvent( NULL );
if ( sc.isFailure() ) {
COUTTHREAD( "Fatal error for executeEvent in the ApplicationMgr " << id_thread )
}
} else {
COUTTHREAD( "---> executeEvent ApplicationMgr : no valid event processor " << id_thread );
}
}
}
pthread_mutex_lock( &mutex );
--worker_done;
if ( worker_done == 0 ) pthread_cond_signal( &condition );
pthread_mutex_unlock( &mutex );
return 0;
}
//--- Example main program
int main( int argc, char** argv )
{
// initialises the mutex and the condition
pthread_mutex_init( &mutex, 0 ); // fast mutex (or recursive?)
pthread_mutex_init( &coutmutex, 0 ); // fast mutex (or recursive?)
pthread_cond_init( &condition, 0 );
// Create an instance of an application manager
auto appMgr = SmartIF<IAppMgrUI>( Gaudi::createApplicationMgr() );
auto propMgr = appMgr.as<IProperty>();
auto dllMgr = appMgr.as<IClassManager>();
if ( !appMgr || !propMgr || !dllMgr ) {
std::cout << "Fatal error while creating the ApplicationMgr " << std::endl;
return 1;
}
// check the arguments
if ( argc < 2 ) {
std::cout << "usage: " << argv[0] << "<JobOptions file> <number-of-threads=4>" << std::endl;
return 1;
}
// Get the input configuration file from arguments
std::string opts = ( argc > 1 ) ? argv[1] : "jobOptions.txt";
// Get the number of worker threads from arguments
std::string s_nt = ( argc > 2 ) ? argv[2] : "4";
// Set properties
propMgr->setProperty( "JobOptionsPath", opts );
propMgr->setProperty( "NoOfThreads", s_nt );
propMgr->setProperty( "EvtSel", "NONE" );
propMgr->setProperty( "MessageSvcType", "MTMessageSvc" );
if ( boost::algorithm::ends_with( opts, ".py" ) ) {
std::cout << "Running with Python not supported" << std::endl;
return 1;
}
// load MTMessageSvc library
if ( !( dllMgr->loadModule( "GaudiMTExample" ) ).isSuccess() ) {
std::cerr << "Can not load MTMessageSvc module (GaudiMTExample)" << std::endl;
return 1;
}
dllMgr.reset();
StatusCode sc;
std::string v_nt;
int nt;
sc = propMgr->getProperty( "NoOfThreads", v_nt );
if ( sc.isFailure() ) {
std::cout << "Cannot get get number of worker threads" << std::endl;
return 1;
} else {
nt = std::stoi( v_nt );
if ( nt <= 0 || nt > MAX_THREADS ) {
std::cout << "Invalid number of worker threads =>> " << v_nt << std::endl;
return 1;
} else {
std::cout << "---> Use " << nt << " worker threads <---" << std::endl;
}
}
propMgr.reset();
// Configure the application manager
sc = appMgr->configure();
std::cout << "---> Configure ApplicationMgr : " << appMgr->stateName() << " Status : " << sc.getCode() << std::endl;
if ( sc.isFailure() ) {
std::cout << "---> Fatal error while configuring the ApplicationMgr " << std::endl;
return 1;
}
// Initialize the application manager
sc = appMgr->initialize();
std::cout << "---> Initialize ApplicationMgr : " << appMgr->stateName() << " Status : " << sc.getCode() << std::endl;
if ( sc.isFailure() ) {
std::cout << "---> Fatal error while initializing the ApplicationMgr " << std::endl;
return 1;
}
// Create threads and process events
worker_done = nt; // Initialized counter
pthread_t thread[nt];
int tID[nt];
for ( int i = 0; i < nt; ++i ) {
/**
* This will start the worker thread. It will stop by itself when the
* called non-member method exits.
*/
tID[i] = i;
pthread_create( &thread[i], 0, work, static_cast<void*>( &tID[i] ) );
}
pthread_mutex_lock( &mutex );
if ( worker_done != 0 ) pthread_cond_wait( &condition, &mutex );
pthread_mutex_unlock( &mutex );
// Finalize the application manager
sc = appMgr->finalize();
std::cout << "---> Finalize ApplicationMgr : " << appMgr->stateName() << " Status : " << sc.getCode() << std::endl;
if ( sc.isFailure() ) {
std::cout << "---> Fatal error while finalizing the ApplicationMgr " << std::endl;
return 1;
}
// Terminate the application manager
sc = appMgr->terminate();
std::cout << "---> Terminate ApplicationMgr : " << appMgr->stateName() << " Status : " << sc.getCode() << std::endl;
if ( sc.isFailure() ) {
std::cout << "---> Fatal error while terminating the ApplicationMgr " << std::endl;
return 1;
}
// destroyes the mutex resources allocated
pthread_cond_destroy( &condition );
pthread_mutex_destroy( &mutex );
pthread_mutex_destroy( &coutmutex );
// All done - exit
appMgr.reset();
return 0;
}
#define GAUDISVC_MTEVENTLOOPMGR_CPP
#include "GaudiKernel/DataObject.h"
#include "GaudiKernel/IConversionSvc.h"
#include "GaudiKernel/IDataManagerSvc.h"
#include "GaudiKernel/IDataProviderSvc.h"
#include "GaudiKernel/IEvtSelector.h"
#include "GaudiKernel/IIncidentSvc.h"
#include "GaudiKernel/Incident.h"
#include "GaudiKernel/MsgStream.h"
#include "GaudiKernel/SmartIF.h"
#include "MTEventLoopMgr.h"
#include "src/ApplicationMgr/HistogramAgent.h"
// Instantiation of a static factory class used by clients to create instances of this service
DECLARE_COMPONENT( MTEventLoopMgr );
//--------------------------------------------------------------------------------------------
// Standard Destructor
//--------------------------------------------------------------------------------------------
MTEventLoopMgr::~MTEventLoopMgr()
{
if ( m_histoDataMgrSvc ) m_histoDataMgrSvc->release();
if ( m_histoPersSvc ) m_histoPersSvc->release();
if ( m_incidentSvc ) m_incidentSvc->release();
if ( m_evtDataMgrSvc ) m_evtDataMgrSvc->release();
if ( m_evtDataSvc ) m_evtDataSvc->release();
if ( m_evtSelector ) m_evtSelector->release();
if ( m_evtCtxt ) delete m_evtCtxt;
}
//--------------------------------------------------------------------------------------------
// implementation of IAppMgrUI::initalize
//--------------------------------------------------------------------------------------------
StatusCode MTEventLoopMgr::initialize()
{
debug() << " ---> MTEventLoopMgr = " << name() << " initializing " << endmsg;
// initilaize the base class
StatusCode sc = MinimalEventLoopMgr::initialize();
if ( sc.isFailure() ) {
debug() << "Error Initializing base class MinimalEventLoopMgr." << endmsg;
return sc;
}
// Setup access to event data services
sc = service( "EventDataSvc", m_evtDataMgrSvc, true );
if ( !sc.isSuccess() ) {
fatal() << "Error retrieving EventDataSvc interface IDataManagerSvc." << endmsg;
return sc;
}
sc = service( "EventDataSvc", m_evtDataSvc, false );
if ( !sc.isSuccess() ) {
fatal() << "Error retrieving EventDataSvc interface IDataProviderSvc." << endmsg;
return sc;
}
// Get the references to the services that are needed by the ApplicationMgr itself
sc = service( "IncidentSvc", m_incidentSvc, true );
if ( !sc.isSuccess() ) {
fatal() << "Error retrieving IncidentSvc" << endmsg;
return sc;
}
// Obtain the IProperty of the ApplicationMgr
auto prpMgr = serviceLocator()->as<IProperty>();
if ( !prpMgr ) {
fatal() << "IProperty interface not found in ApplicationMgr." << endmsg;
return StatusCode::FAILURE;
} else {
m_appMgrProperty = prpMgr;
}
// We do not expect a Event Selector necessarily being declared
setProperty( m_appMgrProperty->getProperty( "EvtSel" ) );
if ( m_evtsel != "NONE" || m_evtsel.empty() ) {
sc = service( "EventSelector", m_evtSelector, true );
if ( sc.isSuccess() ) {
// Setup Event Selector
sc = m_evtSelector->createContext( m_evtCtxt );
if ( !sc.isSuccess() ) {
fatal() << "Failed to create EventSelector context." << endmsg;
return sc;
}
} else {
fatal() << "EventSelector not found." << endmsg;
return StatusCode::FAILURE;
}
} else {
m_evtSelector = nullptr;
m_evtCtxt = nullptr;
warning() << "Unable to locate service \"EventSelector\" " << endmsg;
warning() << "No events will be processed from external input." << endmsg;
}
// Setup access to histogramming services
sc = service( "HistogramDataSvc", m_histoDataMgrSvc, true );
if ( !sc.isSuccess() ) {
fatal() << "Error retrieving HistogramDataSvc" << endmsg;
return sc;
}
// Setup histogram persistency
sc = service( "HistogramPersistencySvc", m_histoPersSvc, true );
if ( !sc.isSuccess() ) {
warning() << "Histograms cannot not be saved - though required." << endmsg;
return sc;
}
return StatusCode::SUCCESS;
}
//--------------------------------------------------------------------------------------------
// implementation of IService::reinitialize
//--------------------------------------------------------------------------------------------
StatusCode MTEventLoopMgr::reinitialize()
{
// initilaize the base class
StatusCode sc = MinimalEventLoopMgr::reinitialize();
if ( sc.isFailure() ) {
debug() << "Error Initializing base class MinimalEventLoopMgr." << endmsg;
return sc;
}
// Check to see whether a new Event Selector has been specified
setProperty( m_appMgrProperty->getProperty( "EvtSel" ) );
if ( m_evtsel != "NONE" || m_evtsel.empty() ) {
IEvtSelector* theEvtSel;
IService* theSvc;
sc = service( "EventSelector", theEvtSel );
sc = service( "EventSelector", theSvc );
if ( sc.isSuccess() && ( theEvtSel != m_evtSelector ) ) {
// Setup Event Selector
m_evtSelector = theEvtSel;
if ( theSvc->state() == IService::INITIALIZED ) {
sc = theSvc->reinitialize();
if ( sc.isFailure() ) {
error() << "Failure Reinitializing EventSelector " << theSvc->name() << endmsg;
return sc;
}
} else {
sc = theSvc->initialize();
if ( sc.isFailure() ) {
error() << "Failure Initializing EventSelector " << theSvc->name() << endmsg;
return sc;
}
}
sc = theEvtSel->createContext( m_evtCtxt );
if ( !sc.isSuccess() ) {
error() << "Can not create Context " << theSvc->name() << endmsg;
return sc;
}
info() << "EventSelector service changed to " << theSvc->name() << endmsg;
}
} else {
m_evtSelector = nullptr;
m_evtCtxt = nullptr;
}
return StatusCode::SUCCESS;
}
//--------------------------------------------------------------------------------------------
// implementation of IAppMgrUI::finalize
//--------------------------------------------------------------------------------------------
StatusCode MTEventLoopMgr::finalize()
{
StatusCode sc;
info() << " Number of events processed : " << m_total_nevt << endmsg;
// Finalize base class
MinimalEventLoopMgr::finalize();
// Save Histograms Now
if ( m_histoPersSvc ) {
HistogramAgent agent;
sc = m_histoDataMgrSvc->traverseTree( &agent );
if ( sc.isSuccess() ) {
IDataSelector* objects = agent.selectedObjects();
// skip /stat entry!
if ( objects->size() > 0 ) {
IDataSelector::iterator i;
for ( i = objects->begin(); i != objects->end(); i++ ) {
IOpaqueAddress* pAddr = nullptr;
StatusCode iret = m_histoPersSvc->createRep( *i, pAddr );
if ( iret.isSuccess() ) {
( *i )->registry()->setAddress( pAddr );
} else {
sc = iret;
}
}
for ( i = objects->begin(); i != objects->end(); i++ ) {
IRegistry* reg = ( *i )->registry();
StatusCode iret = m_histoPersSvc->fillRepRefs( reg->address(), *i );
if ( !iret.isSuccess() ) {
sc = iret;
}
}
}
if ( sc.isSuccess() ) {
info() << "Histograms converted successfully according to request." << endmsg;
} else {
error() << "Error while saving Histograms." << endmsg;
}
} else {
error() << "Error while traversing Histogram data store" << endmsg;
}
}
if ( m_evtCtxt && m_evtSelector ) {
m_evtSelector->releaseContext( m_evtCtxt );
m_evtCtxt = nullptr;
}
// Release all interfaces...
m_histoDataMgrSvc = releaseInterface( m_histoDataMgrSvc );
m_histoPersSvc = releaseInterface( m_histoPersSvc );
m_evtSelector = releaseInterface( m_evtSelector );
m_incidentSvc = releaseInterface( m_incidentSvc );
m_evtDataSvc = releaseInterface( m_evtDataSvc );
m_evtDataMgrSvc = releaseInterface( m_evtDataMgrSvc );
return StatusCode::SUCCESS;
}
//--------------------------------------------------------------------------------------------
// implementation of IAppMgrUI::nextEvent
//--------------------------------------------------------------------------------------------
StatusCode MTEventLoopMgr::nextEvent( int maxevt )
{
DataObject* pObject = nullptr;
StatusCode sc;
// loop over events if the maxevt (received as input) if different from -1.
// if evtmax is -1 it means infinite loop
for ( int nevt = 0; ( maxevt == -1 ? true : nevt < maxevt ); nevt++, m_total_nevt++ ) {
// Clear the event store, if used in the event loop
if ( 0 != m_total_nevt ) {
sc = m_evtDataMgrSvc->clearStore();
if ( !sc.isSuccess() ) {
debug() << "Clear of Event data store failed" << endmsg;
}
}
// Setup event in the event store
if ( m_evtCtxt ) {
IOpaqueAddress* addr = nullptr;
// Only if there is a EventSelector
sc = getEventRoot( addr );
if ( !sc.isSuccess() ) {
info() << "No more events in event selection " << endmsg;
break;
}
// Set root clears the event data store first
sc = m_evtDataMgrSvc->setRoot( "/Event", addr );
if ( !sc.isSuccess() ) {
warning() << "Error declaring event root address." << endmsg;
continue;
}
sc = m_evtDataSvc->retrieveObject( "/Event", pObject );
if ( !sc.isSuccess() ) {
warning() << "Unable to retrieve Event root object" << endmsg;
break;
}
} else {
sc = m_evtDataMgrSvc->setRoot( "/Event", new DataObject() );
if ( !sc.isSuccess() ) {
warning() << "Error declaring event root DataObject" << endmsg;
}
}
// Execute event for all required algorithms
// Fire BeginEvent "Incident"
m_incidentSvc->fireIncident( Incident( name(), IncidentType::BeginEvent ) );
// Execute Algorithms
StatusCode sc = executeEvent( NULL );
// Fire EndEvent "Incident"
m_incidentSvc->fireIncident( Incident( name(), IncidentType::EndEvent ) );
if ( !sc.isSuccess() ) {
error() << "Terminating event processing loop due to errors" << endmsg;
break;
}
}
return StatusCode::SUCCESS;
}
/// Create event address using event selector
StatusCode MTEventLoopMgr::getEventRoot( IOpaqueAddress*& refpAddr )
{
refpAddr = nullptr;
StatusCode sc = m_evtSelector->next( *m_evtCtxt );
if ( !sc.isSuccess() ) {
return sc;
}
// Create root address and assign address to data service
sc = m_evtSelector->createAddress( *m_evtCtxt, refpAddr );
if ( !sc.isSuccess() ) {
sc = m_evtSelector->next( *m_evtCtxt );
if ( sc.isSuccess() ) {
sc = m_evtSelector->createAddress( *m_evtCtxt, refpAddr );
if ( !sc.isSuccess() ) {
warning() << "Error creating IOpaqueAddress." << endmsg;
}
}
}
return sc;
}
#ifndef GAUDISVC_MTEVENTLOOPMGR_H
#define GAUDISVC_MTEVENTLOOPMGR_H 1
// Framework include files
#include "GaudiKernel/IEvtSelector.h"
#include "GaudiKernel/MinimalEventLoopMgr.h"
// Forward declarations
class IIncidentSvc;
class IDataManagerSvc;
class IDataProviderSvc;
/** Class definition of MTEventLoopMgr.
This is the default processing manager of the application manager.
This object handles the minimal requirements needed by the
application manager. It also handles the default user
configuration setup for standard event processing.
<UL>
<LI> handling of the incidents when starting event processing
<LI> handling of the event loop
</UL>
<B>History:</B>
<PRE>
+---------+----------------------------------------------+---------+
| Date | Comment | Who |
+---------+----------------------------------------------+---------+
|13/12/00 | Initial version | M.Frank |
+---------+----------------------------------------------+---------+
</PRE>
@author Markus Frank
@version 1.0
*/
class MTEventLoopMgr : public MinimalEventLoopMgr
{
protected:
Gaudi::Property<std::string> m_histPersName{this, "HistogramPersistency", {}, "Name of the Hist Pers type"};
Gaudi::Property<std::string> m_evtsel{this, "EvtSel", {}, "Event selector"};
/// Reference to the indicent service
IIncidentSvc* m_incidentSvc = nullptr;
/// Reference to the Event Data Service's IDataManagerSvc interface
IDataManagerSvc* m_evtDataMgrSvc = nullptr;
/// Reference to the Event Data Service's IDataProviderSvc interface
IDataProviderSvc* m_evtDataSvc = nullptr;
/// Reference to the Event Selector
IEvtSelector* m_evtSelector = nullptr;
/// Event Iterator
IEvtSelector::Context* m_evtCtxt = nullptr;
/// Reference to the Histogram Data Service
IDataManagerSvc* m_histoDataMgrSvc = nullptr;
/// Reference to the Histogram Persistency Service
IConversionSvc* m_histoPersSvc = nullptr;
/// Property interface of ApplicationMgr
IProperty* m_appMgrProperty = nullptr;
public:
/// Standard Constructor
using MinimalEventLoopMgr::MinimalEventLoopMgr;
/// Standard Destructor
virtual ~MTEventLoopMgr();
/// Create event address using event selector
StatusCode getEventRoot( IOpaqueAddress*& refpAddr );
/// implementation of IService::initalize
virtual StatusCode initialize();
/// implementation of IService::reinitalize
virtual StatusCode reinitialize();
/// implementation of IService::finalize
virtual StatusCode finalize();
/// implementation of IService::nextEvent
virtual StatusCode nextEvent( int maxevt );
/// implementation of IEventProcessor::executeEvent(void* par)
// virtual StatusCode executeEvent(void* par);
/// implementation of IEventProcessor::executeRun()
// virtual StatusCode executeRun(int maxevt);
private:
int m_total_nevt = 0;
};
#endif // GAUDISVC_MTEVENTLOOPMGR_H
#include "MTHelloWorld.h"
#include "GaudiKernel/MsgStream.h"
#include "MTMessageSvc.h"
DECLARE_COMPONENT( MTHelloWorld );
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
StatusCode MTHelloWorld::initialize()
{
// Part 1: Get the messaging service, print where you are
info() << "initialize()" << endmsg;
MTMessageSvc* tmp_msgSvc = dynamic_cast<MTMessageSvc*>( msgSvc() );
if ( tmp_msgSvc != 0 ) {
info() << " Algorithm = " << name() << " is connected to Message Service = " << tmp_msgSvc->name() << endmsg;
}
// Part 2: Print out the property values
info() << " MyInt = " << m_myInt.value() << endmsg;
info() << " MyBool = " << (int)m_myBool.value() << endmsg;
info() << " MyDouble = " << m_myDouble.value() << endmsg;
for ( unsigned int i = 0; i < m_myStringVec.size(); i++ ) {
info() << " MyStringVec[" << i << "] = " << m_myStringVec[i] << endmsg;
}
return StatusCode::SUCCESS;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
StatusCode MTHelloWorld::execute()
{
// Part 1: Get the messaging service, print where you are
info() << "execute()" << endmsg;
// Part 1: Print out the different levels of messages
debug() << "A DEBUG message" << endmsg;
info() << "An INFO message" << endmsg;
warning() << "A WARNING message" << endmsg;
error() << "An ERROR message" << endmsg;
fatal() << "A FATAL error message" << endmsg;
return StatusCode::SUCCESS;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
StatusCode MTHelloWorld::finalize()
{
// Part 1: Get the messaging service, print where you are
info() << "finalize()" << endmsg;
return StatusCode::SUCCESS;
}
#include "GaudiKernel/Algorithm.h"
/////////////////////////////////////////////////////////////////////////////
class MTHelloWorld : public Algorithm
{
public:
using Algorithm::Algorithm;
StatusCode initialize() override;
StatusCode execute() override;
StatusCode finalize() override;
private:
Gaudi::Property<int> m_myInt{this, "MyInt", 0};
Gaudi::Property<bool> m_myBool
{
this, "MyBool", 0;
Gaudi::Property<double> m_myDouble{this, "MyDouble", 0};
Gaudi::Property<std::vector<std::string>> m_myStringVec{this, "MyStringVec", {}};
};
#include "MTMessageSvc.h"
#include "GaudiKernel/Kernel.h"
#include "GaudiKernel/Message.h"
#include "GaudiKernel/StatusCode.h"
#include <iostream>
#include <sstream>
#include <pthread.h>
extern pthread_mutex_t coutmutex;
// Instantiation of a static factory class used by clients to create
// instances of this service
DECLARE_COMPONENT( MTMessageSvc )
// Constructor
MTMessageSvc::MTMessageSvc( const std::string& name, ISvcLocator* svcloc ) : base_class( name, svcloc )
{
m_outputLevel = MSG::NIL;
}
/// Initialize Service
StatusCode MTMessageSvc::initialize()
{
StatusCode sc;
sc = Service::initialize();
if ( sc.isFailure() ) return sc;
// Release pointer to myself done in Service base class
if ( m_messageSvc ) {
m_messageSvc->release();
m_messageSvc = 0;
}
// Set my own properties
setProperties();
// Set the output level thresholds from properties
for ( int lvl = MSG::VERBOSE; lvl < MSG::NUM_LEVELS; lvl++ ) {
std::vector<std::string>& thresholds = m_thresholdProp[lvl];
for ( std::vector<std::string>::iterator it = thresholds.begin(); it != thresholds.end(); it++ ) {
setOutputLevel( *it, lvl );
}
}
return StatusCode::SUCCESS;
}
/// Finalize Service
StatusCode MTMessageSvc::finalize() { return StatusCode::SUCCESS; }
//#############################################################################
// ---------------------------------------------------------------------------
// Routine: reportMessage
// Purpose: dispatches a message to the relevant streams.
// ---------------------------------------------------------------------------
//
void MTMessageSvc::reportMessage( const Message& msg )
{
int key = msg.getType();
StreamMap::const_iterator first = m_streamMap.lower_bound( key );
if ( first != m_streamMap.end() ) {
StreamMap::const_iterator last = m_streamMap.upper_bound( key );
while ( first != last ) {
std::ostream& stream = *( ( *first ).second.second );
stream << msg << std::endl;
first++;
}
} else if ( key >= outputLevel( msg.getSource() ) ) {
msg.setFormat( m_defaultFormat );
pthread_mutex_lock( &coutmutex );
( *m_defaultStream ) << msg << std::endl << std::flush;
pthread_mutex_unlock( &coutmutex );
}
}
//#############################################################################
// ---------------------------------------------------------------------------
// Routine: reportMessage
// Purpose: dispatches a message to the relevant streams.
// ---------------------------------------------------------------------------
//
void MTMessageSvc::reportMessage( const char* source, int type, const char* message )
{
Message msg( source, type, message );
reportMessage( msg );
}
//#############################################################################
// ---------------------------------------------------------------------------
// Routine: reportMessage
// Purpose: dispatches a message to the relevant streams.
// ---------------------------------------------------------------------------
//
void MTMessageSvc::reportMessage( const std::string& source, int type, const std::string& message )
{
Message msg( source, type, message );
reportMessage( msg );
}
//#############################################################################
// ---------------------------------------------------------------------------
// Routine: sendMessage
// Purpose: finds a message for a given status code and dispatches it.
// ---------------------------------------------------------------------------
//
void MTMessageSvc::reportMessage( const StatusCode& key, const std::string& source )
{
MessageMap::const_iterator first = m_messageMap.lower_bound( key );
if ( first != m_messageMap.end() ) {
MessageMap::const_iterator last = m_messageMap.upper_bound( key );
while ( first != last ) {
Message msg = ( *first ).second;
msg.setSource( source );
std::ostringstream os1;
os1 << "Status Code " << key.getCode() << std::ends;
Message stat_code1( source, msg.getType(), os1.str() );
reportMessage( stat_code1 );
reportMessage( msg );
first++;
}
} else {
Message mesg = m_defaultMessage;
mesg.setSource( source );
std::ostringstream os2;
os2 << "Status Code " << key.getCode() << std::ends;
Message stat_code2( source, mesg.getType(), os2.str() );
reportMessage( stat_code2 );
reportMessage( mesg );
}
}
//#############################################################################
// ---------------------------------------------------------------------------
// Routine: insertStream
// Purpose: inserts a stream for a message type.
// ---------------------------------------------------------------------------
//
void MTMessageSvc::insertStream( int key, const std::string& name, std::ostream* stream )
{
typedef StreamMap::value_type value_type;
m_streamMap.insert( value_type( key, NamedStream( name, stream ) ) );
}
//#############################################################################
// ---------------------------------------------------------------------------
// Routine: eraseStream
// Purpose: erases all the streams for all the message types.
// ---------------------------------------------------------------------------
//
void MTMessageSvc::eraseStream() { m_streamMap.erase( m_streamMap.begin(), m_streamMap.end() ); }
//#############################################################################
// ---------------------------------------------------------------------------
// Routine: eraseStream
// Purpose: erases all the streams for a message type.
// ---------------------------------------------------------------------------
//
void MTMessageSvc::eraseStream( int message_type ) { m_streamMap.erase( message_type ); }
//#############################################################################
// ---------------------------------------------------------------------------
// Routine: eraseStream
// Purpose: erases one stream for a message type.
// ---------------------------------------------------------------------------
//
void MTMessageSvc::eraseStream( int key, std::ostream* stream )
{
if ( 0 != stream ) {
bool changed = true;
while ( changed ) {
changed = false;
StreamMap::iterator first = m_streamMap.lower_bound( key );
StreamMap::iterator last = m_streamMap.upper_bound( key );
while ( first != last ) {
if ( ( *first ).second.second == stream ) {
m_streamMap.erase( first );
changed = true;
break;
}
}
}
}
}
//#############################################################################
// ---------------------------------------------------------------------------
// Routine: eraseStream
// Purpose: erases one stream for all message types.
// ---------------------------------------------------------------------------
//
void MTMessageSvc::eraseStream( std::ostream* stream )
{
if ( 0 != stream ) {
bool changed = true;
while ( changed ) {
changed = false;
StreamMap::iterator first = m_streamMap.begin();
while ( first != m_streamMap.end() ) {
if ( ( *first ).second.second == stream ) {
m_streamMap.erase( first );
changed = true;
break;
}
}
}
}
}
//#############################################################################
// ---------------------------------------------------------------------------
// Routine: insertMessage
// Purpose: inserts a message for a status code.
// ---------------------------------------------------------------------------
//
void MTMessageSvc::insertMessage( const StatusCode& key, const Message& msg )
{
typedef MessageMap::value_type value_type;
m_messageMap.insert( value_type( key, msg ) );
}
//#############################################################################
// ---------------------------------------------------------------------------
// Routine: eraseMessage
// Purpose: erases all the messages for all the status codes.
// ---------------------------------------------------------------------------
//
void MTMessageSvc::eraseMessage() { m_messageMap.erase( m_messageMap.begin(), m_messageMap.end() ); }
//#############################################################################
// ---------------------------------------------------------------------------
// Routine: eraseMessage
// Purpose: erases all the messages for a status code.
// ---------------------------------------------------------------------------
//
void MTMessageSvc::eraseMessage( const StatusCode& key ) { m_messageMap.erase( key ); }
//#############################################################################
// ---------------------------------------------------------------------------
// Routine: eraseMessage
// Purpose: erases one message for a status code.
// ---------------------------------------------------------------------------
//
void MTMessageSvc::eraseMessage( const StatusCode& key, const Message& msg )
{
bool changed = true;
while ( changed ) {
changed = false;
MessageMap::iterator first = m_messageMap.lower_bound( key );
MessageMap::iterator last = m_messageMap.upper_bound( key );
while ( first != last ) {
const Message& message = ( *first ).second;
if ( message == msg ) {
m_messageMap.erase( first );
changed = true;
break;
}
}
}
}
// ---------------------------------------------------------------------------
int MTMessageSvc::outputLevel() const
{
// ---------------------------------------------------------------------------
return m_outputLevel;
}
// ---------------------------------------------------------------------------
int MTMessageSvc::outputLevel( const std::string& source ) const
{
// ---------------------------------------------------------------------------
ThresholdMap::const_iterator it;
it = m_thresholdMap.find( source );
if ( it != m_thresholdMap.end() ) {
return ( *it ).second;
} else {
return m_outputLevel;
}
}
// ---------------------------------------------------------------------------
void MTMessageSvc::setOutputLevel( int new_level )
{
// ---------------------------------------------------------------------------
m_outputLevel = new_level;
}
// ---------------------------------------------------------------------------
void MTMessageSvc::setOutputLevel( const std::string& source, int level )
{
// ---------------------------------------------------------------------------
pthread_mutex_lock( &coutmutex );
std::pair<ThresholdMap::iterator, bool> p;
p = m_thresholdMap.insert( ThresholdMap::value_type( source, level ) );
if ( p.second == false ) {
// Already esisting an output level for that source. Erase an enter it again
m_thresholdMap.erase( p.first );
m_thresholdMap.insert( ThresholdMap::value_type( source, level ) );
}
pthread_mutex_unlock( &coutmutex );
}
#ifndef GAUDI_MTMESSAGESVC_H
#define GAUDI_MTMESSAGESVC_H
// Include files
#include <map>
#include <string>
#include "GaudiKernel/IMessageSvc.h"
#include "GaudiKernel/Message.h"
#include "GaudiKernel/Service.h"
#include "GaudiKernel/StatusCode.h"
// Forward declarations
class ISvcLocator;
//
// ClassName: MTMessageSvc
//
// Description: The MTMessageSvc service implements the IMessageSvc interface and provides the
// basic messaging needed by batch oriented applications.
//
// Author: Iain Last
//
class MTMessageSvc : public extends<Service, IMessageSvc>
{
public:
typedef std::pair<std::string, std::ostream*> NamedStream;
typedef std::multimap<int, NamedStream> StreamMap;
typedef std::multimap<StatusCode, Message> MessageMap;
typedef std::map<std::string, int> ThresholdMap;
// Default constructor.
MTMessageSvc( const std::string& name, ISvcLocator* svcloc );
// Implementation of IService::initialize()
virtual StatusCode initialize();
// Implementation of IService::finalize()
virtual StatusCode finalize();
// Implementation of IMessageSvc::reportMessage()
virtual void reportMessage( const Message& message );
// Implementation of IMessageSvc::reportMessage()
virtual void reportMessage( const StatusCode& code, const std::string& source = "" );
// Implementation of IMessageSvc::reportMessage()
virtual void reportMessage( const char* source, int type, const char* message );
// Implementation of IMessageSvc::reportMessage()
virtual void reportMessage( const std::string& source, int type, const std::string& message );
// Implementation of IMessageSvc::insertMessage()
virtual void insertMessage( const StatusCode& code, const Message& message );
// Implementation of IMessageSvc::eraseMessage()
virtual void eraseMessage();
// Implementation of IMessageSvc::eraseMessage()
virtual void eraseMessage( const StatusCode& code );
// Implementation of IMessageSvc::eraseMessage()
virtual void eraseMessage( const StatusCode& code, const Message& message );
// Implementation of IMessageSvc::insertStream()
virtual void insertStream( int message_type, const std::string& name, std::ostream* stream );
// Implementation of IMessageSvc::eraseStream()
virtual void eraseStream();
// Implementation of IMessageSvc::eraseStream()
virtual void eraseStream( int message_type );
// Implementation of IMessageSvc::eraseStream()
virtual void eraseStream( int message_type, std::ostream* stream );
// Implementation of IMessageSvc::eraseStream()
virtual void eraseStream( std::ostream* stream );
// Implementation of IMessageSvc::desaultStream()
virtual std::ostream* defaultStream() const { return m_defaultStream; }
// Implementation of IMessageSvc::setDefaultStream()
virtual void setDefaultStream( std::ostream* stream ) { m_defaultStream = stream; }
// Implementation of IMessageSvc::ouputLevel()
virtual int outputLevel() const;
// Implementation of IMessageSvc::ouputLevel()
virtual int outputLevel( const std::string& source ) const;
// Implementation of IMessageSvc::setOuputLevel()
virtual void setOutputLevel( int new_level );
// Implementation of IMessageSvc::setOuputLevel()
virtual void setOutputLevel( const std::string& source, int new_level );
/** Show whether colors are used
*/
virtual bool useColor() const { return false; }
/** Get the color codes for various log levels
@param logLevel Logging level
*/
virtual std::string getLogColor( int /* logLevel */ ) const { return std::string(); }
virtual int messageCount( MSG::Level /* level */ ) const { return 0; }
private:
Gaudi::Property<std::string> m_defaultFormat{this, "Format", "% F%18W%S%7W%R%T %0W%M", ""};
std::array<Gaudi::Property<std::vector<std::string>>, MSG::NUM_LEVELS> m_thresholdProp{{{/*ignored*/},
{this, "setVerbose"},
{this, "setDebug"},
{this, "setInfo"},
{this, "setWarning"},
{this, "setError"},
{this, "setFatal"},
{this, "setAlways"}}};
std::ostream* m_defaultStream = &std::cout; ///< Pointer to the output stream.
Message m_defaultMessage; ///< Default Message
StreamMap m_streamMap; ///< Stream map
MessageMap m_messageMap; ///< Message map
ThresholdMap m_thresholdMap; ///< Output level threshold map
};
#endif
To run the example, do
cd .../GaudiExamples/v*/${CMTCONFIG}
./GaudiMT.exe ../options/GaudiMT.opts [number of threads (default=4)]
e.g to run with 3 threads do
./GaudiMT.exe ../options/GaudiMT.opts 3
JobOptionsSvc INFO
//GP:================================================================================
//GP: include "../options/GaudiMT.opts" (0,0)
ApplicationMgr.EventLoop = "MTEventLoopMgr"; //GP: (7,1)
ApplicationMgr.ExtSvc += [ "NTupleSvc" ] ; //GP: (8,1)
ApplicationMgr.MultiThreadExtSvc += [ "RndmGenSvc" , "ParticlePropertySvc" ] ;//GP: (9,1)
ApplicationMgr.OutputLevel = 1; //GP: (11,1)
ApplicationMgr.TopAlg = [ "MTHelloWorld" ] ; //GP: (18,1)
MessageSvc.OutputLevel = 1; //GP: (21,1)
ApplicationMgr.EvtMax = 2; //GP: (26,1)
ApplicationMgr.EvtSel = "NONE"; //GP: (27,1)
MTHelloWorld.MyInt = 42; //GP: (34,1)
MTHelloWorld.MyBool = 1; //GP: (35,1)
MTHelloWorld.MyDouble = 3.14159; //GP: (36,1)
MTHelloWorld.MyStringVec = [ "Welcome" , "to" , "MT" , "Gaudi" ] ; //GP: (37,1)
MTHelloWorld__1.MyInt = 21; //GP: (40,1)
MTHelloWorld__1.MyBool = 0; //GP: (41,1)
MTHelloWorld__1.MyDouble = 6.28; //GP: (42,1)
MTHelloWorld__1.MyStringVec = [ "Welcome" , "to" , "Thread" , "1" ] ; //GP: (43,1)
//GP: end "../options/GaudiMT.opts" (45,1)
//GP:================================================================================
JobOptionsSvc INFO Job options successfully read in from ../options/GaudiMT.opts
ApplicationMgr DEBUG Getting my own properties
ApplicationMgr SUCCESS
====================================================================================================================================
Welcome to ApplicationMgr $Revision: 1.38 $
running on pclhcb55.cern.ch on Tue Sep 25 16:50:23 2007
====================================================================================================================================
ApplicationMgr VERBOSE declareMultiSvcType: declared service EvtDataSvc/EventDataSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service DetDataSvc/DetectorDataSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service HistogramSvc/HistogramDataSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service HbookCnv::PersSvc/HbookHistSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service RootHistCnv::PersSvc/RootHistSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service EvtPersistencySvc/EventPersistencySvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service DetPersistencySvc/DetectorPersistencySvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service HistogramPersistencySvc/HistogramPersistencySvc
ApplicationMgr DEBUG Loading declared DLL's
ServiceManager FATAL No Service factory for MTEventLoopMgr available.
ApplicationMgr ERROR addMultiSvc: Cannot add service MTEventLoopMgr/MTEventLoopMgr
ApplicationMgr FATAL Error adding :MTEventLoopMgr
ApplicationMgr FATAL Application configuration failed
......@@ -44,8 +44,6 @@ ApplicationMgr.JobOptionsPreAction:
ApplicationMgr.JobOptionsSvcType:JobOptionsSvc
ApplicationMgr.JobOptionsType:NONE
ApplicationMgr.MessageSvcType:MessageSvc
ApplicationMgr.MultiThreadExtSvc:[ ]
ApplicationMgr.NoOfThreads:0
ApplicationMgr.OutStream:[ ]
ApplicationMgr.OutStreamType:OutputStream
ApplicationMgr.OutputLevel:3
......
......@@ -19,16 +19,16 @@ ApplicationMgr SUCCESS
Welcome to ApplicationMgr $Revision: 1.7 $
running on pclhcb55.cern.ch on Fri May 30 20:38:36 2008
====================================================================================================================================
ApplicationMgr VERBOSE declareMultiSvcType: declared service EvtDataSvc/EventDataSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service DetDataSvc/DetectorDataSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service HistogramSvc/HistogramDataSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service HbookCnv::PersSvc/HbookHistSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service RootHistCnv::PersSvc/RootHistSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service EvtPersistencySvc/EventPersistencySvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service DetPersistencySvc/DetectorPersistencySvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service HistogramPersistencySvc/HistogramPersistencySvc
ApplicationMgr VERBOSE declared service EvtDataSvc/EventDataSvc
ApplicationMgr VERBOSE declared service DetDataSvc/DetectorDataSvc
ApplicationMgr VERBOSE declared service HistogramSvc/HistogramDataSvc
ApplicationMgr VERBOSE declared service HbookCnv::PersSvc/HbookHistSvc
ApplicationMgr VERBOSE declared service RootHistCnv::PersSvc/RootHistSvc
ApplicationMgr VERBOSE declared service EvtPersistencySvc/EventPersistencySvc
ApplicationMgr VERBOSE declared service DetPersistencySvc/DetectorPersistencySvc
ApplicationMgr VERBOSE declared service HistogramPersistencySvc/HistogramPersistencySvc
ApplicationMgr DEBUG Loading declared DLL's
ApplicationMgr VERBOSE addMultiSvc: added service EventLoopMgr/EventLoopMgr
ApplicationMgr VERBOSE added service EventLoopMgr/EventLoopMgr
ApplicationMgr INFO Application Manager Configured successfully
Qotd1 INFO Initializing Qotd1...
Qotd2 INFO Initializing Qotd2...
......
......@@ -18,16 +18,16 @@ ApplicationMgr SUCCESS
Welcome to ApplicationMgr (GaudiCoreSvc v29r0)
running on hpadpmt on Wed Oct 4 10:00:39 2017
====================================================================================================================================
ApplicationMgr VERBOSE declareMultiSvcType: declared service EvtDataSvc/EventDataSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service DetDataSvc/DetectorDataSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service HistogramSvc/HistogramDataSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service HbookCnv::PersSvc/HbookHistSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service RootHistCnv::PersSvc/RootHistSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service EvtPersistencySvc/EventPersistencySvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service DetPersistencySvc/DetectorPersistencySvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service HistogramPersistencySvc/HistogramPersistencySvc
ApplicationMgr VERBOSE declared service EvtDataSvc/EventDataSvc
ApplicationMgr VERBOSE declared service DetDataSvc/DetectorDataSvc
ApplicationMgr VERBOSE declared service HistogramSvc/HistogramDataSvc
ApplicationMgr VERBOSE declared service HbookCnv::PersSvc/HbookHistSvc
ApplicationMgr VERBOSE declared service RootHistCnv::PersSvc/RootHistSvc
ApplicationMgr VERBOSE declared service EvtPersistencySvc/EventPersistencySvc
ApplicationMgr VERBOSE declared service DetPersistencySvc/DetectorPersistencySvc
ApplicationMgr VERBOSE declared service HistogramPersistencySvc/HistogramPersistencySvc
ApplicationMgr DEBUG Loading declared DLL's
ApplicationMgr VERBOSE addMultiSvc: added service EventLoopMgr/EventLoopMgr
ApplicationMgr VERBOSE added service EventLoopMgr/EventLoopMgr
ApplicationMgr INFO Application Manager Configured successfully
THistSvc DEBUG Property update for OutputLevel : new value = 2
THistSvc DEBUG Service base class initialized successfully
......
......@@ -18,16 +18,16 @@ ApplicationMgr SUCCESS
Welcome to ApplicationMgr (GaudiCoreSvc v29r0)
running on hpadpmt on Wed Oct 4 10:00:38 2017
====================================================================================================================================
ApplicationMgr VERBOSE declareMultiSvcType: declared service EvtDataSvc/EventDataSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service DetDataSvc/DetectorDataSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service HistogramSvc/HistogramDataSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service HbookCnv::PersSvc/HbookHistSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service RootHistCnv::PersSvc/RootHistSvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service EvtPersistencySvc/EventPersistencySvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service DetPersistencySvc/DetectorPersistencySvc
ApplicationMgr VERBOSE declareMultiSvcType: declared service HistogramPersistencySvc/HistogramPersistencySvc
ApplicationMgr VERBOSE declared service EvtDataSvc/EventDataSvc
ApplicationMgr VERBOSE declared service DetDataSvc/DetectorDataSvc
ApplicationMgr VERBOSE declared service HistogramSvc/HistogramDataSvc
ApplicationMgr VERBOSE declared service HbookCnv::PersSvc/HbookHistSvc
ApplicationMgr VERBOSE declared service RootHistCnv::PersSvc/RootHistSvc
ApplicationMgr VERBOSE declared service EvtPersistencySvc/EventPersistencySvc
ApplicationMgr VERBOSE declared service DetPersistencySvc/DetectorPersistencySvc
ApplicationMgr VERBOSE declared service HistogramPersistencySvc/HistogramPersistencySvc
ApplicationMgr DEBUG Loading declared DLL's
ApplicationMgr VERBOSE addMultiSvc: added service EventLoopMgr/EventLoopMgr
ApplicationMgr VERBOSE added service EventLoopMgr/EventLoopMgr
ApplicationMgr INFO Application Manager Configured successfully
THistSvc DEBUG Property update for OutputLevel : new value = 2
THistSvc DEBUG Service base class initialized successfully
......
#!/usr/bin/env gaudirun.py
'''
A test for basic functionality of sub-event scheduling.
Algorithms A2 and A3 should run twice per event, in sub-event contexts.
The ViewTester is an algorithm specifically designed to create sub-event
contexts, pass them to the scheduler, and report on the current context.
Four instances of ViewTester are used as follows:
- Algorithm A1 creates two sub-event contexts
- Algorithms A2 and A3 run within the sub-event contexts
- Algorithm A4 runs in the whole event context, after the sub-events
'''
from Gaudi.Configuration import *
from Configurables import (HiveWhiteBoard, HiveSlimEventLoopMgr,
AvalancheSchedulerSvc, AlgResourcePool,
CPUCruncher, GaudiSequencer, Test__ViewTester)
# metaconfig -------------------------------------------------------------------
# It's confortable to collect the relevant parameters at the top of the optionfile
evtslots = 1
evtMax = 10
cardinality = 1
threads = 1
viewsPerEvt = 2
#-------------------------------------------------------------------------------
# The configuration of the whiteboard ------------------------------------------
# It is useful to call it EventDataSvc to replace the usual data service with
# the whiteboard transparently.
whiteboard = HiveWhiteBoard("EventDataSvc", EventSlots=evtslots)
#-------------------------------------------------------------------------------
# Event Loop Manager -----------------------------------------------------------
# It's called slim since it has less functionalities overall than the good-old
# event loop manager. Here we just set its outputlevel to DEBUG.
slimeventloopmgr = HiveSlimEventLoopMgr(
SchedulerName="AvalancheSchedulerSvc", OutputLevel=INFO)
#-------------------------------------------------------------------------------
# ForwardScheduler -------------------------------------------------------------
# We just decide how many algorithms in flight we want to have and how many
# threads in the pool. The default value is -1, which is for TBB equivalent
# to take over the whole machine.
scheduler = AvalancheSchedulerSvc(ThreadPoolSize=threads, OutputLevel=INFO)
#-------------------------------------------------------------------------------
# Algo Resource Pool -----------------------------------------------------------
# Nothing special here, we just set the debug level.
AlgResourcePool(OutputLevel=INFO)
#-------------------------------------------------------------------------------
# Set up of the crunchers, daily business --------------------------------------
a1 = Test__ViewTester("A1")
a1.baseViewName = 'view'
a1.viewNumber = viewsPerEvt
a1.viewNodeName = 'viewNode'
a2 = Test__ViewTester("A2")
a2.viewNodeName = ''
a3 = Test__ViewTester("A3")
a3.viewNodeName = ''
a4 = Test__ViewTester("A4")
a4.viewNodeName = ''
for algo in [a1, a2, a3, a4]:
algo.Cardinality = cardinality
algo.OutputLevel = INFO
viewNode = GaudiSequencer("viewNode",
Members=[a2, a3],
Sequential=False,
OutputLevel=INFO)
createViewSeq = GaudiSequencer("createViewSeq",
Members=[a1, viewNode, a4],
Sequential=True,
OutputLevel=INFO)
# Application Manager ----------------------------------------------------------
# We put everything together and change the type of message service
ApplicationMgr(EvtMax=evtMax,
EvtSel='NONE',
ExtSvc=[whiteboard],
EventLoop=slimeventloopmgr,
TopAlg=[createViewSeq],
MessageSvcType="InertMessageSvc")
#-------------------------------------------------------------------------------
#!/usr/bin/env gaudirun.py
'''
A test for control flow scheduling within sub-event contexts.
The sub-event control flow node has a child node attached.
The ViewTester is an algorithm specifically designed to create sub-event
contexts, pass them to the scheduler, and report on the current context.
Six instances of ViewTester are used as follows:
- Algorithm A1 creates two sub-event contexts
- Algorithms A2 and A3 run within the sub-event contexts
- Algorithms B1 and B2 run within the sub-event contexts,
on a child control flow node
- Algorithm A4 runs in the whole event context, after the sub-events
'''
from Gaudi.Configuration import *
from Configurables import (HiveWhiteBoard, HiveSlimEventLoopMgr,
AvalancheSchedulerSvc, AlgResourcePool,
CPUCruncher, GaudiSequencer, Test__ViewTester)
# metaconfig -------------------------------------------------------------------
# It's confortable to collect the relevant parameters at the top of the optionfile
evtslots = 1
evtMax = 10
cardinality = 1
threads = 1
viewsPerEvt = 2
#-------------------------------------------------------------------------------
# The configuration of the whiteboard ------------------------------------------
# It is useful to call it EventDataSvc to replace the usual data service with
# the whiteboard transparently.
whiteboard = HiveWhiteBoard("EventDataSvc", EventSlots=evtslots)
#-------------------------------------------------------------------------------
# Event Loop Manager -----------------------------------------------------------
# It's called slim since it has less functionalities overall than the good-old
# event loop manager. Here we just set its outputlevel to DEBUG.
slimeventloopmgr = HiveSlimEventLoopMgr(
SchedulerName="AvalancheSchedulerSvc", OutputLevel=DEBUG)
#-------------------------------------------------------------------------------
# ForwardScheduler -------------------------------------------------------------
# We just decide how many algorithms in flight we want to have and how many
# threads in the pool. The default value is -1, which is for TBB equivalent
# to take over the whole machine.
scheduler = AvalancheSchedulerSvc(ThreadPoolSize=threads, OutputLevel=INFO)
#-------------------------------------------------------------------------------
# Algo Resource Pool -----------------------------------------------------------
# Nothing special here, we just set the debug level.
AlgResourcePool(OutputLevel=DEBUG)
#-------------------------------------------------------------------------------
# Set up of the crunchers, daily business --------------------------------------
a1 = Test__ViewTester("A1")
a1.baseViewName = 'view'
a1.viewNumber = viewsPerEvt
a1.viewNodeName = 'viewNode'
a2 = Test__ViewTester("A2")
a2.viewNodeName = ''
a3 = Test__ViewTester("A3")
a3.viewNodeName = ''
a4 = Test__ViewTester("A4")
a4.viewNodeName = ''
b1 = Test__ViewTester("B1")
b1.viewNodeName = ''
b2 = Test__ViewTester("B2")
b2.viewNodeName = ''
for algo in [a1, a2, a3, a4, b1, b2]:
algo.Cardinality = cardinality
algo.OutputLevel = DEBUG
nodeInView = GaudiSequencer("nodeInView",
Members=[b1, b2],
Sequential=False,
OutputLevel=VERBOSE)
viewNode = GaudiSequencer("viewNode",
Members=[a2, nodeInView, a3],
Sequential=False,
OutputLevel=VERBOSE)
createViewSeq = GaudiSequencer("createViewSeq",
Members=[a1, viewNode, a4],
Sequential=True,
OutputLevel=VERBOSE)
# Application Manager ----------------------------------------------------------
# We put everything together and change the type of message service
ApplicationMgr(EvtMax=evtMax,
EvtSel='NONE',
ExtSvc=[whiteboard],
EventLoop=slimeventloopmgr,
TopAlg=[createViewSeq],
MessageSvcType="InertMessageSvc")
#-------------------------------------------------------------------------------
#!/usr/bin/env gaudirun.py
'''
A test for issue 13 in gitlab.
Two different sets of sub-event contexts are created, and the
same algorithms (attached to a common control flow node) run in each
The ViewTester is an algorithm specifically designed to create sub-event
contexts, pass them to the scheduler, and report on the current context.
Five instances of ViewTester are used as follows:
- Algorithm A1 creates two sub-event contexts
- Algorithms A2 and A3 run within the sub-event contexts
- Algorithm A4 creates two more sub-event contexts
- Algorithms A2 and A3 run again, in the new contexts
- Algorithm A5 runs in the whole event context, after the sub-events
'''
from Gaudi.Configuration import *
from Configurables import (HiveWhiteBoard, HiveSlimEventLoopMgr,
AvalancheSchedulerSvc, AlgResourcePool,
CPUCruncher, GaudiSequencer, Test__ViewTester)
# metaconfig -------------------------------------------------------------------
# It's confortable to collect the relevant parameters at the top of the optionfile
evtslots = 1
evtMax = 10
cardinality = 1
threads = 1
viewsPerEvt = 2
#-------------------------------------------------------------------------------
# The configuration of the whiteboard ------------------------------------------
# It is useful to call it EventDataSvc to replace the usual data service with
# the whiteboard transparently.
whiteboard = HiveWhiteBoard("EventDataSvc", EventSlots=evtslots)
#-------------------------------------------------------------------------------
# Event Loop Manager -----------------------------------------------------------
# It's called slim since it has less functionalities overall than the good-old
# event loop manager. Here we just set its outputlevel to DEBUG.
slimeventloopmgr = HiveSlimEventLoopMgr(
SchedulerName="AvalancheSchedulerSvc", OutputLevel=INFO)
#-------------------------------------------------------------------------------
# ForwardScheduler -------------------------------------------------------------
# We just decide how many algorithms in flight we want to have and how many
# threads in the pool. The default value is -1, which is for TBB equivalent
# to take over the whole machine.
scheduler = AvalancheSchedulerSvc(ThreadPoolSize=threads, OutputLevel=INFO)
#-------------------------------------------------------------------------------
# Algo Resource Pool -----------------------------------------------------------
# Nothing special here, we just set the debug level.
AlgResourcePool(OutputLevel=INFO)
#-------------------------------------------------------------------------------
# Set up of the crunchers, daily business --------------------------------------
a1 = Test__ViewTester("A1")
a1.baseViewName = 'viewOne'
a1.viewNumber = viewsPerEvt
a1.viewNodeName = 'viewNodeOne'
a2 = Test__ViewTester("A2")
a2.viewNodeName = ''
a3 = Test__ViewTester("A3")
a3.viewNodeName = ''
a4 = Test__ViewTester("A4")
a4.baseViewName = 'viewTwo'
a4.viewNumber = viewsPerEvt
a4.viewNodeName = 'viewNodeTwo'
a5 = Test__ViewTester("A5")
a5.viewNodeName = ''
for algo in [a1, a2, a3, a4, a5]:
algo.Cardinality = cardinality
algo.OutputLevel = INFO
extraNode = GaudiSequencer("extraNode",
Members=[a2, a3],
Sequential=True,
OutputLevel=INFO)
viewNodeOne = GaudiSequencer("viewNodeOne",
Members=[extraNode],
Sequential=False,
OutputLevel=INFO)
viewNodeTwo = GaudiSequencer("viewNodeTwo",
Members=[extraNode],
Sequential=False,
OutputLevel=INFO)
createViewSeq = GaudiSequencer("createViewSeq",
Members=[a1, viewNodeOne, a4, viewNodeTwo, a5],
Sequential=True,
OutputLevel=INFO)
# Application Manager ----------------------------------------------------------
# We put everything together and change the type of message service
ApplicationMgr(EvtMax=evtMax,
EvtSel='NONE',
ExtSvc=[whiteboard],
EventLoop=slimeventloopmgr,
TopAlg=[createViewSeq],
MessageSvcType="InertMessageSvc")
#-------------------------------------------------------------------------------