Skip to content

[pocl] Enable SPV_EXT_shader_atomic_float_add where supported - #737

Draft
vchuravy wants to merge 1 commit into
mainfrom
vc/pocl-float-atomics
Draft

[pocl] Enable SPV_EXT_shader_atomic_float_add where supported#737
vchuravy wants to merge 1 commit into
mainfrom
vc/pocl-float-atomics

Conversation

@vchuravy

Copy link
Copy Markdown
Member

The SPIR-V backend refuses to translate a module containing an atomic fadd unless the extension guarding it has been listed:

LLVM ERROR: The atomic float instruction requires the following SPIR-V extension: SPV_EXT_shader_atomic_float_add

Enzyme's reverse mode runs into this because it accumulates gradients with atomic fadd, so reverse-mode AD over a POCL kernel fails to compile outright.

Change

Derive the extension list from the device, the same way supports_fp16/supports_fp64 already are, keyed off the corresponding OpenCL extension cl_ext_float_atomics (which PoCL advertises on this machine).

Listing an extension only permits it — nothing is emitted unless a module actually needs those instructions — so kernels that don't use float atomics are unaffected. An explicit extensions= keyword still wins, and the new default_spirv_extensions helper gives later extensions an obvious home.

Verification

extensions = "+SPV_EXT_shader_atomic_float_add"     # default, from the device
override   = "+SPV_KHR_expect_assume"               # explicit kwarg still wins
PLAIN KERNEL: PASS
KA POCL FORWARD-MODE ENZYME: PASS  (dA[1:4] = [2.0, 4.0, 6.0, 8.0])

End-to-end, reverse-mode Enzyme over a POCL kernel now runs and produces correct gradients:

KA POCL REVERSE-MODE ENZYME: PASS  (dA[1:4] = [2.0, 4.0, 6.0, 8.0])

That run needed a SPIRV_LLVM_Backend_jll newer than the currently pinned 22.1.8, because reverse mode also trips two LLVM SPIR-V backend bugs:

  1. A segfault in SPIRVInstructionSelector::selectExtractVal, already fixed upstream by [SPIR-V] Rewrite extractvalue over aggregate spv_extractv result llvm/llvm-project#200065 (fd1f9225458a, 2026-06-07) — not in 22.1.8. Bumping the JLL past that commit is all that is needed.
  2. An OpCompositeExtract pointee-type mismatch on pointers extracted from aggregates, still present on trunk; fix pending upstream.

I verified this by overriding the JLL to point at a patched trunk llc; with the shipped 22.1.8 the same test fails with Failed to translate LLVM code to SPIR-V. This PR is independent of those and is needed regardless — without it the module does not compile even with a fixed backend.

x-ref #583, EnzymeAD/Enzyme.jl#3405, EnzymeAD/Enzyme.jl#3309.

🤖 Generated with Claude Code

The SPIR-V backend refuses to translate a module containing an atomic fadd
unless the extension guarding it has been listed:

    LLVM ERROR: The atomic float instruction requires the following SPIR-V
    extension: SPV_EXT_shader_atomic_float_add

Enzyme's reverse mode runs into this because it accumulates gradients with
atomic fadd, so reverse-mode AD over a POCL kernel fails to compile outright.

Derive the extension list from the device the way `supports_fp16`/`supports_fp64`
already are, keyed off the corresponding OpenCL extension (`cl_ext_float_atomics`,
which PoCL advertises). Listing an extension only permits it -- nothing is
emitted unless a module needs those instructions -- so kernels that do not use
float atomics are unaffected. An explicit `extensions=` keyword still wins, and
`default_spirv_extensions` gives later extensions an obvious home.

Verified end-to-end: with this change, reverse-mode Enzyme over a POCL kernel
compiles, runs and produces correct gradients.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Benchmark Results

