FE-1340: Add an experimental WebGPU compute backend for experiments - #9179
Draft
kube wants to merge 1 commit into
Draft
FE-1340: Add an experimental WebGPU compute backend for experiments#9179kube wants to merge 1 commit into
kube wants to merge 1 commit into
Conversation
One GPU invocation per run, stepping the whole net on the device, with WGSL generated from the net's lowered HIR so user code executes rather than being interpreted per frame. Metrics reduce on-GPU into per-frame histograms and only a compact per-run summary is read back. A subset engine, asked rather than told: it reports whether it can run a net, and one it cannot take falls back to the CPU with the reason recorded. Typed places need capacities, arcs consume at most two typed tokens, and a weight-2 pairwise condition is scanned over every pair by unranking, preserving the CPU's firing order. Results are not seed-identical — WebGPU cannot reproduce the CPU generator — so the backend that ran each experiment is recorded.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
Comment on lines
+647
to
+650
| const value = this.emit(expr, env); | ||
| const literal = /^-?\d+(?:\.0)?$/u.exec( | ||
| value.kind === "f32" ? value.code : "", | ||
| ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🌟 What is the purpose of this PR?
An experiment's runs are independent, which makes them a natural fit for a GPU: one invocation per run, stepping the whole net on the device.
This adds an experimental WebGPU backend that generates WGSL from the net's lowered HIR — the same HIR the CPU engine compiles to buffer programs — so dynamics, firing rates and transition kernels execute on the device rather than being interpreted per frame. Metrics reduce on-GPU into per-frame histograms, and only a compact per-run summary is read back.
It is opt-in per experiment and falls back to the CPU, with the reason recorded, for any net it cannot take.
🔗 Related links
libs/@hashintel/petrinaut-core/docs/simulation-performance.md§8 — the measurements and the design decisions behind this🚫 Blocked by
🔍 What does this change?
A subset engine, asked rather than told. It reports whether it can run a net before an experiment starts, through the contract added in #9178, and a net it declines runs on the CPU instead. Requirements it enforces:
stringoruuidtoken attributes, which need more than the 32 bits WGSL offers;Run state never leaves the device. The host decodes only each run's place counts and status, so the shader writes those into a compact summary buffer. Reading the full state back needed host-visible memory equal to the state itself, which capped a 3112-byte-per-run net at ~689k runs; the summary is ~16 bytes per run.
Device limits are requested, not defaulted.
requestDevice()withoutrequiredLimitsreturns the WebGPU floor — 128 MiB per storage binding — regardless of hardware. An Apple metal-3 adapter reports 4096 MiB for both limits that bind here.Supporting surfaces: a per-experiment backend toggle in the create-experiment drawer, and a Compilation panel (behind a user setting) reporting what the compiler made of each condition, kernel and equation, and what stops a net running on the GPU.
Pre-Merge Checklist 🚀
🚢 Has this modified a publishable library?
This PR:
📜 Does this require a change to the docs?
The changes in this PR:
🕸️ Does this require a change to the Turbo Graph?
The changes in this PR:
web-nagaas a wasm devDependency, or Dawn viawebgpuwith a null backend) can run headlessly in vitest; not wired up here.maxStorageBufferBindingSize. Removing that bound means chunking the dispatch.🐾 Next steps
WGSL validation in the test suite; dispatch chunking; a token-reducing metric kind so expression-style metrics have a GPU-serviceable equivalent.
🛡 What tests cover this?
compile-net-shader.test.ts(shader generation, the summary ABI, and a naga-calibrated same-scope redeclaration check across all three ODE methods),eligibility.test.ts,compilation-report.test.ts,pair-selection.test.ts(pair ordering against the engine's own enumerator),emit-wgsl.test.ts,runner.test.ts(buffer-limit arithmetic, chunked seeding, device limits). Verified end to end on a real adapter: 4096 SIR runs dispatch with no validation or uncaptured errors and decode correctly.❓ How to test this?