19 warnings.filterwarnings(
"ignore", message=
'"is" with a literal', category=SyntaxWarning)
22 from Configurables
import CPUCruncher, Gaudi__Sequencer
28 if not os.path.exists(filePath):
29 __fullFilePath__ = os.path.realpath(
31 os.environ.get(
"ENV_PROJECT_SOURCE_DIR",
""),
37 if not os.path.exists(__fullFilePath__):
38 __fullFilePath__ = os.path.realpath(
40 os.environ.get(
"ENV_PROJECT_SOURCE_DIR",
""),
47 if not os.path.exists(__fullFilePath__):
49 "\nERROR: invalid file path '%s'. "
50 "It must be either absolute, or relative to "
51 "'$ENV_PROJECT_SOURCE_DIR/GaudiHive/data/' or to "
52 "'$ENV_PROJECT_SOURCE_DIR/Gaudi/GaudiHive/data/'." % filePath
56 __fullFilePath__ = filePath
58 return __fullFilePath__
62 """A class to manage uniform algorithm timing"""
68 def get(self, algoName=""):
69 """Get time and its variance (in a tuple) for a given algorithm name"""
75 """A class to manage real algorithm timing"""
77 def __init__(self, path, defaultTime, factor=1):
79 defaultTime -- run time, assigned to an algorithm if no time is found in provided timing library
80 (and it will also be scaled by the 'factor' argument)
91 def get(self, algoName=""):
92 """Get time for a given algorithm name"""
95 time = float(self.
timings[algoName])
97 capAlgoName = algoName[0].upper() + algoName[1 : len(algoName)]
100 time = float(self.
timings[capAlgoName])
104 "WARNING: Timing for %s (or %s) not found in the provided library, using default one: %s"
105 % (algoName, capAlgoName, time)
122 """Provides randomly ordered set of boolean values with requested proportion of True and False."""
127 pattern -- either a dictionary describing proportion of True and False (e.g., {True:5,False:15}), or
128 a list/tuple containing a pattern to be used as-is (e.g., [False,True,True,False])
129 seed -- an int, long or other hashable object to initialize random number generator (passed to random.shuffle as-is)
132 if isinstance(pattern, dict):
135 length = proportion[
True] + proportion[
False]
137 raise "ERROR: Wrong set length requested: %i " % length
140 True for i
in range(proportion[
True])
148 elif isinstance(pattern, (list, tuple)):
151 raise "ERROR: unknown pattern type"
167 """Constructs the sequence tree of CPUCrunchers with provided control flow and data flow precedence rules."""
169 unique_sequencers = []
175 unique_data_objects = []
192 timeValue -- timeValue object to set algorithm execution time
193 BlockingBoolValue -- *BooleanValue object to set whether an algorithm has to experience CPU-blocking execution
194 cfgPath -- relative to $ENV_PROJECT_SOURCE_DIR/GaudiHive/data path to GRAPHML file with control flow dependencies
195 dfgPath -- relative to $ENV_PROJECT_SOURCE_DIR/GaudiHive/data path to GRAPHML file with data flow dependencies
196 showStat -- print out statistics on precedence graph
215 print(
"\n===== Statistics on Algorithms =====")
217 "Total number of algorithm nodes: ",
221 print(
"Number of unique algorithms: ", len(self.
unique_algos))
225 "of them being re-used with the following distribution: ",
230 print(
"\n===== Statistics on Sequencers =====")
232 "Total number of sequencers: ",
240 "of them being re-used with the following distribution: ",
246 print(
"\n===== Statistics on DataObjects =====")
255 """Declare data inputs and outputs for a given algorithm."""
258 for inNode, outNode
in self.
dfg.in_edges(algo_name):
263 if dataName
not in algo.inpKeys:
264 algo.inpKeys.append(dataName)
267 for inNode, outNode
in self.
dfg.out_edges(algo_name):
272 if dataName
not in algo.outKeys:
273 algo.outKeys.append(dataName)
276 """Assemble the tree of sequencers."""
279 seq = Gaudi__Sequencer(name, ShortCircuit=
False)
281 for n
in self.
cfg[name]:
283 algo_name = n.split(
"/")[1]
if "/" in n
else n
285 if "type" in self.
cfg.nodes[n]:
287 algo_type = self.
cfg.nodes[n].
get(
"type")
291 algo_type = n.split(
"/")[0]
if "/" in n
else "Algorithm"
293 if algo_type
in [
"GaudiSequencer",
"AthSequencer",
"ProcessPhase"]:
294 if algo_name
in [
"RecoITSeq",
"RecoOTSeq",
"RecoTTSeq"]:
305 seq_daughter = Gaudi__Sequencer(algo_name, OutputLevel=INFO)
306 if self.
cfg.nodes[n].
get(
"ModeOR") ==
"True":
308 seq_daughter.ModeOR =
True
311 seq_daughter.ShortCircuit =
False
312 if seq_daughter
not in seq.Members:
313 seq.Members += [seq_daughter]
329 algo_daughter = CPUCruncher(
333 varRuntime=varRuntime,
334 avgRuntime=avgRuntime,
343 if algo_daughter
not in seq.Members:
344 seq.Members += [algo_daughter]