From 7f82c2fcf0189226a048486f18f81a3bd099be2a Mon Sep 17 00:00:00 2001 From: ghangz <152254226+ghangz@users.noreply.github.com> Date: Wed, 1 Jul 2026 11:42:50 +0800 Subject: [PATCH 1/2] Add MACA environment doctor --- tools/maca_env_doctor.py | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 tools/maca_env_doctor.py diff --git a/tools/maca_env_doctor.py b/tools/maca_env_doctor.py new file mode 100644 index 0000000..04d6b3f --- /dev/null +++ b/tools/maca_env_doctor.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +"""Collect a lightweight MACA runtime environment report.""" + +from __future__ import annotations + + +import argparse +import json +import os +import shutil +import subprocess +from pathlib import Path + + +DEFAULT_PATHS = ['/opt/maca', '/opt/maca-3.1.0'] + + +def command_output(cmd: list[str]) -> dict[str, object]: + executable = shutil.which(cmd[0]) + if executable is None: + return {"command": cmd, "available": False, "stdout": "", "stderr": "", "returncode": None} + proc = subprocess.run(cmd, text=True, encoding="utf-8", errors="replace", capture_output=True) + return { + "command": cmd, + "available": True, + "stdout": proc.stdout.strip(), + "stderr": proc.stderr.strip(), + "returncode": proc.returncode, + } + + +def collect(extra_paths: list[str]) -> dict[str, object]: + search_paths = [p for p in [*DEFAULT_PATHS, *extra_paths] if p] + existing = [str(Path(p).resolve()) for p in search_paths if Path(p).exists()] + env_names = ["MACA_HOME", "MATRIX_HOME", "LD_LIBRARY_PATH", "PATH", "PYTHONPATH"] + return { + "environment": {name: os.environ.get(name, "") for name in env_names}, + "existing_paths": existing, + "tools": { + "mx-smi": command_output(["mx-smi"]), + "mxcc": command_output(["mxcc", "--version"]), + "python": command_output(["python3", "--version"]), + }, + } + + +def self_test() -> None: + data = collect([]) + assert "tools" in data + assert "environment" in data + print(json.dumps({"ok": True, "tool_count": len(data["tools"])}, ensure_ascii=False)) + + +def main() -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--path", action="append", default=[], help="Additional path to include in the report.") + parser.add_argument("--self-test", action="store_true", help="Run a no-GPU sanity check.") + args = parser.parse_args() + if args.self_test: + self_test() + return 0 + print(json.dumps(collect(args.path), ensure_ascii=False, indent=2)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From dcb2c3d8cd6b9ef96e55886f93c6630f5c896c21 Mon Sep 17 00:00:00 2001 From: ghangz <152254226+ghangz@users.noreply.github.com> Date: Wed, 1 Jul 2026 15:45:17 +0800 Subject: [PATCH 2/2] Handle tool launch errors in env doctor --- tools/maca_env_doctor.py | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/tools/maca_env_doctor.py b/tools/maca_env_doctor.py index 04d6b3f..4413594 100644 --- a/tools/maca_env_doctor.py +++ b/tools/maca_env_doctor.py @@ -12,14 +12,35 @@ from pathlib import Path -DEFAULT_PATHS = ['/opt/maca', '/opt/maca-3.1.0'] +DEFAULT_PATHS = ["/opt/maca", "/opt/maca-3.1.0"] def command_output(cmd: list[str]) -> dict[str, object]: executable = shutil.which(cmd[0]) if executable is None: - return {"command": cmd, "available": False, "stdout": "", "stderr": "", "returncode": None} - proc = subprocess.run(cmd, text=True, encoding="utf-8", errors="replace", capture_output=True) + return { + "command": cmd, + "available": False, + "stdout": "", + "stderr": "", + "returncode": None, + } + try: + proc = subprocess.run( + cmd, + text=True, + encoding="utf-8", + errors="replace", + capture_output=True, + ) + except OSError as exc: + return { + "command": cmd, + "available": True, + "stdout": "", + "stderr": str(exc), + "returncode": None, + } return { "command": cmd, "available": True, @@ -46,8 +67,8 @@ def collect(extra_paths: list[str]) -> dict[str, object]: def self_test() -> None: data = collect([]) - assert "tools" in data - assert "environment" in data + if "tools" not in data or "environment" not in data: + raise RuntimeError(f"self-test failed: {data}") print(json.dumps({"ok": True, "tool_count": len(data["tools"])}, ensure_ascii=False))