Skip to content

Accept callable objects as kernels - #1198

Merged
maleadt merged 1 commit into
mainfrom
tb/callable-kernels
Oct 27, 2026
Merged

maleadt merged 1 commit into
mainfrom
tb/callable-kernels

Conversation

@maleadt

@maleadt maleadt commented Oct 27, 2026

Copy link
Copy Markdown
Member

Remove hipfunction's Function constraint so callable objects (structs with call methods) can be launched as kernels. Previously, this failed with a MethodError:

struct StoreValue
    val::Float64
end
(f::StoreValue)(a) = (a[1] = f.val; return)

@roc StoreValue(2.0)(a)  # MethodError: no method matching hipfunction(::StoreValue, ...)

JuliaGPU/KernelAbstractions.jl#931 launches a callable object in its "partition for the kernel function" test, which fails on AMDGPU. Nothing depends on the constraint, and CUDA.jl's cufunction has none.

@roc converts callable objects like closures, passing their fields as the kernel's first argument. Compiled kernels are cached by type; the added test checks that a new instance reuses the kernel with its own state.

Tests: device/launch (fails without the change, passes with it); kernelabstractions_tests, kernelinterface_tests and device/launch against KernelAbstractions#931 (a2dd21b3) on gfx1036.

Remove `hipfunction`'s `Function` constraint so callable objects (structs
with call methods) can be launched as kernels without a `MethodError`.
JuliaGPU/KernelAbstractions.jl#931 uses such kernels. Nothing depends on
the constraint, and CUDA.jl's `cufunction` has none.
@luraess

luraess commented Oct 27, 2026

Copy link
Copy Markdown
Member

cscs-ci run MI250,MI300

@github-actions

Copy link
Copy Markdown
Contributor

Benchmark results

Compared with 3e7016582, the merge base.
The environment differs from the baseline's: AMDGPUExt 0.5.9 → 0.10.3, AcceleratedKernels 0.5.9 → 0.5.10, Atomix 1.6.0 → 1.7.0, BFloat16sExt 10.4.1 → 10.4.2, JSON 1.12.2 → 1.13.0, LLVM 10.4.1 → 10.4.2, Parsers 3.0.1 → 3.0.2, StructUtils 2.11.1 → 2.11.2, StructUtilsStaticArraysCoreExt 2.11.1 → 2.11.2, StructUtilsTablesExt 2.11.1 → 2.11.2, pocl_standalone_jll 7.2.3+1 → 7.2.3+2.

Times are the minimum time of every benchmark. A change is unusual when it exceeds both three times the benchmark's typical change between consecutive runs on the default branch and a minimum per category (performance 3%, latency 5%, applications 3%, other 3%). A benchmark that starts or stops allocating is listed however few the allocations. A single run can still be a fluke, so rerun before drawing conclusions.

