Migrates symclaw-gpu from cubecl 0.9 to 0.10 (0.9's cuda backend was upstream-
broken) and fixes the long-standing cpu/cuda-backend failures so all three
backends are green.
cubecl 0.10 API migration (eval/ntt/linalg/groebner/poly_gcd/monte_carlo):
- ArrayArg::from_raw_parts(handle, len) — handle by value, no generic/vectorize.
- read_one -> read_one_unchecked (returns Bytes, matching 0.9 behavior).
- scalar launch args passed as plain values (ScalarArg::new removed).
- launch returns () now: drop .is_ok()/.expect()/`let _ =` on launch results.
Correctness fix (the real bug behind the SIGSEGV + 3 failing NTT tests):
- NTT kernels (butterfly, pointwise_mul, scale) lacked bounds guards. The launch
rounds thread count up to the cube dim, so most threads were padding doing
OUT-OF-BOUNDS reads/writes. wgpu/Vulkan tolerated it; the cuda/cpp backends
corrupted the buffer (garbage NTT results) or SIGSEGV'd. Added `if tid < len`
guards. Also inlined gpu_mod_mul's <<16 reductions (no nested cube-fn calls).
Validated on `tank` (RTX 5060 Ti): wgpu 101/0, CUDA 101/0, cpu 118/0 — clippy
clean on all three. The GPU Monte-Carlo interpreter matches analytic integrals
on both CUDA and wgpu. The prior cpu SIGSEGV and 3 NTT failures are resolved.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The previous gpu_monte_carlo_integrate ignored the device (`let _ = device`)
and ran a CPU loop — a stub. Replace it with a genuine GPU implementation:
- mc_eval_kernel: a per-thread CubeCL bytecode INTERPRETER. Each thread samples
the variables (hashed RNG), then walks the uploaded stack-machine program
(encoded ops + f32 const pool) with a private stack, supporting all opcodes
(load var/const, +−×÷, pow via exp·ln, neg, sin/cos/tan, exp, ln, sqrt, abs).
Host reduces the per-sample values → integral.
- cpu_monte_carlo_integrate_nd: the real CPU path (kept, not a stub), used on
the CPU backend or when the program/var count exceeds the kernel's comptime
stack/var limits.
- gpu_monte_carlo_integrate[_nd] now dispatch: GPU kernel on GPU backends
(CUDA/wgpu), CPU loop otherwise. Both are full implementations.
Verified on `tank` (wgpu/Vulkan, SYMCLAW_GPU_TEST=1): the kernel computes
∫₀¹x² dx ≈ 1/3 and ∫₀^π sin x dx ≈ 2 at 1e6 samples. Full default (wgpu) suite
101/101 green; monte_carlo cpu tests 4/4.
Notes: symclaw-gpu is on cubecl 0.9, whose `cuda` backend is upstream-broken;
running symclaw's GPU MC on CUDA needs a cubecl 0.9→0.10 migration of all
symclaw-gpu modules (separate effort) — wgpu already runs on the NVIDIA GPU.
Pre-existing cubecl-cpu software-runtime failures in ntt/eval/poly_gcd are
unrelated to this change.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>