Skip to content

[SYCL] Add CUDA/HIP hardware acceleration for dot_acc (dp4a)#22756

Open
zjin-lcf wants to merge 2 commits into
intel:syclfrom
zjin-lcf:dp4a-cuda-hip-support
Open

[SYCL] Add CUDA/HIP hardware acceleration for dot_acc (dp4a)#22756
zjin-lcf wants to merge 2 commits into
intel:syclfrom
zjin-lcf:dp4a-cuda-hip-support

Conversation

@zjin-lcf

Copy link
Copy Markdown
Contributor

Summary

Lower the sycl_ext_oneapi_dot_accumulate dot_acc helpers to the native dp4a instruction on hardware that supports it, keeping the existing scalar implementation as a portable fallback. The numerical result is identical on every path.

  • NVPTX (CUDA): emit dp4a.{s32,u32}.{s32,u32} on sm_61+ (Pascal and later) for all four operand-signedness combinations.
  • AMDGCN (HIP): use __builtin_amdgcn_sdot4 / udot4 (v_dot4, gfx906+/CDNA/RDNA2) and __builtin_amdgcn_sudot4 (v_dot4_i32_iu8, gfx11/RDNA3+ and gfx12/RDNA4) for the mixed-sign cases and, where sdot4 is unavailable (RDNA3+ dropped v_dot4_i32_i8), the same-sign signed case. Every path is guarded by __builtin_amdgcn_is_invocable, so architectures lacking a given instruction fall back to scalar.

Cleanups

  • Move the scalar fallbacks into detail and drop the Us/Uu unions that leaked into the public sycl::ext::oneapi namespace.
  • Read the packed words through int8_t/uint8_t views instead of a char-based union: fixes signedness on targets where plain char is unsigned (e.g. AArch64) and removes type-punning UB.
  • vec<*8_t, 4> overloads now sycl::bit_cast directly to the packed 32-bit word.

Test plan

  • New check_device_code codegen tests:
    • CUDA sm_90: dp4a.s32.s32, dp4a.u32.u32, dp4a.s32.u32, dp4a.u32.s32.
    • HIP gfx90a, gfx942, gfx1030 (sdot4/udot4) and gfx1100, gfx1200 (sudot4).
  • E2E DotProduct int + vec tests (all four sign combinations) pass on:
    • NVIDIA H100 (sm_90)
    • AMD Instinct MI210 (gfx90a) and MI300A (gfx942)
  • Host equivalence of the refactored fallbacks vs. reference: 0 mismatches over millions of random inputs.

zjin-lcf and others added 2 commits July 23, 2026 14:06
The compare_exchange definition guard grouped __NVPTX__ with __SPIR32__
and only emitted atomics for 32-bit types, so 64-bit integer
__clc_atomic_compare_exchange was declared (via atomic_decl.inc) but never
defined for CUDA, causing "Unresolved extern function
'_Z29__clc_atomic_compare_exchange...'" (ptxas fatal) for 64-bit CAS.

Match the guard used by the sibling clc_atomic_def.inc (restrict only
__SPIR32__ to 32-bit) so both CUDA (NVPTX) and HIP (AMDGPU) get 64-bit
compare_exchange definitions.

Co-authored-by: Cursor <cursoragent@cursor.com>
The `sycl_ext_oneapi_dot_accumulate` `dot_acc` helpers previously always
used a scalar implementation. Lower them to the native dp4a instruction
on hardware that supports it, keeping the scalar path as a portable
fallback (the numerical result is identical):

- NVPTX (CUDA): emit the `dp4a.{s32,u32}.{s32,u32}` instruction on
  sm_61+ (Pascal and later), covering all four operand-signedness
  combinations.
- AMDGCN (HIP): use `__builtin_amdgcn_sdot4` / `udot4` (v_dot4, gfx906+/
  CDNA/RDNA2) and `__builtin_amdgcn_sudot4` (v_dot4_i32_iu8, gfx11/RDNA3+
  and gfx12) for the mixed- and, where sdot4 is unavailable, same-sign
  cases. Each path is guarded by `__builtin_amdgcn_is_invocable` so
  architectures without a given instruction fall back to scalar.

The scalar fallbacks are moved into `detail` (dropping the `Us`/`Uu`
unions that leaked into the public namespace) and now read the packed
words through `int8_t`/`uint8_t` views, which fixes signedness on targets
where plain `char` is unsigned (e.g. AArch64) and avoids type-punning UB.
The `vec` overloads bit-cast directly to the packed 32-bit word.

Add check_device_code tests for the CUDA (sm_90) and HIP (gfx90a, gfx942,
gfx1030, gfx1100, gfx1200) codegen, and update the existing E2E tests'
comments to reflect that they now validate the hardware paths too.

Co-authored-by: Cursor <cursoragent@cursor.com>
@zjin-lcf
zjin-lcf requested review from a team, Maetveis and wenju-he as code owners July 24, 2026 15:42

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.

could you also upstream this change to llvm-project?

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