File size: 1,781 Bytes
3e77c56 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | """Run logging: every run writes a JSON ``{config, git_commit, seed, final_metrics,
wall_clock, gpu, est_cost}`` to ``results/`` (master plan §0.2 principle 3)."""
from __future__ import annotations
import json
import os
import subprocess
from typing import Any, Dict, Optional
def git_commit(default: str = "unknown") -> str:
try:
out = subprocess.check_output(
["git", "rev-parse", "HEAD"], stderr=subprocess.DEVNULL
)
return out.decode().strip()
except Exception:
return default
def write_run_log(
path: str,
config: Dict[str, Any],
seed: int,
final_metrics: Dict[str, Any],
wall_clock_sec: float,
gpu: str,
est_cost_usd: float,
extra: Optional[Dict[str, Any]] = None,
) -> str:
"""Write a single run record as JSON and return the path."""
record = {
"config": config,
"git_commit": git_commit(),
"seed": seed,
"final_metrics": final_metrics,
"wall_clock_sec": round(float(wall_clock_sec), 2),
"gpu": gpu,
"est_cost_usd": round(float(est_cost_usd), 4),
}
if extra:
record.update(extra)
os.makedirs(os.path.dirname(path) or ".", exist_ok=True)
with open(path, "w") as f:
json.dump(record, f, indent=2)
return path
def estimate_cost(wall_clock_sec: float, rate_per_sec: float) -> float:
"""GPU cost estimate = wall-clock seconds x per-second rate (master plan §2.7)."""
return wall_clock_sec * rate_per_sec
# Modal per-second GPU rates (USD), from master plan §2.7 (modal.com/pricing, June 2026).
MODAL_RATES_PER_SEC = {
"A10": 0.000306,
"A100-40GB": 0.000583,
"A100-80GB": 0.000694,
"H100": 0.001097,
"L4": 0.000222,
"T4": 0.000164,
"CPU": 0.0,
}
|