ONNX
onnxruntime
onnx-mlir
quantization
fp32
ONNX_Models / scripts /validate_mlir_ir_graphs.py
purejomo's picture
Finalize public ONNX/ONNX-MLIR validation release
ed3aeeb
Raw
History Blame Contribute Delete
6.77 kB
#!/usr/bin/env python3
"""Validate the 42 published ONNX Dialect execution-dependency graphs."""
from __future__ import annotations
import argparse
import csv
import json
import sys
import xml.etree.ElementTree as ET
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
REPO_ROOT = Path(__file__).resolve().parents[1]
if str(REPO_ROOT) not in sys.path:
sys.path.insert(0, str(REPO_ROOT))
from scripts.mlir_graph_common import (
VARIANTS,
atomic_json,
resolve_coverage_path,
sha256,
)
def utc_now() -> str:
return datetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z")
def normalize_variant(value: str) -> str:
return "public_quantized" if value in {"quantized", "public_quantized"} else value
def read_rows(path: Path) -> list[dict[str, str]]:
with path.open(newline="", encoding="utf-8") as stream:
return list(csv.DictReader(stream))
def validate(args: argparse.Namespace) -> tuple[dict[str, Any], int]:
root = args.repo_root.resolve()
report_dir = (root / args.report_dir).resolve() if not args.report_dir.is_absolute() else args.report_dir.resolve()
matrix = (root / args.coverage_matrix).resolve() if not args.coverage_matrix.is_absolute() else args.coverage_matrix.resolve()
output = (root / args.output).resolve() if not args.output.is_absolute() else args.output.resolve()
for path in (report_dir, matrix, output.parent):
try:
path.relative_to(root)
except ValueError as error:
raise SystemExit(f"path outside repository root: {path}") from error
checks: list[dict[str, Any]] = []
def check(name: str, passed: bool, detail: Any = None) -> None:
checks.append({"name": name, "status": "PASS" if passed else "FAIL", "detail": detail})
rows = read_rows(matrix)
keyed: dict[tuple[str, str], dict[str, str]] = {}
for row in rows:
variant = normalize_variant(row.get("variant", ""))
key = (row.get("model_id", ""), variant)
check("unique_matrix_row", key not in keyed, {"key": key})
keyed[key] = row
model_ids = sorted({model_id for model_id, _ in keyed})
check("matrix_variant_count", len(keyed) == 42, len(keyed))
check("matrix_model_count", len(model_ids) == 21, len(model_ids))
check(
"matrix_pair_completeness",
all((model_id, variant) in keyed for model_id in model_ids for variant in VARIANTS),
)
expected_svg: set[Path] = set()
expected_png: set[Path] = set()
for model_id in model_ids:
for variant in VARIANTS:
row = keyed.get((model_id, variant))
if row is None:
continue
context = f"{model_id}:{variant}"
check("onnx_dialect_status", row.get("onnx_status") == "PASS", {"graph": context, "status": row.get("onnx_status")})
try:
source = resolve_coverage_path(row.get("onnx_artifact", ""), root)
source_ok = source.is_file() and sha256(source) == row.get("onnx_sha256")
except (OSError, ValueError) as error:
source_ok = False
source = Path(row.get("onnx_artifact", ""))
check("onnx_source_resolution", False, {"graph": context, "error": str(error)})
else:
check("onnx_source_checksum", source_ok, {"graph": context, "source": str(source)})
graph_dir = report_dir / "graphs" / model_id / variant / "onnx"
svg = graph_dir / "execution_dependency_graph.svg"
png = graph_dir / "execution_dependency_graph.png"
expected_svg.add(svg)
expected_png.add(png)
try:
svg_text = svg.read_text(encoding="utf-8")
ET.fromstring(svg_text)
svg_ok = "STATIC_MLIR_PROGRAM_ORDER" in svg_text and f"{model_id}:{variant}:ONNX" in svg_text
except (OSError, ET.ParseError) as error:
svg_ok = False
check("svg_read", False, {"graph": context, "error": str(error)})
else:
check("svg_semantics", svg_ok, context)
try:
with png.open("rb") as stream:
png_ok = stream.read(8) == b"\x89PNG\r\n\x1a\n" and png.stat().st_size > 8
except OSError as error:
png_ok = False
check("png_read", False, {"graph": context, "error": str(error)})
else:
check("png_signature", png_ok, context)
actual_svg = set(report_dir.glob("graphs/*/*/*/execution_dependency_graph.svg"))
actual_png = set(report_dir.glob("graphs/*/*/*/execution_dependency_graph.png"))
check("exact_svg_set", actual_svg == expected_svg, {"expected": 42, "actual": len(actual_svg)})
check("exact_png_set", actual_png == expected_png, {"expected": 42, "actual": len(actual_png)})
check("no_affine_graphs", not any("affine_scf_memref" in path.parts for path in report_dir.rglob("*")))
check("no_internal_graph_records", not any(report_dir.rglob("graph_record*.json")))
failed = [row for row in checks if row["status"] != "PASS"]
result = {
"schema_version": "1.0",
"stage": "ONNX_DIALECT_PRIMARY_GRAPH_VALIDATION",
"status": "PASS" if not failed else "FAIL",
"generated_at": utc_now(),
"counts": {
"models": len(model_ids),
"variants": len(keyed),
"svg": len(actual_svg),
"png": len(actual_png),
"checks": len(checks),
"failed": len(failed),
},
"checks": checks,
"policy": {
"primary_graph_stage": "ONNX_DIALECT",
"order_semantics": "STATIC_MLIR_PROGRAM_ORDER",
"supplemental_lower_graphs_included": False,
"model_runtime_run": False,
"mlir_toolchain_run": False,
},
}
output.parent.mkdir(parents=True, exist_ok=True)
atomic_json(output, result)
return result, 0 if result["status"] == "PASS" else 1
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--repo-root", type=Path, default=REPO_ROOT)
parser.add_argument("--report-dir", type=Path, default=Path("reports/graphs/mlir"))
parser.add_argument("--coverage-matrix", type=Path, default=Path("reports/conversion/ir_stage_coverage.csv"))
parser.add_argument("--output", type=Path, required=True)
args = parser.parse_args()
result, exit_code = validate(args)
print(json.dumps({"status": result["status"], "counts": result["counts"]}, ensure_ascii=False, sort_keys=True))
return exit_code
if __name__ == "__main__":
raise SystemExit(main())