19 warnings.filterwarnings(
"ignore", message=
'"is" with a literal', category=SyntaxWarning)
22 from Configurables
import CPUCruncher, GaudiSequencer
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"""
69 def get(self, algoName=""):
70 """Get time and its variance (in a tuple) for a given algorithm name"""
76 """A class to manage real algorithm timing"""
78 def __init__(self, path, defaultTime, factor=1):
80 defaultTime -- run time, assigned to an algorithm if no time is found in provided timing library
81 (and it will also be scaled by the 'factor' argument)
92 def get(self, algoName=""):
93 """Get time for a given algorithm name"""
96 time = float(self.
timings[algoName])
98 capAlgoName = algoName[0].upper() + algoName[1 : len(algoName)]
100 if capAlgoName
in self.
timings:
101 time = float(self.
timings[capAlgoName])
105 "WARNING: Timing for %s (or %s) not found in the provided library, using default one: %s"
106 % (algoName, capAlgoName, time)
125 """Provides randomly ordered set of boolean values with requested proportion of True and False."""
130 pattern -- either a dictionary describing proportion of True and False (e.g., {True:5,False:15}), or
131 a list/tuple containing a pattern to be used as-is (e.g., [False,True,True,False])
132 seed -- an int, long or other hashable object to initialize random number generator (passed to random.shuffle as-is)
135 if isinstance(pattern, dict):
138 length = proportion[
True] + proportion[
False]
140 raise "ERROR: Wrong set length requested: %i " % length
143 True for i
in range(proportion[
True])
151 elif isinstance(pattern, (list, tuple)):
154 raise "ERROR: unknown pattern type"
173 """Constructs the sequence tree of CPUCrunchers with provided control flow and data flow precedence rules."""
175 unique_sequencers = []
181 unique_data_objects = []
198 timeValue -- timeValue object to set algorithm execution time
199 BlockingBoolValue -- *BooleanValue object to set whether an algorithm has to experience CPU-blocking execution
200 cfgPath -- relative to $ENV_PROJECT_SOURCE_DIR/GaudiHive/data path to GRAPHML file with control flow dependencies
201 dfgPath -- relative to $ENV_PROJECT_SOURCE_DIR/GaudiHive/data path to GRAPHML file with data flow dependencies
202 showStat -- print out statistics on precedence graph
221 print(
"\n===== Statistics on Algorithms =====")
223 "Total number of algorithm nodes: ",
227 print(
"Number of unique algorithms: ", len(self.
unique_algos))
231 "of them being re-used with the following distribution: ",
236 print(
"\n===== Statistics on Sequencers =====")
238 "Total number of sequencers: ",
246 "of them being re-used with the following distribution: ",
252 print(
"\n===== Statistics on DataObjects =====")
262 """Declare data inputs and outputs for a given algorithm."""
265 for inNode, outNode
in self.
dfg.in_edges(algo_name):
270 if dataName
not in algo.inpKeys:
271 algo.inpKeys.append(dataName)
274 for inNode, outNode
in self.
dfg.out_edges(algo_name):
279 if dataName
not in algo.outKeys:
280 algo.outKeys.append(dataName)
283 """Assemble the tree of sequencers."""
286 seq = GaudiSequencer(name, ShortCircuit=
False)
288 for n
in self.
cfg[name]:
290 algo_name = n.split(
"/")[1]
if "/" in n
else n
292 if "type" in self.
cfg.nodes[n]:
294 algo_type = self.
cfg.nodes[n].
get(
"type")
298 algo_type = n.split(
"/")[0]
if "/" in n
else "Algorithm"
300 if algo_type
in [
"GaudiSequencer",
"AthSequencer",
"ProcessPhase"]:
301 if algo_name
in [
"RecoITSeq",
"RecoOTSeq",
"RecoTTSeq"]:
312 seq_daughter = GaudiSequencer(algo_name, OutputLevel=INFO)
313 if self.
cfg.nodes[n].
get(
"ModeOR") ==
"True":
315 seq_daughter.ModeOR =
True
318 seq_daughter.ShortCircuit =
False
319 if seq_daughter
not in seq.Members:
320 seq.Members += [seq_daughter]
336 algo_daughter = CPUCruncher(
340 varRuntime=varRuntime,
341 avgRuntime=avgRuntime,
350 if algo_daughter
not in seq.Members:
351 seq.Members += [algo_daughter]