簡単に言えば、私の質問は、ソースファイルで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.c
pgacclnk
nvlink
私の質問:
- 私は間違った道を進んでいますか?GCC から PGI コンパイル ライブラリの関数を呼び出し、それらの関数内で OpenACC を使用できますか?
- 上記の回答が肯定的である場合、PGI が行う手順 (呼び出し
pgacclnk
と) なしで、まだリンクを使用できますか?nvlink
- 上記の回答も肯定的である場合、どうすればよいですか?