Code / benchmarks/hardware_manifest.py

benchmarks/hardware_manifest.py 147 lines
#!/usr/bin/env python3
# =============================================================================
#  Project   : localvm-research
#  File      : benchmarks/hardware_manifest.py
#  Purpose   : macOS hardware/software fingerprint embedded in every result file
#  Author    : Simon-Pierre Boucher
#  Contact   : contact@spboucher.ai
#  Created   : 2026-08-11
#  Modified  : 2026-08-11
#  Platform  : macOS / Apple Silicon (arm64)
#  License   : All rights reserved (research code)
# =============================================================================
"""Collect a reproducibility manifest for the current Mac.

Records chip model, P/E core counts, GPU core count, unified memory size,
SSD model, macOS version, and versions of the key software stack (Python,
MLX, PyTorch, NumPy), plus the current git commit. Every benchmark result
JSON must embed this manifest (CLAUDE.md §0.2, §10).

Usage:
    python3 benchmarks/hardware_manifest.py            # pretty-print JSON
    from hardware_manifest import collect_manifest     # programmatic use
"""

from __future__ import annotations

import json
import platform
import subprocess
import sys
from datetime import datetime, timezone


def _run(cmd: list[str]) -> str:
    try:
        return subprocess.run(cmd, capture_output=True, text=True, timeout=30).stdout.strip()
    except (OSError, subprocess.TimeoutExpired):
        return ""


def _sysctl(key: str) -> str:
    return _run(["sysctl", "-n", key])


def _sysctl_int(key: str) -> int | None:
    val = _sysctl(key)
    try:
        return int(val)
    except ValueError:
        return None


def _gpu_cores() -> int | None:
    """GPU core count via system_profiler (no sysctl key exposes it)."""
    out = _run(["system_profiler", "SPDisplaysDataType", "-json"])
    try:
        displays = json.loads(out)["SPDisplaysDataType"]
        for gpu in displays:
            cores = gpu.get("sppci_cores")
            if cores is not None:
                return int(cores)
    except (json.JSONDecodeError, KeyError, ValueError, TypeError):
        pass
    return None


def _ssd_info() -> dict:
    out = _run(["system_profiler", "SPNVMeDataType", "-json"])
    try:
        items = json.loads(out)["SPNVMeDataType"]
        for controller in items:
            for dev in controller.get("_items", []):
                return {
                    "model": dev.get("device_model", "").strip(),
                    "size": dev.get("size", ""),
                    "smart_status": dev.get("smart_status", ""),
                }
    except (json.JSONDecodeError, KeyError, TypeError):
        pass
    return {"model": None, "size": None, "smart_status": None}


def _pkg_version(module: str) -> str | None:
    try:
        from importlib.metadata import version

        return version(module)
    except Exception:
        return None


def _git_commit() -> dict:
    commit = _run(["git", "rev-parse", "HEAD"])
    dirty = bool(_run(["git", "status", "--porcelain"]))
    return {"commit": commit or None, "dirty_tree": dirty}


def _thermal_state() -> str | None:
    # 'thermal pressure' via thermal level sysctl where available
    lvl = _sysctl("machdep.xcpm.cpu_thermal_level")
    return lvl or None


def collect_manifest() -> dict:
    """Return the full hardware/software manifest as a dict."""
    mem_bytes = _sysctl_int("hw.memsize") or 0
    manifest = {
        "author": "Simon-Pierre Boucher",
        "contact": "contact@spboucher.ai",
        "project": "localvm-research",
        "collected_utc": datetime.now(timezone.utc).isoformat(),
        "chip": {
            "brand": _sysctl("machdep.cpu.brand_string"),
            "arch": platform.machine(),
            "cores_total": _sysctl_int("hw.ncpu"),
            "cores_performance": _sysctl_int("hw.perflevel0.physicalcpu"),
            "cores_efficiency": _sysctl_int("hw.perflevel1.physicalcpu"),
            "gpu_cores": _gpu_cores(),
        },
        "memory": {
            "unified_bytes": mem_bytes,
            "unified_gb": round(mem_bytes / 2**30, 1),
            "pagesize": _sysctl_int("hw.pagesize"),
        },
        "ssd": _ssd_info(),
        "os": {
            "product": _run(["sw_vers", "-productName"]),
            "version": _run(["sw_vers", "-productVersion"]),
            "build": _run(["sw_vers", "-buildVersion"]),
            "kernel": platform.release(),
        },
        "software": {
            "python": sys.version.split()[0],
            "mlx": _pkg_version("mlx"),
            "mlx_lm": _pkg_version("mlx-lm"),
            "torch": _pkg_version("torch"),
            "numpy": _pkg_version("numpy"),
        },
        "git": _git_commit(),
        "thermal_level_at_collect": _thermal_state(),
    }
    return manifest


if __name__ == "__main__":
    print(json.dumps(collect_manifest(), indent=2))