Geometric mean Unusual: slower Unusual: faster Compared
Performance −0.4% 6 9 69
Latency −3.5% 0 1 3
Applications −5.7% 0 2 14
Benchmark Baseline This PR Change
Performance
array/copyto!/gpu_to_gpu 35.1 µs 57.2 µs +62.8% 🔴 slower
kernel/rand 48.3 µs 72.1 µs +49.2% 🔴 slower
array/broadcast 50.6 µs 41.1 µs −18.8% 🟢 faster
array/reductions/mapreduce/Float32/dims=1 55.5 µs 45.5 µs −18.1% 🟢 faster
array/reductions/mapreduce/Float32/dims=1L 59.7 µs 49.1 µs −17.9% 🟢 faster
array/reductions/reduce/Float32/dims=2 59.4 µs 49.0 µs −17.5% 🟢 faster
array/accumulate/Int64/dims=2 91.0 µs 109 µs +19.6% 🔴 slower
array/reductions/mapreduce/Float32/1d 71.0 µs 60.7 µs −14.5% 🟢 faster
array/reductions/reduce/Float32/dims=1L 50.4 µs 58.3 µs +15.6% 🔴 slower
array/sorting/1d 343 µs 297 µs −13.4% 🟢 faster
array/reverse/1d 37.3 µs 42.6 µs +14.1% 🔴 slower
array/accumulate/Float32/dims=2L 124 µs 111 µs −10.5% 🟢 faster
array/accumulate/Float32/dims=1 64.2 µs 57.8 µs −10.0% 🟢 faster
array/reverse/2dL 80.5 µs 73.8 µs −8.3% 🟢 faster
array/iteration/findfirst/bool 54.9 µs 58.4 µs +6.4% 🔴 slower
Latency
import 1.37 s 1.30 s −5.0% 🟢 faster
Applications
gemm/tiled 2.75 ms 1.86 ms −32.3% 🟢 faster
gemm/tiled_unbounded 2.79 ms 1.89 ms −32.2% 🟢 faster
Benchmark Baseline allocations This PR
Applications
prefix_sum none 2 (84 B) 🔴 allocates
All benchmarks
Benchmark Baseline This PR Change
Performance
amdgpu/synchronization/context/device 1.79 µs 1.74 µs −3.1%
amdgpu/synchronization/stream/blocking 228 ns 230 ns +1.1%
amdgpu/synchronization/stream/nonblocking 350 ns 340 ns −2.9%
array/accumulate/Float32/1d 82.6 µs 82.7 µs +0.1%
array/accumulate/Float32/dims=1 64.2 µs 57.8 µs −10.0% 🟢 faster
array/accumulate/Float32/dims=1L 105 µs 107 µs +1.9%
array/accumulate/Float32/dims=2 105 µs 105 µs +0.5%
array/accumulate/Float32/dims=2L 124 µs 111 µs −10.5% 🟢 faster
array/accumulate/Int64/1d 104 µs 104 µs +0.1%
array/accumulate/Int64/dims=1 75.1 µs 76.6 µs +2.1%
array/accumulate/Int64/dims=1L 111 µs 117 µs +6.1%
array/accumulate/Int64/dims=2 91.0 µs 109 µs +19.6% 🔴 slower
array/accumulate/Int64/dims=2L 157 µs 164 µs +4.5%
array/broadcast 50.6 µs 41.1 µs −18.8% 🟢 faster
array/construct 2.29 µs 2.33 µs +1.6%
array/copy 40.3 µs 39.8 µs −1.2%
array/copyto!/cpu_to_gpu 85.9 µs 85.9 µs +0.1%
array/copyto!/gpu_to_cpu 85.8 µs 86.0 µs +0.2%
array/copyto!/gpu_to_gpu 35.1 µs 57.2 µs +62.8% 🔴 slower
array/iteration/findall/bool 94.7 µs 89.9 µs −5.1%
array/iteration/findall/int 107 µs 103 µs −3.1%
array/iteration/findfirst/bool 54.9 µs 58.4 µs +6.4% 🔴 slower
array/iteration/findfirst/int 56.6 µs 56.4 µs −0.3%
array/iteration/findmin/1d 95.0 µs 97.3 µs +2.4%
array/iteration/findmin/2d 79.3 µs 79.4 µs +0.2%
array/iteration/logical 91.0 µs 85.8 µs −5.8%
array/iteration/scalar 307 µs 310 µs +0.7%
array/permutedims/2d 62.1 µs 62.3 µs +0.3%
array/permutedims/3d 49.4 µs 48.0 µs −2.9%
array/permutedims/4d 54.1 µs 54.2 µs +0.0%
array/random/rand!/Float32 50.9 µs 58.8 µs +15.6%
array/random/rand!/Int64 59.8 µs 49.2 µs −17.8%
array/random/rand/Float32 46.9 µs 46.8 µs −0.2%
array/random/rand/Int64 46.4 µs 46.1 µs −0.5%
array/random/randn!/Float32 82.6 µs 60.1 µs −27.2%
array/random/randn/Float32 70.5 µs 70.8 µs +0.5%
array/reductions/mapreduce/Float32/1d 71.0 µs 60.7 µs −14.5% 🟢 faster
array/reductions/mapreduce/Float32/dims=1 55.5 µs 45.5 µs −18.1% 🟢 faster
array/reductions/mapreduce/Float32/dims=1L 59.7 µs 49.1 µs −17.9% 🟢 faster
array/reductions/mapreduce/Float32/dims=2 59.6 µs 57.6 µs −3.3%
array/reductions/mapreduce/Float32/dims=2L 60.7 µs 57.3 µs −5.5%
array/reductions/mapreduce/Int64/1d 71.7 µs 72.1 µs +0.6%
array/reductions/mapreduce/Int64/dims=1 51.6 µs 50.6 µs −2.0%
array/reductions/mapreduce/Int64/dims=1L 70.9 µs 70.1 µs −1.2%
array/reductions/mapreduce/Int64/dims=2 60.7 µs 58.5 µs −3.7%
array/reductions/mapreduce/Int64/dims=2L 78.4 µs 76.2 µs −2.8%
array/reductions/reduce/Float32/1d 70.9 µs 71.2 µs +0.5%
array/reductions/reduce/Float32/dims=1 55.7 µs 54.6 µs −1.9%
array/reductions/reduce/Float32/dims=1L 50.4 µs 58.3 µs +15.6% 🔴 slower
array/reductions/reduce/Float32/dims=2 59.4 µs 49.0 µs −17.5% 🟢 faster
array/reductions/reduce/Float32/dims=2L 72.5 µs 70.1 µs −3.3%
array/reductions/reduce/Int64/1d 71.4 µs 71.7 µs +0.4%
array/reductions/reduce/Int64/dims=1 51.6 µs 50.5 µs −2.2%
array/reductions/reduce/Int64/dims=1L 70.9 µs 69.3 µs −2.2%
array/reductions/reduce/Int64/dims=2 60.6 µs 58.2 µs −3.9%
array/reductions/reduce/Int64/dims=2L 78.2 µs 76.0 µs −2.8%
array/reverse/1d 37.3 µs 42.6 µs +14.1% 🔴 slower
array/reverse/1d_inplace 40.3 µs 50.6 µs +25.8%
array/reverse/1dL 60.5 µs 68.5 µs +13.3%
array/reverse/1dL_inplace 78.8 µs 79.4 µs +0.8%
array/reverse/2d 47.8 µs 47.5 µs −0.6%
array/reverse/2d_inplace 56.1 µs 65.5 µs +16.6%
array/reverse/2dL 80.5 µs 73.8 µs −8.3% 🟢 faster
array/reverse/2dL_inplace 90.5 µs 76.6 µs −15.4%
array/sorting/1d 343 µs 297 µs −13.4% 🟢 faster
kernel/indexing 32.1 µs 30.3 µs −5.4%
kernel/indexing_checked 37.0 µs 44.7 µs +20.7%
kernel/launch 900 ns 903 ns +0.3%
kernel/rand 48.3 µs 72.1 µs +49.2% 🔴 slower
Latency
import 1.37 s 1.30 s −5.0% 🟢 faster
precompile 29.0 s 27.8 s −4.1%
ttfp 1.77 s 1.74 s −1.5%
Applications
bitonic_sort 1.11 ms 1.09 ms −2.4%
byval/reference 39.2 µs 40.8 µs +4.0%
byval/slices=1 41.1 µs 41.1 µs −0.0%
byval/slices=2 158 µs 145 µs −8.2%
byval/slices=3 233 µs 236 µs +1.2%
convolution 76.0 µs 76.3 µs +0.4%
floyd_warshall 9.06 ms 9.00 ms −0.7%
gemm/tiled 2.75 ms 1.86 ms −32.3% 🟢 faster
gemm/tiled_unbounded 2.79 ms 1.89 ms −32.2% 🟢 faster
histogram 782 µs 795 µs +1.7%
prefix_sum 194 µs 194 µs +0.3%
stencil/diffusion3d 1.57 ms 1.57 ms +0.2%
stencil/diffusion3d_checked 1.61 ms 1.61 ms −0.0%
volumerhs 4.86 ms 4.85 ms −0.2%

History: https://juliagpu.org/perf/?pkg=amdgpu

@maleadt
maleadt merged commit f26413d into main Oct 27, 2026
11 checks passed
@maleadt
maleadt deleted the tb/callable-kernels branch October 27, 2026 20:12
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.

2 participants