Skip to content

Commit 12aa00d

Browse files
maleadtclaude
andcommitted
Use budget-based tile sizing for tiled broadcast
Replace the hardcoded 64×64 tile sizes with a greedy budget-based approach (4096 elements) that skips singleton dimensions and caps each tile dim at the array size. This fixes tiled broadcast for arrays with leading singleton or small dimensions (e.g. (1, 1024), (4, 1024)). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent ad2c10f commit 12aa00d

2 files changed

Lines changed: 44 additions & 3 deletions

File tree

ext/CUDAExt.jl

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,15 +349,35 @@ end
349349
(_eval_bc(args[1], bid, tile_size), _eval_bc_args(Base.tail(args), bid, tile_size)...)
350350

351351
"""
352-
_tiled_broadcast!(dest, bc; tile_size=64)
352+
_compute_tile_sizes(dest_size; budget=4096)
353+
354+
Distribute a total element budget greedily across dimensions, skipping singletons.
355+
Each tile dimension is a power of 2, capped by the array size in that dimension.
356+
"""
357+
function _compute_tile_sizes(dest_size::NTuple{N,Int}; budget::Int=4096) where N
358+
ts = ones(Int, N)
359+
remaining = budget
360+
for i in 1:N
361+
s = dest_size[i]
362+
s == 1 && continue
363+
t = prevpow(2, min(remaining, s))
364+
ts[i] = t
365+
remaining = remaining ÷ t
366+
remaining < 2 && break
367+
end
368+
return NTuple{N,Int}(ts)
369+
end
370+
371+
"""
372+
_tiled_broadcast!(dest, bc)
353373
354374
Launch a tiled broadcast kernel for the fused expression `bc` writing to `dest`.
355375
"""
356-
function _tiled_broadcast!(dest::CuArray{T,N}, bc::Broadcasted; tile_size::Int=64) where {T, N}
376+
function _tiled_broadcast!(dest::CuArray{T,N}, bc::Broadcasted) where {T, N}
357377
dest_ta = TileArray(dest)
358378
tiled_bc = _to_tiled_bc(bc)
359379

360-
ts = ntuple(i -> i <= min(N, 2) ? tile_size : 1, N)
380+
ts = _compute_tile_sizes(size(dest))
361381
grid = ntuple(i -> cld(size(dest, i), ts[i]), N)
362382

363383
launch_grid = N <= 3 ? grid : (grid[1], grid[2], prod(grid[i] for i in 3:N))

test/execution/broadcast.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,4 +927,25 @@ end
927927
@test C isa CuArray
928928
@test Array(C) Array(A) .+ Array(B)
929929
end
930+
931+
@testset "leading singleton dim" begin
932+
A = CUDA.rand(Float32, 1, 1024)
933+
B = similar(A)
934+
ct.Tiled(B) .= ct.Tiled(A) .+ 1.0f0
935+
@test Array(B) Array(A) .+ 1.0f0
936+
end
937+
938+
@testset "double leading singleton" begin
939+
A = CUDA.rand(Float32, 1, 1, 512)
940+
B = similar(A)
941+
ct.Tiled(B) .= ct.Tiled(A) .* 2.0f0
942+
@test Array(B) Array(A) .* 2.0f0
943+
end
944+
945+
@testset "small leading dim" begin
946+
A = CUDA.rand(Float32, 4, 1024)
947+
B = similar(A)
948+
ct.Tiled(B) .= ct.Tiled(A) .+ ct.Tiled(A)
949+
@test Array(B) 2 .* Array(A)
950+
end
930951
end

0 commit comments

Comments
 (0)