c-动态链接支持PGI OpenACC的库与gcc
之前,我问了一个关于使用PGI创建静态库并将其链接到使用gcc构建的程序的问题: 现在,我有同样的问题,但是动态地。当我的库是使用PGI动态构建的时,如何使用gcc构建程序 同时,考虑到以下事实:c-动态链接支持PGI OpenACC的库与gcc,gcc,linker,openacc,pgi,pgi-accelerator,Gcc,Linker,Openacc,Pgi,Pgi Accelerator,之前,我问了一个关于使用PGI创建静态库并将其链接到使用gcc构建的程序的问题: 现在,我有同样的问题,但是动态地。当我的库是使用PGI动态构建的时,如何使用gcc构建程序 同时,考虑到以下事实: 我希望它们都能识别相同的OpenMP pragma和例程。例如,当我在库中使用OpenMP关键区域时,整个程序应该在该部分序列化 OpenACC pragmas用于使用PGI构建的库中 在我的应用程序中完全动态加载库。我的意思是使用dlopen打开lib和dlsym查找函数 我还希望我的线程能够同时
- 我希望它们都能识别相同的OpenMP pragma和例程。例如,当我在库中使用OpenMP关键区域时,整个程序应该在该部分序列化
- OpenACC pragmas用于使用PGI构建的库中
- 在我的应用程序中完全动态加载库。我的意思是使用
打开lib和dlopen
查找函数dlsym
- 我还希望我的线程能够同时访问GPU进行数据传输和/或计算。有关更多详细信息,请参阅以下代码段
调用cuMemcpyHtoDAsync返回错误1:无效值
注意:在构建以下代码时,我有意使用LibGOMP(
-lgomp
)而不是PGI的OpenMP库(-lpgmp
),用于lib和main两种情况
库代码:
#include <stdio.h>
#include <stdlib.h>
#include <openacc.h>
#include <omp.h>
double calculate_sum(int n, double *a) {
double sum = 0;
int i;
#pragma omp critical
{
printf("Num devices: %d\n", acc_get_num_devices(acc_device_nvidia));
#pragma acc enter data copyin(a[0:n])
#pragma acc parallel
#pragma acc loop
for(i=0;i<n;i++) {
sum += a[i];
}
#pragma acc exit data delete(a[0:n])
}
return sum;
}
int ret_num_dev(int index) {
int dev = acc_get_num_devices(acc_device_nvidia);
if(dev == acc_device_nvidia)
printf("Num devices: %d - Current device: %d\n", dev, acc_get_device());
return dev;
}
并使用gcc使用以下命令构建了我的主代码,如Mat在上一个问题中所述:
gcc f1.c-L/opt/pgi/linux86-64/16.5/lib-L/usr/lib64-L/usr/lib/gcc/x86_64-redhat-linux/4.8.5-L-laccapi-laccg-laccn-laccg2-ldl-lcudadevice-lgomp-lnuma-lpthread-lnspgc-lpgc-lm-lgcc-lc-lgcc-lmyacc
我做错什么了吗?以上步骤正确吗?您的代码对我来说工作正常。我尝试使用您列出的内容,但需要删除“libctest.so”,更改dlopen获取so的位置,并在gcc编译行中添加“-DN=1024”。之后,它编译并运行良好
% pgcc -acc -ta=nvidia:nordc -fPIC -c libmyacc.c -V16.5
% pgcc -shared -o libmyacc.so -L/opt/pgi/linux86-64/16.5/lib -L/usr/lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -laccapi -laccg -laccn -laccg2 -ldl -lcudadevice -lgomp -lnuma -lpthread -lnspgc -lpgc -lm -lgcc -lc -lgcc libmyacc.o -V16.5
% gcc f1.c -L/proj/pgi/linux86-64/16.5/lib -L/usr/lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L. -laccapi -laccg -laccn -laccg2 -ldl -lcudadevice -lgomp -lnuma -lpthread -lnspgc -lpgc -lm -lgcc -lc -lgcc -lmyacc -DN=1024
% ./a.out
Num devices: 8
-------- SUM: 523776.000
谢谢@mat colgrove。关于libctest.so的事很抱歉。那是个打字错误。在我这边,我把它改成了
libmyacc。所以
复制后,我把它粘贴到这里并开始工作。但是,我在传递给gcc
的选项上犯了一个错误。当我使用gcc上的-fopenmp
启用OpenMP(答案第3行)并删除库中的omp critical
行时,有时它会调用cuMemFreeHost返回错误1:无效值错误。请尝试将“-nomp”添加到PGI选项中。PGI和GNU的OpenMP运行时不兼容,这可能会导致您的问题。请注意,虽然这对我有效,但二进制文件确实周期性地出现seg故障。不过,当我在OpenACC代码周围设置宏保护并仅使用GNU构建时,也出现了这种情况,因此我认为这与此无关,也没有进一步调查。感谢Mat在这个问题上的帮助。我添加了-nomp
来编译库。但是,当我在循环中调用库中的函数时,会得到分段错误错误。我只需调用calculate\u sum
1000次,但在第一次第7次或第8次迭代时,它会错误地停止。这是GDB向我展示的:。有什么想法吗?这是我的主要文件和库:
% pgcc -acc -ta=nvidia:nordc -fPIC -c libmyacc.c -V16.5
% pgcc -shared -o libmyacc.so -L/opt/pgi/linux86-64/16.5/lib -L/usr/lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -laccapi -laccg -laccn -laccg2 -ldl -lcudadevice -lgomp -lnuma -lpthread -lnspgc -lpgc -lm -lgcc -lc -lgcc libmyacc.o -V16.5
% gcc f1.c -L/proj/pgi/linux86-64/16.5/lib -L/usr/lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L. -laccapi -laccg -laccn -laccg2 -ldl -lcudadevice -lgomp -lnuma -lpthread -lnspgc -lpgc -lm -lgcc -lc -lgcc -lmyacc -DN=1024
% ./a.out
Num devices: 8
-------- SUM: 523776.000