Как функция устройства GPU может обращаться к объектам класса, определенным в функциях хоста? - PullRequest
0 голосов
/ 27 июня 2019

У меня есть существующая программа на C ++, и я хочу перенести ее на версию GPU. Функция ядра должна получить доступ к объектам класса, определенным в функции хоста. Например, объект stringstream будет использоваться в потоках. Тем не менее, он не проходит компиляцию в Cuda. Как функция ядра может получить доступ к объектам классов такого типа, определенным в функциях хоста?

Вот пример.

#include <cstdio>
#include <sstream>

using namespace std;

__global__ void kernel(stringstream * sstr)
{
    printf("%s\n", sstr->str());
}

int main(int argc, char ** argv)
{
    stringstream * sstr;
    cudaMallocManaged(&sstr, sizeof(stringstream));
    *sstr  << "Hello world\n";
    kernel<<<32, 32>>>(sstr);
    cudaDeviceSynchronize();
    cudaFree(sstr);
    return 0;
}

Я получил следующую ошибку компиляции.

$ nvcc -o bin src.cu
src.cu(8): warning: non-POD class type passed through ellipsis

src.cu(8): error: calling a __host__ function("std::__cxx11::basic_stringstream<char,  ::std::char_traits<char> , std::allocator<char> > ::str const") from a __global__ function("kernel") is not allowed

src.cu(8): error: identifier "std::__cxx11::basic_stringstream<char,  ::std::char_traits<char> , std::allocator<char> > ::str const" is undefined in device code

src.cu(8): error: calling a __host__ function("std::__cxx11::basic_string<char,  ::std::char_traits<char> , std::allocator<char> > ::~basic_string") from a __global__ function("kernel") is not allowed

src.cu(8): error: identifier "std::__cxx11::basic_string<char,  ::std::char_traits<char> , std::allocator<char> > ::~basic_string" is undefined in device code

4 errors detected in the compilation of "/tmp/tmpxft_00003bd0_00000000-8_src.cpp1.ii".

Ответы [ 2 ]

3 голосов
/ 27 июня 2019

Вы не должны использовать класс C ++ std в своих ядрах, так как связанные с std :: stringstream функции предварительно скомпилированы и связаны с вашей ОС, nvcc не генерирует соответствующие __device__ функции.

см. Эту тему

0 голосов
/ 27 июня 2019

std::stringstream, вероятно, имеет динамически распределенный массив внутри, к которому вы не сможете получить доступ в коде вашего устройства; это уже делает плохой идеей передавать такой класс в графический процессор.

Ваша компиляция здесь не удалась, потому что вы также пытаетесь вызвать функцию __host__ из кода устройства, что невозможно. Вам, вероятно, понадобится пользовательский stringstream, адаптированный к CUDA, если вы хотите, чтобы это работало.

...