Repository navigation
Conversation
|
Looks like this might also be #913 |
|
This indeed fixes #913 too. Reproduced on PoCL: (128,128,16,8) goes from 6.4 ms to 78 µs, and the test suite passes. One change Claude suggests: the tuned-size condition The CI failures are the back ends' own launch configuration tests asserting LinearLaunch for 4-d. |
|
I checked, and a small threshold does measurably help on GPU. Measured on an RTX 4060 (with CUDA.jl main) and on PoCL, forcing each launch kind for 4-d ndranges with a tuned workgroup size, this is the speedup of the fold over the
On PoCL the fold advantage is consistent, but on the GPU it loses when the first three dimensions hold fewer than about 48 work-items (tuned blocks are then smaller than two warps). So a fixed threshold of 64 work-items (013ab13): (8, 8, 8, 1536) and (256, 2, 2, 768) fold now, and shapes like (2, 3, 4, 50000) stay linear. That leaves the 6x on PoCL for those, but folding them costs 1.6x on CUDA, and up to 11x for (1, 1, 1, 60000). Favouring PoCL there would need a per-backend threshold but With the threshold, the back ends' launch configuration tests need two changes: |
013ab13 to
28a846b
Compare
|
Rebased and slightly reworked. I'll open back-end PRs that remove the now-problematic test. |
On a backend with a 3-d grid, an ndrange with more than three dimensions was always launched as a `LinearLaunch`, which decomposes the linear ids of every work-item into Cartesian positions. With a tuned workgroup size, these are divisions by runtime values, which made such kernels 30 to 100 times slower than the same kernel over a 3-d ndrange on PoCL (JuliaGPU#913). Launch it as an `NDLaunch` instead when its workgroups have one work-item along the dimensions past the third: the work-items keep the direct x/y/z mapping, the later dimensions share the grid's z-dimension with the third, and only the group's z-id is decomposed along them, not the ids of the work-items. A tuned workgroup then only has work-items along the first three dimensions, so it only folds if these hold at least 64 work-items. Below that, the folded launch is slower on GPUs (0.7x at 32 work-items and 0.07x for (1, 1, 1, 60000) on an RTX 5080), while from 64 on it is 1.3 to 1.7 times faster there, and many times faster on PoCL. Co-authored-by: Tim Besard <tim.besard@gmail.com> Assisted-By: Claude Opus 5.5 <noreply@anthropic.com>
28a846b to
bfbf67d
Compare
|
Thanks @b-fg! I've reopened this as #919, from a branch in this repository, so that #918 (which makes the 64-item threshold per back end) can be stacked on it; GitHub doesn't stack pull requests from forks. The commit is still yours. Since you last looked, I squashed your two commits and rebased them on main, and:
The threshold of 64 holds on an RTX 5080 as on your RTX 4060. Rather than swapping the shapes in the back ends' tests, JuliaGPU/CUDA.jl#3458, JuliaGPU/AMDGPU.jl#1183, JuliaGPU/Metal.jl#1107, JuliaGPU/oneAPI.jl#734 and JuliaGPU/OpenCL.jl#582 drop their assertions on the launch kind; those go in first. |
|
Noted, thanks! |
The launch configuration tests asserted which kind of launch KernelAbstractions picks for a few shapes. That is KernelAbstractions' policy, not something the back end controls, and the assertions break whenever it changes (JuliaGPU/KernelAbstractions.jl#912 launches 4-d ranges on the N-d grid). Keep the checks of what the back end does affect: that a dynamic 3-d range is indexed without divisions, and that iteration spaces too large for 32-bit indices are indexed correctly, now also one that is only large along its last dimension.
The launch configuration tests asserted which kind of launch KernelAbstractions picks for a few shapes. That is KernelAbstractions' policy, not something the back end controls, and the assertions break whenever it changes (JuliaGPU/KernelAbstractions.jl#912 launches 4-d ranges on the N-d grid). Keep the checks of what the back end does affect: that a dynamic 3-d range is indexed without divisions, and that iteration spaces too large for 32-bit indices are indexed correctly, now also one that is only large along its last dimension.
On a backend with a 3-d grid, an ndrange with more than three dimensions is launched as a
LinearLaunch: every work-item decomposes its linear local and group ids into Cartesian positions. With a tuned workgroup size those are divisions by runtime values, and on PoCL such kernels are 30 to 100 times slower than the same kernel over a 3-d ndrange. WaterLily.jl hit this in its loops over vector fields, whose component is a fourth index (a time step about 2.5 times slower than on KA 0.9), and NNlib inimrotate(#913).This launches them as an
NDLaunchinstead when the workgroups have one work-item along the dimensions past the third. The work-items keep the direct x/y/z mapping of a 3-d launch; the third and later dimensions share the grid's z-dimension, so only the group's z-id is decomposed along them, which is the same for every work-item of a workgroup. A static workgroup size folds when it has one work-item past the third dimension and the folded grid fitsmax_num_groups.A tuned workgroup size is then chosen with work-items along the first three dimensions only, which gives small workgroups when those are small. On GPUs that loses against a linear launch, so tuned launches only fold when the first three dimensions hold at least 64 work-items. Folded over linear, for the
scale!kernel of #913 on an RTX 5080 (the contributor's RTX 4060 gives the same picture):PoCL would gain from folding below 64 as well; that would need a per-backend threshold, which can come later. Shapes that stay linear are no slower than before.
Median time per launch on PoCL (1 thread), tuned workgroup size:
The back ends' launch configuration tests assert which launch kind is selected for a 4-d range, so they fail with this change. JuliaGPU/CUDA.jl#3458, JuliaGPU/AMDGPU.jl#1183, JuliaGPU/Metal.jl#1107, JuliaGPU/oneAPI.jl#734 and JuliaGPU/OpenCL.jl#582 replace those assertions with behavioural checks, and should be merged first.
Tested with the KA test suite on PoCL, which now also launches a tuned 5-d range that folds, and with the KernelAbstractions tests of CUDA.jl (RTX 5080) and OpenCL.jl (PoCL).
Fixes #913