96 algName='GlobalSimTestAlg',
97 OutputLevel=Constants.INFO):
99 logger.setLevel(OutputLevel)
100 cfg = ComponentAccumulator()
102 fn = os.environ.get(
'GS_CFG_FILE',
None)
104 if not os.path.exists(fn):
105 raise RuntimeError (
'specified cfg file ' + fn +
' does not exist')
107 def_fn =
"GlobalSimulation/globalSim_AllChainsCfg.xml"
108 logger.info(
'environment variable GS_CFG_FILE not set ' +
109 'looking for default config file'+ def_fn)
112 logger.info (
'could not find default cfg file ' + def_fn +
114 raise RuntimeError (
'default cfg file ' + def_fn +
' not found')
116 logger.info(
'GlobalSim local config, cfg file: ' + fn)
119 """ obtain a string id for each AlgTool"""
121 a_class = toolEl.attrib[
'class']
122 a_name = toolEl.attrib[
'name']
123 return '/'.join((a_class, a_name))
125 def classname_from_fullname(fullname):
126 return fullname.split(
'/')[0]
129 def configure_algtool(toolEl):
131 Set the AlgTool properties from configure file information.
132 Datahandles are not processed here.
135 a_class = toolEl.attrib[
'class']
136 a_name = toolEl.attrib[
'name']
138 factory = getattr(CompFactory.GlobalSim, a_class)
139 tool = factory(a_name)
141 type_factories = {
'int': int,
145 for prop
in toolEl.iter(
'property'):
146 name = prop.attrib[
'name']
147 value = prop.attrib[
'value']
148 ptype = prop.attrib.get(
"type",
None)
149 if ptype
is not None:
150 value = type_factories[ptype](value)
151 setattr(tool, name, value)
152 prop_names.append(name)
154 logger.debug(
'configure_algtool: ' + str(tool))
158 def fill_alg_ids(root):
160 Assign an index to each AlgTool instance specified by
161 the configuration file.
163 Return this information in a dictionary.
171 for toolType
in (
'TOBWriters',
'TIPWriters'):
172 for writerEl
in root.iter(toolType):
173 for toolEl
in writerEl.iter(
'AlgTool'):
174 f_name = str_id(toolEl)
175 if f_name
in alg_ids:
176 raise AssertionError(
'Algorithm duplicated in ' + fn)
177 alg_ids[f_name] = alg_ind
178 alg_tools[alg_ind] = (configure_algtool(toolEl), toolType)
180 return alg_ids, alg_tools, alg_ind
182 def fill_input_slots(root, alg_ids):
185 {par_alg_id:int || {input_slot:str || child_alg_id:int}}
187 Where is a generic name for the input location, eg "in0", and
188 is used by the config file. The actual location is
189 currently obtained using the read_handles dictionary at the top
193 input_slots = defaultdict(dict)
195 for toolEl
in root.iter(
'AlgTool'):
196 par_full_name = str_id(toolEl)
197 par_id = alg_ids[par_full_name]
199 for childEl
in toolEl.iter(
'child'):
200 child_full_name = str_id(childEl)
201 child_id = alg_ids[child_full_name]
202 slot = childEl.attrib.get(
'slot',
None)
204 msg = [
'No slot information for ',
208 raise AssertionError(
' '.join(msg))
210 input_slots[par_id][child_id] = slot
215 def make_digraph(alg_ids, V):
217 Construct an Algtool Digraph.
219 Obtain parent child relations from the config XML file.
221 The graph knows only about
222 the AlgTool insances's indices, and so works from a
223 dictionary that associates the AlgoTool name (string) to its
229 logger.debug(
'make_digraph alg_ids: ', alg_ids)
230 logger.debug(
'make_digraph: V ' + str(V))
236 for toolType
in (
'TOBWriters',
'TIPWriters'):
238 for writerEl
in root.iter(toolType):
239 for toolEl
in writerEl.iter(
'AlgTool'):
240 f_name = str_id(toolEl)
241 logger.debug(
'make_digraph: toolType ' + toolType +
245 par_id = alg_ids[f_name]
247 for childEl
in toolEl.iter(
'child'):
248 f_c_name = str_id(childEl)
249 if f_c_name
not in alg_ids:
250 raise AssertionError(
'child ' + f_c_name +
253 G.addEdge(par_id, alg_ids[f_c_name])
256 roots = [n
for n
in range(R.V)
if not R.adj(n)
and n != 0]
259 def set_SGout_locations(tools):
261 Set the StoreGate locations to be written to. As the
262 same Algorithm may have > 1 instance, ensure that the
263 write locations differ.
268 for indx, (tool, tooltype)
in tools.items():
269 class_name = tool.__class__.__name__
270 handle = write_handles.get(class_name,
None)
272 if handle
is not None:
273 setattr(tool, handle,
'GlobalSim_'+str(out_index))
277 def set_SGin_locations(tools, alg_ids, input_slots, G):
280 Set locations read from by each Algorithm according to the
283 NOTE: currently we assume a tool has one output location
284 and one input location, which allows only "narrow chains".
285 This will be extended to allow multiple children in the near future.
287 alg_ids is a str:int map
288 tools is a int : (tool, toolType) map
291 for nid
in range(1, G.V):
292 parent = tools[nid][0]
293 child_ids = G.adj(nid)
294 if len(child_ids) == 0:
297 for child_id
in child_ids:
298 slot = input_slots[nid][child_id]
299 child_tool = tools[child_id][0]
300 w_handle_name = write_handles[child_tool.__class__.__name__]
301 read_handle = read_handles[parent.__class__.__name__][slot]
302 read_from = getattr(child_tool, w_handle_name)
303 setattr(parent, read_handle, read_from)
309 root = tree.getroot()
315 alg_ids, alg_tools, V= fill_alg_ids(root)
316 input_slots = fill_input_slots(root, alg_ids)
317 G, roots = make_digraph(alg_ids, V)
318 logger.debug(
'call graph ' + str(G))
320 topological = Topological(G, roots=roots)
321 if not topological.isDAG():
raise AssertionError(
322 'Call graph is not a DAG')
324 index_order = topological.order()
325 set_SGout_locations(tools=alg_tools)
326 set_SGin_locations(tools=alg_tools, alg_ids = alg_ids,
327 input_slots=input_slots, G=G)
329 logger.debug(
'DAG: ' + str(G))
330 logger.debug(
'order: ' + str(index_order))
333 toolType =
'TOBWriters'
334 orderedTOBWriters = [alg_tools[i][0]
for i
in index_order
335 if alg_tools[i][1] == toolType]
337 msg = [str(tool)
for tool
in orderedTOBWriters]
338 logger.debug(toolType +
': ' +
'\n'.join(msg))
341 toolType =
'TIPWriters'
342 orderedTIPWriters = [alg_tools[i][0]
for i
in index_order
343 if alg_tools[i][1] == toolType]
345 tools = [alg_tools[i][0]
for i
in index_order]
346 msg = [
'GlobalSim tool IO dump:']
349 tname = tool.__class__.__name__ +
'/' + tool.name
351 logger.debug(
'GS tool name ' + tname)
352 logger.debug(
'GS r_handle str(tool) ' + str(tool))
354 handle_name = read_handles.get(tool.__class__.__name__,
None)
355 if handle_name
is None:
356 logger.debug(
'GS r_handle not in table')
359 logger.debug(
'GS r_handle from table: ', handle_name)
360 logger.debug(
'GS r_handle loc from tool: ' + tname +
' ' +
361 str(getattr(tool, handle_name[
'in0'])))
363 handle_name = write_handles.get(tool.__class__.__name__,
None)
364 if handle_name
is None:
365 logger.debug(
'GS w_handle not in table')
367 logger.debug(
'GS w_handle from table: ' + handle_name)
368 logger.debug(
'GS w_handle loc from tool: ' + tname +
' ' +
369 str(getattr(tool, handle_name)))
372 alg = CompFactory.GlobalSim.GlobalSimulationAlg(algName)
373 alg.globalsim_algs = orderedTOBWriters
374 alg.TIPwriters = orderedTIPWriters
375 alg.OutputLevel = OutputLevel
376 alg.enableDumps = dump
379 cfg.addEventAlgo(alg)