From 45288635b3c3296f298c9f5c281cd25495e46f06 Mon Sep 17 00:00:00 2001 From: NiccoloN Date: Mon, 27 Jul 2026 12:23:27 +0200 Subject: [PATCH] validation prints immediatly in case of single job --- validation/README.md | 7 -- validation/raptor_validation/validate_one.py | 4 +- validation/validate.py | 96 +++++++++++--------- 3 files changed, 57 insertions(+), 50 deletions(-) diff --git a/validation/README.md b/validation/README.md index abff2a7..cd10b9f 100644 --- a/validation/README.md +++ b/validation/README.md @@ -102,13 +102,6 @@ count with `-j` or `--jobs`: --jobs 8 ``` -Each model's output is buffered as one readable block. Independent workspace -jobs print their blocks when they finish, so their order may differ from the -final table. The final result table is sorted by model path. - -Models in the same directory run sequentially because they share generated -workspace paths. - ## Options | Option | Description | diff --git a/validation/raptor_validation/validate_one.py b/validation/raptor_validation/validate_one.py index dbb68b7..3063a77 100644 --- a/validation/raptor_validation/validate_one.py +++ b/validation/raptor_validation/validate_one.py @@ -165,9 +165,9 @@ class ProgressReporter: if self.enabled: self._clear() if color: - print(color + message + Style.RESET_ALL) + print(color + message + Style.RESET_ALL, flush=True) else: - print(message) + print(message, flush=True) self._render() def set_stage(self, model_index, model_total, model_name, stage_name): diff --git a/validation/validate.py b/validation/validate.py index 9fc00f4..23bccc0 100755 --- a/validation/validate.py +++ b/validation/validate.py @@ -6,7 +6,7 @@ import signal import subprocess import sys from concurrent.futures import ProcessPoolExecutor, as_completed -from contextlib import redirect_stderr, redirect_stdout +from contextlib import nullcontext, redirect_stderr, redirect_stdout from itertools import groupby from pathlib import Path from tempfile import TemporaryDirectory @@ -44,36 +44,43 @@ def run_validation_job(job): enabled=False, verbose=options["verbose"], ) + + def validate(): + try: + return validate_network( + onnx_path, + reporter=reporter, + model_index=index, + model_total=options["model_total"], + verbose=options["verbose"], + mode=options["mode"], + **options["validation_kwargs"], + ) + except Exception as exc: + print_validation_error(reporter, rel, exc) + return ValidationResult(False, pimsim_status=PIMSIM_NOT_RUN) + finally: + reporter.finish() + sys.stdout.flush() sys.stderr.flush() - saved_stdout = os.dup(1) - saved_stderr = os.dup(2) - try: - with open(log_path, "w", encoding="utf-8", buffering=1) as log: - os.dup2(log.fileno(), 1) - os.dup2(log.fileno(), 2) - with redirect_stdout(log), redirect_stderr(log): - try: - result = validate_network( - onnx_path, - reporter=reporter, - model_index=index, - model_total=options["model_total"], - verbose=options["verbose"], - mode=options["mode"], - **options["validation_kwargs"], - ) - except Exception as exc: - result = ValidationResult(False, pimsim_status=PIMSIM_NOT_RUN) - print_validation_error(reporter, rel, exc) - finally: - reporter.finish() - finally: - os.dup2(saved_stdout, 1) - os.dup2(saved_stderr, 2) - os.close(saved_stdout) - os.close(saved_stderr) - completed.append((str(rel), result, str(log_path))) + if log_path is None: + result = validate() + else: + saved_stdout = os.dup(1) + saved_stderr = os.dup(2) + try: + with open(log_path, "w", encoding="utf-8", buffering=1) as log: + os.dup2(log.fileno(), 1) + os.dup2(log.fileno(), 2) + with redirect_stdout(log), redirect_stderr(log): + result = validate() + finally: + os.dup2(saved_stdout, 1) + os.dup2(saved_stderr, 2) + os.close(saved_stdout) + os.close(saved_stderr) + completed.append((str(rel), result, str(log_path) if log_path else None)) return completed @@ -214,7 +221,7 @@ def main(): print(Style.BRIGHT + f"Found {len(onnx_files)} ONNX file(s) to validate." + Style.RESET_ALL) print(f"Operations root: {operations_dir}") - print(f"Parallel jobs: {a.jobs}") + print(f"Max parallel jobs: {a.jobs}") print("=" * 72) mode = MODE_FULL @@ -268,7 +275,8 @@ def main(): list(group) for _, group in groupby(indexed_files, key=lambda indexed_path: indexed_path[1].parent) ] - with TemporaryDirectory(prefix="raptor-validation-") as log_dir: + print_directly = min(a.jobs, len(workspace_groups)) == 1 + with (nullcontext(None) if print_directly else TemporaryDirectory(prefix="raptor-validation-")) as log_dir: jobs = [ ( [ @@ -276,7 +284,7 @@ def main(): index, onnx_path, onnx_path.relative_to(operations_dir), - Path(log_dir) / f"{index}.log", + Path(log_dir) / f"{index}.log" if log_dir else None, ) for index, onnx_path in workspace_group ], @@ -289,16 +297,22 @@ def main(): ) for workspace_group in workspace_groups ] - with ProcessPoolExecutor(max_workers=a.jobs) as executor: - futures = [executor.submit(run_validation_job, job) for job in jobs] - for future in as_completed(futures): - completed_group = future.result() + with (nullcontext(None) if print_directly else ProcessPoolExecutor(max_workers=a.jobs)) as executor: + completed_groups = ( + map(run_validation_job, jobs) + if print_directly + else (future.result() for future in as_completed( + executor.submit(run_validation_job, job) for job in jobs + )) + ) + for completed_group in completed_groups: for rel, result, log_path in completed_group: - reporter.suspend() - output = Path(log_path).read_text(encoding="utf-8", errors="replace") - if output: - print(output, end="" if output.endswith("\n") else "\n") - reporter.resume() + if log_path: + reporter.suspend() + output = Path(log_path).read_text(encoding="utf-8", errors="replace") + if output: + print(output, end="" if output.endswith("\n") else "\n") + reporter.resume() reporter.advance() reporter.record_result(result.passed) results[rel] = result