diff --git a/Control/AthenaConfiguration/python/ComponentAccumulator.py b/Control/AthenaConfiguration/python/ComponentAccumulator.py index 22da2d1ec84308446a0e6484b0fc05472ca4f1e4..d9444a19347d717de9cdaf6928f825a8c58830b1 100644 --- a/Control/AthenaConfiguration/python/ComponentAccumulator.py +++ b/Control/AthenaConfiguration/python/ComponentAccumulator.py @@ -106,6 +106,8 @@ class ComponentAccumulator: self._auditors = [] #List of auditors self._privateTools = None #A placeholder to carry a private tool(s) not yet attached to its parent self._primaryComp = None #A placeholder to designate the primary service + self._currentDomain = None #Currently marked PerfMon domain + self._domainsRegistry = {} #PerfMon domains registry self._theAppProps = dict() #Properties of the ApplicationMgr @@ -372,7 +374,57 @@ class ComponentAccumulator: self.merge(other) return tool - def addEventAlgo(self, algorithms,sequenceName=None,primary=False): + def flagPerfmonDomain(self, name): + """ Mark the beginning of a new PerfMon domain. """ + self._msg.debug(f"Toggling the current algorithm domain to {name}") + self._currentDomain = name + + def getInvertedPerfmonDomains(self): + """ The actual registry keeps "alg":"domain". + This function inverts the registry to get "domain":["algs"]. + """ + result = {} + for i, v in self._domainsRegistry.items(): + result[v] = [i] if v not in result.keys() else result[v] + [i] + return result + + def getAlgPerfmonDomain(self, name): + """ Return the PerfMon domain of the given algorithm """ + if name in self._domainsRegistry: + return self._domainsRegistry[name] + else: + self._msg.info(f"Algorithm {name} is not in PerfMon domains registry") + return None + + def addAlgToPerfmonDomains(self, name, domain, overwrite=False): + """ Add the algorithm to the domains registry. """ + if name not in self._domainsRegistry: + if domain: + self._domainsRegistry[name] = domain + self._msg.debug(f"Added algorithm {name} to the PerfMon domain {domain}") + else: + if overwrite and domain: + self._msg.info(f"Reassigned algorithm {name} " + f"from {self._domainsRegistry[name]} " + f"to {domain} PerfMon domain") + self._domainsRegistry[name] = domain + else: + self._msg.debug(f"Algorithm {name} is already in the PerfMon " + "domain, if you want to reassign do overwrite=True") + + def printPerfmonDomains(self): + """ Print the PerfMon domains. """ + invertedDomains = self.getInvertedPerfmonDomains() + self._msg.info(":: This CA contains the following PerfMon domains ::") + self._msg.info(f":: There are a total of {len(self._domainsRegistry)} " + f"registered algorithms in {len(invertedDomains)} domains ::") + for domain, algs in invertedDomains.items(): + self._msg.info(f"+ Domain : {domain}") + for alg in algs: + self._msg.info("\\_ %s", alg) + self._msg.info(":: End of PerfMon domains ::") + + def addEventAlgo(self, algorithms,sequenceName=None,primary=False,domain=None): if not isinstance(algorithms, Sequence): #Swallow both single algorithms as well as lists or tuples of algorithms algorithms=[algorithms,] @@ -403,6 +455,8 @@ class ComponentAccumulator: existingAlgInDest = findAlgorithm(seq, algo.name) if not existingAlgInDest: seq.Members.append(self._algorithms[algo.name]) + # Assign the algorithm to a domain + self.addAlgToPerfmonDomains(algo.name, self._currentDomain if not domain else domain) if primary: if len(algorithms)>1: @@ -436,7 +490,7 @@ class ComponentAccumulator: seq = findSubSequence(self._sequence, seqName ) return list( OrderedDict.fromkeys( sum( flatSequencers( seq, algsCollection=self._algorithms ).values(), []) ).keys() ) - def addCondAlgo(self,algo,primary=False): + def addCondAlgo(self,algo,primary=False,domain=None): """Add Conditions algorithm""" if not isinstance(algo, (GaudiConfig2._configurables.Configurable, AthenaPython.Configurables.CfgPyAlgorithm)): @@ -460,6 +514,9 @@ class ComponentAccumulator: if "trackCondAlgo" in ComponentAccumulator.debugMode: self._componentsContext[algo.name] = shortCallStack() + # Assign the algorithm to a domain + self.addAlgToPerfmonDomains(algo.name, 'Conditions' if not domain else domain) + return algo @@ -668,6 +725,8 @@ class ComponentAccumulator: deduplicateOne(algInstance, self._algorithms[name]) for _, parent, idx in existingAlgs: # put the deduplicated algo back into original sequences parent.Members[idx] = self._algorithms[name] + # Add the algorithm to the PerfMon domains + self.addAlgToPerfmonDomains(name, other._domainsRegistry[name] if name in other._domainsRegistry else self._currentDomain) dest.Members.append(c) else: # an algorithm @@ -686,6 +745,8 @@ class ComponentAccumulator: self._msg.debug(" Adding algorithm %s to a sequence %s", c.name, dest.name ) dest.Members.append(c) + # Add the algorithm to the PerfMon domains + self.addAlgToPerfmonDomains(c.name, other._domainsRegistry[c.name] if c.name in other._domainsRegistry else self._currentDomain) # Merge sequences: # mergeSequences(destSeq, other._sequence) diff --git a/Database/AthenaPOOL/OutputStreamAthenaPool/python/OutputStreamConfig.py b/Database/AthenaPOOL/OutputStreamAthenaPool/python/OutputStreamConfig.py index 3e1d7c5d417b664efffb22b374d371d2538a7cee..e117bbaf58cf40474769e6115be0fd94ea898953 100644 --- a/Database/AthenaPOOL/OutputStreamAthenaPool/python/OutputStreamConfig.py +++ b/Database/AthenaPOOL/OutputStreamAthenaPool/python/OutputStreamConfig.py @@ -115,7 +115,7 @@ def OutputStreamCfg(configFlags, streamName, ItemList=[], MetadataItemList=[], if "AOD" in streamName: outputStream.WritingTool.SubLevelBranchName = "" - result.addEventAlgo(outputStream) + result.addEventAlgo(outputStream, domain='IO') return result def addToESD(configFlags, itemOrList, **kwargs): diff --git a/Reconstruction/RecJobTransforms/python/RecoSteering.py b/Reconstruction/RecJobTransforms/python/RecoSteering.py index 40632b219e9fd2f792f6c0f894b6fb325abe6c4a..69fb8472be25e3215fc89875890de54e9c35678e 100644 --- a/Reconstruction/RecJobTransforms/python/RecoSteering.py +++ b/Reconstruction/RecJobTransforms/python/RecoSteering.py @@ -18,6 +18,7 @@ def RecoSteering(flags): acc = MainServicesCfg(flags) # setup input + acc.flagPerfmonDomain('IO') if flags.Input.Format is Format.BS: from ByteStreamCnvSvc.ByteStreamConfig import ByteStreamReadCfg acc.merge(ByteStreamReadCfg(flags)) @@ -37,18 +38,21 @@ def RecoSteering(flags): log.info("---------- Configured POOL reading") # AOD2xAOD Truth conversion + acc.flagPerfmonDomain('Truth') if flags.Input.isMC: from xAODTruthCnv.xAODTruthCnvConfigNew import GEN_AOD2xAODCfg acc.merge(GEN_AOD2xAODCfg(flags)) log.info("---------- Configured AODtoxAOD Truth Conversion") # trigger + acc.flagPerfmonDomain('Trigger') if flags.Reco.EnableTrigger: from TriggerJobOpts.TriggerRecoConfig import TriggerRecoCfg acc.merge(TriggerRecoCfg(flags)) log.info("---------- Configured trigger data decoding") # calorimeter + acc.flagPerfmonDomain('Calo') if flags.Detector.EnableCalo: from CaloRec.CaloRecoConfig import CaloRecoCfg acc.merge(CaloRecoCfg(flags)) @@ -61,24 +65,28 @@ def RecoSteering(flags): log.info("---------- Configured calorimeter reconstruction") # ID / ITk + acc.flagPerfmonDomain('ID') if flags.Reco.EnableTracking: from InDetConfig.TrackRecoConfig import InDetTrackRecoCfg acc.merge(InDetTrackRecoCfg(flags)) log.info("---------- Configured tracking") # HGTD + acc.flagPerfmonDomain('HGTD') if flags.Reco.EnableHGTDExtension: from HGTD_Config.HGTD_RecoConfig import HGTD_RecoCfg acc.merge(HGTD_RecoCfg(flags)) log.info("---------- Configured HGTD track extension") # Muon + acc.flagPerfmonDomain('Muon') if flags.Detector.EnableMuon: from MuonConfig.MuonReconstructionConfig import MuonReconstructionCfg acc.merge(MuonReconstructionCfg(flags)) log.info("---------- Configured muon tracking") # EGamma + acc.flagPerfmonDomain('EGamma') if flags.Reco.EnableEgamma: from egammaConfig.egammaSteeringConfig import EGammaSteeringCfg acc.merge(EGammaSteeringCfg(flags)) @@ -86,6 +94,7 @@ def RecoSteering(flags): # Caching of CaloExtension for downstream # Combined Performance algorithms. + acc.flagPerfmonDomain('CaloExtension') if flags.Reco.EnableCaloExtension: from TrackToCalo.CaloExtensionBuilderAlgCfg import ( CaloExtensionBuilderCfg) @@ -93,6 +102,7 @@ def RecoSteering(flags): log.info("---------- Configured track calorimeter extension builder") # Muon Combined + acc.flagPerfmonDomain('CombinedMuon') if flags.Reco.EnableCombinedMuon: from MuonCombinedConfig.MuonCombinedReconstructionConfig import ( MuonCombinedReconstructionCfg) @@ -100,6 +110,7 @@ def RecoSteering(flags): log.info("---------- Configured combined muon reconstruction") # TrackParticleCellAssociation = add cells crossed by high pt ID tracks + acc.flagPerfmonDomain('TrackCellAssociation') if flags.Reco.EnableTrackCellAssociation: from TrackParticleAssociationAlgs.TrackParticleAssociationAlgsConfig import ( TrackParticleCellAssociationAlgCfg) @@ -107,30 +118,35 @@ def RecoSteering(flags): log.info("---------- Configured track particle-cell association") # PFlow + acc.flagPerfmonDomain('PFlow') if flags.Reco.EnablePFlow: from eflowRec.PFRun3Config import PFCfg acc.merge(PFCfg(flags)) log.info("---------- Configured particle flow") # EGamma and CombinedMuon isolation + acc.flagPerfmonDomain('Isolation') if flags.Reco.EnableCombinedMuon or flags.Reco.EnableEgamma: from IsolationAlgs.IsolationSteeringConfig import IsolationSteeringCfg acc.merge(IsolationSteeringCfg(flags)) log.info("---------- Configured isolation") # jets + acc.flagPerfmonDomain('Jets') if flags.Reco.EnableJet: from JetRecConfig.JetRecoSteering import JetRecoSteeringCfg acc.merge(JetRecoSteeringCfg(flags)) log.info("---------- Configured jets") # btagging + acc.flagPerfmonDomain('FTag') if flags.Reco.EnableBTagging: from BTagging.BTagRun3Config import BTagRecoSplitCfg acc.merge(BTagRecoSplitCfg(flags)) log.info("---------- Configured btagging") # Tau + acc.flagPerfmonDomain('Tau') if flags.Reco.EnableTau: from tauRec.TauConfig import TauReconstructionCfg acc.merge(TauReconstructionCfg(flags)) @@ -142,29 +158,34 @@ def RecoSteering(flags): log.info("---------- Configured particle flow tau FE linking") # MET + acc.flagPerfmonDomain('MET') if flags.Reco.EnableMet: from METReconstruction.METRecCfg import METCfg acc.merge(METCfg(flags)) log.info("---------- Configured MET") # HI + acc.flagPerfmonDomain('HI') if flags.Reco.EnableHI: from HIRecConfig.HIRecConfig import HIRecCfg acc.merge(HIRecCfg(flags)) log.info("---------- Configured Heavy Ion reconstruction") # AFP + acc.flagPerfmonDomain('AFP') if flags.Reco.EnableAFP: from ForwardRec.AFPRecConfig import AFPRecCfg acc.merge(AFPRecCfg(flags)) log.info("---------- Configured AFP reconstruction") # Setup the final post-processing + acc.flagPerfmonDomain('PostProcessing') if flags.Reco.EnablePostProcessing: acc.merge(RecoPostProcessingCfg(flags)) log.info("---------- Configured post-processing") # setup output + acc.flagPerfmonDomain('IO') if any((flags.Output.doWriteESD, flags.Output.doWriteAOD, flags.Output.doWriteRDO)): @@ -188,10 +209,12 @@ def RecoSteering(flags): log.info("---------- Configured AOD writing") # Set up PerfMon + acc.flagPerfmonDomain('PerfMon') if flags.PerfMon.doFastMonMT or flags.PerfMon.doFullMonMT: from PerfMonComps.PerfMonCompsConfig import PerfMonMTSvcCfg acc.merge(PerfMonMTSvcCfg(flags)) log.info("---------- Configured PerfMon") + acc.printPerfmonDomains() return acc diff --git a/Reconstruction/egamma/egammaConfig/python/egammaLRTReconstructionConfig.py b/Reconstruction/egamma/egammaConfig/python/egammaLRTReconstructionConfig.py index 174d85f83b188eec7d206ca10a03644226859ca1..dc54a034fdb92c27f2ad2a88f6328d5e94a52708 100644 --- a/Reconstruction/egamma/egammaConfig/python/egammaLRTReconstructionConfig.py +++ b/Reconstruction/egamma/egammaConfig/python/egammaLRTReconstructionConfig.py @@ -17,6 +17,9 @@ def egammaLRTReconstructionCfg(flags, name="egammaLRTReconstruction"): acc = ComponentAccumulator() + # All algorithms defined herein will be assigned to LRT + acc.flagPerfmonDomain('LRT') + # Add e/gamma tracking algorithms if flags.Egamma.doTracking: from egammaAlgs.egammaSelectedTrackCopyConfig import (