19 #include "eformat/ROBFragment.h"
22 #undef _POSIX_C_SOURCE
27 #include "GaudiKernel/Bootstrap.h"
28 #include "GaudiKernel/IAppMgrUI.h"
29 #include "GaudiKernel/IEventProcessor.h"
30 #include "GaudiKernel/IProperty.h"
31 #include "GaudiKernel/IService.h"
32 #include "Gaudi/Interfaces/IOptionsSvc.h"
33 #include "GaudiKernel/IAlgManager.h"
34 #include "GaudiKernel/IAlgorithm.h"
35 #include "GaudiKernel/ServiceHandle.h"
36 #include "Gaudi/Property.h"
37 #include "GaudiKernel/System.h"
47 #include <boost/property_tree/xml_parser.hpp>
49 using namespace boost::property_tree;
56 using T = ptree::key_type;
57 std::ostringstream oss;
58 xml_parser::write_xml(oss,
p,
59 xml_parser::xml_writer_make_settings<T>(
' ', 2));
70 m_pesaAppMgr->release() ;
82 ROOT::EnableThreadSafety();
87 m_config = std::make_unique<Config>(
config);
96 ERS_LOG(
"---> Dump of config cache: \n" << m_config->dumpOptions() );
97 ERS_LOG(
"---> Pesa JobOptions file is = " << m_config->getOption(
"JOBOPTIONSPATH") );
102 ERS_DEBUG(1,
"---> Create Pesa Application Manager");
103 m_pesaAppMgr = Gaudi::createApplicationMgr();
104 ERS_DEBUG(1,
"m_pesaAppMgr = " << m_pesaAppMgr);
106 if( !m_pesaAppMgr ) {
112 ERS_DEBUG(1,
"---> Configure Pesa Property Manager");
113 SmartIF<IProperty> propMgr ( m_pesaAppMgr );
114 if( !propMgr.isValid() ) {
115 ERS_PSC_ERROR(
"Error retrieving IProperty interface of ApplicationMgr");
121 sc = propMgr->setProperty(
"JobOptionsSvcType", m_config->getOption(
"JOBOPTIONSSVCTYPE"));
122 if (
sc.isFailure()) {
128 sc = propMgr->setProperty(
"JobOptionsType", m_config->getOption(
"JOBOPTIONSTYPE"));
129 if (
sc.isFailure()) {
135 sc = propMgr->setProperty(
"JobOptionsPath", m_config->getOption(
"JOBOPTIONSPATH") );
136 if (
sc.isFailure()) {
142 sc = propMgr->setProperty(
"MessageSvcType", m_config->getOption(
"MESSAGESVCTYPE"));
143 if (
sc.isFailure()) {
152 bool jobOptConfig, needPython;
153 if ( m_config->getOption(
"JOBOPTIONSTYPE") ==
"NONE" ) {
154 jobOptConfig = needPython =
true;
156 else if ( m_config->getOption(
"JOBOPTIONSTYPE") ==
"DB" ||
157 m_config->getOption(
"JOBOPTIONSTYPE") ==
"FILE") {
158 jobOptConfig = needPython =
false;
159 if ( (m_config->getOption(
"PRECOMMAND")!=
"") || (m_config->getOption(
"POSTCOMMAND")!=
"") ) {
162 if (m_config->didUserSetLogLevel()) {
167 ERS_PSC_ERROR(
"Unsupported configuration method \"" << m_config->getOption(
"JOBOPTIONSTYPE") <<
"\"");
172 if ( jobOptConfig || needPython ) {
178 if ( ! Py_IsInitialized() ) {
179 ERS_DEBUG(1,
"Initializing Python interpreter");
182 PyConfig_InitPythonConfig (&
config);
184 if (PyStatus_Exception (
status)) {
190 if (PyStatus_Exception (
status)) {
201 if ( ! Py_IsInitialized() ) {
208 ERS_DEBUG(1,
"Python interpreter already initialized");
213 PyObject* pModule = PyImport_ImportModule(
"TrigPSC.PscConfig");
217 std::map<std::string,std::string>::const_iterator iter;
218 for (iter=m_config->optmap.begin(); iter!=m_config->optmap.end(); ++iter) {
219 PyObject*
v = PyUnicode_FromString(iter->second.c_str());
220 std::vector<char> writable(iter->first.size() + 1);
221 std::copy(iter->first.begin(), iter->first.end(), writable.begin());
222 PyMapping_SetItemString(
optmap, &writable[0],
v);
227 ERS_DEBUG(1,
"Could not import TrigPSC.PscConfig.optmap");
233 if ( jobOptConfig ) {
235 std::string pyBasicFile = m_config->getOption(
"PYTHONSETUPFILE") ;
242 if ( !jobOptConfig ) {
248 std::string
cmd = m_config->getOption(
"PRECOMMAND");
250 ERS_LOG(
"Running pre-configure command '" <<
cmd <<
"'");
258 ERS_DEBUG(1,
"Configure ApplicationMgr from database.");
260 if(
sc.isFailure() ) {
268 std::string pyBasicFile = m_config->getOption(
"PYTHONSETUPFILE",
true) ;
269 if ( !pyBasicFile.empty() ) {
281 PyObject* pModule = PyImport_ImportModule(
"TrigPSC.PscConfig");
283 PyObject* pInteractive = PyObject_GetAttrString(pModule,
"interactive");
284 if ( pInteractive && PyBool_Check(pInteractive) ) {
285 m_interactive = (pInteractive==Py_True);
286 ERS_DEBUG(1,
"TrigPSC.PscConfig.interactive = " << m_interactive);
287 Py_DECREF(pInteractive);
290 ERS_DEBUG(1,
"Could not read TrigPSC.PscConfig.interactive");
295 ERS_DEBUG(1,
"Could not import TrigPSC.PscConfig");
299 if ( m_interactive ) ERS_LOG(
"Running in interactive mode");
301 ERS_DEBUG(1,
"Configured ApplicationMgr in state: " << m_pesaAppMgr->FSMState());
304 SmartIF<IProperty> jos_propif{&(*jobOptionSvc)};
305 if(m_config->didUserSetLogLevel())
306 jos_propif->setProperty(
"OutputLevel", m_config->getLogLevelAsNumStr()).ignore();
311 auto props = std::map<std::string,std::string>{
312 {
"DF_PartitionName",
"DF_PARTITION_NAME"},
313 {
"DF_ApplicationName",
"DF_APPLICATIONNAME"},
314 {
"DF_MachineName",
"DF_MACHINE_NAME"},
315 {
"DF_Ppid",
"DF_PPID"},
316 {
"DF_Pid",
"DF_PID"},
317 {
"DF_HostId",
"DF_HOST_ID"},
318 {
"DF_RandomSeed",
"DF_RANDOM_SEED"},
319 {
"DF_NumberOfWorkers",
"NPROCS"}
321 if(!setDFProperties(props))
325 if ( m_config->enabled_robs.size() != 0 ) {
326 jobOptionSvc->set(
"DataFlowConfig.DF_Enabled_ROB_IDs",
328 ERS_DEBUG(1,
"psc::Psc::configure: Wrote configuration for enabled ROBs in JobOptions Catalogue: "
329 <<
" number of ROB IDs read from OKS = " << m_config->enabled_robs.size());
333 if ( m_config->enabled_SubDets.size() != 0 ) {
334 jobOptionSvc->set(
"DataFlowConfig.DF_Enabled_SubDet_IDs",
336 ERS_DEBUG(1,
"psc::Psc::configure: Wrote configuration for enabled sub detectors in JobOptions Catalogue: "
337 <<
" number of Sub Det IDs read from OKS = " << m_config->enabled_SubDets.size());
341 if (std::string
opt = m_config->getOption(
"MAXEVENTSIZEMB"); !
opt.empty()) {
342 jobOptionSvc->set(
"DataFlowConfig.DF_MaxEventSizeMB",
opt);
343 ERS_DEBUG(1,
"psc::Psc::configure: Wrote DF_MaxEventSizeMB=" <<
opt <<
" in JobOptions Catalogue");
347 if ( (m_config->getOption(
"MUONCALBUFFERNAME") !=
"NONE") && (m_config->getOption(
"MUONCALBUFFERNAME") !=
"") ) {
348 jobOptionSvc->set(
"MuonHltCalibrationConfig.MuonCalBufferName", m_config->getOption(
"MUONCALBUFFERNAME"));
349 jobOptionSvc->set(
"MuonHltCalibrationConfig.MuonCalBufferSize", m_config->getOption(
"MUONCALBUFFERSIZE"));
351 ERS_DEBUG(1,
"psc::Psc::configure: Wrote configuration for HLT Muon Calibration in JobOptions Catalogue: "
352 <<
" MuonCalBufferName = " << m_config->getOption(
"MUONCALBUFFERNAME")
353 <<
" MuonCalBufferSize = " << m_config->getOption(
"MUONCALBUFFERSIZE") );
357 if(!setAthenaProperties())
return false;
359 if ( !jobOptConfig ) {
361 std::string
cmd = m_config->getOption(
"POSTCOMMAND");
363 ERS_LOG(
"Running post-configure command '" <<
cmd <<
"'");
371 if ( !m_interactive ) {
372 if ( !doAppMgrInit() )
return false;
383 ERS_DEBUG(1,
"Initialize ApplicationMgr : " << m_pesaAppMgr->FSMState() <<
384 ", Status = " <<
sc.getCode());
385 if(
sc.isFailure() ) {
386 ERS_PSC_ERROR(
"Error while initializing the ApplicationMgr");
391 m_svcLoc = SmartIF<ISvcLocator>( m_pesaAppMgr );
392 if ( !m_svcLoc.isValid() ) {
397 SmartIF<IProperty> propMgr ( m_pesaAppMgr );
398 if( !propMgr.isValid() ) {
399 ERS_PSC_ERROR(
"Error retrieving IProperty interface of ApplicationMgr");
405 sc = propMgr->getProperty(
"EventLoop",
value );
406 if(
sc.isFailure() ) {
407 ERS_PSC_ERROR(
"Error while retrieving Property \'EventLoop\'.");
409 m_nameEventLoopMgr.assign(
value,
value.find_first_of(
"\"")+1,
410 value.find_last_of(
"\"")-
value.find_first_of(
"\"")-1) ;
425 if ( m_interactive ) {
426 if ( !doAppMgrInit() )
return false;
440 ERS_DEBUG(1,
"psc::Psc::prepareForRun ptree:\n" <<
to_string(
args));
445 m_run_number =
args.get<
uint32_t>(
"RunParams.run_number");
447 catch(
const ptree_bad_path &
e)
449 ERS_PSC_ERROR(
"Bad ptree path: \"" <<
e.path<ptree::path_type>().dump()
450 <<
"\" - " <<
e.what())
453 catch(
const ptree_bad_data &
e)
455 ERS_PSC_ERROR(
"Bad ptree data: \"" <<
e.data<ptree::data_type>() <<
"\" - "
462 "prepareForStart").isSuccess()) {
468 if( !
sc.isSuccess() ) {
469 ERS_PSC_ERROR(
"Error executing ApplicationMgr::start() command ");
483 if (ret.isSuccess()) {
488 if(!callOnEventLoopMgr<ITrigEventLoopMgr>(prep,
"prepareForRun").isSuccess()) {
492 if ( Py_IsInitialized() ) {
495 ERS_DEBUG(1,
"Pre-fork initialization of Python interpreter");
511 if(!callOnEventLoopMgr<IService>(&IService::sysStop,
"sysStop").isSuccess())
518 auto sc = m_pesaAppMgr->stop();
519 if ( !
sc.isSuccess() ) {
520 ERS_PSC_ERROR(
"Error executing stop(void) for ApplicationMgr");
526 if (m_workerID != 0) {
527 SmartIF<IService>
histsvc = m_svcLoc->service(
"THistSvc",
false);
529 ERS_LOG(
"Finalize THistSvc to save histograms");
530 if (
histsvc->finalize().isFailure()) {
542 if (m_pesaAppMgr==
nullptr)
return true;
546 ERS_DEBUG(1,
"Finalize ApplicationMgr: " << m_pesaAppMgr->FSMState()
547 <<
". Status : " <<
sc.getCode());
549 if(
sc.isFailure() ) {
555 sc = m_pesaAppMgr->terminate();
556 ERS_DEBUG(1,
"Terminate ApplicationMgr: " << m_pesaAppMgr->FSMState()
557 <<
". Status : " <<
sc.getCode());
559 if (
sc.isFailure() ) {
560 ERS_PSC_ERROR(
"Error while terminating the ApplicationMgr.");
565 Gaudi::setInstance(
static_cast<IAppMgrUI*
>(
nullptr));
566 m_pesaAppMgr =
nullptr;
578 return doAppMgrFinalize();
611 ERS_DEBUG(1,
"psc::Psc::hltUserCommand ptree:\n" <<
to_string(
args));
619 ERS_LOG(
"psc::Psc::doEventLoop: start of doEventLoop()");
624 auto exec = [](IEventProcessor *
mgr)
625 {
return mgr->executeRun(-1);};
626 sc = callOnEventLoopMgr<IEventProcessor>(
exec,
"executeRun");
630 ERS_PSC_ERROR(
"Caught an unexpected ers::Issue: '" <<
e.what() <<
"'");
631 sc = StatusCode::FAILURE;
635 ERS_PSC_ERROR(
"Caught an unexpected std::exception: '" <<
e.what() <<
"'");
636 sc = StatusCode::FAILURE;
641 sc = StatusCode::FAILURE;
643 if (
sc.isFailure()) {
647 ERS_LOG(
"psc::Psc::doEventLoop: end of doEventLoop()");
655 ROOT::EnableThreadSafety();
656 if ( Py_IsInitialized() ) {
657 ERS_DEBUG(1,
"Post-fork initialization of Python interpreter");
658 PyOS_AfterFork_Child();
663 ERS_DEBUG(1,
"Releasing Python GIL");
667 m_workerID =
args.get<
int>(
"workerId");
669 ERS_LOG(
"Individualizing DF properties");
670 m_config->prepareWorker(
args);
672 if (!setDFProperties({{
"DF_Pid",
"DF_PID"},
673 {
"DF_Ppid",
"DF_PPID"},
674 {
"DF_RandomSeed",
"DF_RANDOM_SEED"},
675 {
"DF_WorkerId",
"DF_WORKER_ID"},
676 {
"DF_NumberOfWorkers",
"DF_NUMBER_OF_WORKERS"},
677 {
"DF_ApplicationName",
"DF_APPLICATIONNAME"}})
682 {
return mgr->hltUpdateAfterFork(
args);};
683 if(!callOnEventLoopMgr<ITrigEventLoopMgr>(upd,
"hltUpdateAfterFork").isSuccess())
694 return doAppMgrFinalize();
700 for(
const auto& prop : name_tr_table)
702 const auto&
val = m_config->getOption(prop.second);
703 jobOptionSvc->set(
"DataFlowConfig."+prop.first,
val);
704 ERS_DEBUG(0,
"Wrote configuration for Data Flow in JobOptions Catalogue: "
705 << prop.first <<
" = " <<
val);
713 SmartIF<IProperty> propMgr(m_pesaAppMgr);
714 if (!propMgr.isValid()) {
715 ERS_PSC_ERROR(
"Error retrieving IProperty interface of ApplicationMgr");
718 std::string eventLoopMgrName;
719 if (propMgr->getProperty(
"EventLoop", eventLoopMgrName).isFailure()) {
720 ERS_PSC_ERROR(
"Error while retrieving the property ApplicationMgr.EventLoop");
727 std::string
opt = m_config->getOption(
"HARDTIMEOUT");
729 jobOptionSvc->set(eventLoopMgrName+
".HardTimeout",
opt);
732 ERS_PSC_ERROR(
"Failed to get the HARDTIMEOUT property from the configuration tree");
736 opt = m_config->getOption(
"SOFTTIMEOUTFRACTION");
738 jobOptionSvc->set(eventLoopMgrName+
".SoftTimeoutFraction",
opt);
741 ERS_PSC_ERROR(
"Failed to get the SOFTTIMEOUTFRACTION property from the configuration tree");
749 opt = m_config->getOption(
"NEVENTSLOTS");
751 jobOptionSvc->set(
"EventDataSvc.NSlots",
opt);
754 ERS_PSC_ERROR(
"Failed to get the NEVENTSLOTS property from the configuration tree");
758 opt = m_config->getOption(
"NTHREADS");
760 jobOptionSvc->set(
"AvalancheSchedulerSvc.ThreadPoolSize",
opt);
763 ERS_PSC_ERROR(
"Failed to get the NTHREADS property from the configuration tree");
771 template <
typename T>
773 const std::string&
name)
const
775 SmartIF<T> processingMgr{m_svcLoc->service(m_nameEventLoopMgr)};
777 ERS_PSC_ERROR(
"Error retrieving EventLoopMgr = '" << m_nameEventLoopMgr <<
"'" );
778 return StatusCode::FAILURE;
786 << m_nameEventLoopMgr <<
"'") ;