Skip to content

Look up fold_threshold behind an inference barrier, so that loading a backend doesn't invalidate launches - #937

Merged
maleadt merged 1 commit into
mainfrom
tb/tuning-invalidations
Oct 27, 2026
Merged

maleadt merged 1 commit into
mainfrom
tb/tuning-invalidations

Conversation

@maleadt

@maleadt maleadt commented Oct 27, 2026 •

Copy link
Copy Markdown
Member

KernelAbstractions sets fold_threshold for AMDGPU, Metal and oneAPI in its own package extensions, so that the value can be tuned without releasing the back ends. Those back ends precompile kernel launches (their own, and GPUArrays' and AcceleratedKernels' through them), and select_launch called fold_threshold(backend) on every launch. The precompiled launches therefore depended on the generic method, and loading the extension that adds the backend's method invalidated all of them. With the back ends defining their KernelAbstractions methods in src (JuliaGPU/AMDGPU.jl#1202, JuliaGPU/Metal.jl#1118), fold_threshold is the largest remaining invalidation tree when loading them: 535 method instances on AMDGPU, 322 on Metal.

This PR looks such values up through tuning(hook, backend), which calls the hook behind Base.inferencebarrier and asserts its result type (declared per hook with tuning_type). Compiled code then no longer depends on the hook's methods, and the extensions keep defining them as before. fold_threshold is also only looked up for tuned launches of more than three dimensions, the only ones that can be folded, so 1–3-d launches don't pay for the lookup at all. Further values tuned per backend can use the same helper.

Unique method instances invalidated by using <backend>, KernelAbstractions (SnoopCompile, Julia 1.13.2, back end at the PR in parentheses):