Show table
main 4cc0e6e... main / 4cc0e6e...
saxpy/default/Float32/1024 0.0619 ± 0.032 ms 0.063 ± 0.03 ms 0.982 ± 0.69
saxpy/default/Float32/1048576 0.515 ± 0.033 ms 0.512 ± 0.02 ms 1.01 ± 0.075
saxpy/default/Float32/16384 0.0545 ± 0.03 ms 0.0569 ± 0.03 ms 0.959 ± 0.73
saxpy/default/Float32/2048 0.0642 ± 0.028 ms 0.0652 ± 0.028 ms 0.986 ± 0.6
saxpy/default/Float32/256 0.0548 ± 0.036 ms 0.0619 ± 0.031 ms 0.885 ± 0.73
saxpy/default/Float32/262144 0.183 ± 0.026 ms 0.183 ± 0.013 ms 0.999 ± 0.16
saxpy/default/Float32/32768 0.0617 ± 0.031 ms 0.0619 ± 0.031 ms 0.997 ± 0.71
saxpy/default/Float32/4096 0.067 ± 0.029 ms 0.0657 ± 0.025 ms 1.02 ± 0.58
saxpy/default/Float32/512 0.0517 ± 0.036 ms 0.0603 ± 0.034 ms 0.856 ± 0.77
saxpy/default/Float32/64 0.0605 ± 0.034 ms 0.061 ± 0.033 ms 0.991 ± 0.78
saxpy/default/Float32/65536 0.0842 ± 0.031 ms 0.0804 ± 0.03 ms 1.05 ± 0.55
saxpy/default/Float64/1024 0.0595 ± 0.033 ms 0.0636 ± 0.03 ms 0.935 ± 0.69
saxpy/default/Float64/1048576 0.67 ± 0.11 ms 0.549 ± 0.16 ms 1.22 ± 0.41
saxpy/default/Float64/16384 0.0583 ± 0.031 ms 0.0671 ± 0.03 ms 0.868 ± 0.6
saxpy/default/Float64/2048 0.0634 ± 0.027 ms 0.0651 ± 0.026 ms 0.973 ± 0.57
saxpy/default/Float64/256 0.0517 ± 0.036 ms 0.0624 ± 0.032 ms 0.829 ± 0.72
saxpy/default/Float64/262144 0.183 ± 0.018 ms 0.193 ± 0.067 ms 0.951 ± 0.34
saxpy/default/Float64/32768 0.0737 ± 0.03 ms 0.0668 ± 0.031 ms 1.1 ± 0.68
saxpy/default/Float64/4096 0.0665 ± 0.027 ms 0.0649 ± 0.027 ms 1.02 ± 0.6
saxpy/default/Float64/512 0.0553 ± 0.036 ms 0.0632 ± 0.031 ms 0.874 ± 0.71
saxpy/default/Float64/64 0.0501 ± 0.036 ms 0.0627 ± 0.032 ms 0.799 ± 0.7
saxpy/default/Float64/65536 0.0971 ± 0.028 ms 0.0867 ± 0.029 ms 1.12 ± 0.5
saxpy/static workgroup=(1024,)/Float32/1024 0.0516 ± 0.036 ms 0.0515 ± 0.036 ms 1 ± 0.98
saxpy/static workgroup=(1024,)/Float32/1048576 0.46 ± 0.024 ms 0.459 ± 0.027 ms 1 ± 0.08
saxpy/static workgroup=(1024,)/Float32/16384 0.0523 ± 0.028 ms 0.052 ± 0.028 ms 1.01 ± 0.77
saxpy/static workgroup=(1024,)/Float32/2048 0.0635 ± 0.027 ms 0.0595 ± 0.033 ms 1.07 ± 0.75
saxpy/static workgroup=(1024,)/Float32/256 0.0479 ± 0.036 ms 0.0611 ± 0.034 ms 0.784 ± 0.73
saxpy/static workgroup=(1024,)/Float32/262144 0.169 ± 0.031 ms 0.163 ± 0.031 ms 1.04 ± 0.27
saxpy/static workgroup=(1024,)/Float32/32768 0.0576 ± 0.029 ms 0.0576 ± 0.029 ms 1 ± 0.72
saxpy/static workgroup=(1024,)/Float32/4096 0.0663 ± 0.026 ms 0.0646 ± 0.024 ms 1.03 ± 0.56
saxpy/static workgroup=(1024,)/Float32/512 0.0441 ± 0.036 ms 0.0578 ± 0.036 ms 0.763 ± 0.79
saxpy/static workgroup=(1024,)/Float32/64 0.0524 ± 0.036 ms 0.0565 ± 0.036 ms 0.927 ± 0.88
saxpy/static workgroup=(1024,)/Float32/65536 0.0754 ± 0.031 ms 0.0732 ± 0.03 ms 1.03 ± 0.6
saxpy/static workgroup=(1024,)/Float64/1024 0.059 ± 0.032 ms 0.0573 ± 0.035 ms 1.03 ± 0.84
saxpy/static workgroup=(1024,)/Float64/1048576 0.486 ± 0.02 ms 0.486 ± 0.019 ms 1 ± 0.058
saxpy/static workgroup=(1024,)/Float64/16384 0.0565 ± 0.028 ms 0.0563 ± 0.028 ms 1 ± 0.71
saxpy/static workgroup=(1024,)/Float64/2048 0.063 ± 0.027 ms 0.0619 ± 0.028 ms 1.02 ± 0.63
saxpy/static workgroup=(1024,)/Float64/256 0.0545 ± 0.036 ms 0.0568 ± 0.036 ms 0.96 ± 0.88
saxpy/static workgroup=(1024,)/Float64/262144 0.172 ± 0.029 ms 0.171 ± 0.03 ms 1.01 ± 0.25
saxpy/static workgroup=(1024,)/Float64/32768 0.0632 ± 0.03 ms 0.0635 ± 0.03 ms 0.995 ± 0.67
saxpy/static workgroup=(1024,)/Float64/4096 0.0651 ± 0.026 ms 0.0637 ± 0.025 ms 1.02 ± 0.57
saxpy/static workgroup=(1024,)/Float64/512 0.0533 ± 0.036 ms 0.0553 ± 0.036 ms 0.964 ± 0.9
saxpy/static workgroup=(1024,)/Float64/64 0.0457 ± 0.036 ms 0.0552 ± 0.036 ms 0.828 ± 0.85
saxpy/static workgroup=(1024,)/Float64/65536 0.0879 ± 0.03 ms 0.0831 ± 0.03 ms 1.06 ± 0.53
time_to_load 0.95 ± 0.0026 s 1.04 ± 0.0049 s 0.909 ± 0.0049

Benchmark Plots

A plot of the benchmark results have been uploaded as an artifact to the workflow run for this PR.
Go to "Actions"->"Benchmark a pull request"->[the most recent run]->"Artifacts" (at the bottom).

@simeonschaub

Copy link
Copy Markdown
Member

Have you seen JuliaGPU/OpenCL.jl#453? Might want to copy some of the logic from there. SPV_EXT_shader_atomic_float_min_max might be useful too

@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.89%. Comparing base (65690fd) to head (4cc0e6e).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #737      +/-   ##
==========================================
+ Coverage   64.77%   64.89%   +0.12%     
==========================================
  Files          24       24              
  Lines        2024     2031       +7     
==========================================
+ Hits         1311     1318       +7     
  Misses        713      713              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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