c - Связывание библиотеки PGI с поддержкой OpenACC с помощью gcc

Вкратце, мой вопрос касается компиляции / сборки файлов (с использованием библиотек) с двумя разными компиляторами при использовании конструкций 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;
}

Я могу легко скомпилировать его, используя следующую строку:

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?

Благодаря комментарию Джеффа по этому вопросу: связывание скомпилированной библиотеки pgi с 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

Благодаря -v опция при компиляции f1.c с PGI-компилятором я вижу, что компилятор вызывает так много других инструментов от PGI и NVidia (например, pgacclnk а также nvlink).


Мои вопросы:

  1. Я на неверном пути? Могу ли я вызывать функции в скомпилированных PGI библиотеках из GCC и использовать OpenACC в этих функциях?
  2. Если ответ на этот вопрос положительный, могу ли я использовать неподвижную ссылку без шагов (звонить pgacclnk а также nvlink) что PGI берет?
  3. Если ответ на этот вопрос тоже положительный, что мне делать?

1 ответ

Решение

Добавьте "-ta=tesla:nordc" к вашей компиляции pgcc. По умолчанию PGI использует динамическую компиляцию во время выполнения (RDC) для кода GPU. Однако 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

Надеюсь, это поможет, Мат

Другие вопросы по тегам