OpenACC nvlink undefined ссылка на класс

Я новичок в OpenACC и пишу новую программу с нуля (у меня есть довольно хорошее представление о том, какие циклы потребуют больших вычислительных затрат, если раньше работать с аналогичной проблемой). Я получаю "неопределенную ссылку" от nvlink. Из своего исследования я обнаружил, что это связано с тем, что для созданного мной класса не создается код устройства. Однако я не понимаю, почему это происходит и как это исправить.

Ниже я отправляю MWE из своего кода.

включить / vec1.h

      #ifndef VEC1_H
#define VEC1_H

class Vec1{
    
public:
    double data[1];

    #pragma acc routine seq
    Vec1();
    #pragma acc routine seq
    Vec1(double x);
    
    #pragma acc routine seq
    Vec1 operator* (double x);

};

#endif

src / vec1.cpp

      #include "vec1.h"

Vec1::Vec1(){
    data[0] = .0;
}

Vec1::Vec1(double x){
    data[0] = x;
}


Vec1 Vec1::operator*(double c){
    Vec1 r = Vec1(0.);
    r.data[0] = c*data[0];
    return r;
}

vec1_test_gpu.cpp

      #include "vec1.h"

#define NUM_VECTORS 1000000

int main(){
    
    Vec1 vec1_array[NUM_VECTORS];
    for(int iv=0; iv<NUM_VECTORS; ++iv){
        vec1_array[iv] = Vec1(iv);
    }
    #pragma acc data copyin(vec1_array)
    
    #pragma acc parallel loop
    for(int iv=0; iv<NUM_VECTORS; ++iv){
        vec1_array[iv] = vec1_array[iv]*2;
    }
    return 0;
}

Я компилирую их следующим образом

      $ nvc++ src/vec1.cpp -c -I./include -O3 -march=native -ta=nvidia:cuda11.2 -fPIC
$ nvc++ -shared -o libvec1.so vec1.o
$ nvc++ vec1_test_gpu.cpp -I./include -O3 -march=native -ta=nvidia:cuda11.2 -L./ -lvec1

Сообщение об ошибке появляется сразу после последней команды и гласит nvlink error : Undefined reference to '_ZN4Vec1mlEd' in '/tmp/nvc++jOtCBiT_m38d.o'

1 ответ

Проблема здесь в том, что вы пытаетесь вызвать процедуру устройства «Vec1::operator*», которая содержится в общем объекте ядра в основной программе. Реализация OpenACC в nvc ++ использует CUDA для нацеливания на устройства NVIDIA. Поскольку в CUDA нет динамического компоновщика для кода устройства, по крайней мере, пока, это не поддерживается.

Вам нужно будет либо связать это статически, либо переместить «параллельный цикл» в общий объект.

Обратите внимание, что флаг "-ta" устарел. Пожалуйста, подумайте об использовании вместо этого "-acc -gpu=cuda11.2".

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