diff --git a/Control/PerformanceMonitoring/PerfMonComps/python/JobOptCfg.py b/Control/PerformanceMonitoring/PerfMonComps/python/JobOptCfg.py index 96744943fb9045fb58cb58620d996d197bd5be34..3ca316a2f9341c659eab6ca8466e109f4cef8b9c 100644 --- a/Control/PerformanceMonitoring/PerfMonComps/python/JobOptCfg.py +++ b/Control/PerformanceMonitoring/PerfMonComps/python/JobOptCfg.py @@ -45,13 +45,16 @@ class PerfMonSvc( _PerfMonSvc ): if not isinstance(handle, PerfMonSvc): return - from AthenaCommon import CfgMgr - ## get a handle on the application manager + ## get a handle on the application manager and attach the auditors from AthenaCommon.AppMgr import theApp - if not jobproperties.PerfMonFlags.doFastMon() or jobproperties.PerfMonFlags.doSemiDetailedMonitoring(): - theApp.AuditAlgorithms = True - theApp.AuditTools = True - theApp.AuditServices = True + theApp.AuditAlgorithms = True + theApp.AuditTools = True + theApp.AuditServices = True + + ## For MT=1 jobs use IncidentProcAlgs to trigger begin/end event + if jp.ConcurrencyFlags.NumThreads() == 1: + handle.compBeginEvent = "IncidentProcAlg1" + handle.compEndEvent = "IncidentProcAlg2" ## get output levels import AthenaCommon.Constants as Lvl @@ -59,7 +62,7 @@ class PerfMonSvc( _PerfMonSvc ): ## make sure the application manager explicitly creates the service if hasattr(handle, "getFullJobOptName") : handleName = handle.getFullJobOptName() - if not handleName in theApp.CreateSvc: + if handleName not in theApp.CreateSvc: # we want to be the very first service to be initialized # so we can monitor what happens during initialize theApp.CreateSvc = [ handleName ] + theApp.CreateSvc @@ -99,7 +102,7 @@ class PerfMonSvc( _PerfMonSvc ): if isinstance( v, ( ConfigurableAlgorithm, ConfigurableAlgTool, ConfigurableService ) ) \ - and not k in ('PerfMonSvc', + and k not in ('PerfMonSvc', 'AthenaEventLoopMgr',): componentNames.append (v.getJobOptName()) pass @@ -115,7 +118,8 @@ class PerfMonSvc( _PerfMonSvc ): not jobproperties.PerfMonFlags.doFastMon()) : ## make sure the AthenaPoolCnvSvc is correctly configured - try: svcMgr.AthenaPoolCnvSvc.UseDetailChronoStat = True + try: + svcMgr.AthenaPoolCnvSvc.UseDetailChronoStat = True except AttributeError: # ok... maybe not a 'writeAthenaPool' job... pass @@ -129,7 +133,8 @@ class PerfMonSvc( _PerfMonSvc ): if 'Streams' in Configurable.configurables: outStreams = Configurable.configurables['Streams'] for o in outStreams: - if not hasattr(o, 'ItemList'): continue + if not hasattr(o, 'ItemList'): + continue ioContainers += [ i for i in o.ItemList if not i.endswith("#*") ] pass diff --git a/Control/PerformanceMonitoring/PerfMonComps/src/PerfMonSvc.cxx b/Control/PerformanceMonitoring/PerfMonComps/src/PerfMonSvc.cxx index c160ec3bcc04bfb1c398a6beea9e9d2c76e0f7b5..b11226fd1ff746bf13f8a238b7b07cae4f1ba544 100644 --- a/Control/PerformanceMonitoring/PerfMonComps/src/PerfMonSvc.cxx +++ b/Control/PerformanceMonitoring/PerfMonComps/src/PerfMonSvc.cxx @@ -1116,7 +1116,7 @@ void PerfMonSvc::startAud( const std::string& stepName, const std::string& compName ) { // Performing performance-monitoring for BeginEvent - if ( compName == "AthMasterSeq" && stepName == "evt" ) { + if ( compName == m_compBeginEvent && stepName == "evt" ) { static bool s_firstEvt = true; if ( s_firstEvt ) { s_firstEvt = false; @@ -1131,6 +1131,10 @@ void PerfMonSvc::startAud( const std::string& stepName, startAud( "evt", "PerfMonSlice" ); return; } + else if ( compName == m_compEndEvent && stepName == "evt" ) { + // Avoid mismatched start/stop that leads to bogus measurements + return; + } if (m_extraPrintouts) { double vmem,rss; @@ -1159,12 +1163,16 @@ void PerfMonSvc::stopAud( const std::string& stepName, const std::string& compName ) { // Performing performance-monitoring for EndEvent - if ( compName == "AthMasterSeq" && stepName == "evt" ) { + if ( compName == m_compEndEvent && stepName == "evt" ) { // make sure we update the data from declareInfo... poll(); stopAud( "evt", "PerfMonSlice" ); return; } + else if ( compName == m_compBeginEvent && stepName == "evt" ) { + // Avoid mismatched start/stop that leads to bogus measurements + return; + } if (m_pmonsd) m_pmonsd->stopAud(stepName,compName,m_nevts); diff --git a/Control/PerformanceMonitoring/PerfMonComps/src/PerfMonSvc.h b/Control/PerformanceMonitoring/PerfMonComps/src/PerfMonSvc.h index 976f515e8bf61fb3c866b513b8864fddb62b35b9..4a2c86ffb1591e561d2235211b524ef30b4318e4 100644 --- a/Control/PerformanceMonitoring/PerfMonComps/src/PerfMonSvc.h +++ b/Control/PerformanceMonitoring/PerfMonComps/src/PerfMonSvc.h @@ -351,6 +351,22 @@ private: PMonSD::SemiDetHelper * m_pmonsd; bool m_pf; + +private: + + // In serial Athena each job starts w/ Before AthMasterSeq Execute auditor call + // and ends w/ After AthMasterSeq Execute auditor call. However, in MT this is + // not the case. Although this Service is not MT-safe (see PerfMonMTSvc) + // we still use it in MT = 1 jobs. There we use the incident algorithms as a + // workaround. + + // Component name that'll trigger begin event + Gaudi::Property<std::string> m_compBeginEvent { + this, "compBeginEvent", "AthMasterSeq", "Component name that'll trigger begin event" }; + + // Component name that'll trigger end event + Gaudi::Property<std::string> m_compEndEvent { + this, "compEndEvent", "AthMasterSeq", "Component name that'll trigger end event" }; }; /// I/O operators