11 from __future__
import print_function
20 from Configurables
import GaudiSequencer, CPUCruncher
25 if not os.path.exists(filePath):
26 __fullFilePath__ = os.path.realpath(
28 os.environ.get(
'GAUDIHIVEROOT',
''),
"data", filePath))
29 if not os.path.exists(__fullFilePath__):
31 "\nERROR: invalid file path '%s'. It must be either absolute, or relative to '$GAUDIHIVEROOT/data/'." 35 __fullFilePath__ = filePath
37 return __fullFilePath__
41 """A class to manage uniform algorithm timing""" 48 def get(self, algoName=''):
49 """Get time and its variance (in a tuple) for a given algorithm name""" 55 """A class to manage real algorithm timing""" 57 def __init__(self, path, defaultTime, factor=1):
59 defaultTime -- run time, assigned to an algorithm if no time is found in provided timing library 60 (and it will also be scaled by the 'factor' argument) 71 def get(self, algoName=''):
72 """Get time for a given algorithm name""" 75 time = float(self.
timings[algoName])
77 capAlgoName = algoName[0].upper() + algoName[1:len(algoName)]
80 time = float(self.
timings[capAlgoName])
84 "WARNING: TimiNg for %s (or %s) not found in the provided library, using default one: %s" 85 % (algoName, capAlgoName, time))
103 """Provides randomly ordered set of boolean values with requested proportion of True and False.""" 108 pattern -- either a dictionary describing proportion of True and False (e.g., {True:5,False:15}), or 109 a list/tuple containing a pattern to be used as-is (e.g., [False,True,True,False]) 110 seed -- an int, long or other hashable object to initialize random number generator (passed to random.shuffle as-is) 113 if isinstance(pattern, dict):
116 length = proportion[
True] + proportion[
False]
118 raise "ERROR: Wrong set length requested: %i " % length
121 ] + [
True for i
in range(proportion[
True])]
128 elif isinstance(pattern, (list, tuple)):
131 raise "ERROR: unknown pattern type" 150 """Constructs the sequence tree of CPUCrunchers with provided control flow and data flow precedence rules.""" 152 unique_sequencers = []
158 unique_data_objects = []
172 timeValue -- timeValue object to set algorithm execution time 173 IOboolValue -- *BooleanValue object to set whether an algorithm has to experience IO-bound execution 174 cfgPath -- relative to $GAUDIHIVEROOT/data path to GRAPHML file with control flow dependencies 175 dfgPath -- relative to $GAUDIHIVEROOT/data path to GRAPHML file with data flow dependencies 176 showStat -- print out statistics on precedence graph 196 print(
"\n===== Statistics on Algorithms =====")
197 print(
"Total number of algorithm nodes: ", len(self.
unique_algos) +
199 print(
"Number of unique algorithms: ", len(self.
unique_algos))
201 "of them being re-used with the following distribution: ",
205 print(
"\n===== Statistics on Sequencers =====")
210 "of them being re-used with the following distribution: ",
215 print(
"\n===== Statistics on DataObjects =====")
216 print(
"Number of unique DataObjects: ",
226 """ Declare data inputs and outputs for a given algorithm. """ 229 for inNode, outNode
in self.
dfg.in_edges(algo_name):
234 if dataName
not in algo.inpKeys:
235 algo.inpKeys.append(dataName)
238 for inNode, outNode
in self.
dfg.out_edges(algo_name):
243 if dataName
not in algo.outKeys:
244 algo.outKeys.append(dataName)
247 """ Assemble the tree of sequencers. """ 250 seq = GaudiSequencer(name, ShortCircuit=
False)
252 for n
in self.
cfg[name]:
254 algo_name = n.split(
'/')[1]
if '/' in n
else n
256 if 'type' in self.
cfg.node[n]:
258 algo_type = self.
cfg.node[n].
get(
'type')
262 algo_type = n.split(
'/')[0]
if '/' in n
else 'Algorithm' 264 if algo_type
in [
'GaudiSequencer',
'AthSequencer',
'ProcessPhase']:
265 if algo_name
in [
'RecoITSeq',
'RecoOTSeq',
'RecoTTSeq']:
276 seq_daughter = GaudiSequencer(algo_name, OutputLevel=INFO)
277 if self.
cfg.node[n].
get(
'ModeOR') ==
'True':
279 seq_daughter.ModeOR =
True 282 seq_daughter.ShortCircuit =
False 283 if seq_daughter
not in seq.Members:
284 seq.Members += [seq_daughter]
300 algo_daughter = CPUCruncher(
303 varRuntime=varRuntime,
304 avgRuntime=avgRuntime,
311 if algo_daughter
not in seq.Members:
312 seq.Members += [algo_daughter]
def __init__(self, path, defaultTime, factor=1)
def _generate_sequence(self, name, seq=None)
def get(self, algoName='')
def __init__(self, timeValue, IOboolValue, sleepFraction, cfgPath, dfgPath, topSequencer, showStat=False, timeline=False, outputLevel=INFO)
def _declare_data_deps(self, algo_name, algo)
def _buildFilePath(filePath)
decltype(auto) range(Args &&... args)
Zips multiple containers together to form a single range.
def __init__(self, pattern, seed=None)
def _create_generator(self, pattern)