Skip to content

hip/gfx906: cudaFuncSetAttribute must be a function, not a macro (ROCm 7.2.1 build fix) - #808

Closed
xxDoman wants to merge 1 commit into
Niko1221:mainfrom
xxDoman:fix-gfx906-cudafuncsetattribute
Closed

xxDoman wants to merge 1 commit into
Niko1221:mainfrom
xxDoman:fix-gfx906-cudafuncsetattribute

Conversation

@xxDoman

@xxDoman xxDoman commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Problem

Building the gfx906 backend (-DSTRATA_HIP_GFX906=ON) from source fails on ROCm 7.2.1: cudaFuncSetAttribute is a function-like macro in include/strata/platform/hip_compat/strata_hip.h, and the call sites pass a template instantiation whose argument list contains commas — the preprocessor splits on them and the macro gets too many arguments.

Environment

OS Ubuntu 26.04.1 LTS, kernel 7.0.0-38, x86_64
CPU Intel Core i5-12400F
GPU AMD Instinct MI50 32 GB — gfx906 (Vega 20, wave64)
ROCm 7.2.1
HIP compiler AMD clang 22.0.0git (roc-7.2.1, commit 26084)
CMake / Make 4.2.3 / 4.4.1 · gcc 15.2.0 · glibc 2.43
cmake -DSTRATA_HIP_GFX906=ON -DCMAKE_HIP_ARCHITECTURES=gfx906 \
      -DCMAKE_HIP_COMPILER=/opt/rocm-7.2.1/lib/llvm/bin/clang++ \
      -DCMAKE_BUILD_TYPE=Release ..
make -j11 strata      # EXIT 2

Error

include/strata/platform/hip_compat/strata_hip.h:154:

#define cudaFuncSetAttribute(fn, attr, val) hipFuncSetAttribute(reinterpret_cast<const void*>(fn), attr, val)

src/kernels/cuda/fused_gr.cu:1089-1093:

cudaFuncSetAttribute(gr_down_v3_kernel<1, kFusedGrMaxT, false>, cudaFuncAttributeMaxDynamicSharedMemorySize, need1) == cudaSuccess &&
cudaFuncSetAttribute(gr_down_v3_kernel<1, 6, true>, cudaFuncAttributeMaxDynamicSharedMemorySize, need6) == cudaSuccess) {
    cudaFuncSetAttribute(gr_down_v3_kernel<1, 4, true>, cudaFuncAttributePreferredSharedMemoryCarveout, 100);
    ...
fused_gr.cu:1089:81: error: too many arguments provided to function-like macro invocation
strata_hip.h:154:9: note: macro 'cudaFuncSetAttribute' defined here
fused_gr.cu:1089:17: error: use of undeclared identifier 'cudaFuncSetAttribute'

5 errors (lines 1089-1093). The preprocessor reads gr_down_v3_kernel<1, kFusedGrMaxT, false> as several macro arguments (<1, kFusedGrMaxT, …) and chokes on the rest. This is standard preprocessor behaviour, not a toolchain quirk — a plain gcc -E on the same construct gives "passed 5 arguments, but takes just 3".

Fix (2 changes, both in strata_hip.h)

(1) cudaFuncSetAttribute back to a template function — as it was in 0.1.38's hip_compat/cuda_runtime.h:130 (which is why the wave32 backend never tripped on this):

template <typename Kernel>
inline hipError_t cudaFuncSetAttribute(Kernel kernel, hipFuncAttribute attribute, int value) {
    return hipFuncSetAttribute(reinterpret_cast<const void*>(kernel), attribute, value);
}

(2) Two definitions used beside it were missing from the platform header (present in the old one):

#define cudaFuncAttributePreferredSharedMemoryCarveout hipFuncAttributePreferredSharedMemoryCarveout
#define cudaSharedmemCarveoutMaxShared 100   // CUDA's max-carveout percentage; HIP has no constant

Scope / safety

include/strata/platform/hip_compat/ is only added to the include path inside if(STRATA_HIP_GFX906) (CMakeLists.txt:106-120), and the affected calls are inside #if defined(STRATA_HIP_GFX906). CUDA builds use the real CUDA function and the wave32 RDNA backend uses the older header — neither is touched. The change only makes the gfx906 build compile.

Verified on MI50 32 GB (IQ2_XS, 4k prompt, 256 decode, --spec 3)

build prefill decode
0.1.39 + this fix (clean source) 293 tok/s 42.5 tok/s
0.1.38 + local gfx906 + our patches 294 tok/s 32.4 tok/s

Correctness on both: 17*23 → 391. After the fix make is EXIT 0, the binary links libhipblas/librocblas, 108 gfx906 code objects, engine loads and serves.

Question for @JeanP00l

Thanks for the gfx906 port — it works great once building. We don't know which ROCm/toolchain you built on: on ROCm 7.2.1 the macro above is a hard error here, yet it built for you (and gcc/clang agree the construct is malformed regardless of version). Could you share your HIP/ROCm version? If your build took a path that skips these lines, that would explain it — and is worth documenting either way.

(We also have a community MI50 benchmark open as #758.)

A function-like macro splits its arguments on the commas inside a template
argument list, so cudaFuncSetAttribute(kernel<1, 6, true>, ...) failed to
compile (fused_gr.cu:1089-1093, 'too many arguments provided to function-like
macro invocation'). Restore the template function 0.1.38's hip_compat/
cuda_runtime.h had, and add the two carveout definitions used beside it.

gfx906-only: include/strata/platform/hip_compat/ is on the include path only
inside if(STRATA_HIP_GFX906); CUDA and the wave32 RDNA backend are untouched.
@JeanP00l

JeanP00l commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Thanks for the detailed report and the reproducible fix. Our gfx906 build was made with HIP/ROCm 7.14 from mixa3607/rocm-gfx906:7.14-complete, so we have not verified this build path on ROCm 7.2.1. Your explanation of the template commas being split by the function-like macro is clear, and the template wrapper is a sensible fix; the MI50 build and inference results are especially useful.

@xxDoman

xxDoman commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

Two other open PRs fix the same two lines in this header:

All three replace the function-like cudaFuncSetAttribute macro with a template function (the macro splits on the commas in gr_down_v3_kernel<1, 4, true>) and map cudaFuncAttributePreferredSharedMemoryCarveout. Whichever lands first, the other two will need a rebase — flagging it here so it is visible from one place. This one stays small and scoped to gfx906.

@Niko1221

Niko1221 commented Oct 6, 2026

Copy link
Copy Markdown
Owner

Merged for 0.1.40 (cudaFuncSetAttribute as a function on HIP/gfx906). Thank you.

@Niko1221 Niko1221 closed this Oct 6, 2026
Niko1221 pushed a commit that referenced this pull request Oct 8, 2026
…lockingSync)

Two gfx906 build failures on v0.1.40.2. Both are one-line gates that know
about the wave32 HIP backend but not about STRATA_HIP_GFX906 -- the same
class as #808 and #1083. Neither is fixed on main (e8ca9af).

1) src/prefill/prefill.cpp:399 builds an event with
   cudaEventDisableTiming | cudaEventBlockingSync, but the gfx906 compat
   header include/strata/platform/hip_compat/strata_hip.h maps only
   cudaEventDisableTiming and cudaEventDefault. The wave32 header
   include/strata/hip_compat/cuda_runtime.h:39 has the mapping.
   -> add #define cudaEventBlockingSync hipEventBlockingSync there.

   A diff of the whole set of cuda* defines between the two headers lists
   one other name the gfx906 header lacks, cudaDevAttrIntegrated, and that
   one is already gated upstream (#if defined(__linux__) &&
   !defined(STRATA_HIP_GFX906) in src/core/expert_cache.cpp:31), so it is
   deliberately not touched here.

2) Link error: undefined symbol
   void mul_mat_q_case<(ggml_type)14>(ggml_backend_cuda_context&, mmq_args const&, ihipStream_t*)
   (14 = GGML_TYPE_Q6_K).
   src/prefill/moe_mmq.cu:219 calls it under
   #if defined(__HIPCC__) || defined(STRATA_Q6K_EXPERTS), so any HIP
   compilation references it; mmq.cuh declares the case as an extern
   template, so the definition must come from
   template-instances/mmq-instance-q6_k.cu. The CUDA branch of
   CMakeLists.txt adds that file only under STRATA_Q6K_EXPERTS.
   STRATA_HIP_GFX906=ON forces STRATA_ENABLE_CUDA=ON, so gfx906 takes the
   CUDA branch while its .cu files are compiled as HIP.
   -> widen the gate: STRATA_Q6K_EXPERTS OR STRATA_HIP_GFX906.
   This adds one MMQ instance to the static library. It does not enable
   STRATA_Q6K_EXPERTS (the grouped Q6_K expert kernels that allocate extra
   VRAM), and STRATA_HIP_GFX906 is only ever ON in the gfx906 build, so
   CUDA and wave32 builds are untouched.

