From 989bdbb0ffef595c0c3483bd5c2c222324e94238 Mon Sep 17 00:00:00 2001 From: Alex Cameron Date: Sat, 24 Oct 2026 21:48:16 +1100 Subject: [PATCH 1/2] test(gpu_test): require offers whose driver supports the image CUDA version --- gpu_test/test_vast_session.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/gpu_test/test_vast_session.py b/gpu_test/test_vast_session.py index 3df0128..9db0a6d 100644 --- a/gpu_test/test_vast_session.py +++ b/gpu_test/test_vast_session.py @@ -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: From 129ee0d999a9d45f32c6dcabd08af1bf6ad833e3 Mon Sep 17 00:00:00 2001 From: Alex Cameron Date: Sat, 24 Oct 2026 21:48:16 +1100 Subject: [PATCH 2/2] fix(gpu_test): skip Vast.ai hosts whose driver predates CUDA 12.4 Hosts with an older driver load the image's forward-compatibility libcuda, which fails with CUDA error 804 on consumer GPUs. Filter offers on cuda_max_good and log the rented GPU, driver and max CUDA version. Fixes #131 --- .claude/skills/verify-warpforth/SKILL.md | 2 +- gpu_test/conftest.py | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.claude/skills/verify-warpforth/SKILL.md b/.claude/skills/verify-warpforth/SKILL.md index 0fcae95..13312e1 100644 --- a/.claude/skills/verify-warpforth/SKILL.md +++ b/.claude/skills/verify-warpforth/SKILL.md @@ -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. diff --git a/gpu_test/conftest.py b/gpu_test/conftest.py index 8578f5b..70f843b 100644 --- a/gpu_test/conftest.py +++ b/gpu_test/conftest.py @@ -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-" @@ -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) @@ -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,