Skip to content

GPU plotting via wgpu (Vulkan/Metal), backed by abundance's proof-of-space - #3883

Open
vedhavyas wants to merge 19 commits into
mainfrom
feat/wgpu-plotter-gpu-clean
Open

GPU plotting via wgpu (Vulkan/Metal), backed by abundance's proof-of-space#3883
vedhavyas wants to merge 19 commits into
mainfrom
feat/wgpu-plotter-gpu-clean

Conversation

@vedhavyas

@vedhavyas vedhavyas commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

This brings GPU plotting to the farmer through wgpu: one farmer binary plots on Vulkan and Metal (macOS included) with a CPU fallback. It retires the vendor-specific CUDA and ROCm plotters, which wgpu replaces.

The proof-of-space comes from abundance, vendored into the tree rather than pulled as a git dependency - its CPU and GPU proof-of-space crates are copied into shared/, re-pointed at our own core primitives, and Subspace's little-endian s-bucket convention is baked into the binning so new proofs verify under the existing ChiaTable verifier with no consensus change. This is the vendoring route we agreed on over the git-dep in nazar-pc/abundance#724 (now closed). Supersedes #3878, the earlier CPU-only approach.

Commits in order, worth reading one by one:

  • Bump nightly to 2026-05-03: the toolchain bump the rest needs.
  • vendor abundance ab-proof-of-space (cpu) at fc8da99: abundance's CPU chiapos re-pointed to our primitives, trimmed to what we use.
  • vendor abundance ab-proof-of-space-gpu (gpu) at fc8da99: the rust-gpu shaders plus a proofs-only host, same re-point, one shader crate so there's a single cargo-gpu compile.
  • bake little-endian s-bucket binning into vendored proof of space: our s-bucket convention baked into the CPU binning and the f7 shader so proofs land where ChiaTable expects them.
  • add abundance-backed proof of space: a dense ChiaV2Table on top of the vendored crate, verified by the existing ChiaTable verifier.
  • add farm cutover point with in-place v0 upgrade: an existing farm upgrades in place at a cutover point; old sectors keep working, new ones plot with the new table.
  • dispatch proof-of-space per sector by history size: pick the old or new table per sector, at the cutover boundary.
  • add tests and benches for the abundance proof of space.
  • add wgpu GPU plotter backed by abundance proof of space: the wgpu plotter wired into the farmer behind a wgpu feature, encoding records with our KZG scheme.
  • add wgpu byte-identity test against CPU ChiaV2Table: a GPU-plotted sector is byte-for-byte identical to a CPU-plotted one, so both read and verify under the same path.
  • remove CUDA/ROCm + sppark; make wgpu the default GPU plotter: drop the vendor plotters and their CI, release, and Docker steps; wgpu becomes the default. CI moves over to the wgpu build, with the macOS runners (CI and release) on 26 and lavapipe on Linux and Windows so the byte-identity test runs there.
  • add --cpu-only flag to skip GPU plotting.

GPU plotting is verified on Apple Silicon M1; M2/M3/M4 aren't validated yet and may need further work.

Code contributor checklist:

@vedhavyas

Copy link
Copy Markdown
Contributor Author

@BugBot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 64a7290. Configure here.

Latest nightly that still supports generic_const_exprs.
@vedhavyas
vedhavyas force-pushed the feat/wgpu-plotter-gpu-clean branch from 64a7290 to 816db7f Compare July 7, 2026 07:39
@vedhavyas

Copy link
Copy Markdown
Contributor Author

@BugBot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 816db7f. Configure here.

@vedhavyas
vedhavyas marked this pull request as ready for review July 7, 2026 09:47
@vedhavyas
vedhavyas requested a review from nazar-pc as a code owner July 7, 2026 09:47
@immunefi-magnus

Copy link
Copy Markdown

🛡️ Immunefi PR Reviews

We noticed that your project isn't set up for automatic code reviews. If you'd like this PR reviewed by the Immunefi team, you can request it manually using the link below:

🔗 Send this PR in for review

Once submitted, we'll take care of assigning a reviewer and follow up here.

@vedhavyas
vedhavyas marked this pull request as draft July 7, 2026 10:09
vedhavyas added 4 commits July 7, 2026 20:44
Vendor abundance's chiapos proof-of-space engine (fc8da99) into shared/ab-proof-of-space as a path dependency, re-pointed from ab_core_primitives to subspace_core_primitives. Only the chiapos tables + PosProofs that ChiaV2Table needs are kept; abundance's Chia/Shim table-trait layer is left out. Adds ab-blake3 + rclite as workspace deps. Binning is abundance's raw first_k_bits; Subspace's little-endian s-bucket convention lands in a later commit.
Vendor abundance's GPU proof-of-space (fc8da99) into shared/ab-proof-of-space-gpu as a path dependency, re-pointed to subspace_core_primitives. Only the rust-gpu shader kernels + the proofs-only host (GpuRecordsEncoderInstance/create_proofs) are kept; abundance's Reed-Solomon RecordsEncoder host, the ab-erasure-coding/ab-farmer-components deps, and the shader kernel tests are left out. subspace-proof-of-space-wgpu is host-only, consuming the vendored shader + proofs-only API and encoding with subspace's KZG scheme, so there is one cargo-gpu shader compile. f7 binning is abundance's raw first_k_bits; Subspace's little-endian convention lands next. Adds spirv-std + wgpu + cargo-gpu-install workspace deps.
Subspace bins proofs into s-buckets little-endian (a bucket's little-endian bytes are the challenge, matching the ChiaTable verifier's challenge_index.to_le_bytes()). Bake it directly into the vendored CPU chiapos create_proof_targets and the GPU find_matches_and_compute_f7 shader, replacing abundance's raw first_k_bits binning. No generic map; the convention is fixed. chiapos self_verification checks the dense binning against the little-endian search (for_s_bucket(cs) == find_proof(cs.to_le_bytes())).
chia_v2::ChiaV2Table wraps the vendored ab-proof-of-space chiapos Tables and builds the full proof table with create_proofs, so the proofs verify under the existing ChiaTable verifier; verification delegates to ChiaTable. The alloc feature gates it so the no_std runtime never links it.
@vedhavyas
vedhavyas force-pushed the feat/wgpu-plotter-gpu-clean branch from 816db7f to 98bd5aa Compare July 7, 2026 18:29
@vedhavyas

