Skip to content

Commit 9d97e94

Browse files
authored
Merge pull request #2153 from byuccl/vtr_task_specify_run_dir
Add custom output directory for run_vtr_task and parse_vtr_task scripts
2 parents 02252c8 + 25fb148 commit 9d97e94

File tree

7 files changed

+93
-38
lines changed

7 files changed

+93
-38
lines changed

doc/src/vtr/parse_vtr_task.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ Detailed Command-line Options
4747
A file containing a list of tasks to parse.
4848
Each task name should be on a separate line.
4949

50+
.. option:: -temp_dir <path>
51+
52+
Alternate directory containing task results to parse (see run_vtr_task).
53+
54+
**Default:** ``config/..`` for each task being parsed
55+
56+
Specifies the parent directory for the output of a set of tasks, which will contain ``<task_name>/run<#>`` directories, as well as any generated parse results.
57+
58+
A task folder or list with a config directory must still be specified when invoking the script.
59+
5060
.. option:: -create_golden
5161

5262
The results will be stored as golden results.

doc/src/vtr/run_vtr_task.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ Detailed Command-line Options
6060
<task_name3>
6161
...
6262

63+
.. option:: -temp_dir <path>
64+
65+
Alternate directory for files generated by a set of tasks.
66+
The script will automatically create this directory if necessary.
67+
68+
**Default:** ``config/..`` for each task being run
69+
70+
Specifies the parent directory for the output of this set of tasks, which will contain ``<task_name>/run<#>`` directories, as well as any generated parse results.
71+
72+
A task folder or list with a config directory must still be specified when invoking the script.
73+
6374
.. option:: -system {local | scripts}
6475

6576
Controls how the actions (e.g. invocations of :ref:`run_vtr_flow`) are called.

requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
prettytable
22
lxml
33
psutil
4+
45
# Python linter and formatter
6+
click==8.0.2 # Our version of black needs an older version of click (https://stackoverflow.com/questions/71673404/importerror-cannot-import-name-unicodefun-from-click)
57
black==20.8b1
68
pylint==2.7.4
9+
710
# Surelog
811
orderedmultidict

vtr_flow/scripts/python_libs/vtr/parse_vtr_task.py

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ def vtr_command_argparser(prog=None):
9494
help="A file listing tasks to be run",
9595
)
9696

97+
parser.add_argument(
98+
"-temp_dir",
99+
default=None,
100+
metavar="TEMP_DIR",
101+
dest="alt_tasks_dir",
102+
help="Alternate directory to run the tasks in (will be created if non-existant)",
103+
)
104+
97105
parser.add_argument(
98106
"-parse_qor",
99107
default=False,
@@ -148,16 +156,16 @@ def vtr_command_main(arg_list, prog=None):
148156
num_failed = 0
149157

150158
jobs = create_jobs(args, configs, after_run=True)
151-
parse_tasks(configs, jobs)
159+
parse_tasks(configs, jobs, args.alt_tasks_dir)
152160

153161
if args.create_golden:
154-
create_golden_results_for_tasks(configs)
162+
create_golden_results_for_tasks(configs, args.alt_tasks_dir)
155163

156164
if args.check_golden:
157-
num_failed += check_golden_results_for_tasks(configs)
165+
num_failed += check_golden_results_for_tasks(configs, args.alt_tasks_dir)
158166

159167
if args.calc_geomean:
160-
summarize_qor(configs)
168+
summarize_qor(configs, args.alt_tasks_dir)
161169
calc_geomean(args, configs)
162170

163171
except CommandError as error:
@@ -178,29 +186,29 @@ def vtr_command_main(arg_list, prog=None):
178186
return num_failed
179187

180188

181-
def parse_tasks(configs, jobs):
189+
def parse_tasks(configs, jobs, alt_tasks_dir=None):
182190
"""
183191
Parse the selection of tasks specified in configs and associated jobs
184192
"""
185193
for config in configs:
186194
config_jobs = [job for job in jobs if job.task_name() == config.task_name]
187-
parse_task(config, config_jobs)
195+
parse_task(config, config_jobs, alt_tasks_dir=alt_tasks_dir)
188196

189197

190-
def parse_task(config, config_jobs, flow_metrics_basename=FIRST_PARSE_FILE):
198+
def parse_task(config, config_jobs, flow_metrics_basename=FIRST_PARSE_FILE, alt_tasks_dir=None):
191199
"""
192200
Parse a single task run.
193201
194202
This generates a file parse_results.txt in the task's working directory,
195203
which is an amalgam of the parse_rests.txt's produced by each job (flow invocation)
196204
"""
197-
run_dir = find_latest_run_dir(config)
205+
run_dir = find_latest_run_dir(config, alt_tasks_dir)
198206

199207
# Record max widths for pretty printing
200208
max_arch_len = len("architecture")
201209
max_circuit_len = len("circuit")
202210
for job in config_jobs:
203-
work_dir = job.work_dir(get_latest_run_dir(find_task_dir(config)))
211+
work_dir = job.work_dir(get_latest_run_dir(find_task_dir(config, alt_tasks_dir)))
204212
if job.parse_command():
205213
parse_filepath = str(PurePath(work_dir) / flow_metrics_basename)
206214
with open(parse_filepath, "w+") as parse_file:
@@ -261,42 +269,42 @@ def parse_files(config_jobs, run_dir, flow_metrics_basename=FIRST_PARSE_FILE):
261269
)
262270

