Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude/skills/verify-warpforth/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ description: Drive the real WarpForth toolchain to prove a change works. Compile
WarpForth is a CLI compiler: the user writes a `.forth` kernel, runs `warpforthc` to get PTX, and runs that PTX on an NVIDIA GPU with `warpforth-runner`. There is no server or UI. This machine (macOS) has no CUDA GPU, no `nvcc`, no `ptxas`, so:

- **Local surface** (free, always available): `warpforthc`, `warpforth-translate`, `warpforth-opt`. Proves parsing, diagnostics, lowering, and that PTX is emitted.
- **GPU surface** (costs money, needs `VASTAI_API_KEY`): rents one Vast.ai GPU (cap $0.50/hr, `nvidia/cuda:12.4.0-devel-ubuntu22.04`), builds `warpforth-runner` there with `nvcc`, executes PTX, reads back a buffer. This is the only proof that a kernel computes the right values. **Ask the user before each GPU run**: it spends their money.
- **GPU surface** (costs money, needs `VASTAI_API_KEY`): rents one Vast.ai GPU (cap $0.50/hr, `nvidia/cuda:12.4.0-devel-ubuntu22.04`, host driver must support CUDA 12.4), builds `warpforth-runner` there with `nvcc`, executes PTX, reads back a buffer. This is the only proof that a kernel computes the right values. **Ask the user before each GPU run**: it spends their money.

Other surfaces, not mapped yet: the GPT-2 demo (`demo/`, `docs/demo.md`) needs a PyTorch Vast.ai image and a manual scp.

Expand Down
16 changes: 13 additions & 3 deletions gpu_test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
RUNNER_SRC = PROJECT_ROOT / "tools" / "warpforth-runner" / "warpforth-runner.cpp"

MAX_COST_PER_HOUR = 0.50
CUDA_VERSION = "12.4"
CUDA_IMAGE = f"nvidia/cuda:{CUDA_VERSION}.0-devel-ubuntu22.04"
POLL_INTERVAL_S = 10
POLL_TIMEOUT_S = 300
INSTANCE_LABEL_PREFIX = "warpforth-test-"
Expand Down Expand Up @@ -229,6 +231,7 @@ def _launch(self) -> None:
query = (
f"num_gpus=1 rentable=True rented=False compute_cap>={minimum_compute_capability}"
f" reliability>=0.95 inet_up>=100 dph<={MAX_COST_PER_HOUR}"
f" cuda_max_good>={CUDA_VERSION}"
)
offers = self.sdk.search_offers(query=query, order="dph", limit=5)

Expand All @@ -237,13 +240,20 @@ def _launch(self) -> None:
raise RuntimeError(msg)

offer = offers[0] if isinstance(offers, list) else offers
offer_id = int(offer["id"]) if isinstance(offer, dict) else int(offer)
logger.info("Launching instance from offer %s", offer_id)
details = offer if isinstance(offer, dict) else {"id": offer}
offer_id = int(details["id"])
logger.info(
"Launching instance from offer %s: gpu=%s driver=%s cuda_max_good=%s",
offer_id,
details.get("gpu_name"),
details.get("driver_version"),
details.get("cuda_max_good"),
)
self._creation_ambiguous = True
try:
result = self.sdk.create_instance(
id=offer_id,
image="nvidia/cuda:12.4.0-devel-ubuntu22.04",
image=CUDA_IMAGE,
disk=10.0,
runtype="ssh_direc ssh_proxy",
label=self.instance_label,
Expand Down
13 changes: 13 additions & 0 deletions gpu_test/test_vast_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,19 @@ def test_architecture_constrains_gpu_offer_compute_capability(
assert "compute_cap>=890" in str(sdk.search_calls[0]["query"])


def test_offers_require_a_driver_supporting_the_image_cuda_version(
monkeypatch: pytest.MonkeyPatch,
) -> None:
sdk = FakeVastAI()
configure_session_test(monkeypatch, sdk)

with VastSession("key"):
pass

assert "cuda_max_good>=12.4" in str(sdk.search_calls[0]["query"])
assert str(sdk.create_calls[0]["image"]).startswith("nvidia/cuda:12.4.")


def test_rejected_response_reconciles_without_creating_again(
monkeypatch: pytest.MonkeyPatch,
) -> None:
Expand Down
Loading