mirror of
https://github.com/Comfy-Org/comfy-kitchen.git
synced 2026-11-04 23:37:42 +00:00
[GH-ISSUE #170] HIP backend: kernels taking __bf16 never launch on ROCm 7.1 / clang 21 (host stub and device symbol mangled differently) #54
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Comfy-Org/comfy-kitchen#54
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @dyc-dev on GitHub (Sep 10, 2026).
Original GitHub issue: https://github.com/Comfy-Org/comfy-kitchen/issues/170
HIP backend: kernels taking
__bf16never launch on ROCm 7.1 / clang 21 (host stub and device symbol mangled differently)Environment
comfy_kitchen/backends/hip)gfx1201(RDNA4, wave32)/opt/rocm,libhsa-runtime64.so.1.18.0, HIP 7.1.52801)/opt/rocm/llvm/bin/clang++)cmake -S comfy_kitchen/backends/hip -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCOMFY_HIP_ARCHS=gfx1201 -Dnanobind_DIR=<venv>/nanobind/cmake -DPython_EXECUTABLE=<venv>/bin/pythonSymptom
The extension builds and loads fine (
hipbackend reportsavailable: True, 39 capabilities), and kernels that don't touch__bf16work (quantize_int8_rowwise✅). But every kernel whose signature mentions__bf16fails at launch with:Affected: all
gemm_wmma_kernel<..., __bf16, ...>instantiations (int8 / int4 / fp8 GEMMs),adaln,rms_adaln,dequantize_per_tensor_fp8,convrot_w4a4_linear,gemv_awq, the rope kernels and the sage/int8-attention family — i.e. anything instantiated with a bf16 output type or taking a__bf16*parameter. The official test suite cannot run:pytest tests/test_hip_wmma.py→ 399 skipped ("HIP extension not built") once the module path is fixed, or the process aborts (Fatal Python error) when the int8 cases actually launch.Root cause:
__bf16is mangled differently in the host pass and in the device passMinimal reproduction (no comfy-kitchen needed) —
repro/bf16-mangling-repro.shin this report:Same for template arguments:
So the host-side launch stub embeds
...u6__bf16...while the device code object exports...DF16b...; the HIP runtime looks the symbol up by the host-side name and never finds it. Note the__AMDGCN_WAVEFRONT_SIZE__deprecation warnings in clang 21 suggest the toolchain has been changing builtin handling in this cycle.Evidence from a real build (comfy-kitchen HIP extension)
Diffing the host-referenced names against the device code objects extracted from the same
.so(
llvm-objcopy --dump-section .hip_fatbin=…):i.e. the only thing missing from the device code is the bf16-output spelling.
What does NOT fix it
-mllvm -amdgpu-internalize-symbols=false(verified in the compile command line, still fails — so it's not internalization)-fclang-abi-compat=17/=18ops/*.hipTUs compile;adaln.hip.o,gemm_int8.hip.o,per_tensor_fp8.hip.oare all in the build dir) — the symbols are simply stamped with the device-pass spelling.Workaround that works (fully verified)
Spell the type as
hip_bfloat16in every signature position (kernel parameter types, template arguments at launch sites, and the dtype-dispatch macro invocations), while leaving__bf16everywhere it is a hardware vector type (ext_vector_type,mma.h'sElem,v8bf/v16bf).Three passes are needed; the third is the easy one to miss:
__global__,<<<,launch_*<,store_out<,rope_store<,operator()<;COMFY_LAUNCH_QUANT(__bf16),COMFY_LAUNCH_DEQUANT(__bf16),CK_LAUNCH_DEQUANT_CONVROT(__bf16),CK_ROPE_LAUNCH(__bf16),CK_RMS_ROPE_LAUNCH(__bf16),CK_AWQ_LAUNCH(__bf16),CK_SVD_LAUNCH(__bf16,…),COMFY_REQUANT_LAUNCH(__bf16),SAGE_QK_DISPATCH_DTYPE(__bf16). Missing these leaves the corresponding op broken even after 1 and 2.After the change (and adding
#include <hip/hip_bfloat16.h>to the touched files):Numerical cross-check against the
eagerbackend for the previously-crashing ops:int8_linearrel. mean err 7.7e-3;adaln,rms_adaln,dequantize_per_tensor_fp8bit-identical. Performance on gfx1201: int8 GEMM 4096³ = 155 TFLOPS (vs 34 TFLOPS for the eager fallback),sol_attn/int8_attentionrun as WMMA kernels (int8 attention ~100 TFLOPS at S=4096·H=16·D=128 vs 48 TFLOPS for SDPA).Side note (separate, minor):
setup.py --hipcannot configure on this toolchainsetup.py's CMake invocation passes-DCMAKE_C_COMPILER=/opt/rocm/bin/hipcc -DCMAKE_CXX_COMPILER=/opt/rocm/bin/hipcc; with hipcc as the C/CXX compiler CMake configuration fails. Using default system compilers (gcc 15 for C/CXX, clang 21 discovered for HIP) configures fine. Also, ifCOMFY_HIP_ARCHSis not passed, the build targets all 17 archs.Suggestion
Mangle-stable handling would be to avoid the builtin
__bf16in mangled positions (usehip_bfloat16, or a fixed-width carrier such asunsigned shortwith a reinterpret_cast at kernel entry), and/or use an alias that both passes mangle identically. Astatic_assert-style check at build time (compile a small TU that launches a__bf16kernel and compare host stub vs device symbol) would catch this class of breakage early on new toolchains.Happy to provide the patched tree / full write-up if useful.
@0xDELUXA commented on GitHub (Sep 12, 2026):
Confirmed the diagnosis. With stock clang 21.1.6, AArch64 mangles
__bf16asu6__bf16on the host andDF16bon the AMDGPU device, so the stub registers a symbol the code object does not export. x86_64 usesDF16bon both sides, which is why this is AArch64-only.This is an upstream, deliberate ABI rule: AArch64/ARM retain
u6__bf16. llvm/llvm-project#115521 and llvm/llvm-project#115956 are still open, and upgrading clang/ROCm does not fix it. AMD also does not support AArch64 hosts for ROCm, so this only affects unsupported, source-built configurations.Given that, a broad change to avoid
__bf16in all mangled positions is not worth carrying for now. The local workaround should stay: avoid__bf16in kernel parameters, template arguments, and dtype-dispatch macros; use it only for vector element types and casts inside kernel bodies. Prefer__hip_bfloat16from<hip/hip_bf16.h>over the olderhip_bfloat16.The architecture fallback is deliberate.
setup.pyfirst honors an explicit override, otherwise uses visible AMD GPUs, and only falls back to the fullDEFAULT_HIP_ARCHSlist when no GPU can be enumerated.CMakeLists.txtfollows the same logic. Getting all 17 means no GPU was detected at build time, so setCOMFY_HIP_ARCHS=gfx1201to build only that target.The
setup.py --hipfailure withhipccasCC/CXXis unrelated and should be tracked separately with the CMake configure log.