263271

264-
def create_golden_results_for_tasks(configs):
272+
def create_golden_results_for_tasks(configs, alt_tasks_dir=None):
265273
"""Runs create_golden_results_for_task on all of the give configuration"""
266274

267275
for config in configs:
268-
create_golden_results_for_task(config)
276+
create_golden_results_for_task(config, alt_tasks_dir)
269277

270278

271-
def create_golden_results_for_task(config):
279+
def create_golden_results_for_task(config, alt_tasks_dir=None):
272280
"""
273281
Copies the latest task run's parse_results.txt into the config directory as golden_results.txt
274282
"""
275-
run_dir = find_latest_run_dir(config)
283+
run_dir = find_latest_run_dir(config, alt_tasks_dir)
276284

277285
task_results = str(PurePath(run_dir).joinpath(FIRST_PARSE_FILE))
278286
golden_results_filepath = str(PurePath(config.config_dir).joinpath("golden_results.txt"))
279287

280288
shutil.copy(task_results, golden_results_filepath)
281289

282290

283-
def check_golden_results_for_tasks(configs):
291+
def check_golden_results_for_tasks(configs, alt_tasks_dir=None):
284292
"""runs check_golden_results_for_task on all the input configurations"""
285293
num_qor_failures = 0
286294

287295
print("\nCalculating QoR results...")
288296
for config in configs:
289-
num_qor_failures += check_golden_results_for_task(config)
297+
num_qor_failures += check_golden_results_for_task(config, alt_tasks_dir)
290298

291299
return num_qor_failures
292300

293301

294-
def check_golden_results_for_task(config):
302+
def check_golden_results_for_task(config, alt_tasks_dir=None):
295303
"""
296304
Copies the latest task run's parse_results.txt into the config directory as golden_results.txt
297305
"""
298306
num_qor_failures = 0
299-
run_dir = find_latest_run_dir(config)
307+
run_dir = find_latest_run_dir(config, alt_tasks_dir)
300308

