1
编译器
C程序OpenACC动态链接库运行报错
2025-04-17 22:16:01
110

操作系统版本: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再链接到主程序,则程序运行报错。若使用静态链接库则运行正常。

全部评论(5)
只看楼主
W
wangs
4楼

编译过程可参考:# 编译主程序对象(确保使用 -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
2025/4/22
H
HwHiAiUser007
回复 @wangs
嗯嗯,已修改调试ok。之前创建共享库时忘加-fopenacc/openmp的系列选项了。感谢
2025/4/24
H
HwHiAiUser007
楼主
3楼

报错内容

```

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

```
2025/4/17
H
HwHiAiUser007
楼主
2楼

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];

}

}

```
2025/4/17
H
HwHiAiUser007
楼主
1楼

主程序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;

}

```
2025/4/17
没有更多内容了
--
楼主
Level.1
0 帖子
楼主热帖
暂无数据