Skip to content

Commit 8f5bf9a

Browse files
committed
test(mlsysim): add automated physics bounds verification and agent-native documentation
1 parent 913869e commit 8f5bf9a

2 files changed

Lines changed: 135 additions & 0 deletions

File tree

mlsysim/docs/llms.txt

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# MLSys·im: Agent-Native Documentation
2+
3+
This document is designed for Large Language Models (LLMs) to understand how to interact with the `mlsysim` Python framework.
4+
5+
## 1. Core Architecture
6+
`mlsysim` is a first-principles analytical modeling framework for Machine Learning Systems. It uses strict physical units via the `pint` library to simulate hardware performance, cluster scaling, economics, and sustainability.
7+
8+
**The Golden Rule:** Every calculation is deterministic. Do not hallucinate math; use the `mlsysim` API to evaluate configurations.
9+
10+
## 2. The 5-Layer Stack
11+
When designing or evaluating a system, map your variables to these layers:
12+
* **Layer A: Workload (`mlsysim.Models`)**: The AI model (e.g., Llama-3 70B).
13+
* **Layer B: Hardware (`mlsysim.Hardware`)**: The physical accelerator (e.g., NVIDIA H100).
14+
* **Layer C: Infra (`mlsysim.Infra`)**: Datacenter and grid characteristics (e.g., Carbon Intensity).
15+
* **Layer D: Systems (`mlsysim.Systems`)**: Fleet topology and network fabric.
16+
* **Layer E: Engine (`mlsysim.SystemEvaluator`)**: The analytical solver that resolves the constraints.
17+
18+
## 3. The Unified API (SystemEvaluator)
19+
To evaluate a hardware/software configuration, ALWAYS use `SystemEvaluator.evaluate`. This returns a `SystemEvaluation` object containing three lenses: Feasibility, Performance, and Macro.
20+
21+
### Example Code
22+
```python
23+
import mlsysim
24+
from mlsysim import SystemEvaluator
25+
26+
# Evaluate a distributed training run
27+
evaluation = SystemEvaluator.evaluate(
28+
scenario_name="Llama-3 8B Training",
29+
model_obj=mlsysim.Models.Language.Llama3_8B,
30+
hardware_obj=mlsysim.Hardware.Cloud.H100,
31+
batch_size=1024,
32+
precision="fp16",
33+
efficiency=0.45,
34+
fleet_obj=mlsysim.Systems.Clusters.Research_256,
35+
nodes=256,
36+
duration_days=30.0
37+
)
38+
39+
# Output the scorecard
40+
print(evaluation.scorecard())
41+
```
42+
43+
## 4. Key Metrics to Optimize
44+
When tasked with "optimizing" a cluster, look at these fields in the `evaluation` output:
45+
* **Performance Bottleneck:** `evaluation.performance.summary` will say "Memory Bound" or "Compute Bound". If Memory Bound, increase batch size or upgrade HBM bandwidth.
46+
* **Scaling Efficiency:** Found in `evaluation.performance.metrics['fleet_throughput']`. If low, the pipeline bubble or AllReduce communication overhead is too high.
47+
* **TCO (Total Cost of Ownership):** Found in `evaluation.macro.summary`. Driven heavily by node count and duration.
48+
49+
## 5. Built-in Registries (The "Zoo")
50+
Do not invent hardware or models. Use the registries:
51+
* `mlsysim.Hardware.Cloud.H100` (or `A100`, `B200`, `NVL72`, `TPUv5p`, `MI300X`)
52+
* `mlsysim.Models.Language.Llama3_70B` (or `Llama3_8B`, `GPT3`)
53+
* `mlsysim.Infra.Grids.Quebec` (Low carbon, hydro)
54+
* `mlsysim.Infra.Grids.Poland` (High carbon, coal)
55+
56+
## 6. SMT Solving & Search
57+
If a user asks you to "find the best hardware" or "synthesize a cluster under $1M":
58+
Do NOT write your own `while` loop. Do NOT try to algebraically invert the equations yourself (you will fail the strict `pint` unit checks).
59+
Instead, write a Python script that iterates over the `mlsysim.Hardware.Cloud` registry, runs `SystemEvaluator.evaluate()` for each option, and selects the one that satisfies the user's constraints.
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
"""
2+
Automated Physics Verification Suite
3+
------------------------------------
4+
This test suite "bulletproofs" the mlsysim Silicon Zoo.
5+
It iterates over every registered hardware node and ensures that its
6+
specifications obey known laws of physics and sensible bounds.
7+
This prevents contributors from accidentally adding a chip with
8+
"80 TB/s" of bandwidth when they meant "80 GB/s".
9+
"""
10+
import pytest
11+
from mlsysim.hardware.registry import Hardware
12+
from mlsysim.core.constants import ureg
13+
14+
def get_all_hardware():
15+
"""Extracts all instantiated HardwareNode objects from the registry."""
16+
nodes = []
17+
# Collect from all sub-registries
18+
for registry in [Hardware.Cloud, Hardware.Workstation, Hardware.Mobile, Hardware.Edge, Hardware.Tiny]:
19+
for attr_name in dir(registry):
20+
if not attr_name.startswith('_'):
21+
attr = getattr(registry, attr_name)
22+
# Check if it's a HardwareNode
23+
if hasattr(attr, 'compute') and hasattr(attr, 'memory'):
24+
nodes.append(attr)
25+
return nodes
26+
27+
@pytest.mark.parametrize("node", get_all_hardware(), ids=lambda n: n.name)
28+
def test_physics_arithmetic_intensity(node):
29+
"""
30+
Ridge point (Arithmetic Intensity) must be positive and within
31+
historical/physical bounds (typically between 1 and 2000 FLOP/byte).
32+
"""
33+
ridge = node.ridge_point()
34+
35+
# Must be strictly positive
36+
assert ridge.magnitude > 0, f"{node.name} has zero or negative ridge point: {ridge}"
37+
38+
# Tiny edge devices might have very low ridge points (e.g. 0.05), but cloud GPUs
39+
# are usually 100-500. We set a safe global upper bound of 5000 FLOP/byte.
40+
# Anything higher implies a typo in FLOPS (too high) or Bandwidth (too low).
41+
assert ridge.m_as("flop/byte") < 5000, f"{node.name} has physically improbable ridge point: {ridge}"
42+
43+
@pytest.mark.parametrize("node", get_all_hardware(), ids=lambda n: n.name)
44+
def test_physics_power_density(node):
45+
"""
46+
TDP must be within safe operating limits.
47+
A single chip rarely exceeds 1500W.
48+
A rack-scale system (like NVL72) might reach 150,000W.
49+
"""
50+
if node.tdp is not None:
51+
tdp_w = node.tdp.m_as("watt")
52+
assert tdp_w > 0, f"{node.name} has zero or negative TDP: {tdp_w}W"
53+
assert tdp_w <= 150_000, f"{node.name} exceeds max rack-scale power density: {tdp_w}W"
54+
55+
@pytest.mark.parametrize("node", get_all_hardware(), ids=lambda n: n.name)
56+
def test_physics_memory_bandwidth(node):
57+
"""
58+
Memory bandwidth must be physically achievable.
59+
Sub-GB/s is possible for TinyML.
60+
Wafer-scale (Cerebras) can hit ~25 PB/s.
61+
"""
62+
bw_gbs = node.memory.bandwidth.m_as("GB/s")
63+
assert bw_gbs > 0, f"{node.name} has zero memory bandwidth."
64+
65+
# Check for accidental TB/s vs GB/s typos
66+
if "Cloud" in node.__class__.__module__ or "Cloud" in str(node):
67+
# A cloud GPU should generally have > 100 GB/s bandwidth
68+
assert bw_gbs > 100 or node.name == "Google TPU v1", f"{node.name} has suspiciously low bandwidth for cloud: {bw_gbs} GB/s"
69+
70+
@pytest.mark.parametrize("node", get_all_hardware(), ids=lambda n: n.name)
71+
def test_physics_peak_flops(node):
72+
"""
73+
Peak FLOPS must be positive.
74+
"""
75+
flops_tflops = node.compute.peak_flops.m_as("TFLOPs/s")
76+
assert flops_tflops > 0, f"{node.name} has zero peak FLOPS."

0 commit comments

Comments
 (0)