301309
if not config.pass_requirements_file:
302310
print(
@@ -460,32 +468,38 @@ def check_two_files(
460468
# pylint: enable=too-many-branches,too-many-locals
461469

462470

463-
def summarize_qor(configs):
471+
def summarize_qor(configs, alt_tasks_dir=None):
464472
"""Summarize the Qor results"""
465473

466474
first = True
467-
task_path = Path(configs[0].config_dir).parent
475+
task_path = Path(find_task_dir(configs[0], alt_tasks_dir))
468476
if len(configs) > 1 or (task_path.parent / "task_list.txt").is_file():
469477
task_path = task_path.parent
470478
task_path = task_path / "task_summary"
471479
task_path.mkdir(exist_ok=True)
472-
out_file = task_path / (str(Path(find_latest_run_dir(configs[0])).stem) + "_summary.txt")
480+
out_file = task_path / (
481+
str(Path(find_latest_run_dir(configs[0], alt_tasks_dir)).stem) + "_summary.txt"
482+
)
473483
with out_file.open("w+") as out:
474484
for config in configs:
475-
with (Path(find_latest_run_dir(config)) / QOR_PARSE_FILE).open("r") as in_file:
485+
with (Path(find_latest_run_dir(config, alt_tasks_dir)) / QOR_PARSE_FILE).open(
486+
"r"
487+
) as in_file:
476488
headers = in_file.readline()
477489
if first:
478490
print("task_name \t{}".format(headers), file=out, end="")
479491
first = False
480492
for line in in_file:
481493
print("{}\t{}".format(config.task_name, line), file=out, end="")
482-
pretty_print_table(str(Path(find_latest_run_dir(config)) / QOR_PARSE_FILE))
494+
pretty_print_table(
495+
str(Path(find_latest_run_dir(config, alt_tasks_dir)) / QOR_PARSE_FILE)
496+
)
483497

484498

485499
def calc_geomean(args, configs):
486500
"""caclulate and ouput the geomean values to the geomean file"""
487501
first = False
488-
task_path = Path(configs[0].config_dir).parent
502+
task_path = Path(find_task_dir(configs[0], args.alt_tasks_dir))
489503
if len(configs) > 1 or (task_path.parent / "task_list.txt").is_file():
490504
task_path = task_path.parent
491505
out_file = task_path / "qor_geomean.txt"
@@ -494,7 +508,7 @@ def calc_geomean(args, configs):
494508
summary_file = (
495509
task_path
496510
/ "task_summary"
497-
/ (str(Path(find_latest_run_dir(configs[0])).stem) + "_summary.txt")
511+
/ (str(Path(find_latest_run_dir(configs[0], args.alt_tasks_dir)).stem) + "_summary.txt")
498512
)
499513

500514
with out_file.open("w" if first else "a") as out:
@@ -508,7 +522,7 @@ def calc_geomean(args, configs):
508522
first = False
509523
lines = summary.readlines()
510524
print(
511-
get_latest_run_number(str(Path(configs[0].config_dir).parent)),
525+
get_latest_run_number(find_task_dir(configs[0], args.alt_tasks_dir)),
512526
file=out,
513527
end="\t",
514528
)
@@ -550,9 +564,9 @@ def calculate_individual_geo_mean(lines, index, geo_mean, num):
550564
return geo_mean, num, previous_value
551565

552566

553-
def find_latest_run_dir(config):
567+
def find_latest_run_dir(config, alt_tasks_dir=None):
554568
"""Find the latest run directory for given configuration"""
555-
task_dir = find_task_dir(config)
569+
task_dir = find_task_dir(config, alt_tasks_dir)
556570

557571
run_dir = get_latest_run_dir(task_dir)
558572

vtr_flow/scripts/python_libs/vtr/task.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,9 +336,11 @@ def create_jobs(args, configs, after_run=False):
336336
work_dir = str(PurePath(arch).joinpath(circuit))
337337

338338
run_dir = (
339-
str(Path(get_latest_run_dir(find_task_dir(config))) / work_dir)
339+
str(Path(get_latest_run_dir(find_task_dir(config, args.alt_tasks_dir))) / work_dir)
340340
if after_run
341-
else str(Path(get_next_run_dir(find_task_dir(config))) / work_dir)
341+
else str(
342+
Path(get_next_run_dir(find_task_dir(config, args.alt_tasks_dir))) / work_dir
343+
)
342344
)
343345

344346
# Collect any extra script params from the config file

vtr_flow/scripts/python_libs/vtr/util.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -450,13 +450,20 @@ def get_next_run_dir(base_dir):
450450
return str(PurePath(base_dir) / run_dir_name(get_next_run_number(base_dir)))
451451

452452

453-
def find_task_dir(config):
453+
def find_task_dir(config, alt_tasks_dir=None):
454454
"""
455-
find the task directory
455+
Finds the task directory.
456+
457+
Returns the parent of the config directory, or if specified,
458+
a directory with the task's name in an alternate location
456459
"""
457460
task_dir = None
458-
# Task dir is just above the config directory
459-
task_dir = Path(config.config_dir).parent
461+
462+
if alt_tasks_dir is None:
463+
task_dir = Path(config.config_dir).parent
464+
else:
465+
task_dir = Path(alt_tasks_dir) / config.task_name
466+
task_dir.mkdir(parents=True, exist_ok=True)
460467
assert task_dir.is_dir
461468

462469
return str(task_dir)

vtr_flow/scripts/run_vtr_task.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ def vtr_command_argparser(prog=None):
9797
help="A file listing tasks to be run",
9898
)
9999

100+
parser.add_argument(
101+
"-temp_dir",
102+
default=None,
103+
metavar="TEMP_DIR",
104+
dest="alt_tasks_dir",
105+
help="Alternate directory to run the tasks in (will be created if non-existant)",
106+
)
107+
100108
parser.add_argument(
101109
"-parse",
102110
default=False,
@@ -272,7 +280,7 @@ def run_tasks(
272280

273281
run_dirs = {}
274282
for config in configs:
275-
task_dir = find_task_dir(config)
283+
task_dir = find_task_dir(config, args.alt_tasks_dir)
276284
task_run_dir = get_next_run_dir(task_dir)
277285
run_dirs[config.task_name] = task_run_dir
278286

@@ -290,17 +298,17 @@ def run_tasks(
290298
print("\nParsing test results...")
291299
if len(args.list_file) > 0:
292300
print("scripts/parse_vtr_task.py -l {}".format(args.list_file[0]))
293-
parse_tasks(configs, jobs)
301+
parse_tasks(configs, jobs, args.alt_tasks_dir)
294302
print("Elapsed time: {}".format(format_elapsed_time(datetime.now() - start)))
295303

296304
if args.create_golden:
297-
create_golden_results_for_tasks(configs)
305+
create_golden_results_for_tasks(configs, args.alt_tasks_dir)
298306

299307
if args.check_golden:
300-
num_failed += check_golden_results_for_tasks(configs)
308+
num_failed += check_golden_results_for_tasks(configs, args.alt_tasks_dir)
301309

302310
if args.calc_geomean:
303-
summarize_qor(configs)
311+
summarize_qor(configs, args.alt_tasks_dir)
304312
calc_geomean(args, configs)
305313
# This option generates a shell script (vtr_flow.sh) for each architecture,
306314
# circuit, script_params

0 commit comments

Comments
 (0)