3939
4040class ExperimentManager :
4141
42- def __init__ (self , experiments = None , actions = None , args = None ):
42+ def __init__ (self , experiments = None , actions = None , args = None , callbacks = {} ):
4343 """Initializes the class from the command-line arguments."""
4444 if args is not None :
4545 self .args = args
@@ -50,6 +50,9 @@ def __init__(self, experiments=None, actions=None, args=None):
5050 else :
5151 self .actions = self .args .actions
5252
53+ # Save callbacks
54+ self .callbacks = callbacks
55+
5356 # Save directory
5457 self .dir = Path .cwd ()
5558 self .run_dir = self .dir / self .args .run_dir
@@ -146,12 +149,27 @@ def run(self):
146149
147150 # Build software
148151 if 'sw' in self .actions or 'all' in self .actions :
152+ processes = []
149153 for experiment in experiments :
154+ target = experiment ['app' ]
155+ build_dir = experiment ['elf' ].parent
150156 defines = self .derive_cdefines (experiment )
151157 data_cfg = self .derive_data_cfg (experiment )
152158 hw_cfg = self .derive_hw_cfg (experiment )
153- build .build (experiment ['app' ], experiment ['elf' ].parent , defines = defines ,
154- data_cfg = data_cfg , hw_cfg = hw_cfg )
159+ if 'sw' in self .callbacks :
160+ func = self .callbacks ['sw' ]
161+ else :
162+ func = build .build
163+ print (colored ('Build app' , 'black' , attrs = ['bold' ]),
164+ colored (target , 'cyan' , attrs = ['bold' ]),
165+ colored ('in' , 'black' , attrs = ['bold' ]),
166+ colored (build_dir , 'cyan' , attrs = ['bold' ]))
167+ process = func (
168+ target = target , build_dir = build_dir , defines = defines ,
169+ data_cfg = data_cfg , hw_cfg = hw_cfg , dry_run = dry_run
170+ )
171+ processes .append (process )
172+ common .wait_processes (processes , dry_run = dry_run )
155173
156174 # Run experiments
157175 if 'run' in self .actions or 'all' in self .actions :
@@ -195,11 +213,7 @@ def run(self):
195213 process = common .make ('perf' , vars , flags = flags , sync = False )
196214 processes .append (process )
197215
198- # Wait for all processes to complete
199- for i , process in enumerate (processes ):
200- return_code = process .wait ()
201- if return_code != 0 :
202- raise Exception (f'Failed to generate performance dump for experiment { i } ' )
216+ common .wait_processes (processes )
203217
204218 # Build visual traces
205219 if 'visual-trace' in self .actions or 'all' in self .actions :
@@ -361,3 +375,46 @@ def get_area_results(self):
361375 df = pd .concat (columns , axis = 1 )
362376
363377 return df
378+
379+
380+ def derive_axes_from_keys (experiment , keys ):
381+ """Designate some keys in the experiment as the experiment axes."""
382+ return {key : experiment [key ] for key in keys }
383+
384+
385+ def derive_data_cfg_from_template (experiment , template_path = "cfg.json.tpl" ,
386+ root_cfg_dir = Path ('data' ).absolute ()):
387+ """Derive the data configuration file from a template.
388+
389+ Fills the template file using the experiment dictionary.
390+ Writes it to a file under the root data configuration directory, creating
391+ a directory hierarchy defined by the experiment name.
392+ The output filename is derived from the template's, stripped of the '.tpl'
393+ suffix, when this suffix exists.
394+
395+ Args:
396+ experiment: Experiment dictionary.
397+ template_path: Path to the template file.
398+ root_cfg_dir: Root data configuration directory.
399+ """
400+ # Read the template file
401+ with open (template_path , 'r' ) as f :
402+ template = mako .template .Template (f .read ())
403+
404+ # Fill in (render) the template with the experiment parameters
405+ cfg = template .render (experiment = experiment )
406+
407+ # Derive output filename from template basename by stripping a trailing '.tpl'
408+ cfg_name = template_path .stem if template_path .suffix == '.tpl' else template_path .name
409+
410+ # Compose destination path from the root data configuration directory,
411+ # following a directory hierarchy defined by the experiment name
412+ cfg_path = root_cfg_dir / experiment ["name" ] / cfg_name
413+ cfg_path .parent .mkdir (parents = True , exist_ok = True )
414+
415+ # Write the rendered template to file
416+ with open (cfg_path , 'w' ) as f :
417+ f .write (cfg )
418+
419+ # Return the path to the rendered configuration file
420+ return cfg_path
0 commit comments