Skip to content

Fold smaller workgroups of N-d launches on hardware that runs them fast - #918

Merged
maleadt merged 1 commit into
tb/ndlaunch-foldfrom
tb/fold-threshold
Oct 26, 2026
Merged

maleadt merged 1 commit into
tb/ndlaunch-foldfrom
tb/fold-threshold

Conversation

@maleadt

@maleadt maleadt commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

#919 folds tuned launches of iteration spaces with more than three dimensions onto the N-d grid only when the first three dimensions hold at least 64 work-items. Below that, NVIDIA GPUs run the folded launch slower than a linear one, but other hardware keeps gaining from folding well below 64. Folded over linear, by work-items in the first three dimensions:

64 32 16 12 8
CUDA, RTX 5080 1.35 0.72 0.45
CUDA, RTX 6000 Ada 0.85 0.51 0.50
AMDGPU, Radeon iGPU (gfx1036) 2.85 2.85 1.43 1.09 0.73
Metal, M1 1.93 1.92 1.02 0.80 0.63
oneAPI, Arc A770 1.41 1.42 1.17 1.18 0.97
PoCL, 8 threads 4.3 6.1 2.3

This makes the threshold a per-backend fold_threshold: 1 on PoCL, whose work-items are iterations of a loop, 16 on AMDGPU, Metal and oneAPI, and 64 otherwise. The default also covers the OpenCL back end, which serves NVIDIA devices too (0.90 at 64 on the RTX 6000 Ada).

Like the tunables of AcceleratedKernels, the values live in KernelAbstractions, as extensions on AMDGPU, Metal and oneAPI, rather than in the back ends, so they can be tuned without releasing those. The extensions load on Julia 1.10 and 1.13, even though their triggers depend on KernelAbstractions.

The AMDGPU numbers come from an integrated RDNA2 GPU; discrete RDNA and wave64 CDNA GPUs weren't measured.

Tested with the KA test suite on PoCL, and the KernelAbstractions tests of AMDGPU.jl (gfx1036), Metal.jl (M1) and oneAPI.jl (Arc A770), each with the extension loaded.

@maleadt
maleadt changed the base branch from main to tb/ndlaunch-fold October 23, 2026 14:42
@maleadt
maleadt added this pull request to stack #920 October 23, 2026 14:42
@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 5bc49c9... main / 5bc49c9...
const/@Const/Float32/262144 0.308 ± 0.012 ms 0.312 ± 0.012 ms 0.984 ± 0.053
const/@Const/Float32/65536 0.103 ± 0.0027 ms 0.104 ± 0.0079 ms 0.989 ± 0.08
const/@Const/Float64/262144 0.548 ± 0.013 ms 0.546 ± 0.012 ms 1 ± 0.033
const/@Const/Float64/65536 0.161 ± 0.0091 ms 0.162 ± 0.0088 ms 0.999 ± 0.079
const/unmarked/Float32/262144 0.503 ± 0.014 ms 0.503 ± 0.015 ms 0.999 ± 0.041
const/unmarked/Float32/65536 0.143 ± 0.0039 ms 0.145 ± 0.014 ms 0.991 ± 0.099
const/unmarked/Float64/262144 0.937 ± 0.016 ms 0.939 ± 0.0065 ms 0.998 ± 0.018
const/unmarked/Float64/65536 0.25 ± 0.0099 ms 0.25 ± 0.0096 ms 1 ± 0.055
dgsem/2D/Float32/fluxdiff/element 0.433 ± 0.011 ms 0.437 ± 0.0098 ms 0.99 ± 0.034
dgsem/2D/Float32/fluxdiff/node E=8 0.606 ± 0.012 ms 0.605 ± 0.011 ms 1 ± 0.027
dgsem/2D/Float32/fluxdiff/node halfsweep E=8 0.5 ± 0.014 ms 0.501 ± 0.0098 ms 0.998 ± 0.034
dgsem/2D/Float32/fluxdiff/node halfsweep v-last E=8 0.523 ± 0.0099 ms 0.525 ± 0.02 ms 0.997 ± 0.043
dgsem/2D/Float32/weak/element 0.146 ± 0.0079 ms 0.148 ± 0.014 ms 0.985 ± 0.11
dgsem/2D/Float32/weak/element private 0.16 ± 0.0092 ms 0.161 ± 0.0027 ms 0.994 ± 0.06
dgsem/2D/Float32/weak/node localmem E=1 0.143 ± 0.024 ms 0.142 ± 0.017 ms 1.01 ± 0.21
dgsem/2D/Float32/weak/node localmem E=8 0.135 ± 0.01 ms 0.135 ± 0.0032 ms 1 ± 0.077
dgsem/2D/Float32/weak/node localmem v-last E=1 0.203 ± 0.01 ms 0.202 ± 0.0096 ms 1 ± 0.07
dgsem/2D/Float32/weak/node localmem v-last E=8 0.195 ± 0.0093 ms 0.195 ± 0.0039 ms 0.998 ± 0.052
dgsem/2D/Float32/weak/node recompute E=8 0.381 ± 0.01 ms 0.384 ± 0.013 ms 0.992 ± 0.042
dgsem/2D/Float64/fluxdiff/element 0.452 ± 0.0095 ms 0.47 ± 0.016 ms 0.963 ± 0.039
dgsem/2D/Float64/fluxdiff/node E=8 0.591 ± 0.019 ms 0.589 ± 0.013 ms 1 ± 0.039
dgsem/2D/Float64/fluxdiff/node halfsweep E=8 0.462 ± 0.013 ms 0.469 ± 0.014 ms 0.985 ± 0.039
dgsem/2D/Float64/fluxdiff/node halfsweep v-last E=8 0.493 ± 0.017 ms 0.501 ± 0.019 ms 0.983 ± 0.049
dgsem/2D/Float64/weak/element 0.162 ± 0.012 ms 0.173 ± 0.0098 ms 0.936 ± 0.089
dgsem/2D/Float64/weak/element private 0.173 ± 0.0083 ms 0.177 ± 0.0026 ms 0.976 ± 0.049
dgsem/2D/Float64/weak/node localmem E=1 0.145 ± 0.0019 ms 0.146 ± 0.0028 ms 0.989 ± 0.023
dgsem/2D/Float64/weak/node localmem E=8 0.14 ± 0.025 ms 0.139 ± 0.0016 ms 1.01 ± 0.18
dgsem/2D/Float64/weak/node localmem v-last E=1 0.209 ± 0.0041 ms 0.21 ± 0.02 ms 0.998 ± 0.097
dgsem/2D/Float64/weak/node localmem v-last E=8 0.21 ± 0.021 ms 0.201 ± 0.012 ms 1.04 ± 0.12
dgsem/2D/Float64/weak/node recompute E=8 0.473 ± 0.012 ms 0.479 ± 0.014 ms 0.988 ± 0.038
dgsem/3D/Float32/fluxdiff/element 1.49 ± 0.0081 ms 1.49 ± 0.0098 ms 0.996 ± 0.0085
dgsem/3D/Float32/fluxdiff/node E=2 2.33 ± 0.047 ms 2.35 ± 0.0098 ms 0.991 ± 0.02
dgsem/3D/Float32/fluxdiff/node halfsweep E=1 1.76 ± 0.0092 ms 1.64 ± 0.017 ms 1.07 ± 0.012
dgsem/3D/Float32/fluxdiff/node halfsweep v-last E=1 2.09 ± 0.017 ms 1.95 ± 0.041 ms 1.07 ± 0.024
dgsem/3D/Float32/weak/element 0.524 ± 0.012 ms 0.525 ± 0.015 ms 0.998 ± 0.036
dgsem/3D/Float32/weak/element private 0.541 ± 0.015 ms 0.538 ± 0.015 ms 1.01 ± 0.039
dgsem/3D/Float32/weak/node localmem E=1 0.765 ± 0.023 ms 0.501 ± 0.016 ms 1.53 ± 0.068
dgsem/3D/Float32/weak/node localmem E=2 0.769 ± 0.0059 ms 0.759 ± 0.0069 ms 1.01 ± 0.012
dgsem/3D/Float32/weak/node localmem v-last E=1 1.25 ± 0.0089 ms 1.03 ± 0.0043 ms 1.22 ± 0.01
dgsem/3D/Float32/weak/node localmem v-last E=2 1.27 ± 0.0078 ms 1.26 ± 0.0083 ms 1.01 ± 0.0091
dgsem/3D/Float32/weak/node recompute E=2 1.54 ± 0.0088 ms 1.54 ± 0.0081 ms 1 ± 0.0078
dgsem/3D/Float32/weak/slab E=1 2.1 ± 0.022 ms 2.1 ± 0.036 ms 0.998 ± 0.02
dgsem/3D/Float32/weak/slab E=8 4.32 ± 0.024 ms 4.34 ± 0.041 ms 0.995 ± 0.011
dgsem/3D/Float32/weak/slab double-buffered E=1 1.24 ± 0.0065 ms 1.24 ± 0.016 ms 0.999 ± 0.014
dgsem/3D/Float32/weak/slab double-buffered E=8 1.78 ± 0.016 ms 1.75 ± 0.02 ms 1.02 ± 0.015
dgsem/3D/Float32/weak/slab double-buffered v-last E=1 1.28 ± 0.0075 ms 1.29 ± 0.018 ms 0.991 ± 0.015
dgsem/3D/Float32/weak/slab double-buffered v-last E=8 1.91 ± 0.012 ms 1.84 ± 0.033 ms 1.04 ± 0.02
dgsem/3D/Float32/weak/slab v-last E=1 2.07 ± 0.0071 ms 2.1 ± 0.0086 ms 0.986 ± 0.0053
dgsem/3D/Float32/weak/slab v-last E=8 4.3 ± 0.037 ms 4.35 ± 0.043 ms 0.989 ± 0.013
dgsem/3D/Float64/fluxdiff/element 1.61 ± 0.011 ms 1.61 ± 0.0093 ms 0.997 ± 0.0091
dgsem/3D/Float64/fluxdiff/node E=2 2.37 ± 0.011 ms 2.41 ± 0.012 ms 0.983 ± 0.0069
dgsem/3D/Float64/fluxdiff/node halfsweep E=1 1.78 ± 0.019 ms 1.69 ± 0.032 ms 1.05 ± 0.023
dgsem/3D/Float64/fluxdiff/node halfsweep v-last E=1 2.22 ± 0.028 ms 2.04 ± 0.037 ms 1.09 ± 0.024
dgsem/3D/Float64/weak/element 0.625 ± 0.016 ms 0.63 ± 0.017 ms 0.992 ± 0.038
dgsem/3D/Float64/weak/element private 0.648 ± 0.015 ms 0.644 ± 0.01 ms 1.01 ± 0.028
dgsem/3D/Float64/weak/node localmem E=1 0.807 ± 0.02 ms 0.526 ± 0.011 ms 1.53 ± 0.05
dgsem/3D/Float64/weak/node localmem E=2 0.825 ± 0.015 ms 0.828 ± 0.023 ms 0.996 ± 0.033
dgsem/3D/Float64/weak/node localmem v-last E=1 1.28 ± 0.011 ms 1.04 ± 0.0032 ms 1.23 ± 0.012
dgsem/3D/Float64/weak/node localmem v-last E=2 1.3 ± 0.01 ms 1.28 ± 0.026 ms 1.01 ± 0.022
dgsem/3D/Float64/weak/node recompute E=2 1.69 ± 0.016 ms 1.68 ± 0.039 ms 1.01 ± 0.025
dgsem/3D/Float64/weak/slab E=1 2.14 ± 0.019 ms 2.23 ± 0.022 ms 0.959 ± 0.013
dgsem/3D/Float64/weak/slab E=8 5.32 ± 0.25 ms 5.12 ± 0.053 ms 1.04 ± 0.049
dgsem/3D/Float64/weak/slab double-buffered E=1 1.29 ± 0.012 ms 1.27 ± 0.0096 ms 1.01 ± 0.012
dgsem/3D/Float64/weak/slab double-buffered E=8 1.79 ± 0.027 ms 1.87 ± 0.047 ms 0.956 ± 0.028
dgsem/3D/Float64/weak/slab double-buffered v-last E=1 1.29 ± 0.017 ms 1.28 ± 0.015 ms 1.01 ± 0.018
dgsem/3D/Float64/weak/slab double-buffered v-last E=8 1.79 ± 0.019 ms 1.85 ± 0.024 ms 0.967 ± 0.016
dgsem/3D/Float64/weak/slab v-last E=1 2.17 ± 0.036 ms 2.35 ± 0.023 ms 0.924 ± 0.018
dgsem/3D/Float64/weak/slab v-last E=8 5.13 ± 0.05 ms 5.13 ± 0.043 ms 1 ± 0.013
launch/3D static workgroup, dynamic ndrange 8.84 ± 0.78 μs 8.85 ± 0.64 μs 0.999 ± 0.11
launch/3D static workgroup, static ndrange 8.93 ± 1 μs 9.01 ± 0.85 μs 0.992 ± 0.15
launch/dynamic workgroup, dynamic ndrange 8.71 ± 1 μs 8.58 ± 0.99 μs 1.02 ± 0.17
launch/dynamic workgroup, dynamic ndrange, workgroupsize given 9.75 ± 2.3 μs 8.46 ± 0.98 μs 1.15 ± 0.3
launch/static workgroup, dynamic ndrange 9.36 ± 1.8 μs 8.47 ± 1.5 μs 1.11 ± 0.28
launch/static workgroup, static ndrange 8.48 ± 1.3 μs 8.67 ± 1.7 μs 0.978 ± 0.25
narrow workgroup/masked/W=16 0.397 ± 0.011 ms 0.396 ± 0.011 ms 1 ± 0.041
narrow workgroup/masked/W=4 0.39 ± 0.013 ms 0.385 ± 0.011 ms 1.01 ± 0.045
narrow workgroup/unmasked/W=16 0.394 ± 0.012 ms 0.393 ± 0.012 ms 1 ± 0.043
narrow workgroup/unmasked/W=4 0.393 ± 0.011 ms 0.393 ± 0.011 ms 1 ± 0.038
partition/dynamic workgroup, dynamic ndrange 0.0496 ± 0.02 μs 0.0473 ± 0.019 μs 1.05 ± 0.6
partition/static workgroup, dynamic ndrange 0.0549 ± 0.011 μs 0.0551 ± 0.011 μs 0.998 ± 0.29
partition/static workgroup, static ndrange 1.35 ± 0 ns 1.35 ± 0 ns 1 ± 0
saxpy/default/Float16/1024 9.7 ± 1 μs 9.1 ± 0.9 μs 1.07 ± 0.16
saxpy/default/Float16/1048576 0.378 ± 0.013 ms 0.379 ± 0.015 ms 0.999 ± 0.052
saxpy/default/Float16/16384 16.7 ± 0.98 μs 16.6 ± 0.58 μs 1 ± 0.069
saxpy/default/Float16/2048 10.4 ± 2.6 μs 10.9 ± 2 μs 0.956 ± 0.3
saxpy/default/Float16/256 8.35 ± 1.3 μs 8.26 ± 1.2 μs 1.01 ± 0.22
saxpy/default/Float16/262144 0.124 ± 0.0087 ms 0.123 ± 0.008 ms 1.01 ± 0.097
saxpy/default/Float16/32768 22 ± 0.55 μs 22.1 ± 0.56 μs 0.995 ± 0.036
saxpy/default/Float16/4096 12.5 ± 0.53 μs 13.1 ± 2.4 μs 0.958 ± 0.18
saxpy/default/Float16/512 9.35 ± 0.33 μs 9.43 ± 0.42 μs 0.992 ± 0.056
saxpy/default/Float16/64 8.17 ± 0.28 μs 8.19 ± 0.31 μs 0.998 ± 0.051
saxpy/default/Float16/65536 0.0328 ± 0.00088 ms 0.0329 ± 0.00087 ms 0.996 ± 0.038
saxpy/default/Float32/1024 11.5 ± 0.54 μs 11.5 ± 0.21 μs 0.999 ± 0.05
saxpy/default/Float32/1048576 0.253 ± 0.028 ms 0.248 ± 0.024 ms 1.02 ± 0.15
saxpy/default/Float32/16384 15.7 ± 1.4 μs 16.4 ± 2.2 μs 0.956 ± 0.15
saxpy/default/Float32/2048 9.7 ± 1.1 μs 9.77 ± 2.6 μs 0.992 ± 0.29
saxpy/default/Float32/256 9.06 ± 0.93 μs 9.63 ± 2.1 μs 0.941 ± 0.23
saxpy/default/Float32/262144 0.0945 ± 0.016 ms 0.0939 ± 0.014 ms 1.01 ± 0.23
saxpy/default/Float32/32768 20.4 ± 2.7 μs 20.2 ± 2.9 μs 1.01 ± 0.2
saxpy/default/Float32/4096 10.1 ± 1.2 μs 9.65 ± 1.5 μs 1.04 ± 0.21
saxpy/default/Float32/512 9.61 ± 2.3 μs 9.19 ± 1.7 μs 1.05 ± 0.32
saxpy/default/Float32/64 8.1 ± 0.32 μs 8.48 ± 0.93 μs 0.955 ± 0.11
saxpy/default/Float32/65536 27.5 ± 5.7 μs 0.0321 ± 0.007 ms 0.857 ± 0.26
saxpy/default/Float64/1024 9.85 ± 2 μs 9.78 ± 2.7 μs 1.01 ± 0.34
saxpy/default/Float64/1048576 0.521 ± 0.047 ms 0.506 ± 0.053 ms 1.03 ± 0.14
saxpy/default/Float64/16384 20 ± 2.3 μs 20.3 ± 2.8 μs 0.982 ± 0.18
saxpy/default/Float64/2048 9.93 ± 1.1 μs 11.5 ± 1.7 μs 0.863 ± 0.16
saxpy/default/Float64/256 11.1 ± 0.29 μs 9.31 ± 2.1 μs 1.19 ± 0.27
saxpy/default/Float64/262144 0.124 ± 0.013 ms 0.124 ± 0.012 ms 0.997 ± 0.14
saxpy/default/Float64/32768 27.3 ± 6.2 μs 28.5 ± 5.4 μs 0.96 ± 0.28
saxpy/default/Float64/4096 13.7 ± 1 μs 13.6 ± 0.72 μs 1 ± 0.092
saxpy/default/Float64/512 9.59 ± 1.9 μs 9.54 ± 1.1 μs 1 ± 0.23
saxpy/default/Float64/64 8.2 ± 1.4 μs 8.98 ± 0.94 μs 0.913 ± 0.18
saxpy/default/Float64/65536 0.0446 ± 0.0059 ms 0.0441 ± 0.0064 ms 1.01 ± 0.2
saxpy/static workgroup=(1024,)/Float16/1024 9.01 ± 0.96 μs 8.83 ± 1.3 μs 1.02 ± 0.19
saxpy/static workgroup=(1024,)/Float16/1048576 0.378 ± 0.015 ms 0.379 ± 0.017 ms 0.997 ± 0.06
saxpy/static workgroup=(1024,)/Float16/16384 17 ± 1.7 μs 16.5 ± 0.51 μs 1.03 ± 0.11
saxpy/static workgroup=(1024,)/Float16/2048 10 ± 0.98 μs 10 ± 1.9 μs 1 ± 0.22
saxpy/static workgroup=(1024,)/Float16/256 8.45 ± 0.28 μs 8.43 ± 0.28 μs 1 ± 0.047
saxpy/static workgroup=(1024,)/Float16/262144 0.124 ± 0.0075 ms 0.124 ± 0.0078 ms 1 ± 0.088
saxpy/static workgroup=(1024,)/Float16/32768 22 ± 0.94 μs 22.2 ± 3.1 μs 0.989 ± 0.15
saxpy/static workgroup=(1024,)/Float16/4096 14 ± 1.7 μs 10.6 ± 1.4 μs 1.32 ± 0.24
saxpy/static workgroup=(1024,)/Float16/512 9.66 ± 0.83 μs 9.6 ± 0.83 μs 1.01 ± 0.12
saxpy/static workgroup=(1024,)/Float16/64 10.2 ± 0.34 μs 8.44 ± 0.17 μs 1.21 ± 0.047
saxpy/static workgroup=(1024,)/Float16/65536 0.0326 ± 0.00073 ms 0.0328 ± 0.00072 ms 0.995 ± 0.031
saxpy/static workgroup=(1024,)/Float32/1024 10.8 ± 1.8 μs 9.44 ± 1.7 μs 1.14 ± 0.28
saxpy/static workgroup=(1024,)/Float32/1048576 0.277 ± 0.043 ms 0.246 ± 0.029 ms 1.12 ± 0.22
saxpy/static workgroup=(1024,)/Float32/16384 15 ± 0.97 μs 16.7 ± 0.67 μs 0.899 ± 0.068
saxpy/static workgroup=(1024,)/Float32/2048 9.68 ± 1.2 μs 9.27 ± 1.1 μs 1.04 ± 0.17
saxpy/static workgroup=(1024,)/Float32/256 8.34 ± 0.92 μs 8.41 ± 0.83 μs 0.992 ± 0.15
saxpy/static workgroup=(1024,)/Float32/262144 0.0985 ± 0.017 ms 0.0973 ± 0.016 ms 1.01 ± 0.24
saxpy/static workgroup=(1024,)/Float32/32768 20.1 ± 3 μs 21.5 ± 1.2 μs 0.935 ± 0.15
saxpy/static workgroup=(1024,)/Float32/4096 10.2 ± 1.7 μs 9.52 ± 1.2 μs 1.07 ± 0.22
saxpy/static workgroup=(1024,)/Float32/512 9.31 ± 1.3 μs 9.3 ± 1.7 μs 1 ± 0.23
saxpy/static workgroup=(1024,)/Float32/64 8.37 ± 0.2 μs 8.34 ± 0.16 μs 1 ± 0.03
saxpy/static workgroup=(1024,)/Float32/65536 0.0318 ± 0.0076 ms 29.7 ± 6.5 μs 1.07 ± 0.35
saxpy/static workgroup=(1024,)/Float64/1024 11.3 ± 1.7 μs 9.37 ± 1.3 μs 1.2 ± 0.25
saxpy/static workgroup=(1024,)/Float64/1048576 0.548 ± 0.049 ms 0.504 ± 0.042 ms 1.09 ± 0.13
saxpy/static workgroup=(1024,)/Float64/16384 19.6 ± 1.6 μs 20.5 ± 2.8 μs 0.959 ± 0.15
saxpy/static workgroup=(1024,)/Float64/2048 9.97 ± 1.7 μs 10 ± 1.7 μs 0.997 ± 0.23
saxpy/static workgroup=(1024,)/Float64/256 10.3 ± 21 μs 10.7 ± 19 μs 0.966 ± 2.6
saxpy/static workgroup=(1024,)/Float64/262144 0.126 ± 0.015 ms 0.125 ± 0.013 ms 1.01 ± 0.16
saxpy/static workgroup=(1024,)/Float64/32768 29.2 ± 4.3 μs 29.1 ± 6.3 μs 1 ± 0.26
saxpy/static workgroup=(1024,)/Float64/4096 10.2 ± 1.5 μs 10.6 ± 1.6 μs 0.961 ± 0.2
saxpy/static workgroup=(1024,)/Float64/512 9.53 ± 1.4 μs 9.18 ± 1.1 μs 1.04 ± 0.2
saxpy/static workgroup=(1024,)/Float64/64 8.68 ± 1.7 μs 8.47 ± 1.8 μs 1.03 ± 0.3
saxpy/static workgroup=(1024,)/Float64/65536 0.0418 ± 0.0087 ms 0.0434 ± 0.0067 ms 0.964 ± 0.25
time_to_load 0.473 ± 0.013 s 0.448 ± 0.00093 s 1.06 ± 0.029
main 5bc49c9... main / 5bc49c9...
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).

A tuned launch of an iteration space with more than three dimensions is
only folded onto the N-d grid if the first three dimensions hold 64
work-items. Below that, NVIDIA GPUs run the folded launch slower than a
linear one, but other hardware keeps gaining from it. Folded over
linear, for a kernel scaling an array, by work-items in the first three
dimensions:

                         64     32     16      8
  CUDA, RTX 5080       1.35   0.72      -   0.45
  CUDA, RTX 6000 Ada   0.85   0.51      -   0.50
  AMDGPU, gfx1036      2.85   2.85   1.43   0.73
  Metal, M1            1.93   1.92   1.02   0.63
  oneAPI, Arc A770     1.41   1.42   1.17   0.97
  PoCL, 8 threads      4.3    6.1       -   2.3

Make the threshold a per-backend `fold_threshold`: 1 on PoCL, 16 on
AMDGPU, Metal and oneAPI, and 64 otherwise, which also covers OpenCL
devices from NVIDIA. Like the tunables of AcceleratedKernels, the values
live in KernelAbstractions (in extensions on the back ends), so they can
be changed without releasing those.
@codecov

codecov Bot commented Oct 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.91%. Comparing base (78b2c4e) to head (5bc49c9).

Additional details and impacted files
@@                 Coverage Diff                  @@
##           tb/ndlaunch-fold     #918      +/-   ##
====================================================
+ Coverage             82.87%   82.91%   +0.03%     
====================================================
  Files                    28       31       +3     
  Lines                  2494     2499       +5     
====================================================
+ Hits                   2067     2072       +5     
  Misses                  427      427              

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

@maleadt
maleadt merged commit a103347 into main Oct 26, 2026
69 checks passed
@maleadt
maleadt deleted the tb/fold-threshold branch October 26, 2026 05:46
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