11 from __future__
import print_function
20 warnings.filterwarnings(
21 "ignore", message=
'"is" with a literal', category=SyntaxWarning)
26 from Configurables
import GaudiSequencer, CPUCruncher
31 if not os.path.exists(filePath):
32 __fullFilePath__ = os.path.realpath(
34 os.environ.get(
'ENV_CMAKE_SOURCE_DIR',
''),
"GaudiHive",
36 if not os.path.exists(__fullFilePath__):
37 __fullFilePath__ = os.path.realpath(
39 os.environ.get(
'ENV_CMAKE_SOURCE_DIR',
''),
"Gaudi",
40 "GaudiHive",
"data", filePath))
41 if not os.path.exists(__fullFilePath__):
42 print(
"\nERROR: invalid file path '%s'. "
43 "It must be either absolute, or relative to "
44 "'$ENV_CMAKE_SOURCE_DIR/GaudiHive/data/' or to "
45 "'$ENV_CMAKE_SOURCE_DIR/Gaudi/GaudiHive/data/'." %
49 __fullFilePath__ = filePath
51 return __fullFilePath__
55 """A class to manage uniform algorithm timing"""
62 def get(self, algoName=''):
63 """Get time and its variance (in a tuple) for a given algorithm name"""
69 """A class to manage real algorithm timing"""
71 def __init__(self, path, defaultTime, factor=1):
73 defaultTime -- run time, assigned to an algorithm if no time is found in provided timing library
74 (and it will also be scaled by the 'factor' argument)
85 def get(self, algoName=''):
86 """Get time for a given algorithm name"""
89 time = float(self.
timings[algoName])
91 capAlgoName = algoName[0].upper() + algoName[1:len(algoName)]
94 time = float(self.
timings[capAlgoName])
98 "WARNING: Timing for %s (or %s) not found in the provided library, using default one: %s"
99 % (algoName, capAlgoName, time))
117 """Provides randomly ordered set of boolean values with requested proportion of True and False."""
122 pattern -- either a dictionary describing proportion of True and False (e.g., {True:5,False:15}), or
123 a list/tuple containing a pattern to be used as-is (e.g., [False,True,True,False])
124 seed -- an int, long or other hashable object to initialize random number generator (passed to random.shuffle as-is)
127 if isinstance(pattern, dict):
130 length = proportion[
True] + proportion[
False]
132 raise "ERROR: Wrong set length requested: %i " % length
135 ] + [
True for i
in range(proportion[
True])]
142 elif isinstance(pattern, (list, tuple)):
145 raise "ERROR: unknown pattern type"
164 """Constructs the sequence tree of CPUCrunchers with provided control flow and data flow precedence rules."""
166 unique_sequencers = []
172 unique_data_objects = []
187 timeValue -- timeValue object to set algorithm execution time
188 BlockingBoolValue -- *BooleanValue object to set whether an algorithm has to experience CPU-blocking execution
189 cfgPath -- relative to $ENV_CMAKE_SOURCE_DIR/GaudiHive/data path to GRAPHML file with control flow dependencies
190 dfgPath -- relative to $ENV_CMAKE_SOURCE_DIR/GaudiHive/data path to GRAPHML file with data flow dependencies
191 showStat -- print out statistics on precedence graph
212 print(
"\n===== Statistics on Algorithms =====")
214 "Total number of algorithm nodes: ",
217 print(
"Number of unique algorithms: ", len(self.
unique_algos))
219 "of them being re-used with the following distribution: ",
223 print(
"\n===== Statistics on Sequencers =====")
225 "Total number of sequencers: ",
230 "of them being re-used with the following distribution: ",
235 print(
"\n===== Statistics on DataObjects =====")
236 print(
"Number of unique DataObjects: ",
246 """ Declare data inputs and outputs for a given algorithm. """
249 for inNode, outNode
in self.
dfg.in_edges(algo_name):
254 if dataName
not in algo.inpKeys:
255 algo.inpKeys.append(dataName)
258 for inNode, outNode
in self.
dfg.out_edges(algo_name):
263 if dataName
not in algo.outKeys:
264 algo.outKeys.append(dataName)
267 """ Assemble the tree of sequencers. """
270 seq = GaudiSequencer(name, ShortCircuit=
False)
272 for n
in self.
cfg[name]:
274 algo_name = n.split(
'/')[1]
if '/' in n
else n
276 if 'type' in self.
cfg.node[n]:
278 algo_type = self.
cfg.node[n].
get(
'type')
282 algo_type = n.split(
'/')[0]
if '/' in n
else 'Algorithm'
284 if algo_type
in [
'GaudiSequencer',
'AthSequencer',
'ProcessPhase']:
285 if algo_name
in [
'RecoITSeq',
'RecoOTSeq',
'RecoTTSeq']:
296 seq_daughter = GaudiSequencer(algo_name, OutputLevel=INFO)
297 if self.
cfg.node[n].
get(
'ModeOR') ==
'True':
299 seq_daughter.ModeOR =
True
302 seq_daughter.ShortCircuit =
False
303 if seq_daughter
not in seq.Members:
304 seq.Members += [seq_daughter]
320 algo_daughter = CPUCruncher(
324 varRuntime=varRuntime,
325 avgRuntime=avgRuntime,
332 if algo_daughter
not in seq.Members:
333 seq.Members += [algo_daughter]