Commit 56fcb06b authored by one's avatar one
Browse files

[mre] Add dtk-hip-c-pollution

parent 82065bff
cmake_minimum_required(VERSION 3.23)
project(hip_c_pollution_mre C CXX)
find_package(hip CONFIG REQUIRED)
add_library(legacy_c_obj OBJECT legacy.c)
target_link_libraries(legacy_c_obj PRIVATE hip::device)
# HIP C target pollution 最小复现
## 问题描述
使用 Spack 在 DTK26.04 环境编译 Nalu-Wind 依赖的 `trilinos@16.1.0` 时,Ifpack/ML 等 legacy C 文件会继承 HIP 编译参数并被按 HIP/C++ 编译,进而触发 C/C++ 语法不兼容错误。
原始问题中首先暴露在 Ifpack 的 legacy C 文件上:
```text
Ifpack_MultiListSort.c: error: ISO C++17 does not allow 'register' storage class specifier
```
典型现象是 C 文件的编译命令中出现了 `-xhip` 和多个 `--offload-arch=...`
```text
mpicc ... -xhip --offload-arch=gfx906 --offload-arch=gfx926 --offload-arch=gfx928 --offload-arch=gfx936 --offload-arch=gfx938 ... -c Ifpack_MultiListSort.c
```
环境信息:
- Target: gfx936
- Image: harbor.sourcefind.cn:5443/dcu/admin/base/pytorch:2.7.1-ubuntu22.04-dtk26.04-py3.11
## 复现方式
拷贝目录中的文件到容器中,然后运行脚本:
```sh
./run.sh
```
容器中使用原版 `hip-config.cmake` 时,预期会有类似如下编译错误:
```text
legacy.c:2:7: error: declaration of anonymous class must be a definition
int class;
^
legacy.c:6:36: error: expected a field designator, such as '.field = 4'
struct legacy_record record = { .class = 7 };
^
legacy.c:7:17: error: expected unqualified-id
return record.class;
^
```
## 原因分析
这个复现说明问题的关键不是 Ifpack 或 ML 本身,而是 DTK 原版 `hip-config.cmake` 中的 `hip::device` 会把 HIP 编译参数无条件传播给所有消费它的 target。
- `legacy.c` 是普通 C 源文件,不应该继承 `-xhip`。它是合法 C 代码,但包含 C++ 中不可作为字段名使用的 `class` 标识符;如果它被 `-xhip` 当成 HIP/C++ 编译,就会失败。
- `CMakeLists.txt` 中的 `legacy_c_obj` 链接 `hip::device`,用于模拟 Trilinos 通过 `Kokkos::kokkos -> roc::rocthrust -> roc::rocprim_hip -> hip::device` 间接继承 HIP 配置的情况。
- 使用原版 `hip-config.cmake` 时,`hip::device``INTERFACE_COMPILE_OPTIONS` 没有语言限制,因此 C 文件也会继承 `-xhip``--offload-arch=...`
使用修复后的 `hip-config.cmake` 时,HIP compile options 通过 `COMPILE_LANGUAGE:CXX` 限制到 CXX 编译语言,`legacy.c` 不再被按 HIP/C++ 编译,因此可以正常构建。
struct legacy_record {
int class;
};
int legacy_value(void) {
struct legacy_record record = { .class = 7 };
return record.class;
}
#!/usr/bin/env bash
set -eu
src_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
build_dir="${src_dir}/build"
rm -rf "${build_dir}"
cmake \
-S "${src_dir}" \
-B "${build_dir}" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_VERBOSE_MAKEFILE=ON \
-DCMAKE_PREFIX_PATH=/opt/dtk/hip \
-DCMAKE_C_COMPILER=/opt/dtk/llvm/bin/clang \
-DCMAKE_CXX_COMPILER=/opt/dtk/llvm/bin/clang++
cmake --build "${build_dir}" --target legacy_c_obj --verbose
...@@ -2,12 +2,7 @@ ...@@ -2,12 +2,7 @@
## 问题描述 ## 问题描述
使用 Spack 在如下环境编译 Nalu-Wind 依赖的 Trilinos+Kokkos 时遇到编译错误: 使用 Spack 在 DTK26.04 环境编译 Nalu-Wind 依赖的 Trilinos+Kokkos 时遇到编译错误:
- Target: gfx936
- Image: harbor.sourcefind.cn:5443/dcu/admin/base/pytorch:2.7.1-ubuntu22.04-dtk26.04-py3.11
报错信息:
```text ```text
lld: error: undefined protected symbol: kokkos_impl_hip_constant_memory_buffer lld: error: undefined protected symbol: kokkos_impl_hip_constant_memory_buffer
...@@ -15,6 +10,11 @@ lld: error: undefined protected symbol: kokkos_impl_hip_constant_memory_buffer ...@@ -15,6 +10,11 @@ lld: error: undefined protected symbol: kokkos_impl_hip_constant_memory_buffer
dcc: error: amdgcn-link command failed with exit code 1 dcc: error: amdgcn-link command failed with exit code 1
``` ```
环境信息:
- Target: gfx936
- Image: harbor.sourcefind.cn:5443/dcu/admin/base/pytorch:2.7.1-ubuntu22.04-dtk26.04-py3.11
## 复现方式 ## 复现方式
拷贝目录中的文件到容器中,然后运行脚本: 拷贝目录中的文件到容器中,然后运行脚本:
...@@ -23,7 +23,7 @@ dcc: error: amdgcn-link command failed with exit code 1 ...@@ -23,7 +23,7 @@ dcc: error: amdgcn-link command failed with exit code 1
./run.sh ./run.sh
``` ```
容器中使用 DTK26 原版 `hip-config.cmake` 时,预期会有编译错误: 容器中使用 DTK 原版 `hip-config.cmake` 时,预期会有编译错误:
```text ```text
lld: error: undefined protected symbol: kokkos_impl_hip_constant_memory_buffer lld: error: undefined protected symbol: kokkos_impl_hip_constant_memory_buffer
...@@ -39,6 +39,6 @@ clang++: error: amdgcn-link command failed with exit code 1 ...@@ -39,6 +39,6 @@ clang++: error: amdgcn-link command failed with exit code 1
- `consumer.cpp` 声明并引用同名 constant memory symbol,编译 target 来自 `hip::device` - `consumer.cpp` 声明并引用同名 constant memory symbol,编译 target 来自 `hip::device`
- 两个编译单元都使用 `-fgpu-rdc`,最终链接也使用 `-fgpu-rdc`,从而触发 RDC device link 阶段的符号解析。 - 两个编译单元都使用 `-fgpu-rdc`,最终链接也使用 `-fgpu-rdc`,从而触发 RDC device link 阶段的符号解析。
使用 DTK26 原版 `hip-config.cmake` 时,`hip::device` 会向 consumer 编译和最终链接注入 `gfx906;gfx926;gfx928;gfx936;gfx938` 五个 target。此时 provider 只提供 `gfx936` 的 device symbol 定义,而 consumer 在其它 target 上也引用了这个符号,因此 device link 报错。 使用 DTK 原版 `hip-config.cmake` 时,`hip::device` 会向 consumer 编译和最终链接注入 `gfx906;gfx926;gfx928;gfx936;gfx938` 五个 target。此时 provider 只提供 `gfx936` 的 device symbol 定义,而 consumer 在其它 target 上也引用了这个符号,因此 device link 报错。
使用修复后的 `hip-config.cmake` 时,`hip::device` 在容器中自动检测为 `gfx936`,provider、consumer 和最终 device link 的 target 一致,因此可以正常链接。 使用修复后的 `hip-config.cmake` 时,`hip::device` 在容器中自动检测为 `gfx936`,provider、consumer 和最终 device link 的 target 一致,因此可以正常链接。
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment