操作系统版本:CentOS Linux release 7.6.181
DTK版本:DTK24.04.1
驱动版本:/
DCU类型:gfx906
编译器:/public/software/compiler/rocm/dtk-24.04.1/llvm/bin/clang
编译过程:
clang -lm -pg -g -O3 -Wall -fopenacc -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx906 -Wall -g -Iinclude -c src/main.c -o obj/main.o
clang -shared -o lib/libmy_kernel.so obj/my_kernel.o
clang -lm -pg -g -O3 -Wall -fopenacc -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx906 -Wall -g -Iinclude -fPIC -c src/my_kernel.c -o obj/my_kernel.o
clang -lm -pg -g -O3 -Wall -fopenacc -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx906 -Wall -g -Iinclude -o bin/app obj/main.o -Llib -lmy_kernel
问题描述:将kernel编译创建为so再链接到主程序,则程序运行报错。若使用静态链接库则运行正常。

暂无数据
编译过程可参考:# 编译主程序对象(确保使用 -fPIC)
clang -lm -pg -g -O3 -Wall -fopenacc -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx906 -Iinclude -fPIC -c src/main.c -o obj/main.o
# 编译内核对象并导出符号
clang -fPIC -fvisibility=default -fopenmp -fopenacc -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx906 -Iinclude -c src/my_kernel.c -o obj/my_kernel.o
# 创建共享库(链接 OpenMP)
clang -shared -fopenmp -o lib/libmy_kernel.so obj/my_kernel.o
# 链接主程序并指定运行时路径
clang -fopenmp -o bin/app obj/main.o -Llib -lmy_kernel -Wl,-rpath=./lib报错内容
```
Libomptarget device 0 info: Entering OpenMP kernel at my_kernel.c:6:5 with 4 arguments:
Libomptarget device 0 info: firstprivate(N)[4]
Libomptarget device 0 info: use_address(C[0:0])[0]
Libomptarget device 0 info: use_address(A[0:0])[0]
Libomptarget device 0 info: use_address(B[0:0])[0]
Libomptarget error: Host ptr 0x00002acbedb87ec8 does not have a matching target pointer.
Libomptarget device 0 info: OpenMP Host-Device pointer mappings after block at my_kernel.c:6:5:
Libomptarget device 0 info: Host Ptr Target Ptr Size (B) DynRefCount HoldRefCount Declaration
Libomptarget device 0 info: 0x00002accfb1c0010 0x00002ad01ac00000 4194304 0 1 A[0:N] at my_kernel.c:4:31
Libomptarget device 0 info: 0x00002accfb5c1010 0x00002ad01b800000 4194304 0 1 B[0:N] at my_kernel.c:4:41
Libomptarget device 0 info: 0x00002accfb9c2010 0x00002ad01c400000 4194304 0 1 C[0:N] at my_kernel.c:4:51
my_kernel.c:6:5: Libomptarget fatal error 1: failure of target construct while offloading is mandatory
```my_kernel.c
```c
#include <openacc.h>
// 定义element-wise multiplication的OpenACC kernel函数
void element_wise_mult(float* A, float* B, float* C, int N) {
#pragma acc data copy(A[0:N], B[0:N], C[0:N])
#pragma acc parallel loop
for (int i = 0; i < N; i++) {
C[i] = A[i] * B[i];
}
}
```主程序main.c
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <openacc.h>
#include "my_kernel.h" // 假设头文件声明
int main() {
const int N = 1 << 20; // 1M elements
float *A = (float*)malloc(N * sizeof(float));
float *B = (float*)malloc(N * sizeof(float));
float *C = (float*)malloc(N * sizeof(float));
// 初始化数据
for (int i = 0; i < N; i++) {
A[i] = (float)rand() / RAND_MAX;
B[i] = (float)rand() / RAND_MAX;
}
// 主测试acc
printf("Main Test\n");
#pragma acc data copy(A[0:N], B[0:N], C[0:N])
#pragma acc parallel loop
for (int i = 0; i < N; i++) {
C[i] = A[i] * B[i];
}
// 库测试acc
// 数据转移到GPU(显式数据管理)
printf("Lib Test\n");
element_wise_mult(A, B, C, N);
// 验证结果(简单验证)
for (int i = 0; i < 10; i++) {
float expected = A[i] * B[i];
float error = fabs(C[i] - expected);
if (error > 1e-6) {
fprintf(stderr, "Error at index %d: %f vs %f\n", i, C[i], expected);
return 1;
}
}
free(A);
free(B);
free(C);
printf("Validation passed!\n");
return 0;
}
```