Copy link
Copy Markdown
Contributor Author

@BugBot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 98bd5aa. Configure here.

@vedhavyas
vedhavyas marked this pull request as ready for review July 8, 2026 02:53
@vedhavyas

Copy link
Copy Markdown
Contributor Author

@BugBot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 6f0a848. Configure here.

@vedhavyas
vedhavyas force-pushed the feat/wgpu-plotter-gpu-clean branch from 0e1f9ca to d3f0043 Compare July 14, 2026 11:24
@vedhavyas

Copy link
Copy Markdown
Contributor Author

@BugBot run

Comment thread crates/subspace-farmer/src/single_disk_farm/plotting.rs
PlotMetadataHeader gains a cutover field (Option<HistorySize>) and a typed PlotMetadataVersion (V0/V1); a version-aware Decode reads old V0 headers as cutover = None and rejects unknown versions (the old-binary lockout). Opening a V0 plot records the cutover as the highest history size among existing sectors and rewrites the header as V1.

New-sector plotting then waits until history advances past the cutover, so no sector is stamped at history_size <= cutover and later misread with the old proof-of-space. Sectors at or below the cutover use the old proof-of-space, newer ones the new; nothing dispatches on it yet.
PosTable (subspace-proof-of-space, alloc-gated) dispatches between the old ChiaTable and the new ChiaV2Table; both proofs verify under ChiaTable, so the choice is a farmer-side read/prove concern. The Table trait gains generator_for(is_post_cutover) and SolutionCandidates a history_size() accessor; the farmer picks per sector by comparing history_size against the farm's cutover at reading, proving, and auditing. New sectors always use the new implementation.
Cross-verify abundance-backed proofs against the existing ChiaTable verifier, a plot->read round-trip, and the per-sector V1/V2 dispatch selection. Point the benches at the new table.
WgpuRecordsEncoder wires the vendored wgpu proof-of-space into the farmer behind a wgpu feature (Vulkan/Metal, macOS included): the host-side WgpuDevice runs the little-endian f7 shader and does subspace KZG encoding, with the plotting setup shared by the farm and cluster-plotter commands.
Plot the same sector with wgpu and with CpuRecordsEncoder<ChiaV2Table> and assert the sector bytes are identical, keeping the GPU path consensus-compatible with the CPU read/verify path.
wgpu covers all GPU vendors (SPIR-V + Metal/Vulkan) with CPU fallback, so the vendor-specific CUDA (sppark) and ROCm plotters are redundant. Drops the subspace-proof-of-space-gpu crate, the cuda/rocm farmer plotters, their features, and the CUDA/ROCm CI, release, and Docker steps; wgpu becomes a default feature so one farmer binary per platform ships with GPU built in.

CI moves over to the wgpu build: the macOS CI and release runners go to 26, and lavapipe (software Vulkan) is installed on the Linux and Windows runners so the byte-identity test runs there instead of skipping. There is a single cargo-gpu shader compile, so no rust-gpu toolchain pre-install step is needed.
Pick plotting devices by type instead of using every enumerated GPU: discrete GPUs, else integrated, else a virtual GPU as a last resort; unknown and CPU-emulated adapters are skipped. --wgpu-gpus still selects exact GPUs by device id and bypasses the tiering, and the chosen GPUs are logged.
@vedhavyas
vedhavyas force-pushed the feat/wgpu-plotter-gpu-clean branch from c2c8ae0 to 3021641 Compare July 21, 2026 15:41
@vedhavyas

Copy link
Copy Markdown
Contributor Author

@BugBot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 3021641. Configure here.


if let Some(error) = self.mapping_error.lock().take() {
return Err(RecordEncodingError::BufferMapping(error));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GPU error permanently stalls plotting

High Severity

A transient failure in create_proofs leaves tainted set, so that queue returns DeviceBroken forever. WgpuRecordsEncoder runs every queue via spawn_broadcast and fails the whole sector if any queue errors, so one dead queue breaks all later encodes. With GPU present, CPU plotting is auto-disabled, leaving no fallback and retries that cannot recover.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3021641. Configure here.

@vedhavyas
vedhavyas marked this pull request as draft July 21, 2026 15:51

@nazar-pc nazar-pc left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should update subspace.plotter.*.plot-sector to something like subspace.plotter.*.plot-sector-v2 in

const SUBJECT: &'static str = "subspace.plotter.*.plot-sector";
to make sure old and new plotter do not overlap. Otherwise during partial upgrade old plotter might create a sector that farmer will think follows the new algorithm and vice versa.

Resolve Cargo.toml and Cargo.lock against the prometheus-client 0.25.0
bump and the advanced libp2p and polkadot-sdk fork pins, keeping the
wgpu dependencies from this branch.
The plot-sector payload is unchanged, so during a partial cluster upgrade
an old plotter would decode a new farmer's request and plot the sector
with the old proof-of-space. Versioning the subject makes that routing
impossible, and versioning free-instance keeps a new farmer from
discovering old plotters at all.
@vedhavyas
vedhavyas marked this pull request as ready for review July 30, 2026 09:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants