Skip to content

DGSEM benchmarks: variants with tiles (#864) - #874

Draft
vchuravy wants to merge 1 commit into
mainfrom
vc/dgsem-benchmarks-tiles
Draft

vchuravy wants to merge 1 commit into
mainfrom
vc/dgsem-benchmarks-tiles

Conversation

@vchuravy

@vchuravy vchuravy commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

Stacked on #875 (← #871 ← #870 ← #866). Uses the tiles of #864.

Restacked on #875 (the per-backend local-memory layout switch): weak/node localmem tile_barrier now takes the layout too, and gets a variant in the backend's other layout. The timings below were taken before the restack, when the unsuffixed local-memory variants used the variable index first on every backend. On CUDA the two layouts are within 5% of each other in these kernels (see #875), so the comparisons still hold.

This adds DGSEM kernels with tiles. The N² = 16 work-items of an element (2D) or of a slab (3D) form a tile, and they exchange values with tile_shfl instead of @localmem and @synchronize. The kernels are in a new benchmark/dgsem_tiles.jl, which dgsem.jl only includes if KernelAbstractions defines tile_shfl, so the suite still runs without #864. The variants:

name
weak/node tile E=… (2D) as weak/node localmem: the fluxes of the other nodes on a line come from tile_shfl
weak/node localmem tile_barrier E=… (2D) weak/node localmem with tile_barrier instead of @synchronize, since each element reads only its own local memory; in the backend's default layout and the other one (#875)
fluxdiff/node halfsweep tile E=… (2D) each two-point flux is computed once and exchanged with tile_shfl, as are the partner's state and metric terms. For control flow that is uniform over the tile, node i computes the fluxes with i + o (cyclically) for o in 1:N÷2 and gets those with i - o from those nodes; for even N the pair at o = N÷2 is computed by both, with half the weight
weak/slab tile E=… (3D) weak/slab with the slab's fluxes from tile_shfl: no local memory and no barrier

They use the N-D ndrange (N, N, nelem) and narrow tiles that share a sub-group, from #864's latest commit (214d8c3). The lane of node (i, j) is i + N(j - 1). E (tiles per workgroup) is min(128 ÷ N², tiles_per_workgroup(backend, N²)): 8 on CUDA, 1 on PoCL. Tile kernels are only added when tiles_per_workgroup allows the width. This adds 7 benchmarks per precision on backends with tiles.

The design follows a local study of #864 for Trixi-style DGSEM kernels (posted as feedback on #864), but uses the N-D ndrange instead of mapping lanes to nodes by hand.

⚠️ Tuple shuffles crash on PoCL with #864's head

On PoCL, tile_shfl of any tuple of two or more elements fails at kernel compilation, and the process exits:

InvalidModule: Invalid SPIR-V module: input SPIR-V module uses extension 'SPV_INTEL_subgroups' which were disabled by --spirv-ext option

#864 includes 4694613 ("POCL: shuffle packed structs with vector shuffles"), which shuffles packed structs with __spirv_SubgroupShuffleINTEL on devices with cl_intel_subgroups. Its commit message says PoCL's CPU device accepts these since pocl/pocl#2394, but that PR is still open. The released pocl_standalone_jll 7.2.2+4 advertises cl_intel_subgroups, but rejects the module. Reproducer, with KA at 214d8c3 and pocl_standalone_jll 7.2.2+4:

using KernelAbstractions
@kernel tile function shfl_tuple!(out, @Const(x))
    t = @tile()
    I = @index(Global, Linear)
    v = tile_shfl(t, (x[1, I], x[2, I]), 1)
    out[1, I], out[2, I] = v
end
x = KernelAbstractions.allocate(CPU(), Float32, 2, 16)
shfl_tuple!(CPU(), 16; tile = 16)(similar(x), x; ndrange = 16)

Scalar shuffles and NTuple{1} work. So until that is fixed in #864 (or PoCL), three of the four tile variants crash the CPU benchmark run: all except tile_barrier. To check these kernels on PoCL, I swapped tile_shfl of a tuple for a shuffle per element in a scratch copy. That copy is what the PoCL numbers below measure.

Correctness

I compared every variant with weak/element or fluxdiff/element in 2D and 3D (including a partially filled last workgroup), in Float32 and Float64: 92 of 92 within 100 eps on CUDA, and on PoCL with the per-element shuffles. Without #864 (KA main from #866), the 82 non-tile checks still pass, so the include guard works. The tile versions of the weak form and the slab kernel give exactly the same results as their local-memory counterparts.

Timings

Minimum / median in µs, at the suite's mesh sizes (2D 256² elements and 3D 32³ on CUDA).

CUDA, Quadro RTX 4000, CUDA.jl vc/ki-subgroup-ops (CUDACore) and KA at 214d8c3. Both runs waited for an idle GPU; in both, another process had started by the time they ended.

2D F32 2D F64 3D F32 3D F64
weak/node localmem E=8 / E=2 141 / 143 528 / 553 428 / 432 1830 / 1947
weak/node localmem tile_barrier E=8 143 / 144 529 / 566
weak/node tile E=8 144 / 145 545 / 582
fluxdiff/node (full sweep) E=8 257 / 269 2918 / 2923
fluxdiff/node halfsweep E=8 322 / 359 2470 / 2474
fluxdiff/node halfsweep v-last E=8 313 / 352 2478 / 2481
fluxdiff/node halfsweep tile E=8 144 / 171 1782 / 1788
weak/slab E=8 445 / 458 1849 / 1955
weak/slab double-buffered E=8 440 / 452 1851 / 1954
weak/slab tile E=8 434 / 438 1865 / 1987

PoCL, 1 thread, with the per-element shuffle workaround (E = 1: PoCL can't put narrow tiles side by side, so each tile is a workgroup of 16):

2D F32 2D F64 3D F32 3D F64
weak/node localmem E=1 111 / 117 121 / 128 434 / 474 462 / 485
weak/node localmem tile_barrier E=1 186 / 199 212 / 217
weak/node tile E=1 560 / 583 856 / 902
fluxdiff/node halfsweep E=8 / E=1 354 / 371 386 / 410
fluxdiff/node halfsweep tile E=1 853 / 884 1362 / 1412
weak/slab double-buffered E=1 1056 / 1100 1068 / 1115
weak/slab tile E=1 1771 / 1852 2975 / 3026

Observations:

  • CUDA, half sweep: the tile version is the fastest flux differencing kernel. In Float32 it is 2.2× faster than the local-memory half sweep and 1.8× faster than the full sweep. In Float64 it is 1.4× faster than the local-memory half sweep. It has no local memory or barrier, and it also gets the partner's state from a shuffle instead of global memory.
  • CUDA, weak form and slab: about the same as local memory, within 3%. In Float64 the shuffles are 1–3% slower, since each double takes two SHFL. tile_barrier costs the same as @synchronize.
  • PoCL: every sub-group operation is a work-group barrier, so the shuffle kernels are 2–7× slower than local memory there, with per-element shuffles. Even tile_barrier is 1.7× slower than @synchronize, with the same 16-work-item workgroups. With working vector shuffles (Accept SPV_INTEL_subgroups SPIR-V on the CPU device again pocl/pocl#2394) the shuffle kernels should improve: 4694613 measured 2.7× for SVector{4, Float32}.

🤖 Generated with Claude Code

@codecov

codecov Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.49%. Comparing base (bc4014d) to head (e133135).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##            main     #874       +/-   ##
==========================================
+ Coverage   1.96%   80.49%   +78.52%     
==========================================
  Files         24       26        +2     
  Lines       1980     2210      +230     
==========================================
+ Hits          39     1779     +1740     
+ Misses      1941      431     -1510     

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

@vchuravy
vchuravy force-pushed the vc/dgsem-benchmarks-tiles branch from db555f2 to 96ef92d Compare October 11, 2026 12:07
@github-actions

github-actions Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Benchmark Results

Show table
main e133135... main / e133135...
const/@Const/Float32/262144 0.534 ± 0.027 ms 0.535 ± 0.029 ms 0.998 ± 0.074
const/@Const/Float32/65536 0.216 ± 0.0092 ms 0.223 ± 0.0071 ms 0.97 ± 0.051
const/@Const/Float64/262144 0.891 ± 0.02 ms 0.893 ± 0.019 ms 0.997 ± 0.031
const/@Const/Float64/65536 0.366 ± 0.014 ms 0.369 ± 0.015 ms 0.992 ± 0.054
const/unmarked/Float32/262144 2.34 ± 0.025 ms 2.28 ± 0.027 ms 1.02 ± 0.016
const/unmarked/Float32/65536 0.608 ± 0.026 ms 0.604 ± 0.021 ms 1.01 ± 0.055
const/unmarked/Float64/262144 3.11 ± 0.034 ms 3.11 ± 0.031 ms 1 ± 0.015
const/unmarked/Float64/65536 0.804 ± 0.012 ms 0.814 ± 0.026 ms 0.988 ± 0.035
dgsem/2D/Float32/fluxdiff/element 0.577 ± 0.014 ms 0.558 ± 0.019 ms 1.03 ± 0.043
dgsem/2D/Float32/fluxdiff/node E=8 0.793 ± 0.0098 ms 0.788 ± 0.0081 ms 1.01 ± 0.016
dgsem/2D/Float32/fluxdiff/node halfsweep E=8 0.579 ± 0.017 ms 0.575 ± 0.016 ms 1.01 ± 0.04
dgsem/2D/Float32/fluxdiff/node halfsweep v-last E=8 0.605 ± 0.016 ms 0.607 ± 0.033 ms 0.997 ± 0.06
dgsem/2D/Float32/weak/element 0.208 ± 0.0038 ms 0.209 ± 0.013 ms 0.996 ± 0.066
dgsem/2D/Float32/weak/element private 0.217 ± 0.016 ms 0.229 ± 0.0068 ms 0.947 ± 0.073
dgsem/2D/Float32/weak/node localmem E=1 0.219 ± 0.028 ms 0.198 ± 0.003 ms 1.11 ± 0.14
dgsem/2D/Float32/weak/node localmem E=8 0.224 ± 0.027 ms 0.226 ± 0.028 ms 0.991 ± 0.17
dgsem/2D/Float32/weak/node localmem v-last E=1 0.265 ± 0.024 ms 0.26 ± 0.014 ms 1.02 ± 0.11
dgsem/2D/Float32/weak/node localmem v-last E=8 0.27 ± 0.018 ms 0.291 ± 0.03 ms 0.927 ± 0.12
dgsem/2D/Float32/weak/node recompute E=8 0.533 ± 0.025 ms 0.537 ± 0.015 ms 0.993 ± 0.054
dgsem/2D/Float64/fluxdiff/element 0.593 ± 0.022 ms 0.591 ± 0.013 ms 1 ± 0.044
dgsem/2D/Float64/fluxdiff/node E=8 0.799 ± 0.015 ms 0.802 ± 0.022 ms 0.997 ± 0.034
dgsem/2D/Float64/fluxdiff/node halfsweep E=8 0.627 ± 0.028 ms 0.622 ± 0.021 ms 1.01 ± 0.056
dgsem/2D/Float64/fluxdiff/node halfsweep v-last E=8 0.647 ± 0.021 ms 0.645 ± 0.013 ms 1 ± 0.038
dgsem/2D/Float64/weak/element 0.251 ± 0.017 ms 0.25 ± 0.019 ms 1 ± 0.1
dgsem/2D/Float64/weak/element private 0.236 ± 0.014 ms 0.246 ± 0.014 ms 0.958 ± 0.079
dgsem/2D/Float64/weak/node localmem E=1 0.204 ± 0.0046 ms 0.202 ± 0.0081 ms 1.01 ± 0.047
dgsem/2D/Float64/weak/node localmem E=8 0.202 ± 0.026 ms 0.205 ± 0.019 ms 0.987 ± 0.16
dgsem/2D/Float64/weak/node localmem v-last E=1 0.293 ± 0.024 ms 0.287 ± 0.023 ms 1.02 ± 0.12
dgsem/2D/Float64/weak/node localmem v-last E=8 0.293 ± 0.025 ms 0.277 ± 0.012 ms 1.06 ± 0.1
dgsem/2D/Float64/weak/node recompute E=8 0.668 ± 0.015 ms 0.657 ± 0.018 ms 1.02 ± 0.036
dgsem/3D/Float32/fluxdiff/element 1.89 ± 0.021 ms 1.89 ± 0.023 ms 0.999 ± 0.016
dgsem/3D/Float32/fluxdiff/node E=2 3.23 ± 0.014 ms 3.22 ± 0.012 ms 1 ± 0.0057
dgsem/3D/Float32/fluxdiff/node halfsweep E=1 2.44 ± 0.043 ms 2.47 ± 0.038 ms 0.989 ± 0.023
dgsem/3D/Float32/fluxdiff/node halfsweep v-last E=1 2.13 ± 0.018 ms 2.11 ± 0.0098 ms 1.01 ± 0.0097
dgsem/3D/Float32/weak/element 0.668 ± 0.018 ms 0.661 ± 0.019 ms 1.01 ± 0.04
dgsem/3D/Float32/weak/element private 0.689 ± 0.015 ms 0.696 ± 0.016 ms 0.991 ± 0.032
dgsem/3D/Float32/weak/node localmem E=1 0.684 ± 0.011 ms 0.701 ± 0.027 ms 0.976 ± 0.04
dgsem/3D/Float32/weak/node localmem E=2 0.835 ± 0.0039 ms 0.844 ± 0.0055 ms 0.989 ± 0.0079
dgsem/3D/Float32/weak/node localmem v-last E=1 0.909 ± 0.0065 ms 0.899 ± 0.0053 ms 1.01 ± 0.0094
dgsem/3D/Float32/weak/node localmem v-last E=2 1.07 ± 0.0036 ms 1.04 ± 0.0098 ms 1.03 ± 0.01
dgsem/3D/Float32/weak/node recompute E=2 2.13 ± 0.017 ms 2.12 ± 0.014 ms 1 ± 0.01
dgsem/3D/Float32/weak/slab E=1 2.78 ± 0.043 ms 2.65 ± 0.0095 ms 1.05 ± 0.016
dgsem/3D/Float32/weak/slab E=8 5.49 ± 0.016 ms 5.4 ± 0.014 ms 1.02 ± 0.004
dgsem/3D/Float32/weak/slab double-buffered E=1 1.64 ± 0.012 ms 1.71 ± 0.013 ms 0.96 ± 0.01
dgsem/3D/Float32/weak/slab double-buffered E=8 2.05 ± 0.013 ms 2.05 ± 0.01 ms 0.998 ± 0.008
dgsem/3D/Float32/weak/slab double-buffered v-last E=1 1.63 ± 0.023 ms 1.69 ± 0.024 ms 0.961 ± 0.019
dgsem/3D/Float32/weak/slab double-buffered v-last E=8 2.11 ± 0.018 ms 2.1 ± 0.012 ms 1.01 ± 0.01
dgsem/3D/Float32/weak/slab v-last E=1 2.77 ± 0.041 ms 2.7 ± 0.0097 ms 1.03 ± 0.016
dgsem/3D/Float32/weak/slab v-last E=8 5.4 ± 0.038 ms 5.34 ± 0.02 ms 1.01 ± 0.008
dgsem/3D/Float64/fluxdiff/element 1.96 ± 0.023 ms 1.94 ± 0.0088 ms 1.01 ± 0.013
dgsem/3D/Float64/fluxdiff/node E=2 2.99 ± 0.012 ms 2.99 ± 0.013 ms 1 ± 0.0058
dgsem/3D/Float64/fluxdiff/node halfsweep E=1 2.26 ± 0.01 ms 2.26 ± 0.021 ms 1 ± 0.01
dgsem/3D/Float64/fluxdiff/node halfsweep v-last E=1 2.23 ± 0.027 ms 2.23 ± 0.014 ms 1 ± 0.014
dgsem/3D/Float64/weak/element 0.807 ± 0.015 ms 0.815 ± 0.015 ms 0.99 ± 0.026
dgsem/3D/Float64/weak/element private 0.843 ± 0.0074 ms 0.84 ± 0.0067 ms 1 ± 0.012
dgsem/3D/Float64/weak/node localmem E=1 0.723 ± 0.0099 ms 0.722 ± 0.011 ms 1 ± 0.021
dgsem/3D/Float64/weak/node localmem E=2 0.853 ± 0.0053 ms 0.849 ± 0.012 ms 1 ± 0.016
dgsem/3D/Float64/weak/node localmem v-last E=1 0.905 ± 0.013 ms 0.905 ± 0.0088 ms 1 ± 0.017
dgsem/3D/Float64/weak/node localmem v-last E=2 1.05 ± 0.0044 ms 1.07 ± 0.0089 ms 0.982 ± 0.0091
dgsem/3D/Float64/weak/node recompute E=2 2.25 ± 0.033 ms 2.21 ± 0.02 ms 1.02 ± 0.017
dgsem/3D/Float64/weak/slab E=1 2.88 ± 0.044 ms 2.82 ± 0.011 ms 1.02 ± 0.016
dgsem/3D/Float64/weak/slab E=8 6.25 ± 0.052 ms 6.35 ± 0.04 ms 0.985 ± 0.01
dgsem/3D/Float64/weak/slab double-buffered E=1 1.68 ± 0.011 ms 1.75 ± 0.014 ms 0.96 ± 0.01
dgsem/3D/Float64/weak/slab double-buffered E=8 2.16 ± 0.012 ms 2.11 ± 0.014 ms 1.02 ± 0.0089
dgsem/3D/Float64/weak/slab double-buffered v-last E=1 1.64 ± 0.012 ms 1.73 ± 0.013 ms 0.947 ± 0.0099
dgsem/3D/Float64/weak/slab double-buffered v-last E=8 2.18 ± 0.03 ms 2.19 ± 0.012 ms 0.995 ± 0.015
dgsem/3D/Float64/weak/slab v-last E=1 2.93 ± 0.038 ms 2.77 ± 0.028 ms 1.06 ± 0.017
dgsem/3D/Float64/weak/slab v-last E=8 6.12 ± 0.033 ms 6.24 ± 0.023 ms 0.981 ± 0.0063
launch/3D static workgroup, dynamic ndrange 23.5 ± 14 μs 10.9 ± 0.53 μs 2.16 ± 1.3
launch/3D static workgroup, static ndrange 11.5 ± 0.32 μs 11 ± 13 μs 1.05 ± 1.2
launch/dynamic workgroup, dynamic ndrange 16.8 ± 0.81 μs 12.4 ± 0.54 μs 1.35 ± 0.088
launch/dynamic workgroup, dynamic ndrange, workgroupsize given 11.8 ± 0.24 μs 16.8 ± 0.42 μs 0.702 ± 0.023
launch/static workgroup, dynamic ndrange 10.6 ± 0.29 μs 10.9 ± 0.19 μs 0.975 ± 0.032
launch/static workgroup, static ndrange 10.2 ± 0.5 μs 10.9 ± 0.61 μs 0.941 ± 0.07
partition/dynamic workgroup, dynamic ndrange 0.0586 ± 0.0018 μs 0.0586 ± 0.0023 μs 1 ± 0.05
partition/static workgroup, dynamic ndrange 0.0684 ± 0.012 μs 0.0667 ± 0.012 μs 1.03 ± 0.26
partition/static workgroup, static ndrange 1.55 ± 0.009 ns 1.55 ± 0.01 ns 1 ± 0.0087
saxpy/default/Float16/1024 26.3 ± 11 μs 12.3 ± 4.6 μs 2.14 ± 1.2
saxpy/default/Float16/1048576 1.47 ± 0.027 ms 1.48 ± 0.026 ms 0.993 ± 0.025
saxpy/default/Float16/16384 0.0371 ± 0.00074 ms 0.0384 ± 0.018 ms 0.967 ± 0.45
saxpy/default/Float16/2048 16.9 ± 2.4 μs 17 ± 1.5 μs 0.995 ± 0.17
saxpy/default/Float16/256 11.3 ± 0.39 μs 11.6 ± 0.55 μs 0.977 ± 0.058
saxpy/default/Float16/262144 0.406 ± 0.02 ms 0.414 ± 0.023 ms 0.981 ± 0.072
saxpy/default/Float16/32768 0.098 ± 0.017 ms 0.0963 ± 0.017 ms 1.02 ± 0.25
saxpy/default/Float16/4096 20.8 ± 1.8 μs 21 ± 11 μs 0.99 ± 0.54
saxpy/default/Float16/512 11.3 ± 0.29 μs 11.6 ± 0.29 μs 0.974 ± 0.035
saxpy/default/Float16/64 11.1 ± 0.35 μs 16.1 ± 1.2 μs 0.689 ± 0.054
saxpy/default/Float16/65536 0.139 ± 0.018 ms 0.135 ± 0.0084 ms 1.03 ± 0.15
saxpy/default/Float32/1024 16.4 ± 11 μs 14.8 ± 0.89 μs 1.11 ± 0.75
saxpy/default/Float32/1048576 0.811 ± 0.12 ms 0.806 ± 0.072 ms 1.01 ± 0.17
saxpy/default/Float32/16384 28.4 ± 12 μs 26.5 ± 1.9 μs 1.07 ± 0.44
saxpy/default/Float32/2048 26.3 ± 9.9 μs 26 ± 0.98 μs 1.01 ± 0.38
saxpy/default/Float32/256 11.1 ± 0.29 μs 11.5 ± 0.43 μs 0.964 ± 0.044
saxpy/default/Float32/262144 0.235 ± 0.031 ms 0.237 ± 0.034 ms 0.991 ± 0.19
saxpy/default/Float32/32768 0.0404 ± 0.0023 ms 0.0561 ± 0.02 ms 0.72 ± 0.26
saxpy/default/Float32/4096 17.7 ± 0.59 μs 17.8 ± 0.75 μs 0.997 ± 0.054
saxpy/default/Float32/512 14.9 ± 15 μs 24.7 ± 11 μs 0.602 ± 0.65
saxpy/default/Float32/64 11.1 ± 0.42 μs 11.4 ± 0.42 μs 0.979 ± 0.052
saxpy/default/Float32/65536 0.0999 ± 0.013 ms 0.0638 ± 0.046 ms 1.57 ± 1.1
saxpy/default/Float64/1024 24.8 ± 9.5 μs 16 ± 0.66 μs 1.55 ± 0.6
saxpy/default/Float64/1048576 1.22 ± 0.21 ms 1.12 ± 0.16 ms 1.09 ± 0.25
saxpy/default/Float64/16384 31.2 ± 1.2 μs 0.0453 ± 0.013 ms 0.688 ± 0.2
saxpy/default/Float64/2048 17.2 ± 9 μs 17.1 ± 0.63 μs 1.01 ± 0.53
saxpy/default/Float64/256 10.2 ± 4.7 μs 10.5 ± 4.6 μs 0.968 ± 0.61
saxpy/default/Float64/262144 0.284 ± 0.034 ms 0.29 ± 0.035 ms 0.979 ± 0.17
saxpy/default/Float64/32768 0.0465 ± 0.042 ms 0.0462 ± 0.0074 ms 1.01 ± 0.93
saxpy/default/Float64/4096 26.5 ± 9.1 μs 18.9 ± 0.79 μs 1.41 ± 0.48
saxpy/default/Float64/512 14.3 ± 0.99 μs 24.9 ± 0.94 μs 0.572 ± 0.045
saxpy/default/Float64/64 11.1 ± 0.3 μs 11.3 ± 0.64 μs 0.984 ± 0.062
saxpy/default/Float64/65536 0.108 ± 0.014 ms 0.108 ± 0.018 ms 0.995 ± 0.21
saxpy/static workgroup=(1024,)/Float16/1024 15.5 ± 4.5 μs 26.4 ± 6.9 μs 0.588 ± 0.23
saxpy/static workgroup=(1024,)/Float16/1048576 1.47 ± 0.017 ms 1.47 ± 0.032 ms 0.998 ± 0.025
saxpy/static workgroup=(1024,)/Float16/16384 0.0373 ± 0.00064 ms 0.0375 ± 0.00072 ms 0.995 ± 0.026
saxpy/static workgroup=(1024,)/Float16/2048 18 ± 12 μs 17.7 ± 1.7 μs 1.02 ± 0.69
saxpy/static workgroup=(1024,)/Float16/256 12 ± 13 μs 11.8 ± 0.32 μs 1.02 ± 1.1
saxpy/static workgroup=(1024,)/Float16/262144 0.407 ± 0.019 ms 0.417 ± 0.023 ms 0.974 ± 0.069
saxpy/static workgroup=(1024,)/Float16/32768 0.0922 ± 0.0097 ms 0.0921 ± 0.0095 ms 1 ± 0.15
saxpy/static workgroup=(1024,)/Float16/4096 20.6 ± 0.51 μs 21.6 ± 11 μs 0.956 ± 0.51
saxpy/static workgroup=(1024,)/Float16/512 25.1 ± 0.85 μs 12 ± 0.4 μs 2.1 ± 0.1
saxpy/static workgroup=(1024,)/Float16/64 11.5 ± 5.7 μs 11.7 ± 0.23 μs 0.983 ± 0.49
saxpy/static workgroup=(1024,)/Float16/65536 0.142 ± 0.018 ms 0.151 ± 0.018 ms 0.94 ± 0.16
saxpy/static workgroup=(1024,)/Float32/1024 14.7 ± 0.65 μs 15.4 ± 11 μs 0.958 ± 0.69
saxpy/static workgroup=(1024,)/Float32/1048576 0.806 ± 0.082 ms 0.779 ± 0.13 ms 1.03 ± 0.2
saxpy/static workgroup=(1024,)/Float32/16384 29.3 ± 13 μs 26.8 ± 2 μs 1.09 ± 0.48
saxpy/static workgroup=(1024,)/Float32/2048 17.2 ± 9.8 μs 17.1 ± 1.5 μs 1.01 ± 0.58
saxpy/static workgroup=(1024,)/Float32/256 11.3 ± 0.21 μs 11.5 ± 0.31 μs 0.98 ± 0.032
saxpy/static workgroup=(1024,)/Float32/262144 0.235 ± 0.028 ms 0.226 ± 0.029 ms 1.04 ± 0.18
saxpy/static workgroup=(1024,)/Float32/32768 0.0579 ± 0.0012 ms 0.0383 ± 0.0017 ms 1.51 ± 0.073
saxpy/static workgroup=(1024,)/Float32/4096 17.8 ± 0.64 μs 18.7 ± 11 μs 0.953 ± 0.55
saxpy/static workgroup=(1024,)/Float32/512 10.3 ± 0.46 μs 11 ± 13 μs 0.933 ± 1.1
saxpy/static workgroup=(1024,)/Float32/64 11.6 ± 0.18 μs 11.9 ± 0.41 μs 0.976 ± 0.037
saxpy/static workgroup=(1024,)/Float32/65536 0.0941 ± 0.011 ms 0.109 ± 0.02 ms 0.864 ± 0.19
saxpy/static workgroup=(1024,)/Float64/1024 15.9 ± 0.75 μs 16.1 ± 9 μs 0.982 ± 0.55
saxpy/static workgroup=(1024,)/Float64/1048576 1.23 ± 0.19 ms 1.18 ± 0.15 ms 1.04 ± 0.21
saxpy/static workgroup=(1024,)/Float64/16384 31.2 ± 3.9 μs 31.3 ± 15 μs 0.996 ± 0.49
saxpy/static workgroup=(1024,)/Float64/2048 25.6 ± 9.7 μs 17.5 ± 8.7 μs 1.46 ± 0.91
saxpy/static workgroup=(1024,)/Float64/256 10.8 ± 0.62 μs 11.1 ± 4.6 μs 0.976 ± 0.41
saxpy/static workgroup=(1024,)/Float64/262144 0.287 ± 0.037 ms 0.275 ± 0.039 ms 1.05 ± 0.2
saxpy/static workgroup=(1024,)/Float64/32768 0.0463 ± 0.0053 ms 0.0466 ± 0.049 ms 0.993 ± 1
saxpy/static workgroup=(1024,)/Float64/4096 18.8 ± 9.3 μs 19 ± 0.71 μs 0.99 ± 0.49
saxpy/static workgroup=(1024,)/Float64/512 14.4 ± 0.63 μs 15 ± 1.1 μs 0.957 ± 0.082
saxpy/static workgroup=(1024,)/Float64/64 11.6 ± 0.39 μs 11.8 ± 0.4 μs 0.979 ± 0.047
saxpy/static workgroup=(1024,)/Float64/65536 0.106 ± 0.01 ms 0.116 ± 0.022 ms 0.915 ± 0.19
time_to_load 0.519 ± 0.007 s 0.519 ± 0.0015 s 1 ± 0.014
main e133135... main / e133135...
const/@Const/Float32/262144 9 allocs: 0.203 kB 9 allocs: 0.203 kB 1
const/@Const/Float32/65536 9 allocs: 0.203 kB 9 allocs: 0.203 kB 1
const/@Const/Float64/262144 9 allocs: 0.203 kB 9 allocs: 0.203 kB 1
const/@Const/Float64/65536 9 allocs: 0.203 kB 9 allocs: 0.203 kB 1
const/unmarked/Float32/262144 9 allocs: 0.203 kB 9 allocs: 0.203 kB 1
const/unmarked/Float32/65536 9 allocs: 0.203 kB 9 allocs: 0.203 kB 1
const/unmarked/Float64/262144 9 allocs: 0.203 kB 9 allocs: 0.203 kB 1
const/unmarked/Float64/65536 9 allocs: 0.203 kB 9 allocs: 0.203 kB 1
dgsem/2D/Float32/fluxdiff/element 10 allocs: 0.219 kB 10 allocs: 0.219 kB 1
dgsem/2D/Float32/fluxdiff/node E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float32/fluxdiff/node halfsweep E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float32/fluxdiff/node halfsweep v-last E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float32/weak/element 10 allocs: 0.219 kB 10 allocs: 0.219 kB 1
dgsem/2D/Float32/weak/element private 10 allocs: 0.219 kB 10 allocs: 0.219 kB 1
dgsem/2D/Float32/weak/node localmem E=1 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float32/weak/node localmem E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float32/weak/node localmem v-last E=1 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float32/weak/node localmem v-last E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float32/weak/node recompute E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float64/fluxdiff/element 10 allocs: 0.219 kB 10 allocs: 0.219 kB 1
dgsem/2D/Float64/fluxdiff/node E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float64/fluxdiff/node halfsweep E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float64/fluxdiff/node halfsweep v-last E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float64/weak/element 10 allocs: 0.219 kB 10 allocs: 0.219 kB 1
dgsem/2D/Float64/weak/element private 10 allocs: 0.219 kB 10 allocs: 0.219 kB 1
dgsem/2D/Float64/weak/node localmem E=1 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float64/weak/node localmem E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float64/weak/node localmem v-last E=1 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float64/weak/node localmem v-last E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/2D/Float64/weak/node recompute E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float32/fluxdiff/element 10 allocs: 0.219 kB 10 allocs: 0.219 kB 1
dgsem/3D/Float32/fluxdiff/node E=2 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float32/fluxdiff/node halfsweep E=1 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float32/fluxdiff/node halfsweep v-last E=1 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float32/weak/element 10 allocs: 0.219 kB 10 allocs: 0.219 kB 1
dgsem/3D/Float32/weak/element private 10 allocs: 0.219 kB 10 allocs: 0.219 kB 1
dgsem/3D/Float32/weak/node localmem E=1 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float32/weak/node localmem E=2 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float32/weak/node localmem v-last E=1 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float32/weak/node localmem v-last E=2 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float32/weak/node recompute E=2 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float32/weak/slab E=1 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float32/weak/slab E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float32/weak/slab double-buffered E=1 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float32/weak/slab double-buffered E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float32/weak/slab double-buffered v-last E=1 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float32/weak/slab double-buffered v-last E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float32/weak/slab v-last E=1 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float32/weak/slab v-last E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float64/fluxdiff/element 10 allocs: 0.219 kB 10 allocs: 0.219 kB 1
dgsem/3D/Float64/fluxdiff/node E=2 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float64/fluxdiff/node halfsweep E=1 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float64/fluxdiff/node halfsweep v-last E=1 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float64/weak/element 10 allocs: 0.219 kB 10 allocs: 0.219 kB 1
dgsem/3D/Float64/weak/element private 10 allocs: 0.219 kB 10 allocs: 0.219 kB 1
dgsem/3D/Float64/weak/node localmem E=1 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float64/weak/node localmem E=2 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float64/weak/node localmem v-last E=1 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float64/weak/node localmem v-last E=2 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float64/weak/node recompute E=2 13 allocs: 0.391 kB 13 allocs: 0.391 kB 1
dgsem/3D/Float64/weak/slab E=1 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float64/weak/slab E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float64/weak/slab double-buffered E=1 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float64/weak/slab double-buffered E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float64/weak/slab double-buffered v-last E=1 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float64/weak/slab double-buffered v-last E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float64/weak/slab v-last E=1 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
dgsem/3D/Float64/weak/slab v-last E=8 10 allocs: 0.234 kB 10 allocs: 0.234 kB 1
launch/3D static workgroup, dynamic ndrange 9 allocs: 0.219 kB 9 allocs: 0.219 kB 1
launch/3D static workgroup, static ndrange 9 allocs: 0.219 kB 9 allocs: 0.219 kB 1
launch/dynamic workgroup, dynamic ndrange 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
launch/dynamic workgroup, dynamic ndrange, workgroupsize given 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
launch/static workgroup, dynamic ndrange 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
launch/static workgroup, static ndrange 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
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 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float16/1048576 12 allocs: 0.25 kB 12 allocs: 0.25 kB 1
saxpy/default/Float16/16384 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float16/2048 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float16/256 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
saxpy/default/Float16/262144 12 allocs: 0.25 kB 12 allocs: 0.25 kB 1
saxpy/default/Float16/32768 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float16/4096 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float16/512 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float16/64 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
saxpy/default/Float16/65536 12 allocs: 0.25 kB 12 allocs: 0.25 kB 1
saxpy/default/Float32/1024 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float32/1048576 12 allocs: 0.25 kB 12 allocs: 0.25 kB 1
saxpy/default/Float32/16384 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float32/2048 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float32/256 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
saxpy/default/Float32/262144 12 allocs: 0.25 kB 8 allocs: 0.141 kB 1.78
saxpy/default/Float32/32768 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float32/4096 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float32/512 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float32/64 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
saxpy/default/Float32/65536 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float64/1024 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float64/1048576 12 allocs: 0.25 kB 12 allocs: 0.25 kB 1
saxpy/default/Float64/16384 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float64/2048 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float64/256 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
saxpy/default/Float64/262144 12 allocs: 0.25 kB 12 allocs: 0.25 kB 1
saxpy/default/Float64/32768 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float64/4096 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float64/512 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/default/Float64/64 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
saxpy/default/Float64/65536 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float16/1024 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float16/1048576 12 allocs: 0.25 kB 12 allocs: 0.25 kB 1
saxpy/static workgroup=(1024,)/Float16/16384 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float16/2048 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float16/256 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
saxpy/static workgroup=(1024,)/Float16/262144 12 allocs: 0.25 kB 12 allocs: 0.25 kB 1
saxpy/static workgroup=(1024,)/Float16/32768 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float16/4096 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float16/512 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float16/64 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
saxpy/static workgroup=(1024,)/Float16/65536 12 allocs: 0.25 kB 12 allocs: 0.25 kB 1
saxpy/static workgroup=(1024,)/Float32/1024 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float32/1048576 12 allocs: 0.25 kB 12 allocs: 0.25 kB 1
saxpy/static workgroup=(1024,)/Float32/16384 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float32/2048 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float32/256 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
saxpy/static workgroup=(1024,)/Float32/262144 12 allocs: 0.25 kB 12 allocs: 0.25 kB 1
saxpy/static workgroup=(1024,)/Float32/32768 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float32/4096 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float32/512 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float32/64 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
saxpy/static workgroup=(1024,)/Float32/65536 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float64/1024 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float64/1048576 12 allocs: 0.25 kB 12 allocs: 0.25 kB 1
saxpy/static workgroup=(1024,)/Float64/16384 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float64/2048 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float64/256 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
saxpy/static workgroup=(1024,)/Float64/262144 12 allocs: 0.25 kB 12 allocs: 0.25 kB 1
saxpy/static workgroup=(1024,)/Float64/32768 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float64/4096 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float64/512 8 allocs: 0.141 kB 8 allocs: 0.141 kB 1
saxpy/static workgroup=(1024,)/Float64/64 5 allocs: 0.0938 kB 5 allocs: 0.0938 kB 1
saxpy/static workgroup=(1024,)/Float64/65536 8 allocs: 0.141 kB 8 allocs: 0.141 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).

@vchuravy
vchuravy changed the base branch from vc/dgsem-benchmarks-localmem-layout to vc/dgsem-benchmarks-layout-switch October 11, 2026 12:16
@vchuravy
vchuravy added this pull request to stack #873 October 11, 2026 12:20
@vchuravy
vchuravy force-pushed the vc/dgsem-benchmarks-tiles branch 3 times, most recently from a5c8758 to 74f036b Compare October 11, 2026 15:58
Base automatically changed from vc/dgsem-benchmarks-layout-switch to main October 11, 2026 15:58
With a KernelAbstractions that has tiles (#864), add DGSEM kernels in
which the N² work-items of an element (2D) or of a slab (3D) form a
tile and exchange values with `tile_shfl` instead of `@localmem` and
`@synchronize`: the 2D weak form, the 2D half-sweep flux differencing
(each two-point flux computed once, cyclically, for uniform control
flow) and the 3D slab kernel. "weak/node localmem tile_barrier" keeps
the local memory and replaces `@synchronize` with `tile_barrier`. The
kernels live in benchmark/dgsem_tiles.jl, which is only included if
KernelAbstractions defines `tile_shfl`, so the suite still runs on
versions without tiles.

Assisted-by: Claude Code (Opus 5.5)
@vchuravy
vchuravy force-pushed the vc/dgsem-benchmarks-tiles branch from 74f036b to e133135 Compare October 11, 2026 15:58
@maleadt maleadt mentioned this pull request Oct 12, 2026

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.

1 participant