113 lines
4.5 KiB
Python
113 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
"""DGR-030: native CI/build matrix over the CPU default plus accelerator lanes.
|
|
|
|
Runs the exact deterministic CPU lane DGR-029 locked (unchanged), then probes
|
|
each accelerator preset (CUDA, ROCm, Vulkan, Metal) from `UPSTREAM_LOCK.json`
|
|
and compiles the ones whose SDK is present on this machine into their own
|
|
out-of-tree build directory.
|
|
|
|
A lane whose SDK is absent is reported as `skipped` with the exact probe
|
|
reason, never treated as a false pass. A lane that compiles is reported as
|
|
`built`, carrying exact compiler/SDK/upstream-pin/patch-stack/build-option
|
|
evidence — never as a certified capability. This script never runs an
|
|
accelerator binary and never certifies a backend/model/recipe: real-hardware
|
|
certification is separate future work (DGR-041/053/067).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import pathlib
|
|
import sys
|
|
from typing import Any
|
|
|
|
ROOT = pathlib.Path(__file__).resolve().parents[1]
|
|
sys.path.insert(0, str(ROOT / "scripts"))
|
|
import llama_cpp_dependency as dep # noqa: E402
|
|
|
|
|
|
def _cpu_lane(source: pathlib.Path, workspace: pathlib.Path) -> dict[str, Any]:
|
|
build_dir = workspace.resolve() / "build"
|
|
if build_dir.exists():
|
|
return {
|
|
"lane": "cpu",
|
|
"status": "skipped",
|
|
"reason": f"build directory already exists; remove for a clean rebuild: {build_dir}",
|
|
}
|
|
binary = dep.build(source, build_dir)
|
|
dep.smoke(binary)
|
|
dep.ctest_lane(build_dir)
|
|
metadata = json.loads((build_dir / "meshnet-build-metadata.json").read_text())
|
|
return {"lane": "cpu", "status": "built", "build_dir": str(build_dir), "metadata": metadata}
|
|
|
|
|
|
def _accelerator_lane(source: pathlib.Path, workspace: pathlib.Path, name: str, lock: dict[str, Any]) -> dict[str, Any]:
|
|
status = dep.accelerator_status(name, lock)
|
|
if not status["available"]:
|
|
return {"lane": name, "status": "skipped", "reason": status["reason"]}
|
|
build_dir = workspace.resolve() / f"build-{name}"
|
|
if build_dir.exists():
|
|
return {
|
|
"lane": name,
|
|
"status": "skipped",
|
|
"reason": f"build directory already exists; remove for a clean rebuild: {build_dir}",
|
|
}
|
|
dep.accelerator_build(source, name, build_dir)
|
|
metadata = json.loads((build_dir / "meshnet-build-metadata.json").read_text())
|
|
return {"lane": name, "status": "built", "build_dir": str(build_dir), "metadata": metadata}
|
|
|
|
|
|
def run_matrix(workspace: pathlib.Path) -> dict[str, Any]:
|
|
"""Fetch/apply once, run every lane, then always reverse the checkout."""
|
|
source = dep.fetch(workspace)
|
|
dep.apply(source)
|
|
lanes: list[dict[str, Any]] = []
|
|
try:
|
|
lock = dep._load_lock()
|
|
try:
|
|
lanes.append(_cpu_lane(source, workspace))
|
|
except dep.DependencyError as error:
|
|
lanes.append({"lane": "cpu", "status": "failed", "reason": str(error)})
|
|
for name in lock.get("accelerator_presets", {}):
|
|
try:
|
|
lanes.append(_accelerator_lane(source, workspace, name, lock))
|
|
except dep.DependencyError as error:
|
|
lanes.append({"lane": name, "status": "failed", "reason": str(error)})
|
|
finally:
|
|
dep.reverse(source)
|
|
failed_lanes = [lane["lane"] for lane in lanes if lane["status"] == "failed"]
|
|
return {
|
|
"lanes": lanes,
|
|
"hardware_certified": False,
|
|
"note": (
|
|
"A `built` lane means it compiled with the exact recorded compiler/SDK/"
|
|
"upstream-pin/patch-stack/build-option evidence — it never means an "
|
|
"accelerator device was exercised. Every backend/model/recipe lane "
|
|
"stays registered-dark until a separate real-hardware certification "
|
|
"record exists."
|
|
),
|
|
"failed_lanes": failed_lanes,
|
|
}
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--workspace", type=pathlib.Path, default=ROOT / "build/llama.cpp")
|
|
parser.add_argument("--out", type=pathlib.Path, default=None, help="also write the JSON report here")
|
|
args = parser.parse_args()
|
|
try:
|
|
report = run_matrix(args.workspace)
|
|
except dep.DependencyError as error:
|
|
print(f"DGR-030 dependency error: {error}", file=sys.stderr)
|
|
return 2
|
|
text = json.dumps(report, indent=2, sort_keys=True)
|
|
print(text)
|
|
if args.out:
|
|
args.out.write_text(text + "\n")
|
|
return 1 if report["failed_lanes"] else 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|