Skip to content

[libclc][amdgpu] Implement __spirv_GroupNonUniform*Shuffle* builtins#22665

Open
zjin-lcf wants to merge 1 commit into
intel:syclfrom
zjin-lcf:amdgpu-group-nonuniform-shuffle
Open

[libclc][amdgpu] Implement __spirv_GroupNonUniform*Shuffle* builtins#22665
zjin-lcf wants to merge 1 commit into
intel:syclfrom
zjin-lcf:amdgpu-group-nonuniform-shuffle

Conversation

@zjin-lcf

Copy link
Copy Markdown
Contributor

The amdgcn libspirv device library declares the SPIR-V group non-uniform shuffle builtins (__spirv_GroupNonUniformShuffle{,Up,Down,Xor}) via libspirv/group/group_shuffle*.h but never defines them for the amdgpu target. The SYCL headers (sycl/detail/spirv.hpp) emit these directly for sub-group shuffle/permute/scan, and oneDPL work-group algorithms (inclusive_scan, sort, ...) rely on them. Device linking for amdgcn-amd-amdhsa therefore fails with e.g.

undefined symbol: __spirv_GroupNonUniformShuffleUp

Unlike SPIR-V targets there is no runtime translation of these instructions, so the device library must provide them.

Add group/group_shuffle.cl for the amdgpu target, mapping the four non-uniform shuffle operations onto the existing, validated __spirv_SubgroupShuffle*INTEL primitives (misc/sub_group_shuffle.cl), which lower to the hardware ds_bpermute wavefront shuffle. These primitives derive the wavefront size from __spirv_BuiltInSubgroupMaxSize() rather than hardcoding it and use only ds_bpermute, so they are correct across all wave64 CDNA generations (CDNA1 gfx908, CDNA2 gfx90a, CDNA3 gfx942, CDNA4 gfx950) with no arch-specific code. Only scalar overloads are defined: the SYCL headers scalarize all vector/marray shuffles and lower bitcast/generic shuffles onto integer scalars before reaching the intrinsic, matching the scalar-only __spirv_GroupBroadcast definitions in group/collectives.cl.

The amdgcn libspirv device library declares the SPIR-V group non-uniform
shuffle builtins (__spirv_GroupNonUniformShuffle{,Up,Down,Xor}) via
libspirv/group/group_shuffle*.h but never defines them for the amdgpu
target. The SYCL headers (sycl/detail/spirv.hpp) emit these directly for
sub-group shuffle/permute/scan, and oneDPL work-group algorithms
(inclusive_scan, sort, ...) rely on them. Device linking for
amdgcn-amd-amdhsa therefore fails with e.g.

  undefined symbol: __spirv_GroupNonUniformShuffleUp

Unlike SPIR-V targets there is no runtime translation of these
instructions, so the device library must provide them.

Add group/group_shuffle.cl for the amdgpu target, mapping the four
non-uniform shuffle operations onto the existing, validated
__spirv_SubgroupShuffle*INTEL primitives (misc/sub_group_shuffle.cl),
which lower to the hardware ds_bpermute wavefront shuffle. These
primitives derive the wavefront size from __spirv_BuiltInSubgroupMaxSize()
rather than hardcoding it and use only ds_bpermute, so they are correct
across all wave64 CDNA generations (CDNA1 gfx908, CDNA2 gfx90a,
CDNA3 gfx942, CDNA4 gfx950) with no arch-specific code. Only scalar
overloads are defined: the SYCL headers scalarize all vector/marray
shuffles and lower bitcast/generic shuffles onto integer scalars before
reaching the intrinsic, matching the scalar-only __spirv_GroupBroadcast
definitions in group/collectives.cl.

Co-authored-by: Cursor <cursoragent@cursor.com>
@zjin-lcf
zjin-lcf requested review from a team, Maetveis and wenju-he as code owners July 18, 2026 11:38
@zjin-lcf
zjin-lcf requested a review from kweronsx July 18, 2026 11:38
// Subgroup path of __spirv_GroupBroadcast in group/collectives.cl.
#define __CLC_GROUP_NON_UNIFORM_SHUFFLE(TYPE) \
_CLC_DEF _CLC_OVERLOAD _CLC_CONVERGENT TYPE __spirv_GroupNonUniformShuffle( \
int scope, TYPE value, uint id) { \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
int scope, TYPE value, uint id) { \
int execution, TYPE value, uint id) { \

_CLC_DEF _CLC_OVERLOAD _CLC_CONVERGENT TYPE __spirv_GroupNonUniformShuffle( \
int scope, TYPE value, uint id) { \
(void)scope; \
return __spirv_SubgroupShuffleINTEL(value, id); \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (execution == Subgroup)
  return __spirv_SubgroupShuffleINTEL(value, id);
return 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

current implementation is also fine since the spec requires Execution is .... . It must be Subgroup.

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