Skip to content

Launch ndranges with more than three dimensions on the N-d grid - #919

Open
maleadt wants to merge 1 commit into
mainfrom
tb/ndlaunch-fold
Open

maleadt wants to merge 1 commit into
mainfrom
tb/ndlaunch-fold

Conversation

@maleadt

@maleadt maleadt commented Oct 23, 2026

Copy link
Copy Markdown
Member

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 in imrotate (#913).

This launches them as an NDLaunch instead 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 fits max_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):

ndrange first three dims CUDA PoCL, 8 threads
(128, 128, 16, 8) 262144 1.70 33.8
(8, 8, 8, 1536) 512 1.62 7.8
(4, 4, 4, 8192) 64 1.31 4.3
(4, 4, 3, 10923) 48 1.03 4.7
(4, 4, 2, 16384) 32 0.71 6.1
(2, 3, 4, 50000) 24 0.50 3.9
(1, 1, 1, 60000) 1 0.07 1.2

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:

ndrange main this PR same work-items as 3-d
(128, 128, 16, 8) 12.4 ms 117 µs 127 µs
(64, 64, 64, 3) 4.6 ms 51 µs
(16, 16, 4, 4, 32) 1.5 ms 9 µs

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

This is #912 by @b-fg, reopened from a branch in this repository so that follow-ups can be stacked on it.

Fixes #913

@github-actions

Copy link
Copy Markdown
Contributor

@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Benchmark Results

