2

簡単に言えば、私の質問は、ソースファイルでOpenACCコンストラクトを利用しながら、2つの異なるコンパイラを使用してファイルをコンパイル/ビルド(ライブラリを使用)することに依存しています。

OpenACC コンストラクトを持つ C ソース ファイルがあります。配列の総和を計算する単純な関数しかありません。

#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;
}

次の行を使用して簡単にコンパイルできます。

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

次に、次の行で静的ライブラリを作成します。

ar -cvq libmyacc.a libmyacc.o

ライブラリを使用するために、次のようなコードを書きました。

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

#define N 1000

extern double calculate_sum(int n, double *a);

int main() {
    printf("Hello --- Start of the main.\n");
    double *a = (double*) malloc(sizeof(double) * N);
    int i;
    for(i=0;i<N;i++) {
        a[i] = (i+1) * 1.0;
    }

    double sum = 0.0;
    for(i=0;i<N;i++) {
        sum += a[i];
    }
    printf("Sum: %.3f\n", sum);


    double sum2 = -1;
    sum2 = calculate_sum(N, a);
    printf("Sum2: %.3f\n", sum2);

    return 0;
}

これで、この静的ライブラリを PGI コンパイラ自体で使用して、上記のソースをコンパイルできます ( f1.c):

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

そして、それは完璧に実行されます。ただし、gcc の場合は異なります。私の質問はここにあります。どうすればgccで正しくビルドできますか?

この質問に対する Jeff のコメント: linking pgicompiled library with gcc linkerのおかげで 、エラーなしでソース ファイル ( 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 コンパイラで-vコンパイルするときのオプションのおかげで、コンパイラが PGI と NVidia から非常に多くの他のツール (や など) を呼び出すことがわかります。f1.cpgacclnknvlink


私の質問:

  1. 私は間違った道を進んでいますか?GCC から PGI コンパイル ライブラリの関数を呼び出し、それらの関数内で OpenACC を使用できますか?
  2. 上記の回答が肯定的である場合、PGI が行う手順 (呼び出しpgacclnkと) なしで、まだリンクを使用できますか?nvlink
  3. 上記の回答も肯定的である場合、どうすればよいですか?
4

1 に答える 1

2

"-ta=tesla:nordc" を pgcc コンパイルに追加します。デフォルトでは、PGI は GPU コードにランタイム動的コンパイル (RDC) を使用します。ただし、RDC には、gcc がサポートしていない追加のリンク手順 (nvlink を使用) が必要です。「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

これが役に立てば幸いです、マット

于 2016-07-05T23:01:05.400 に答える