main this PR
AMDGPU (JuliaGPU/AMDGPU.jl#1202) 1268 832
Metal (JuliaGPU/Metal.jl#1118) 1320 1177
oneAPI (JuliaGPU/oneAPI.jl#748) 787 787

oneAPI.jl doesn't precompile launches on its backend, so there is nothing to invalidate. On Metal, most of the rest of the launch path is invalidated by AcceleratedKernels' extension, which JuliaGPU/AcceleratedKernels.jl#189 addresses the same way.

The lookup is a dynamic dispatch, which adds about 3 ns to select_launch for a 4-d launch (107 vs 111 ns on a Radeon iGPU, for a launch of ~1.3 µs). The time to the first launches doesn't change measurably by itself: on an M1, broadcasting, indexing, reductions, scans, sorts and a 4-d broadcast take 4.69–4.79 s from a fresh process, against 4.75–4.85 s before; on an Arc A770 13.8–14.0 s either way.

The test suite passes on PoCL.

Launches compiled before KernelAbstractions' extension for a backend is
loaded, such as those precompiled by AMDGPU.jl and Metal.jl through
GPUArrays and AcceleratedKernels, depended on the generic method of
fold_threshold, so loading the extension that adds the backend's method
invalidated them. Look tuned values up through a `tuning` helper that
hides the call from inference, and only for the launches that can be
folded: tuned ones of more than three dimensions.
@github-actions

Copy link
Copy Markdown
Contributor

Benchmark results

Compared with d2ada37c6, the latest measured ancestor of the merge base (1 commit before it).
The environment differs from the baseline's: Parsers 3.0.1 → 3.0.2.

Times are the minimum time of every benchmark. A change is unusual when it exceeds both three times the benchmark's typical change between consecutive runs on the default branch and a minimum per category (performance 3%, latency 5%, applications 3%, other 3%). A benchmark that starts or stops allocating is listed however few the allocations. A single run can still be a fluke, so rerun before drawing conclusions.

Geometric mean Unusual: slower Unusual: faster Compared
Performance +0.7% 0 0 32
Latency −0.3% 0 0 13
Applications +6.6% 0 0 5

No unusual changes.

All benchmarks
Benchmark Baseline This PR Change
Performance
julia/serial/arithmetic/muladd-reference 655 µs 655 µs −0.0% noise unknown
julia/serial/math/exp-f64-reference 284 µs 379 µs +33.3% noise unknown
julia/serial/narrow/masked-reference 702 µs 709 µs +1.0% noise unknown
pocl/parallel/atomics/histogram 5.16 ms 5.13 ms −0.6% noise unknown
pocl/parallel/groupreduce/add-f64 1.66 ms 1.67 ms +0.4% noise unknown
pocl/parallel/groupreduce/fallback 18.1 ms 18.1 ms +0.0% noise unknown
pocl/parallel/groupscan/add-i32 2.53 ms 2.52 ms −0.5% noise unknown
pocl/parallel/indexing/cartesian3d 84.8 µs 86.6 µs +2.1% noise unknown
pocl/parallel/indexing/linear3d 84.4 µs 79.8 µs −5.4% noise unknown
pocl/parallel/indexing/ntuple3d 81.4 µs 79.5 µs −2.3% noise unknown
pocl/parallel/indexing/ntuple4d 164 µs 162 µs −1.1% noise unknown
pocl/parallel/localmem/transpose-naive 459 µs 458 µs −0.3% noise unknown
pocl/parallel/localmem/transpose-tiled 101 µs 122 µs +20.4% noise unknown
pocl/parallel/private/across-barrier 164 µs 159 µs −3.1% noise unknown
pocl/parallel/scheduling/default 181 µs 181 µs −0.2% noise unknown
pocl/parallel/scheduling/explicit 181 µs 181 µs −0.2% noise unknown
pocl/parallel/stream/copy/cache 6.06 µs 6.24 µs +2.9% noise unknown
pocl/parallel/stream/copy/dram 6.32 ms 6.33 ms +0.2% noise unknown
pocl/parallel/stream/triad/cache 6.90 µs 6.63 µs −3.9% noise unknown
pocl/parallel/stream/triad/dram 8.94 ms 9.33 ms +4.4% noise unknown
pocl/parallel/util/copyto-small 4.59 µs 4.53 µs −1.2% noise unknown
pocl/parallel/util/zeros-large 998 µs 983 µs −1.5% noise unknown
pocl/parallel/util/zeros-small 665 ns 630 ns −5.3% noise unknown
pocl/serial/arithmetic/contract 1.91 ms 1.89 ms −0.9% noise unknown
pocl/serial/arithmetic/muladd 759 µs 768 µs +1.1% noise unknown
pocl/serial/const/marked 728 µs 731 µs +0.4% noise unknown
pocl/serial/const/unmarked 915 µs 891 µs −2.6% noise unknown
pocl/serial/math/exp-f64 147 µs 146 µs −0.8% noise unknown
pocl/serial/math/sin-f64 202 µs 189 µs −6.4% noise unknown
pocl/serial/narrow/masked 854 µs 847 µs −0.8% noise unknown
pocl/serial/narrow/unmasked 765 µs 770 µs +0.6% noise unknown
pocl/serial/stream/triad/dram 8.63 ms 8.58 ms −0.6% noise unknown
Latency
host/import/ka 506 ms 503 ms −0.6% noise unknown
host/precompile/ka 44.9 s 44.2 s −1.5% noise unknown
host/startup 133 ms 132 ms −1.4% noise unknown
pocl/parallel/launch/dynamic-default 4.39 µs 4.37 µs −0.5% noise unknown
pocl/parallel/launch/groupreduce-f64 18.5 µs 18.6 µs +0.7% noise unknown
pocl/parallel/launch/many-args 12.0 µs 12.3 µs +2.5% noise unknown
pocl/parallel/launch/partial-workgroup 4.18 µs 4.02 µs −3.8% noise unknown
pocl/serial/compile/groupreduce 2.06 s 2.06 s +0.0% noise unknown
pocl/serial/compile/localmem-barrier 808 ms 799 ms −1.2% noise unknown
pocl/serial/compile/new-kernel 118 ms 120 ms +1.5% noise unknown
pocl/serial/compile/new-workgroupsize 13.6 ms 13.8 ms +1.6% noise unknown
pocl/serial/first-kernel/cold-cache 2.02 s 2.01 s −0.3% noise unknown
pocl/serial/first-kernel/warm-cache 360 ms 359 ms −0.1% noise unknown
Applications
pocl/parallel/dgsem/fluxdiff-node 291 µs 289 µs −0.5% noise unknown
pocl/parallel/dgsem/weak-element 160 µs 181 µs +13.5% noise unknown
pocl/parallel/dgsem/weak-node-localmem 118 µs 145 µs +22.7% noise unknown
pocl/parallel/stencil/timestep 7.91 ms 7.96 ms +0.7% noise unknown
pocl/serial/stencil/timestep 11.3 ms 11.1 ms −1.1% noise unknown

History: https://juliagpu.org/perf/?pkg=kernelabstractions

@maleadt
maleadt merged commit 466ad8a into main Oct 27, 2026
46 of 47 checks passed
@maleadt
maleadt deleted the tb/tuning-invalidations branch October 27, 2026 20:06
@codecov

codecov Bot commented Oct 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.19%. Comparing base (d2ada37) to head (03be940).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #937      +/-   ##
==========================================
+ Coverage   82.87%   83.19%   +0.31%     
==========================================
  Files          31       31              
  Lines        2564     2571       +7     
==========================================
+ Hits         2125     2139      +14     
+ Misses        439      432       -7     

☔ 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.

1 participant