Conversation
Implement the sub-group communication of KernelInterface's updated contract: `shfl`, `shfl_up` and `shfl_xor` next to `shfl_down`, and the votes `sub_group_any`, `sub_group_all` and `sub_group_ballot`, using the warp intrinsics with the full mask. The shuffles, and `supports_shuffle`, are restricted to the primitive types CUDA's warp shuffles support, so that KernelInterface shuffles structs and tuples (including `Complex`) field by field. Lanes and offsets are truncated rather than converted, so that out-of-range values give an unspecified value instead of throwing. The warp size is now the constant 32 rather than a read of `%WARP_SZ`, so that `get_max_sub_group_size` is a compile-time constant of the generated code, as KernelInterface requires. Assisted-by: Claude Code (Opus 5.5)
…roup-ops branch Test against JuliaGPU/KernelAbstractions.jl#831. Drop this commit (going back to KernelAbstractions' main branch) once that is merged. Assisted-by: Claude Code (Opus 5.5)
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 communication of KernelInterface's updated contract from JuliaGPU/KernelAbstractions.jl#831 in the CUDA back-end (
CUDACore/src/CUDAKernels.jl).What's implemented
KI.shfl,KI.shfl_down,KI.shfl_up,KI.shfl_xor, all with the full warp mask, like the existingshfl_downoverride.KI.supports_shuffle, now only matchconst ShuffleTypes = Union{Bool, Base.BitInteger, Base.IEEEFloat}. These are the primitive types CUDA.jl's warp shuffles handle, splitting the wider ones into 32-bit shuffles. Otherisbitstypes,Complexincluded, go to KI's generic fallback, which shuffles them field by field. Before this PR,shfl_downandsupports_shufflewere genericwhere {T}methods.% UInt32rather than converted, so an out-of-range value returns an unspecified value instead of throwing anInexactError.shfl_synctakes a 1-based lane and subtracts 1, soKI.shflwraps the lane into1:32first, which is the same wrapping PTX applies to the 0-based lane.KI.sub_group_any,KI.sub_group_all,KI.sub_group_ballot. Ballot widens theUInt32fromvote_ballot_synctoUInt64. Biti - 1is set for lanei, sincelaneid()is 1-based.32i32(WARP_SIZE) instead of a read of%WARP_SZ.KI.get_max_sub_group_size(T)returns32 % T, a compile-time constant of the generated code as the contract requires. The other sub-group queries (get_num_sub_groups,get_sub_group_id, the partial-warp size) use the same constant. Every NVIDIA GPU has a warp size of 32, and CUDA.jl's warp intrinsics already hard-code it (ws = Int32(32)inwarp.jl). The host-sideKI.sub_group_size(::CUDABackend)still querieswarpsize(device()), which returns 32.shfl(val, lane)shfl_sync(FULL_MASK, val, lane′)withlane′ = ((lane - 1) % UInt32 & 0x1f) + 1shfl_down(val, offset)shfl_down_sync(FULL_MASK, val, offset % UInt32)shfl_up(val, offset)shfl_up_sync(FULL_MASK, val, offset % UInt32)shfl_xor(val, mask)shfl_xor_sync(FULL_MASK, val, mask % UInt32)sub_group_any(pred)vote_any_sync(FULL_MASK, pred)sub_group_all(pred)vote_all_sync(FULL_MASK, pred)sub_group_ballot(pred)UInt64(vote_ballot_sync(FULL_MASK, pred))get_max_sub_group_size(T)32i32 % Tsupports_shuffle(::CUDABackend, ::Type{<:ShuffleTypes})true(composites go to KI's fallback)[TEMP]commitThe second commit,
[TEMP] Get KernelAbstractions and KernelInterface from the vc/ki-subgroup-ops branch, changes the[sources]revs inCUDACore,CUDATools,lib/cusparseandtest, and the Buildkite clone for Julia 1.10/1.11, from KA'smaintovc/ki-subgroup-ops. This makes CI test against #831. Drop it, or squash it into the existing[TEMP]commit, once #831 is merged.The CUDA back-end doesn't need the
SPIRVIntrinsicssource that KA's branch uses for POCL. Without it, the test environment resolves the registered SPIRVIntrinsics v1.2.0, and KA precompiles and loads fine.Heads-up, a problem
ka-0.10already has: KA'smainand #831 both requireLLVM = "10", butka-0.10still hasLLVM = "9.6"inCUDACoreand"9.3.1"inCUDATools.mainhas since moved to LLVM.jl 10 (#3323). Soka-0.10doesn't resolve against either KA branch, and CI on this PR will fail to resolve untilka-0.10is rebased ontomain. This PR doesn't fix that.Local testing
I tested on a Quadro RTX 4000 (sm_75) with Julia 1.12.7. I used a throwaway local branch where
ka-0.10, plus these commits, was rebased ontomain; the only conflicts were the LLVM and version compat entries. It resolved KA/KI0.10.0-dev/0.4.0-devfrom#vc/ki-subgroup-ops(7f09a6c), LLVM v10.0.0 and GPUCompiler v2.11.1.Result:
Overall | 3612 pass, 17 broken, 3629 total, SUCCESS. The 17 broken tests are existing@test_brokens. This includes KI's testsuite from #831: the new shuffles (including structs), the votes and the constant width.I also ran these checks by hand:
KI.shflwith lanes0, -5, 33, typemax(Int),shfl_down(Int8, typemax(Int))andshfl_up(UInt16, 40)don't throw.KI.get_max_sub_group_size()doesn't read%WARP_SZ.KI.shflonComplexF64goes through the KI fallback and gives the correct result.supports_shufflereturnstrueforComplexF64andfalseforChar.🤖 Generated with Claude Code