c-将支持PGI OpenACC的库与gcc链接

c-将支持PGI OpenACC的库与gcc链接,gcc,linker,openacc,pgi,pgi-accelerator,Gcc,Linker,Openacc,Pgi,Pgi Accelerator,简单地说,我的问题是在利用源文件中的OpenACC构造的同时,使用两个不同的编译器编译/构建文件(使用库) 我有一个C源文件,它有一个OpenACC结构。它只有一个简单的函数来计算数组的总和: #include <stdio.h> #include <stdlib.h> #include <openacc.h> double calculate_sum(int n, double *a) { double sum = 0; int i;

简单地说,我的问题是在利用源文件中的OpenACC构造的同时,使用两个不同的编译器编译/构建文件(使用库)

我有一个C源文件,它有一个OpenACC结构。它只有一个简单的函数来计算数组的总和:

#include <stdio.h>
#include <stdlib.h>
#include <openacc.h>

double calculate_sum(int n, double *a) {
    double sum = 0;
    int i;

    printf("Num devices: %d\n", acc_get_num_devices(acc_device_nvidia));

    #pragma acc parallel copyin(a[0:n])
    #pragma acc loop
    for(i=0;i<n;i++) {
        sum += a[i];
    }

    return sum;
}
现在,我可以使用这个静态库和PGI编译器本身来编译上面的源代码(
f1.c
):

pgcc-acc-ta=nvidia f1.c libmyacc.a

它将完美地执行。但是,gcc的情况有所不同。我的问题就在这里。如何使用gcc正确构建它

感谢杰夫对这个问题的评论: ,现在我可以构建源文件(
f1.c
)而不会出错,但可执行文件会发出一些致命错误

这是我使用gcc编译源文件时使用的(
f1.c
):

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-lpgmp-lnuma-lpthread-lnspgc-lpgc-lm-lgcc-lc-lgcc-lmyacc

这就是错误:

Num devices: 2
Accelerator Fatal Error: No CUDA device code available

在使用PGI编译器编译
f1.c
时,由于使用了
-v
选项,我看到编译器调用了PGI和NVidia中的许多其他工具(如
pgacclnk
nvlink


我的问题是:

  • 我走错路了吗?我可以从GCC调用PGI编译库中的函数并在这些函数中使用OpenACC吗
  • 如果上面的回答是肯定的,我可以使用没有PGI采取的步骤(调用
    pgacclnk
    nvlink
    )的静态链接吗
  • 若上面的答案也是肯定的,我该怎么办
  • 将“-ta=tesla:nordc”添加到pgcc编译中。默认情况下,PGI对GPU代码使用运行时动态编译(RDC)。但是,RDC需要额外的链接步骤(使用nvlink),gcc不支持该步骤。“nordc”子选项禁用RDC,因此您可以在库中使用OpenACC代码。但是,通过禁用RDC,您不能再从计算区域调用外部设备例程

    % pgcc -acc -ta=tesla:nordc -c libmyacc.c
    % ar -cvq libmyacc.a libmyacc.o
    a - libmyacc.o
    % 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 -lpgmp -lnuma -lpthread -lnspgc -lpgc -lm -lgcc -lc -lgcc -lmyacc
    % a.out
    Hello --- Start of the main.
    Sum: 500500.000
    Num devices: 8
    Sum2: 500500.000
    
    希望这有帮助,
    垫子

    谢谢垫子。当然是我想要的。我能问一下你在最后一句中所说的“外部设备例程”是什么意思吗?你指的是OpenACC中的哪些函数?这意味着从设备代码调用子程序,而子程序位于不同的对象中。如果子例程位于同一源中,则可以内联,但需要链接外部例程。亲爱的@MatColgrove,现在NVHPC SDK正在替换旧的PGI编译器,共享库似乎已更改,我尝试了示例中使用的标志,但找不到多个库报告,请你把那行再更新一次好吗?我试着自己做,但结果是托管内存功能丢失,我在运行时看到700个错误是的,所有库的名称都随着重新标记而更改。但是,一般来说,库可能会随着版本的不同而变化,因此最好查看编译器的详细“干运行”输出,以了解我们传递给链接器的内容。使用与您将用于行运行“nvc-dryrun x.o”并查找link(ld)命令相同的标志。
    % pgcc -acc -ta=tesla:nordc -c libmyacc.c
    % ar -cvq libmyacc.a libmyacc.o
    a - libmyacc.o
    % 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 -lpgmp -lnuma -lpthread -lnspgc -lpgc -lm -lgcc -lc -lgcc -lmyacc
    % a.out
    Hello --- Start of the main.
    Sum: 500500.000
    Num devices: 8
    Sum2: 500500.000