better throughput in pipeline mode
Validate Operations / validate-operations (push) Waiting to run

This commit is contained in:
NiccoloN
2026-08-19 16:03:52 +02:00
parent 4a2487d095
commit db8d1c1707
24 changed files with 1287 additions and 529 deletions
@@ -1153,6 +1153,7 @@ def write_report(
pimcomp_pipeline: str,
pimcomp_replication: str,
):
report_path.parent.mkdir(parents=True, exist_ok=True)
lines = [
"# Raptor vs PIMCOMP Comparison Report",
"",
@@ -1302,6 +1303,11 @@ def write_report(
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--model", required=True, type=Path)
parser.add_argument(
"--functional-model",
type=Path,
help="Optional canonical model used only for Raptor functional validation.",
)
parser.add_argument("--out-dir", required=True, type=Path)
parser.add_argument(
"--common-dir",
@@ -1325,7 +1331,7 @@ def main():
parser.add_argument("--pimsim-nn-build-dir", default=REPO / "backend-simulators/pim/pimsim-nn/build", type=Path)
parser.add_argument("--seed", type=int, default=0)
parser.add_argument("--threshold", type=float, default=1e-3)
parser.add_argument("--rtol", type=float, default=1e-5)
parser.add_argument("--rtol", type=float, default=1e-4)
parser.add_argument(
"--timeout-seconds",
type=float,
@@ -1390,6 +1396,11 @@ def main():
args.pimcomp_pipeline = "element" if args.pimsim_mode == "latency" else "batch"
model_path = args.model.resolve()
functional_model_path = (
args.functional_model.resolve()
if args.functional_model is not None
else model_path
)
args.pimcomp_dir = args.pimcomp_dir.resolve()
args.pimcomp_config = (
args.pimcomp_config.resolve()
@@ -1407,7 +1418,7 @@ def main():
if args.prepare_common:
print_step("Prepare shared artifacts")
prepare_common_artifacts(args, model_path, common_dir)
prepare_common_artifacts(args, functional_model_path, common_dir)
print(f"Shared artifacts: {common_dir}")
return
@@ -1450,7 +1461,13 @@ def main():
if loaded_hardware is not None:
hardware = loaded_hardware
model_io = try_stage(failures, "Load model inputs", load_model_inputs, model_path, args.seed)
model_io = try_stage(
failures,
"Load model inputs",
load_model_inputs,
functional_model_path,
args.seed,
)
if model_io is not None:
inputs_desc, outputs_desc, arrays_in_order = model_io
runtime_inputs = arrays_in_order
@@ -1530,7 +1547,7 @@ def main():
"Compile reference",
compile_reference,
args,
model_path,
functional_model_path,
common_dir,
steps,
)
@@ -1548,7 +1565,7 @@ def main():
generate_reference_outputs,
runner_path,
runner_path.parent,
model_path,
functional_model_path,
arrays_in_order,
steps,
args,
@@ -1578,7 +1595,7 @@ def main():
generate_reference_batch_outputs,
runner_path,
runner_path.parent,
model_path,
functional_model_path,
input_batch,
steps,
args,
@@ -1610,13 +1627,33 @@ def main():
"Raptor PIM compile was skipped because the ONNX model or hardware configuration is not available.",
)
if not reuse_raptor and raptor_pim_dir is not None:
raptor_functional_pim_dir = raptor_pim_dir
if (
not reuse_raptor
and functional_model_path != model_path
and hardware["core_count"] > 0
):
compiled_functional = try_stage(
failures,
"Compile Raptor functional PIM",
compile_raptor_target,
functional_model_path,
out_dir / "raptor_functional",
hardware,
args,
steps,
)
raptor_functional_pim_dir = (
compiled_functional[0] if compiled_functional is not None else None
)
if not reuse_raptor and raptor_functional_pim_dir is not None:
wrote_inputs = try_stage_success(
failures,
"Write Raptor inputs",
write_inputs_to_memory_bin,
raptor_pim_dir / "memory.bin",
raptor_pim_dir / "config.json",
raptor_functional_pim_dir / "memory.bin",
raptor_functional_pim_dir / "config.json",
runtime_inputs,
)
if wrote_inputs and reference_dirs and outputs_desc:
@@ -1625,8 +1662,8 @@ def main():
"Functional Validation Raptor",
run_functional_validation,
"Functional Validation Raptor",
raptor_pim_dir,
raptor_pim_dir / "config.json",
raptor_functional_pim_dir,
raptor_functional_pim_dir / "config.json",
out_dir / "simulation/out.bin",
raptor_input_bins,
outputs_desc,
@@ -1847,6 +1884,7 @@ def main():
json_report = {
"model": str(model_path),
"functional_model": str(functional_model_path),
"hardware": hardware,
"pimsim_mode": args.pimsim_mode,
"pimsim_time_ms": args.pimsim_time_ms,
@@ -1874,6 +1912,7 @@ def main():
"batch_outputs": optional_path(out_dir / "simulation/out_iterations"),
"reference_runner": optional_path(runner_path),
"raptor_pim": optional_path(raptor_pim_dir),
"raptor_functional_pim": optional_path(raptor_functional_pim_dir),
"raptor_pimsim_nn": optional_path(raptor_pimsim_dir),
"pimcomp_simulation_info": optional_path(simulation_info),
"pimcomp_exported_pim": optional_path(pimcomp_export_dir),
@@ -36,6 +36,10 @@ MODELS = {
"googlenet": SUITE / "googlenet/googlenet-12-pimsim-nn.onnx",
"yolo11n": SUITE / "yolo11n/yolo11n-pimsim-nn.onnx",
}
FUNCTIONAL_MODELS = {
**MODELS,
"yolo11n": REPO / "validation/networks/yolo11n/depth_51/yolo11n_depth_51.onnx",
}
COMPARISONS = (
("latency", 1, "element"),
("throughput", 2, "batch"),
@@ -48,6 +52,7 @@ COMPARISONS = (
class ComparisonSpec:
label: str
model: Path
functional_model: Path
output_dir: Path
common_dir: Path
config: Path
@@ -68,6 +73,11 @@ def result_dir(root: Path | None, name: str, arch: str, mode: str, pipeline: int
return base / arch / suffix
def common_dir(root: Path | None, name: str) -> Path:
suffix = "common" if FUNCTIONAL_MODELS[name] == MODELS[name] else "common-functional"
return model_dir(root, name) / suffix
def clean_artifacts(root: Path | None, models: list[str], arches: list[str]) -> int:
removed = 0
for name in models:
@@ -78,10 +88,10 @@ def clean_artifacts(root: Path | None, models: list[str], arches: list[str]) ->
if path.is_dir() and not path.is_symlink():
shutil.rmtree(path)
removed += 1
common = base / "common"
if common.is_dir() and not common.is_symlink():
shutil.rmtree(common)
removed += 1
for common in (base / "common", base / "common-functional"):
if common.is_dir() and not common.is_symlink():
shutil.rmtree(common)
removed += 1
for path in (
(root or SUITE) / "results.csv",
(root or SUITE) / "results_latency.csv",
@@ -316,6 +326,7 @@ def validate_pimcomp_source() -> None:
def comparison_command(
model: Path,
functional_model: Path,
result_dir: Path,
common_dir: Path,
config: Path,
@@ -343,6 +354,8 @@ def comparison_command(
str(COMPARE),
"--model",
str(model),
"--functional-model",
str(functional_model),
"--out-dir",
str(result_dir),
"--common-dir",
@@ -394,6 +407,7 @@ def comparison_command_for(
report = spec.output_dir / "pimcomp/comparison_report.json"
return comparison_command(
spec.model,
spec.functional_model,
spec.output_dir,
spec.common_dir,
spec.config,
@@ -586,7 +600,12 @@ def main() -> int:
comparisons_by_arch[arch] = comparisons
configs_by_arch[arch] = configs
missing = [str(MODELS[name]) for name in args.models if not MODELS[name].exists()]
missing = [
str(path)
for name in args.models
for path in (MODELS[name], FUNCTIONAL_MODELS[name])
if not path.exists()
]
if missing:
parser.error(f"missing model(s): {', '.join(missing)}")
@@ -631,8 +650,8 @@ def main() -> int:
try:
run(
prepare_common_command(
MODELS[name],
model_dir(out_dir, name) / "common",
FUNCTIONAL_MODELS[name],
common_dir(out_dir, name),
args.timeout_seconds,
),
dry_run=args.dry_run,
@@ -660,8 +679,9 @@ def main() -> int:
ComparisonSpec(
label=label,
model=MODELS[name],
functional_model=FUNCTIONAL_MODELS[name],
output_dir=model_result_dir,
common_dir=model_dir(out_dir, name) / "common",
common_dir=common_dir(out_dir, name),
config=configs[mode],
mode=mode,
pipeline=pipeline,