Repository navigation
Conversation
There was a problem hiding this comment.
Metal Benchmarks
Details
| Benchmark suite | Current: 942b315 | Previous: 76951f2 | Ratio |
|---|---|---|---|
array/accumulate/Float32/1d |
393583 ns |
391959 ns |
1.00 |
array/accumulate/Float32/dims=1 |
369250 ns |
370167 ns |
1.00 |
array/accumulate/Float32/dims=1L |
8864875 ns |
8878291 ns |
1.00 |
array/accumulate/Float32/dims=2 |
433167 ns |
427250 ns |
1.01 |
array/accumulate/Float32/dims=2L |
2803000 ns |
2669209 ns |
1.05 |
array/accumulate/Int64/1d |
845125 ns |
849083 ns |
1.00 |
array/accumulate/Int64/dims=1 |
909584 ns |
913084 ns |
1.00 |
array/accumulate/Int64/dims=1L |
9551208 ns |
9560458 ns |
1.00 |
array/accumulate/Int64/dims=2 |
1218125 ns |
1210792 ns |
1.01 |
array/accumulate/Int64/dims=2L |
6563833 ns |
6543625 ns |
1.00 |
array/broadcast |
241709 ns |
224916 ns |
1.07 |
array/construct |
2250 ns |
2291 ns |
0.98 |
array/permutedims/2d |
341709 ns |
455458 ns |
0.75 |
array/permutedims/3d |
464042 ns |
1028542 ns |
0.45 |
array/permutedims/4d |
625041 ns |
1119334 ns |
0.56 |
array/private/copy |
224958 ns |
228583 ns |
0.98 |
array/private/copyto!/cpu_to_gpu |
229000 ns |
213417 ns |
1.07 |
array/private/copyto!/gpu_to_cpu |
217958 ns |
215708 ns |
1.01 |
array/private/copyto!/gpu_to_gpu |
214584 ns |
221916 ns |
0.97 |
array/private/iteration/findall/bool |
1047583 ns |
1051292 ns |
1.00 |
array/private/iteration/findall/int |
1215250 ns |
1217584 ns |
1.00 |
array/private/iteration/findfirst/bool |
1011125 ns |
1008458 ns |
1.00 |
array/private/iteration/findfirst/int |
1019709 ns |
1016083 ns |
1.00 |
array/private/iteration/findmin/1d |
1087792 ns |
1073084 ns |
1.01 |
array/private/iteration/findmin/2d |
1024875 ns |
1020750 ns |
1.00 |
array/private/iteration/logical |
1539833 ns |
1551500 ns |
0.99 |
array/private/iteration/scalar |
1381167 ns |
1398250 ns |
0.99 |
array/random/rand/Float32 |
444209 ns |
407458 ns |
1.09 |
array/random/rand/Int64 |
521208 ns |
499458 ns |
1.04 |
array/random/rand!/Float32 |
424583 ns |
401125 ns |
1.06 |
array/random/rand!/Int64 |
443417 ns |
426625 ns |
1.04 |
array/random/randn/Float32 |
369458 ns |
391666 ns |
0.94 |
array/random/randn!/Float32 |
355833 ns |
375875 ns |
0.95 |
array/reductions/mapreduce/Float32/1d |
270042 ns |
277875 ns |
0.97 |
array/reductions/mapreduce/Float32/dims=1 |
353875 ns |
353792 ns |
1.00 |
array/reductions/mapreduce/Float32/dims=1L |
612959 ns |
603417 ns |
1.02 |
array/reductions/mapreduce/Float32/dims=2 |
356375 ns |
358417 ns |
0.99 |
array/reductions/mapreduce/Float32/dims=2L |
1220125 ns |
1236416 ns |
0.99 |
array/reductions/mapreduce/Int64/1d |
459208 ns |
459958 ns |
1.00 |
array/reductions/mapreduce/Int64/dims=1 |
635584 ns |
634125 ns |
1.00 |
array/reductions/mapreduce/Int64/dims=1L |
1005583 ns |
1014250 ns |
0.99 |
array/reductions/mapreduce/Int64/dims=2 |
777375 ns |
788625 ns |
0.99 |
array/reductions/mapreduce/Int64/dims=2L |
2205917 ns |
2200083 ns |
1.00 |
array/reductions/reduce/Float32/1d |
271583 ns |
271167 ns |
1.00 |
array/reductions/reduce/Float32/dims=1 |
355958 ns |
359625 ns |
0.99 |
array/reductions/reduce/Float32/dims=1L |
615042 ns |
618458 ns |
0.99 |
array/reductions/reduce/Float32/dims=2 |
245708 ns |
247334 ns |
0.99 |
array/reductions/reduce/Float32/dims=2L |
468500 ns |
463500 ns |
1.01 |
array/reductions/reduce/Int64/1d |
455166 ns |
462250 ns |
0.98 |
array/reductions/reduce/Int64/dims=1 |
639000 ns |
639250 ns |
1.00 |
array/reductions/reduce/Int64/dims=1L |
1007833 ns |
1007959 ns |
1.00 |
array/reductions/reduce/Int64/dims=2 |
257083 ns |
258125 ns |
1.00 |
array/reductions/reduce/Int64/dims=2L |
656667 ns |
663458 ns |
0.99 |
array/shared/copy |
129959 ns |
128000 ns |
1.02 |
array/shared/copyto!/cpu_to_gpu |
37500 ns |
38292 ns |
0.98 |
array/shared/copyto!/gpu_to_cpu |
38542 ns |
36708 ns |
1.05 |
array/shared/copyto!/gpu_to_gpu |
39000 ns |
36792 ns |
1.06 |
array/shared/iteration/findall/bool |
1052375 ns |
1061167 ns |
0.99 |
array/shared/iteration/findall/int |
1211958 ns |
1223625 ns |
0.99 |
array/shared/iteration/findfirst/bool |
974834 ns |
932917 ns |
1.04 |
array/shared/iteration/findfirst/int |
947584 ns |
987583 ns |
0.96 |
array/shared/iteration/findmin/1d |
1045167 ns |
1055750 ns |
0.99 |
array/shared/iteration/findmin/2d |
1029708 ns |
1028333 ns |
1.00 |
array/shared/iteration/logical |
1521167 ns |
1512792 ns |
1.01 |
array/shared/iteration/scalar |
76.70328542094455 ns |
76.42374616171955 ns |
1.00 |
array/sorting/1d |
1910875 ns |
1912167 ns |
1.00 |
array/sorting/2d |
8344500 ns |
8268833 ns |
1.01 |
integration/byval/reference |
1118959 ns |
1122583 ns |
1.00 |
integration/byval/slices=1 |
1124792 ns |
1119417 ns |
1.00 |
integration/byval/slices=2 |
2032750 ns |
2029125 ns |
1.00 |
integration/byval/slices=3 |
6798916 ns |
6760792 ns |
1.01 |
integration/metaldevrt |
394292 ns |
397583 ns |
0.99 |
kernel/indexing |
212750 ns |
212542 ns |
1.00 |
kernel/indexing_checked |
389875 ns |
396666 ns |
0.98 |
kernel/launch |
2120.3333333333335 ns |
2092.5555555555557 ns |
1.01 |
kernel/rand |
407042 ns |
408917 ns |
1.00 |
latency/import |
1732971750 ns |
1858464250 ns |
0.93 |
latency/precompile |
25785776708 ns |
31532892250 ns |
0.82 |
latency/ttfp |
2222702541 ns |
2289033959 ns |
0.97 |
metal/synchronization/context |
535.5263157894736 ns |
530.921052631579 ns |
1.01 |
metal/synchronization/stream |
628.4093567251462 ns |
618.2151162790698 ns |
1.02 |
This comment was automatically generated by workflow using github-action-benchmark.
52f3c6a to
e3dd87e
Compare
| function KI.max_num_groups(backend::MetalBackend)::NTuple{3, Int} | ||
| Int(typemax(UInt32)) .÷ KI.max_work_group_dims(backend) | ||
| end |
There was a problem hiding this comment.
This assumes the work group is always the max which doesn't feel right. I think it would be more useful to have it take into account the work groups size. (I can open an issue in KA if that would be better)
Metal.jl BenchmarksDetails
This comment was automatically generated by workflow using github-action-benchmark. |
KernelAbstractions 0.10 builds on KernelInterface, which defines what a back end provides: memory and device management, compiling and launching kernels, and the device-side intrinsics. KernelAbstractions then launches `@kernel` kernels itself on any KernelInterface back end, which replaces Metal's copy of that launch path: partitioning the ndrange, building the kernel's context, and sizing the threadgroups. `MetalBackend` now implements KernelInterface, and Metal depends on it instead of on KernelAbstractions. What KernelAbstractions still needs from a back end moves to an extension: the stack allocation behind `@private`, and the Adapt rule for moving arrays to the CPU. KernelInterface's default `launch_configuration` uses the pipeline's `maxTotalThreadsPerThreadgroup`, as Metal's launch did. `KI.kernel_function` receives the callable unconverted, and keeps it as the kernel's source, which is converted again at every launch, as with `@metal`: the buffers a closure captures are declared to the encoder and kept alive. `KI.launch` passes the kernel arguments on as a tuple, to the same launch function `HostKernel` calls, so kernels with many arguments aren't splatted. Like `HostKernel`, it first waits for another task's queue that still uses one of the arguments' buffers. It passes Metal's `queue` and `submit` options on, and rejects `threads` and `groups`, which would override the launch geometry that KernelInterface validated. `KI.copyto!` also accepts contiguous views of host arrays, and `adapt(MetalBackend(), x)` moves any array to the GPU, as `adapt(MtlArray, x)` does, rather than only `Array`s. KernelAbstractions now computes indices in 32 bits where they fit, so its conversion tests pass and are no longer skipped. Its test of a kernel with 41 arguments is skipped instead, since a Metal kernel takes at most 31 buffers. Co-authored-by: Christian Guinard <28689358+christiangnrd@users.noreply.github.com>
Sub-groups are SIMD-groups: implement the sub-group queries, `sub_group_barrier` and `shfl_down`, and report their support to KernelInterface, with `shfl_down` for the types `simd_shuffle_down` supports. The sub-group width that `KI.sub_group_size` promises is 32, which `kernel_function` checks against the pipeline's `threadExecutionWidth`. KernelInterface leaves unspecified how work-items are grouped into sub-groups; Metal forms SIMD-groups from consecutive linear thread indices, so the last one of a threadgroup can be partial, which a test checks. Co-authored-by: Christian Guinard <28689358+christiangnrd@users.noreply.github.com>
Implement `KI.record_event` with an `MTLSharedEvent` that a command buffer signals after the task's queued work, and `KI.wait_event` by encoding a wait for it in the task's open batch of work, so that the GPU waits instead of the host. `KernelAbstractions.@spawn` uses them to order a new task's work after the work its parent had queued, without synchronizing the parent; the default is a full synchronization. KernelInterface's testsuite checks them once `record_event` returns an event. Co-authored-by: Christian Guinard <28689358+christiangnrd@users.noreply.github.com>
`KI.versioninfo(MetalBackend())` prints `Metal.versioninfo()`.
KernelAbstractions now backs @Private itself, with an overlay in GPUCompiler's shared method table that returns a PrivateArray over a stack alloca, so drop our Scratchpad override. This relies on Metal's compiler consulting that shared method table, i.e., declaring its tables through GPUCompiler.method_tables rather than overriding method_table_view.
Implement the sub-group communication of KernelInterface (JuliaGPU/KernelAbstractions.jl#831): - `shfl`, `shfl_down`, `shfl_up` and `shfl_xor` map to the SIMD-group shuffles, only for the primitive types Metal supports natively, so that other types reach KernelInterface's fallbacks (64-bit integers as `UInt32` words, structs field by field). Offsets past the SIMD-group width return the work-item's own value, also ones that don't fit in the intrinsics' `Int16`. - `sub_group_ballot` is `simd_ballot` masked to the lanes of the SIMD-group, since MSL leaves the upper bits undefined, and `sub_group_any`/`sub_group_all` are derived from it. - `get_max_sub_group_size` returns the constant `SIMD_WIDTH`, which `kernel_function` checks the pipeline's execution width against. - Sub-groups are reported as linear and independent: Metal doesn't specify the layout, but Apple GPUs form SIMD-groups from consecutive threads, which the testsuite checks. Co-authored-by: Tim Besard <tim@juliahub.com>
KernelInterface's functions with a `width` only need the caller's segment of the SIMD-group if the back end reports `supports_partitionable_subgroups`, which lets KernelAbstractions pack several narrow tiles into a SIMD-group. The shuffles and votes already only involve the active threads. MSL has no barrier for part of a SIMD-group, so the narrow `sub_group_barrier(width)` is a SIMD-group-scope fence and relies on Apple GPUs executing a SIMD-group with one program counter, so that the lanes of a segment in segment-uniform control flow execute in lock-step. That is the hardware's execution model (as documented by the Asahi reverse engineering) rather than an MSL guarantee; a stress test of diverging segments exchanging values through threadgroup and device memory found no errors in over 10^10 checks on M1 and M3, and the fence keeps the compiler from moving memory accesses across it.
Launching on a queue other than the default one, as the KernelInterface tests do, compiled `try_launch` again, failing the test that launch code is shared between kernels when those tests ran first in a worker.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #994 +/- ##
==========================================
+ Coverage 86.51% 86.82% +0.30%
==========================================
Files 89 89
Lines 6326 6419 +93
==========================================
+ Hits 5473 5573 +100
+ Misses 853 846 -7 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Hello, just while testing : julia> using Atomix, Metal, KernelAbstractions
julia> @kernel function atomictest(out)
Atomix.@atomic out[1] += 1f0
end
julia> out = MtlArray(zeros(Float32, 1))
1-element MtlVector{Float32, Metal.SharedStorage}:
0.0
julia> ker = atomictest(MetalBackend(), 32)
KernelAbstractions.Kernel{MetalBackend, KernelAbstractions.NDIteration.StaticSize{(32,)}, KernelAbstractions.NDIteration.DynamicSize, typeof(gpu_atomictest)}(MetalBackend(), gpu_atomictest)
julia> ker(out; ndrange=32)
ERROR: Compilation to native code failed; see below for details.
If you think this is a bug, please file an issue and attach:
- /var/folders/px/4l1mqd354pbdzzdp94rgc40h0000gn/T/jl_DiNqzCjQdA.air
- /var/folders/px/4l1mqd354pbdzzdp94rgc40h0000gn/T/jl_DiNqzCjQdA.metallib
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:44
[2] macro expansion
@ ~/.julia/packages/Metal/uNxGY/src/compiler/compilation.jl:567 [inlined]
[3] macro expansion
@ ~/.julia/packages/ObjectiveC/lG1iL/src/os.jl:264 [inlined]
[4] macro expansion
@ ~/.julia/packages/Metal/uNxGY/src/compiler/compilation.jl:556 [inlined]
[5] (::Metal.var"#link_pipeline##0#link_pipeline##1"{Metal.MTL.MTLDevice, Vector{UInt8}, Vector{UInt8}, String})()
@ Metal ~/.julia/packages/ObjectiveC/lG1iL/src/foundation.jl:733
[6] macro expansion
@ ~/.julia/packages/ObjectiveC/lG1iL/src/foundation.jl:661 [inlined]
[7] macro expansion
@ ./lock.jl:376 [inlined]
[8] ObjectiveC.Foundation.NSAutoreleasePool(f::Metal.var"#link_pipeline##0#link_pipeline##1"{…})
@ ObjectiveC.Foundation ~/.julia/packages/ObjectiveC/lG1iL/src/foundation.jl:653
[9] link_pipeline
@ ~/.julia/packages/Metal/uNxGY/src/compiler/compilation.jl:552 [inlined]
[10] macro expansion
@ ~/.julia/packages/Metal/uNxGY/src/compiler/execution.jl:254 [inlined]
[11] macro expansion
@ ./lock.jl:376 [inlined]
[12] link_kernel(mi::Core.MethodInstance; name::Nothing, kwargs::@Kwargs{})
@ Metal ~/.julia/packages/Metal/uNxGY/src/compiler/execution.jl:237
[13] mtlfunction(f::typeof(gpu_atomictest), tt::Type{…}; source::typeof(gpu_atomictest), kwargs::@Kwargs{…})
@ Metal ~/.julia/packages/Metal/uNxGY/src/compiler/execution.jl:231
[14] mtlfunction
@ ~/.julia/packages/Metal/uNxGY/src/compiler/execution.jl:230 [inlined]
[15] #kernel_function#2
@ ~/.julia/packages/Metal/uNxGY/src/MetalKernels.jl:102 [inlined]
[16] kernel_function
@ ~/.julia/packages/Metal/uNxGY/src/MetalKernels.jl:99 [inlined]
[17] launch_kernel(obj::KernelAbstractions.Kernel{…}, launch::KernelAbstractions.NDLaunch{…}, subgroups::Nothing, ndrange::Tuple{…}, _workgroupsize::Nothing, iterspace::KernelAbstractions.NDIteration.NDRange{…}, args::Tuple{…})
@ KernelAbstractions ~/.julia/packages/KernelAbstractions/tHp3q/src/backend_launch.jl:132
[18] launch_kernel
@ ~/.julia/packages/KernelAbstractions/tHp3q/src/backend_launch.jl:122 [inlined]
[19] launch_tuple(obj::KernelAbstractions.Kernel{…}, args::Tuple{…}; ndrange::Int64, workgroupsize::Nothing)
@ KernelAbstractions ~/.julia/packages/KernelAbstractions/tHp3q/src/backend_launch.jl:109
[20] launch_tuple
@ ~/.julia/packages/KernelAbstractions/tHp3q/src/backend_launch.jl:98 [inlined]
[21] top-level scope
@ REPL[32]:1
[22] top-level scope
@ ~/.julia/packages/Metal/uNxGY/src/initialization.jl:106
caused by: NSError: Compilation failed due to an interrupted connection: XPC_ERROR_CONNECTION_INTERRUPTED. This error occurred after multiple retries. (AGXMetalG17X, code 2)
Stacktrace:
[1] throw_error(err::ObjectiveC.id{ObjectiveC.Foundation.NSError})
@ Metal.MTL ~/.julia/packages/Metal/uNxGY/lib/mtl/MTL.jl:23
[2] MTLComputePipelineState
@ ~/.julia/packages/Metal/uNxGY/lib/mtl/compute_pipeline.jl:25 [inlined]
[3] macro expansion
@ ~/.julia/packages/Metal/uNxGY/src/compiler/compilation.jl:560 [inlined]
[4] macro expansion
@ ~/.julia/packages/ObjectiveC/lG1iL/src/os.jl:264 [inlined]
[5] macro expansion
@ ~/.julia/packages/Metal/uNxGY/src/compiler/compilation.jl:556 [inlined]
[6] (::Metal.var"#link_pipeline##0#link_pipeline##1"{Metal.MTL.MTLDevice, Vector{UInt8}, Vector{UInt8}, String})()
@ Metal ~/.julia/packages/ObjectiveC/lG1iL/src/foundation.jl:733
[7] macro expansion
@ ~/.julia/packages/ObjectiveC/lG1iL/src/foundation.jl:661 [inlined]
[8] macro expansion
@ ./lock.jl:376 [inlined]
[9] ObjectiveC.Foundation.NSAutoreleasePool(f::Metal.var"#link_pipeline##0#link_pipeline##1"{…})
@ ObjectiveC.Foundation ~/.julia/packages/ObjectiveC/lG1iL/src/foundation.jl:653
[10] link_pipeline
@ ~/.julia/packages/Metal/uNxGY/src/compiler/compilation.jl:552 [inlined]
[11] macro expansion
@ ~/.julia/packages/Metal/uNxGY/src/compiler/execution.jl:254 [inlined]
[12] macro expansion
@ ./lock.jl:376 [inlined]
[13] link_kernel(mi::Core.MethodInstance; name::Nothing, kwargs::@Kwargs{})
@ Metal ~/.julia/packages/Metal/uNxGY/src/compiler/execution.jl:237
[14] mtlfunction(f::typeof(gpu_atomictest), tt::Type{…}; source::typeof(gpu_atomictest), kwargs::@Kwargs{…})
@ Metal ~/.julia/packages/Metal/uNxGY/src/compiler/execution.jl:231
[15] mtlfunction
@ ~/.julia/packages/Metal/uNxGY/src/compiler/execution.jl:230 [inlined]
[16] #kernel_function#2
@ ~/.julia/packages/Metal/uNxGY/src/MetalKernels.jl:102 [inlined]
[17] kernel_function
@ ~/.julia/packages/Metal/uNxGY/src/MetalKernels.jl:99 [inlined]
[18] launch_kernel(obj::KernelAbstractions.Kernel{…}, launch::KernelAbstractions.NDLaunch{…}, subgroups::Nothing, ndrange::Tuple{…}, _workgroupsize::Nothing, iterspace::KernelAbstractions.NDIteration.NDRange{…}, args::Tuple{…})
@ KernelAbstractions ~/.julia/packages/KernelAbstractions/tHp3q/src/backend_launch.jl:132
[19] launch_kernel
@ ~/.julia/packages/KernelAbstractions/tHp3q/src/backend_launch.jl:122 [inlined]
[20] launch_tuple(obj::KernelAbstractions.Kernel{…}, args::Tuple{…}; ndrange::Int64, workgroupsize::Nothing)
@ KernelAbstractions ~/.julia/packages/KernelAbstractions/tHp3q/src/backend_launch.jl:109
[21] launch_tuple
@ ~/.julia/packages/KernelAbstractions/tHp3q/src/backend_launch.jl:98 [inlined]
[22] top-level scope
@ REPL[32]:1
[23] top-level scope
@ ~/.julia/packages/Metal/uNxGY/src/initialization.jl:106
Some type information was truncated. Use `show(err)` to see complete types.it works with |
|
I'll take a look. In the future, please open an issue; this problem is unrelated to this PR. |
…jectiveC 7, launch latency
KernelAbstractions 0.10 moves its back-end API into a separate package, KernelInterface. A back end implements KernelInterface: allocating and copying memory, selecting devices, compiling and launching kernels, and the device-side intrinsics. KernelAbstractions then launches
@kernelkernels the same way on every back end (JuliaGPU/KernelAbstractions.jl#801). This PR ports Metal.jl to that model in one step. It replaces #917, which added KernelInterface next to the existing KernelAbstractions 0.9 back end, and thekaintrbranch, which ported an earlier version of it to KernelAbstractions 0.10.MetalBackendnow implements KernelInterface, and Metal depends on KernelInterface instead of KernelAbstractions. That makes the KernelInterface layer usable on its own, without KernelAbstractions' macros:KernelAbstractions becomes a weak dependency. Its extension only provides what KernelAbstractions still needs from a back end: the stack allocation behind
@private, and the rule for moving anMtlArrayto the CPU withadapt. Metal's own copy of the KernelAbstractions launch path goes away: partitioning the ndrange, building the kernel's context, sizing the threadgroups, calling the kernel, and the overrides of KernelAbstractions' index functions.KI.copyto!now also accepts contiguous views of host arrays, andadapt(MetalBackend(), x)moves any array to the GPU, asadapt(MtlArray, x)does, not onlyArrays. Threadgroups are still as large as the pipeline'smaxTotalThreadsPerThreadgroupallows, which is what KernelInterface's defaultlaunch_configurationpicks, so Metal doesn't override it.Kernels behave the same, but they are launched differently. KernelAbstractions now launches them on a 3-D grid, and computes
@indexin 32 bits when the iteration space fits (JuliaGPU/KernelAbstractions.jl#797). So a kernel over a 3-Dndrangedoesn't need divisions to compute its index, which the test suite checks for the generated LLVM IR. On Metal this matters a lot, since 64-bit integer division is slow on Apple GPUs. With a KA kernel that copies aFloat32array, on an M1 (GPU time of the command buffer):@index(Global, Cartesian)@index(Global, Linear)@index(Global, Cartesian)@index(Global, Linear)The kernel times vary by about 10% between runs of this PR. The launch benchmark uses 28 arguments rather than the 40 of CUDA.jl's, because a Metal kernel takes at most 31 buffers, and every argument, the kernel's context and Metal's kernel state each take one.
KernelInterface 0.4 passes the arguments to the back end as a tuple (JuliaGPU/KernelAbstractions.jl#811). Metal has no public launch function that takes a tuple, but calling a
HostKernelforwards its arguments as one to an internal function, andKI.launchcalls that function directly, so nothing is splatted.KI.launchrejectsthreadsandgroups, which would override the launch geometry KernelInterface has validated, but passes Metal's other launch options on:The first commit is the port. The next ones implement parts of KernelInterface that are optional: sub-groups (SIMD-groups, including a partial last one), ordering work across tasks with Metal events for
KernelAbstractions.@spawn, where the waiting task's command buffer waits on the GPU instead of blocking the host, andKI.versioninfo.KernelAbstractions' conversion tests, skipped until now, pass with 32-bit indices. Its test that launches a kernel with 41 arguments is skipped, since a Metal kernel takes at most 31 buffers, one per argument. That limit isn't new, but it now shows in KernelAbstractions' test suite. Unlike CUDA.jl, Metal already converted the arguments twice (once for the types to compile for, and again while encoding them), so KernelAbstractions' generic launch doesn't add a conversion.
This needs a breaking release, since it requires KernelAbstractions 0.10, which isn't registered yet. Until then, the last commit takes KernelAbstractions and KernelInterface from their development branch through
[sources]. Julia 1.10 ignores[sources]and Julia 1.11 doesn't support workspaces, so on Buildkite those two set up the test environment by hand and run the tests in it directly. That commit is dropped before merging.