Show table
main 78b2c4e... main / 78b2c4e...
const/@Const/Float32/262144 0.633 ± 0.02 ms 0.632 ± 0.024 ms 1 ± 0.05
const/@Const/Float32/65536 0.196 ± 0.015 ms 0.193 ± 0.013 ms 1.02 ± 0.1
const/@Const/Float64/262144 0.83 ± 0.019 ms 0.827 ± 0.018 ms 1 ± 0.031
const/@Const/Float64/65536 0.358 ± 0.015 ms 0.366 ± 0.014 ms 0.977 ± 0.056
const/unmarked/Float32/262144 2.31 ± 0.02 ms 2.3 ± 0.023 ms 1 ± 0.013
const/unmarked/Float32/65536 0.622 ± 0.026 ms 0.608 ± 0.02 ms 1.02 ± 0.055
const/unmarked/Float64/262144 3.1 ± 0.026 ms 3.14 ± 0.033 ms 0.986 ± 0.013
const/unmarked/Float64/65536 0.805 ± 0.012 ms 0.81 ± 0.021 ms 0.993 ± 0.029
dgsem/2D/Float32/fluxdiff/element 0.561 ± 0.02 ms 0.565 ± 0.013 ms 0.993 ± 0.042
dgsem/2D/Float32/fluxdiff/node E=8 0.823 ± 0.01 ms 0.842 ± 0.025 ms 0.977 ± 0.032
dgsem/2D/Float32/fluxdiff/node halfsweep E=8 0.661 ± 0.032 ms 0.648 ± 0.022 ms 1.02 ± 0.06
dgsem/2D/Float32/fluxdiff/node halfsweep v-last E=8 0.609 ± 0.02 ms 0.626 ± 0.016 ms 0.972 ± 0.04
dgsem/2D/Float32/weak/element 0.202 ± 0.017 ms 0.206 ± 0.019 ms 0.979 ± 0.12
dgsem/2D/Float32/weak/element private 0.225 ± 0.016 ms 0.215 ± 0.014 ms 1.04 ± 0.1
dgsem/2D/Float32/weak/node localmem E=1 0.188 ± 0.017 ms 0.211 ± 0.0058 ms 0.89 ± 0.085
dgsem/2D/Float32/weak/node localmem E=8 0.183 ± 0.02 ms 0.183 ± 0.014 ms 1 ± 0.13
dgsem/2D/Float32/weak/node localmem v-last E=1 0.267 ± 0.023 ms 0.251 ± 0.023 ms 1.07 ± 0.13
dgsem/2D/Float32/weak/node localmem v-last E=8 0.267 ± 0.005 ms 0.268 ± 0.016 ms 0.996 ± 0.061
dgsem/2D/Float32/weak/node recompute E=8 0.498 ± 0.012 ms 0.514 ± 0.027 ms 0.967 ± 0.055
dgsem/2D/Float64/fluxdiff/element 0.576 ± 0.02 ms 0.591 ± 0.02 ms 0.975 ± 0.047
dgsem/2D/Float64/fluxdiff/node E=8 0.794 ± 0.026 ms 0.795 ± 0.016 ms 0.998 ± 0.038
dgsem/2D/Float64/fluxdiff/node halfsweep E=8 0.613 ± 0.02 ms 0.626 ± 0.025 ms 0.979 ± 0.05
dgsem/2D/Float64/fluxdiff/node halfsweep v-last E=8 0.626 ± 0.022 ms 0.63 ± 0.022 ms 0.995 ± 0.049
dgsem/2D/Float64/weak/element 0.242 ± 0.0064 ms 0.236 ± 0.017 ms 1.02 ± 0.077
dgsem/2D/Float64/weak/element private 0.234 ± 0.015 ms 0.234 ± 0.014 ms 0.999 ± 0.086
dgsem/2D/Float64/weak/node localmem E=1 0.216 ± 0.0061 ms 0.217 ± 0.026 ms 0.998 ± 0.12
dgsem/2D/Float64/weak/node localmem E=8 0.212 ± 0.021 ms 0.187 ± 0.022 ms 1.13 ± 0.17
dgsem/2D/Float64/weak/node localmem v-last E=1 0.263 ± 0.02 ms 0.283 ± 0.0099 ms 0.93 ± 0.079
dgsem/2D/Float64/weak/node localmem v-last E=8 0.276 ± 0.017 ms 0.277 ± 0.017 ms 0.996 ± 0.086
dgsem/2D/Float64/weak/node recompute E=8 0.649 ± 0.015 ms 0.644 ± 0.02 ms 1.01 ± 0.039
dgsem/3D/Float32/fluxdiff/element 1.94 ± 0.0081 ms 1.94 ± 0.02 ms 1 ± 0.011
dgsem/3D/Float32/fluxdiff/node E=2 3.35 ± 0.017 ms 3.38 ± 0.019 ms 0.992 ± 0.0076
dgsem/3D/Float32/fluxdiff/node halfsweep E=1 2.47 ± 0.021 ms 2.25 ± 0.013 ms 1.1 ± 0.011
dgsem/3D/Float32/fluxdiff/node halfsweep v-last E=1 2.18 ± 0.01 ms 2.03 ± 0.006 ms 1.07 ± 0.006
dgsem/3D/Float32/weak/element 0.669 ± 0.02 ms 0.685 ± 0.018 ms 0.976 ± 0.039
dgsem/3D/Float32/weak/element private 0.69 ± 0.015 ms 0.711 ± 0.012 ms 0.971 ± 0.026
dgsem/3D/Float32/weak/node localmem E=1 0.689 ± 0.019 ms 0.652 ± 0.019 ms 1.06 ± 0.043
dgsem/3D/Float32/weak/node localmem E=2 0.762 ± 0.018 ms 0.732 ± 0.015 ms 1.04 ± 0.033
dgsem/3D/Float32/weak/node localmem v-last E=1 0.908 ± 0.023 ms 0.854 ± 0.019 ms 1.06 ± 0.036
dgsem/3D/Float32/weak/node localmem v-last E=2 0.933 ± 0.0062 ms 0.919 ± 0.0048 ms 1.01 ± 0.0086
dgsem/3D/Float32/weak/node recompute E=2 2.04 ± 0.011 ms 2.05 ± 0.013 ms 0.997 ± 0.0085
dgsem/3D/Float32/weak/slab E=1 2.64 ± 0.011 ms 2.63 ± 0.011 ms 1 ± 0.0059
dgsem/3D/Float32/weak/slab E=8 5.48 ± 0.036 ms 5.54 ± 0.044 ms 0.99 ± 0.01
dgsem/3D/Float32/weak/slab double-buffered E=1 1.58 ± 0.01 ms 1.64 ± 0.012 ms 0.961 ± 0.0093
dgsem/3D/Float32/weak/slab double-buffered E=8 2.05 ± 0.016 ms 2.04 ± 0.0074 ms 1 ± 0.0087
dgsem/3D/Float32/weak/slab double-buffered v-last E=1 1.62 ± 0.022 ms 1.67 ± 0.025 ms 0.972 ± 0.019
dgsem/3D/Float32/weak/slab double-buffered v-last E=8 2.14 ± 0.023 ms 2.13 ± 0.0084 ms 1.01 ± 0.011
dgsem/3D/Float32/weak/slab v-last E=1 2.64 ± 0.032 ms 2.68 ± 0.043 ms 0.985 ± 0.02
dgsem/3D/Float32/weak/slab v-last E=8 5.47 ± 0.046 ms 5.51 ± 0.015 ms 0.992 ± 0.0087
dgsem/3D/Float64/fluxdiff/element 2 ± 0.025 ms 1.98 ± 0.011 ms 1.01 ± 0.014
dgsem/3D/Float64/fluxdiff/node E=2 3.08 ± 0.011 ms 3.01 ± 0.021 ms 1.02 ± 0.0081
dgsem/3D/Float64/fluxdiff/node halfsweep E=1 2.42 ± 0.016 ms 2.18 ± 0.022 ms 1.11 ± 0.013
dgsem/3D/Float64/fluxdiff/node halfsweep v-last E=1 2.29 ± 0.021 ms 2.15 ± 0.016 ms 1.07 ± 0.013
dgsem/3D/Float64/weak/element 0.815 ± 0.012 ms 0.823 ± 0.007 ms 0.991 ± 0.016
dgsem/3D/Float64/weak/element private 0.859 ± 0.02 ms 0.87 ± 0.025 ms 0.988 ± 0.036
dgsem/3D/Float64/weak/node localmem E=1 0.721 ± 0.019 ms 0.665 ± 0.014 ms 1.09 ± 0.036
dgsem/3D/Float64/weak/node localmem E=2 0.796 ± 0.01 ms 0.782 ± 0.022 ms 1.02 ± 0.032
dgsem/3D/Float64/weak/node localmem v-last E=1 0.941 ± 0.023 ms 0.869 ± 0.013 ms 1.08 ± 0.031
dgsem/3D/Float64/weak/node localmem v-last E=2 0.967 ± 0.027 ms 0.962 ± 0.011 ms 1.01 ± 0.031
dgsem/3D/Float64/weak/node recompute E=2 2.13 ± 0.011 ms 2.15 ± 0.026 ms 0.989 ± 0.013
dgsem/3D/Float64/weak/slab E=1 2.8 ± 0.05 ms 2.76 ± 0.023 ms 1.02 ± 0.02
dgsem/3D/Float64/weak/slab E=8 6.33 ± 0.046 ms 6.35 ± 0.023 ms 0.997 ± 0.008
dgsem/3D/Float64/weak/slab double-buffered E=1 1.61 ± 0.012 ms 1.61 ± 0.0096 ms 0.997 ± 0.0093
dgsem/3D/Float64/weak/slab double-buffered E=8 2.07 ± 0.013 ms 2.06 ± 0.012 ms 1.01 ± 0.0084
dgsem/3D/Float64/weak/slab double-buffered v-last E=1 1.66 ± 0.035 ms 1.65 ± 0.01 ms 1.01 ± 0.022
dgsem/3D/Float64/weak/slab double-buffered v-last E=8 2.14 ± 0.017 ms 2.17 ± 0.012 ms 0.987 ± 0.0097
dgsem/3D/Float64/weak/slab v-last E=1 2.73 ± 0.017 ms 2.74 ± 0.023 ms 0.996 ± 0.01
dgsem/3D/Float64/weak/slab v-last E=8 6.29 ± 0.018 ms 6.23 ± 0.021 ms 1.01 ± 0.0044
launch/3D static workgroup, dynamic ndrange 11.4 ± 0.45 μs 11.9 ± 2.4 μs 0.96 ± 0.19
launch/3D static workgroup, static ndrange 10.4 ± 1.1 μs 10.6 ± 0.46 μs 0.982 ± 0.12
launch/dynamic workgroup, dynamic ndrange 12 ± 1.7 μs 16.5 ± 0.46 μs 0.727 ± 0.11
launch/dynamic workgroup, dynamic ndrange, workgroupsize given 11.7 ± 0.69 μs 12.1 ± 0.69 μs 0.969 ± 0.08
launch/static workgroup, dynamic ndrange 10.5 ± 0.46 μs 10.9 ± 0.29 μs 0.968 ± 0.05
launch/static workgroup, static ndrange 12.3 ± 3.1 μs 16.2 ± 4.1 μs 0.759 ± 0.27
narrow workgroup/masked/W=16 0.73 ± 0.018 ms 0.721 ± 0.028 ms 1.01 ± 0.046
narrow workgroup/masked/W=4 0.691 ± 0.032 ms 0.672 ± 0.024 ms 1.03 ± 0.06
narrow workgroup/unmasked/W=16 0.435 ± 0.019 ms 0.433 ± 0.017 ms 1.01 ± 0.06
narrow workgroup/unmasked/W=4 0.429 ± 0.017 ms 0.432 ± 0.019 ms 0.992 ± 0.059
partition/dynamic workgroup, dynamic ndrange 0.0596 ± 0.011 μs 0.0588 ± 0.0018 μs 1.01 ± 0.18
partition/static workgroup, dynamic ndrange 0.0665 ± 0.012 μs 0.0668 ± 0.012 μs 0.995 ± 0.25
partition/static workgroup, static ndrange 1.55 ± 0.01 ns 1.55 ± 0.01 ns 1 ± 0.0091
saxpy/default/Float16/1024 10.9 ± 3.8 μs 10.9 ± 0.56 μs 1 ± 0.36
saxpy/default/Float16/1048576 1.47 ± 0.026 ms 1.46 ± 0.021 ms 1 ± 0.023
saxpy/default/Float16/16384 0.0364 ± 0.00062 ms 0.0366 ± 0.00098 ms 0.996 ± 0.032
saxpy/default/Float16/2048 16.7 ± 1.4 μs 15.9 ± 1.3 μs 1.05 ± 0.12
saxpy/default/Float16/256 11.3 ± 0.31 μs 11.5 ± 0.26 μs 0.983 ± 0.035
saxpy/default/Float16/262144 0.403 ± 0.016 ms 0.409 ± 0.019 ms 0.985 ± 0.061
saxpy/default/Float16/32768 0.0972 ± 0.013 ms 0.098 ± 0.015 ms 0.992 ± 0.2
saxpy/default/Float16/4096 19.7 ± 0.48 μs 30.6 ± 11 μs 0.646 ± 0.24
saxpy/default/Float16/512 16 ± 0.41 μs 11.6 ± 0.39 μs 1.38 ± 0.059
saxpy/default/Float16/64 15.1 ± 4.3 μs 11.3 ± 0.24 μs 1.33 ± 0.38
saxpy/default/Float16/65536 0.146 ± 0.018 ms 0.14 ± 0.016 ms 1.05 ± 0.17
saxpy/default/Float32/1024 13.5 ± 3.8 μs 24 ± 10 μs 0.564 ± 0.29
saxpy/default/Float32/1048576 0.86 ± 0.043 ms 0.844 ± 0.043 ms 1.02 ± 0.073
saxpy/default/Float32/16384 28.4 ± 15 μs 28 ± 5.4 μs 1.01 ± 0.56
saxpy/default/Float32/2048 15.9 ± 1.1 μs 25.9 ± 9.2 μs 0.616 ± 0.22
saxpy/default/Float32/256 11.2 ± 0.49 μs 11.4 ± 4.3 μs 0.98 ± 0.38
saxpy/default/Float32/262144 0.249 ± 0.022 ms 0.252 ± 0.024 ms 0.988 ± 0.13
saxpy/default/Float32/32768 0.0411 ± 0.011 ms 0.0409 ± 0.0033 ms 1.01 ± 0.27
saxpy/default/Float32/4096 18.2 ± 10 μs 27.9 ± 11 μs 0.654 ± 0.44
saxpy/default/Float32/512 10 ± 0.48 μs 10.9 ± 13 μs 0.92 ± 1.1
saxpy/default/Float32/64 11.4 ± 0.49 μs 15.4 ± 4.8 μs 0.738 ± 0.23
saxpy/default/Float32/65536 0.114 ± 0.012 ms 0.102 ± 0.021 ms 1.12 ± 0.26
saxpy/default/Float64/1024 15.1 ± 0.55 μs 15.1 ± 0.69 μs 0.999 ± 0.059
saxpy/default/Float64/1048576 1.15 ± 0.16 ms 1.14 ± 0.12 ms 1.01 ± 0.17
saxpy/default/Float64/16384 0.0442 ± 0.0037 ms 31.2 ± 14 μs 1.42 ± 0.66
saxpy/default/Float64/2048 23.9 ± 8.8 μs 17.2 ± 8.3 μs 1.39 ± 0.84
saxpy/default/Float64/256 13.3 ± 5.2 μs 22.8 ± 13 μs 0.584 ± 0.41
saxpy/default/Float64/262144 0.259 ± 0.035 ms 0.27 ± 0.048 ms 0.962 ± 0.22
saxpy/default/Float64/32768 0.0445 ± 0.007 ms 0.0455 ± 0.017 ms 0.978 ± 0.39
saxpy/default/Float64/4096 18.2 ± 7.6 μs 18.4 ± 8 μs 0.987 ± 0.59
saxpy/default/Float64/512 13.4 ± 0.51 μs 13.5 ± 0.97 μs 0.991 ± 0.081
saxpy/default/Float64/64 16.5 ± 0.25 μs 15.4 ± 0.37 μs 1.07 ± 0.03
saxpy/default/Float64/65536 0.111 ± 0.021 ms 0.113 ± 0.024 ms 0.981 ± 0.27
saxpy/static workgroup=(1024,)/Float16/1024 23.2 ± 14 μs 10.9 ± 0.43 μs 2.13 ± 1.3
saxpy/static workgroup=(1024,)/Float16/1048576 1.47 ± 0.026 ms 1.48 ± 0.037 ms 0.988 ± 0.03
saxpy/static workgroup=(1024,)/Float16/16384 0.0367 ± 0.01 ms 0.0369 ± 0.00076 ms 0.995 ± 0.27
saxpy/static workgroup=(1024,)/Float16/2048 16.4 ± 11 μs 26.9 ± 0.78 μs 0.61 ± 0.41
saxpy/static workgroup=(1024,)/Float16/256 11.6 ± 1.2 μs 11.8 ± 0.55 μs 0.976 ± 0.11
saxpy/static workgroup=(1024,)/Float16/262144 0.411 ± 0.02 ms 0.409 ± 0.023 ms 1 ± 0.075
saxpy/static workgroup=(1024,)/Float16/32768 0.0943 ± 0.013 ms 0.0918 ± 0.014 ms 1.03 ± 0.21
saxpy/static workgroup=(1024,)/Float16/4096 19.7 ± 0.66 μs 20 ± 0.67 μs 0.984 ± 0.047
saxpy/static workgroup=(1024,)/Float16/512 11.5 ± 0.21 μs 16.5 ± 0.44 μs 0.699 ± 0.023
saxpy/static workgroup=(1024,)/Float16/64 11.5 ± 0.32 μs 11.8 ± 0.24 μs 0.975 ± 0.034
saxpy/static workgroup=(1024,)/Float16/65536 0.14 ± 0.016 ms 0.137 ± 0.015 ms 1.02 ± 0.16
saxpy/static workgroup=(1024,)/Float32/1024 24.2 ± 1.3 μs 15.6 ± 9.9 μs 1.55 ± 0.98
saxpy/static workgroup=(1024,)/Float32/1048576 0.868 ± 0.05 ms 0.848 ± 0.057 ms 1.02 ± 0.09
saxpy/static workgroup=(1024,)/Float32/16384 27.9 ± 1.8 μs 27.6 ± 5.5 μs 1.01 ± 0.21
saxpy/static workgroup=(1024,)/Float32/2048 15.8 ± 1.4 μs 15.8 ± 1.6 μs 1 ± 0.14
saxpy/static workgroup=(1024,)/Float32/256 11.7 ± 0.53 μs 15.9 ± 4.9 μs 0.733 ± 0.23
saxpy/static workgroup=(1024,)/Float32/262144 0.249 ± 0.024 ms 0.247 ± 0.022 ms 1.01 ± 0.13
saxpy/static workgroup=(1024,)/Float32/32768 0.0424 ± 0.044 ms 0.0403 ± 0.0046 ms 1.05 ± 1.1
saxpy/static workgroup=(1024,)/Float32/4096 22.9 ± 11 μs 18 ± 10 μs 1.27 ± 0.95
saxpy/static workgroup=(1024,)/Float32/512 11.9 ± 2 μs 23.1 ± 1.5 μs 0.514 ± 0.092
saxpy/static workgroup=(1024,)/Float32/64 11.3 ± 0.2 μs 12 ± 0.81 μs 0.945 ± 0.066
saxpy/static workgroup=(1024,)/Float32/65536 0.103 ± 0.018 ms 0.11 ± 0.019 ms 0.939 ± 0.23
saxpy/static workgroup=(1024,)/Float64/1024 13.5 ± 0.45 μs 15 ± 8.4 μs 0.901 ± 0.5
saxpy/static workgroup=(1024,)/Float64/1048576 1.17 ± 0.15 ms 1.04 ± 0.12 ms 1.13 ± 0.2
saxpy/static workgroup=(1024,)/Float64/16384 31.3 ± 14 μs 29.8 ± 14 μs 1.05 ± 0.7
saxpy/static workgroup=(1024,)/Float64/2048 24.7 ± 9.1 μs 16.4 ± 7.8 μs 1.51 ± 0.91
saxpy/static workgroup=(1024,)/Float64/256 14 ± 12 μs 24.2 ± 5.2 μs 0.581 ± 0.53
saxpy/static workgroup=(1024,)/Float64/262144 0.262 ± 0.033 ms 0.27 ± 0.048 ms 0.97 ± 0.21
saxpy/static workgroup=(1024,)/Float64/32768 0.0441 ± 0.0062 ms 0.0434 ± 0.012 ms 1.02 ± 0.31
saxpy/static workgroup=(1024,)/Float64/4096 18.3 ± 8.7 μs 18.1 ± 0.84 μs 1.01 ± 0.48
saxpy/static workgroup=(1024,)/Float64/512 13.8 ± 3.3 μs 14.8 ± 8.3 μs 0.931 ± 0.57
saxpy/static workgroup=(1024,)/Float64/64 12.3 ± 4.9 μs 11.8 ± 0.46 μs 1.04 ± 0.42
saxpy/static workgroup=(1024,)/Float64/65536 0.113 ± 0.02 ms 0.117 ± 0.016 ms 0.968 ± 0.22
time_to_load 0.515 ± 0.0025 s 0.52 ± 0.0044 s 0.991 ± 0.0097
main 78b2c4e... main / 78b2c4e...
const/@Const/Float32/262144 0 allocs: 0 B 0 allocs: 0 B
const/@Const/Float32/65536 0 allocs: 0 B 0 allocs: 0 B
const/@Const/Float64/262144 0 allocs: 0 B 0 allocs: 0 B
const/@Const/Float64/65536 0 allocs: 0 B 0 allocs: 0 B
const/unmarked/Float32/262144 0 allocs: 0 B 0 allocs: 0 B
const/unmarked/Float32/65536 0 allocs: 0 B 0 allocs: 0 B
const/unmarked/Float64/262144 0 allocs: 0 B 0 allocs: 0 B
const/unmarked/Float64/65536 0 allocs: 0 B 0 allocs: 0 B
dgsem/2D/Float32/fluxdiff/element 1 allocs: 16 B 1 allocs: 16 B 1
dgsem/2D/Float32/fluxdiff/node E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float32/fluxdiff/node halfsweep E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float32/fluxdiff/node halfsweep v-last E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float32/weak/element 1 allocs: 16 B 1 allocs: 16 B 1
dgsem/2D/Float32/weak/element private 1 allocs: 16 B 1 allocs: 16 B 1
dgsem/2D/Float32/weak/node localmem E=1 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float32/weak/node localmem E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float32/weak/node localmem v-last E=1 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float32/weak/node localmem v-last E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float32/weak/node recompute E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float64/fluxdiff/element 1 allocs: 16 B 1 allocs: 16 B 1
dgsem/2D/Float64/fluxdiff/node E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float64/fluxdiff/node halfsweep E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float64/fluxdiff/node halfsweep v-last E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float64/weak/element 1 allocs: 16 B 1 allocs: 16 B 1
dgsem/2D/Float64/weak/element private 1 allocs: 16 B 1 allocs: 16 B 1
dgsem/2D/Float64/weak/node localmem E=1 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float64/weak/node localmem E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float64/weak/node localmem v-last E=1 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float64/weak/node localmem v-last E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/2D/Float64/weak/node recompute E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float32/fluxdiff/element 1 allocs: 16 B 1 allocs: 16 B 1
dgsem/3D/Float32/fluxdiff/node E=2 4 allocs: 0.188 kB 4 allocs: 0.188 kB 1
dgsem/3D/Float32/fluxdiff/node halfsweep E=1 4 allocs: 0.188 kB 1 allocs: 0.0469 kB 4
dgsem/3D/Float32/fluxdiff/node halfsweep v-last E=1 4 allocs: 0.188 kB 1 allocs: 0.0469 kB 4
dgsem/3D/Float32/weak/element 1 allocs: 16 B 1 allocs: 16 B 1
dgsem/3D/Float32/weak/element private 1 allocs: 16 B 1 allocs: 16 B 1
dgsem/3D/Float32/weak/node localmem E=1 4 allocs: 0.188 kB 1 allocs: 0.0469 kB 4
dgsem/3D/Float32/weak/node localmem E=2 4 allocs: 0.188 kB 4 allocs: 0.188 kB 1
dgsem/3D/Float32/weak/node localmem v-last E=1 4 allocs: 0.188 kB 1 allocs: 0.0469 kB 4
dgsem/3D/Float32/weak/node localmem v-last E=2 4 allocs: 0.188 kB 4 allocs: 0.188 kB 1
dgsem/3D/Float32/weak/node recompute E=2 4 allocs: 0.188 kB 4 allocs: 0.188 kB 1
dgsem/3D/Float32/weak/slab E=1 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float32/weak/slab E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float32/weak/slab double-buffered E=1 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float32/weak/slab double-buffered E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float32/weak/slab double-buffered v-last E=1 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float32/weak/slab double-buffered v-last E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float32/weak/slab v-last E=1 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float32/weak/slab v-last E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float64/fluxdiff/element 1 allocs: 16 B 1 allocs: 16 B 1
dgsem/3D/Float64/fluxdiff/node E=2 4 allocs: 0.188 kB 4 allocs: 0.188 kB 1
dgsem/3D/Float64/fluxdiff/node halfsweep E=1 4 allocs: 0.188 kB 1 allocs: 0.0469 kB 4
dgsem/3D/Float64/fluxdiff/node halfsweep v-last E=1 4 allocs: 0.188 kB 1 allocs: 0.0469 kB 4
dgsem/3D/Float64/weak/element 1 allocs: 16 B 1 allocs: 16 B 1
dgsem/3D/Float64/weak/element private 1 allocs: 16 B 1 allocs: 16 B 1
dgsem/3D/Float64/weak/node localmem E=1 4 allocs: 0.188 kB 1 allocs: 0.0469 kB 4
dgsem/3D/Float64/weak/node localmem E=2 4 allocs: 0.188 kB 4 allocs: 0.188 kB 1
dgsem/3D/Float64/weak/node localmem v-last E=1 4 allocs: 0.188 kB 1 allocs: 0.0469 kB 4
dgsem/3D/Float64/weak/node localmem v-last E=2 4 allocs: 0.188 kB 4 allocs: 0.188 kB 1
dgsem/3D/Float64/weak/node recompute E=2 4 allocs: 0.188 kB 4 allocs: 0.188 kB 1
dgsem/3D/Float64/weak/slab E=1 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float64/weak/slab E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float64/weak/slab double-buffered E=1 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float64/weak/slab double-buffered E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float64/weak/slab double-buffered v-last E=1 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float64/weak/slab double-buffered v-last E=8 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float64/weak/slab v-last E=1 1 allocs: 32 B 1 allocs: 32 B 1
dgsem/3D/Float64/weak/slab v-last E=8 1 allocs: 32 B 1 allocs: 32 B 1
launch/3D static workgroup, dynamic ndrange 4 allocs: 0.125 kB 4 allocs: 0.125 kB 1
launch/3D static workgroup, static ndrange 4 allocs: 0.125 kB 4 allocs: 0.125 kB 1
launch/dynamic workgroup, dynamic ndrange 0 allocs: 0 B 0 allocs: 0 B
launch/dynamic workgroup, dynamic ndrange, workgroupsize given 0 allocs: 0 B 0 allocs: 0 B
launch/static workgroup, dynamic ndrange 0 allocs: 0 B 0 allocs: 0 B
launch/static workgroup, static ndrange 0 allocs: 0 B 0 allocs: 0 B
narrow workgroup/masked/W=16 0 allocs: 0 B 0 allocs: 0 B
narrow workgroup/masked/W=4 0 allocs: 0 B 0 allocs: 0 B
narrow workgroup/unmasked/W=16 0 allocs: 0 B 0 allocs: 0 B
narrow workgroup/unmasked/W=4 0 allocs: 0 B 0 allocs: 0 B
partition/dynamic workgroup, dynamic ndrange 2 allocs: 0.0625 kB 2 allocs: 0.0625 kB 1
partition/static workgroup, dynamic ndrange 2 allocs: 32 B 2 allocs: 32 B 1
partition/static workgroup, static ndrange 0 allocs: 0 B 0 allocs: 0 B
saxpy/default/Float16/1024 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float16/1048576 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float16/16384 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float16/2048 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float16/256 0 allocs: 0 B 0 allocs: 0 B
saxpy/default/Float16/262144 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float16/32768 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float16/4096 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float16/512 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float16/64 0 allocs: 0 B 0 allocs: 0 B
saxpy/default/Float16/65536 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float32/1024 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float32/1048576 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float32/16384 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float32/2048 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float32/256 0 allocs: 0 B 0 allocs: 0 B
saxpy/default/Float32/262144 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float32/32768 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float32/4096 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float32/512 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float32/64 0 allocs: 0 B 0 allocs: 0 B
saxpy/default/Float32/65536 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float64/1024 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float64/1048576 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float64/16384 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float64/2048 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float64/256 0 allocs: 0 B 0 allocs: 0 B
saxpy/default/Float64/262144 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float64/32768 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float64/4096 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float64/512 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/default/Float64/64 0 allocs: 0 B 0 allocs: 0 B
saxpy/default/Float64/65536 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float16/1024 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float16/1048576 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float16/16384 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float16/2048 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float16/256 0 allocs: 0 B 0 allocs: 0 B
saxpy/static workgroup=(1024,)/Float16/262144 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float16/32768 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float16/4096 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float16/512 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float16/64 0 allocs: 0 B 0 allocs: 0 B
saxpy/static workgroup=(1024,)/Float16/65536 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float32/1024 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float32/1048576 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float32/16384 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float32/2048 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float32/256 0 allocs: 0 B 0 allocs: 0 B
saxpy/static workgroup=(1024,)/Float32/262144 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float32/32768 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float32/4096 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float32/512 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float32/64 0 allocs: 0 B 0 allocs: 0 B
saxpy/static workgroup=(1024,)/Float32/65536 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float64/1024 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float64/1048576 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float64/16384 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float64/2048 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float64/256 0 allocs: 0 B 0 allocs: 0 B
saxpy/static workgroup=(1024,)/Float64/262144 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float64/32768 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float64/4096 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float64/512 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
saxpy/static workgroup=(1024,)/Float64/64 0 allocs: 0 B 0 allocs: 0 B
saxpy/static workgroup=(1024,)/Float64/65536 3 allocs: 0.0469 kB 3 allocs: 0.0469 kB 1
time_to_load 0.2 k allocs: 11.8 kB 0.2 k allocs: 11.8 kB 1

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

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 (#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>

This branch has not been deployed

No deployments
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.

CPU backend: a 4-dimensional ndrange makes kernels up to 100× slower

2 participants