Repository navigation
Conversation
maleadt
force-pushed
the
vc/ki-subgroup-ops
branch
from
October 10, 2026 17:36
8e0e202 to
c507ee3
Compare
maleadt
added this pull request to stack #1154
October 10, 2026 17:45
Co-authored-by: Tim Besard <tim@juliahub.com>
Implement `shfl`, `shfl_down`, `shfl_up` and `shfl_xor` with `ds_bpermute` on the hardware lane, for the primitive types it supports by decomposing them into 32-bit words; other types use KernelInterface's fallbacks. Past the wavefront, `shfl_down` and `shfl_up` return the work-item's own value, as on CUDA, comparing the offset before narrowing it. The votes use the wavefront ballot, which only has bits for the work-items of the wavefront. Wavefronts are formed from consecutive linear work-item indices and execute independently, so report both `supports_linear_subgroups` and `supports_independent_subgroups`. Co-authored-by: Tim Besard <tim@juliahub.com>
The device overrides of `Base.min` and `Base.max` for floats called OCML's `__ocml_min`/`__ocml_max`, which, like C's `fmin`/`fmax`, return the other argument for a NaN, while Julia's `min` and `max` return NaN. Drop them: Julia's own definitions (`llvm.minimum`/`llvm.maximum` on Julia 1.12+, arithmetic before) compile for AMDGPU. Assisted-by: Claude Code (Opus 5.5) Co-authored-by: Tim Besard <tim@juliahub.com>
maleadt
force-pushed
the
vc/ki-subgroup-ops
branch
from
October 10, 2026 18:45
c507ee3 to
c3d2f0d
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the sub-group contract of KernelInterface from JuliaGPU/KernelAbstractions.jl#831 for
ROCBackend: the shufflesshfl,shfl_down,shfl_upandshfl_xor, the votessub_group_any,sub_group_allandsub_group_ballot, and aget_max_sub_group_sizethat is a constant of the generated code.What's implemented
shfl(val, lane)ds_bpermute(Device.bpermute) from hardware lanelane - 1shfl_down(val, offset)ds_bpermutefrom hardware lanembcnt + offset, ormbcntpast the wavefrontshfl_up(val, offset)ds_bpermutefrom hardware lanembcnt - offset, ormbcntif that is negativeshfl_xor(val, mask)ds_bpermutefrom hardware lanembcnt ⊻ masksub_group_ballot(pred)Device.ballot(pred)(llvm.amdgcn.ballot.i32/.i64, widened toUInt64)sub_group_any(pred)Device.ballot(pred) != 0sub_group_all(pred)Device.ballot(!pred) == 0get_max_sub_group_size()Device.wavefrontsize(), folded to a constant (unchanged)mbcnt), likeget_sub_group_local_id, notactivelane. They don't useDevice.shfl*, which clamp out-of-range offsets to the own lane and work onactivelane.ds_bpermuteonly uses the low bits of the address, so a lane out of range reads an unspecified value rather than trapping. Lanes and offsets are truncated with% Cint, so there is no checked conversion: the IR of a kernel using all shuffles and votes with runtimeIntlanes/offsets has nothrow/trap/unreachable.supports_shuffleare now only defined forconst ShuffleTypes = Union{Bool, Base.BitInteger, Base.IEEEFloat}(whatDevice._shfldecomposes into 32-bitbpermutes). The previous genericwhere {T}shfl_downoverride and thesupports_shufflethat listedComplexare gone, soComplexand otherisbitsstructs/tuples go through KernelInterface's field-by-field fallback.shfl_down/shfl_upreturn the work-item's own value where the source lane is past the wavefront (as KernelInterface now requires, like CUDA): one compare and select against the constant wavefront size before theds_bpermute.shfl_xorneeds no change, as KernelInterface requiresmaskbelow the width.width(KI.shfl(val, lane, width)etc.) use KernelInterface's fallbacks: oneds_bpermutefrom a lane computed with a few integer operations, the same asDevice.shfletc. DPP/ds_swizzlecould be cheaper for constant offsets, but isn't used here.KI.supports_linear_subgroupsandKI.supports_independent_subgroupsaretrue: wavefronts are formed from consecutive linear work-item ids, x fastest (KernelInterface's layout tests check this), and are independent. KernelInterface no longer implies either fromsupports_subgroups.ballotsetting only the bits of active lanes, i.e. of the work-items of the (possibly partial) sub-group. The result is uniform.Constant width
This needed no new code.
KI.kernel_functioncompiles for the device's wavefront size (and rejects a conflictingwavefrontsize64), andfold_wavefrontsize!infinish_module!already replacesllvm.amdgcn.wavefrontsizewith the compiled-for size before optimization. I checked this with@device_code_llvmon a kernel that storesKI.get_max_sub_group_size(): it compiles tostore i64 32withwavefrontsize64=falseandstore i64 64withwavefrontsize64=true, and the call tollvm.amdgcn.wavefrontsizeis gone. I added a comment saying so.[TEMP]commit[TEMP] Test against KernelAbstractions' vc/ki-subgroup-ops branchpoints KernelAbstractions and KernelInterface atvc/ki-subgroup-ops. SPIRVIntrinsics 1.4 is registered, so the earlier pin to OpenCL.jl'svc/subgroup-votesis gone. Drop the commit once KernelAbstractions.jl#831 is merged.Local testing
gfx1036 iGPU (wave32), Julia 1.12, on
ka-0.10rebased ontomain, KernelAbstractions at the current #831: KernelInterface testsuite 6089/6089, KernelAbstractions testsuite 2639 passed, 4 broken, in three runs without hangs. Offsets up totypemax(Int64)give the own value past the wavefront.