diff --git a/hpvm/projects/hpvm-profiler/hpvm_profiler/__init__.py b/hpvm/projects/hpvm-profiler/hpvm_profiler/__init__.py index e007ca9277f9e584708488ee57fd08c693a00279..123a35a781f515a089598a10e1334fd7d6067cd3 100644 --- a/hpvm/projects/hpvm-profiler/hpvm_profiler/__init__.py +++ b/hpvm/projects/hpvm-profiler/hpvm_profiler/__init__.py @@ -1,8 +1,11 @@ from pathlib import Path +from subprocess import CalledProcessError, PIPE from typing import Iterable, List, Tuple, Union from dataclasses import dataclass +from tqdm import trange PathLike = Union[Path, str] +conf_opening, conf_closing = "+++++", "-----" def profile_configs( @@ -43,12 +46,18 @@ def profile_configs( raise ValueError("Config file with no configs is unsupported.") temp_file = NamedTemporaryFile("w") baseline_time, baseline_acc = None, None - for idx, config in enumerate(configs): + for idx in trange(len(configs), desc="Configs profiled"): + config = configs[idx] # Write config to temp config file write_hpvm_config(header, [config], Path(temp_file.name)) # Run binary_path binary, # which generates `profile_filename` and `qos_filename` file in cwd. - check_call(str(binary_path)) + try: + check_call([str(binary_path), "-c", str(temp_file.name)], stdout=PIPE) + except CalledProcessError as e: + print("Output from the program:") + print(e.output) + raise e # Read these two files for time and QoS info. time = _read_profile_file(Path(profile_filename)) acc = _read_qos_file(Path(qos_filename)) @@ -129,7 +138,8 @@ class Config: self.qos_loss, ] header = " ".join(str(field) for field in header_fields) - return f"{header}\n{self.config_body}" + lines = [conf_opening, header, *self.config_body, conf_closing] + return "\n".join(lines) __str__ = __repr__ @@ -139,13 +149,12 @@ def read_hpvm_configs(config_file: PathLike) -> Tuple[str, List[Config]]: ret_configs = [] with open(config_file) as f: text = f.read() - opening, closing = "+++++", "-----" # There's 1 float sitting on the first line of config file. # We don't use it, but want to keep that intact. - header, *configs = text.split(opening) + header, *configs = text.split(conf_opening) header = header.strip() for config_text in configs: - config_text = config_text.replace(closing, "").strip() + config_text = config_text.replace(conf_closing, "").strip() config_header, *config_body = config_text.splitlines() conf_name, *number_fields = config_header.split(" ") speedup, energy, qos, qos_drop = [float(s) for s in number_fields]