Verified on a single Instinct MI50 32 GB (gfx906, wave64), ROCm/HIP 7.14,
-DSTRATA_HIP_GFX906=ON -DCMAKE_HIP_ARCHITECTURES=gfx906
-DSTRATA_MMQ_KQUANTS=ON:

- the engine builds and serves UD-IQ4_XS (Qwen3.8-Flash-Next) end to end:
  /v1/models, chat completions, tool calls, MTP drafts accepted;
- nm -C shows mul_mat_q_case<(ggml_type)14> in the binary (13 instances:
  7 8 12 13 14 16 17 18 20 21 22 23 42);
- change 2 is load-bearing: removing mmq-instance-q6_k.cu.o from
  libstrata_mmq.a and relinking with the same link command line fails with
  exactly the undefined symbol above (the archive holds one U reference
  and that one W definition), while the untouched archive relinks cleanly.
giridhart pushed a commit to giridhart/Strata that referenced this pull request Oct 15, 2026
…lockingSync)

Two gfx906 build failures on v0.1.40.2. Both are one-line gates that know
about the wave32 HIP backend but not about STRATA_HIP_GFX906 -- the same
class as Niko1221#808 and Niko1221#1083. Neither is fixed on main (ef29f14).

1) src/prefill/prefill.cpp:399 builds an event with
   cudaEventDisableTiming | cudaEventBlockingSync, but the gfx906 compat
   header include/strata/platform/hip_compat/strata_hip.h maps only
   cudaEventDisableTiming and cudaEventDefault. The wave32 header
   include/strata/hip_compat/cuda_runtime.h:39 has the mapping.
   -> add #define cudaEventBlockingSync hipEventBlockingSync there.

   A diff of the whole set of cuda* defines between the two headers lists
   one other name the gfx906 header lacks, cudaDevAttrIntegrated, and that
   one is already gated upstream (#if defined(__linux__) &&
   !defined(STRATA_HIP_GFX906) in src/core/expert_cache.cpp:31), so it is
   deliberately not touched here.

2) Link error: undefined symbol
   void mul_mat_q_case<(ggml_type)14>(ggml_backend_cuda_context&, mmq_args const&, ihipStream_t*)
   (14 = GGML_TYPE_Q6_K).
   src/prefill/moe_mmq.cu:219 calls it under
   #if defined(__HIPCC__) || defined(STRATA_Q6K_EXPERTS), so any HIP
   compilation references it; mmq.cuh declares the case as an extern
   template, so the definition must come from
   template-instances/mmq-instance-q6_k.cu. The CUDA branch of
   CMakeLists.txt adds that file only under STRATA_Q6K_EXPERTS.
   STRATA_HIP_GFX906=ON forces STRATA_ENABLE_CUDA=ON, so gfx906 takes the
   CUDA branch while its .cu files are compiled as HIP.
   -> widen the gate: STRATA_Q6K_EXPERTS OR STRATA_HIP_GFX906.
   This adds one MMQ instance to the static library. It does not enable
   STRATA_Q6K_EXPERTS (the grouped Q6_K expert kernels that allocate extra
   VRAM), and STRATA_HIP_GFX906 is only ever ON in the gfx906 build, so
   CUDA and wave32 builds are untouched.

Verified on a single Instinct MI50 32 GB (gfx906, wave64), ROCm/HIP 7.14,
-DSTRATA_HIP_GFX906=ON -DCMAKE_HIP_ARCHITECTURES=gfx906
-DSTRATA_MMQ_KQUANTS=ON:

- the engine builds and serves UD-IQ4_XS (Qwen3.8-Flash-Next) end to end:
  /v1/models, chat completions, tool calls, MTP drafts accepted;
- nm -C shows mul_mat_q_case<(ggml_type)14> in the binary (13 instances:
  7 8 12 13 14 16 17 18 20 21 22 23 42);
- change 2 is load-bearing: removing mmq-instance-q6_k.cu.o from
  libstrata_mmq.a and relinking with the same link command line fails with
  exactly the undefined symbol above (the archive holds one U reference
  and that one W definition), while the untouched archive relinks cleanly.
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.

3 participants