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,
}