выборочно компилировать заголовки и функции класса в CUDA

Я пытаюсь использовать свои классы С++ в CUDA.

У меня есть класс как таковой:

#include<string>
#include<stdlib.h>

class exampleClass{
int i;
__host__ __device__ exampleClass(int _i):i(_i){};
__host__ __device__ void increment(){i++;}
__host__ __device__ string outputMessage(return itoa(i);}

};

Я установил это в файле .cu и установил для компиляции CUDA c/С++

Это не скомпилируется с помощью nvcc, потому что у cuda нет строк.

Я хотел бы сохранить только функции CUDA, выполнив что-то вроде:

#ifndef __CUDA_ARCH__
  #include<string>
#endif
    #include<stdlib.h>

    class exampleClass{
    int i;
    __host__ __device__ exampleClass(int _i):i(_i){};
    __host__ __device__ void increment(){i++;}
#ifndef __CUDA_ARCH__
     string outputMessage(return itoa(i);}
#endif

    };

Но я знаю, что это не работает... по крайней мере, это не работает для меня. Nvcc не нравится ни включение строки, ни, очевидно, функция, требующая строкового типа.

Извините, если пример не первоклассный. Подводя итог, я бы хотел, чтобы члены основного класса выполнялись на CUDA, сохраняя при этом возможность иметь причудливые хост-операции для анализа и вывода на стороне хоста.

ОБНОВЛЕНИЕ. Моей конечной целью здесь является создание базового класса, содержащего несколько типов указателей на несколько полиморфных классов. Сам этот базовый класс будет производным. Я думал, что это возможно в CUDA5.0. Я ошибаюсь?


person PaulD    schedule 28.03.2013    source источник
comment
У меня не было проблем с использованием классов stl, таких как строка или вектор, с nvcc. Вы, конечно, не можете отправить строку в ядро ​​или использовать строковую функцию в ядре, но это не похоже на то, что вы пытаетесь сделать... вы должны просто иметь возможность удалить устройство украшение.   -  person IdeaHat    schedule 29.03.2013
comment
MadScienceDreams был прав в ответе на мой вопрос. Однако проблема, лежащая в основе проблемы, нашла свое решение здесь: stackoverflow.com/questions/5994005/   -  person PaulD    schedule 29.03.2013
comment
В частности, вам нужно включить флаг -dc в компилятор CUDA C/C++, чтобы разрешить связь между несколькими файлами cu.   -  person PaulD    schedule 29.03.2013


Ответы (1)


Строится следующий код, хотя я его не запускал:

class exampleClass{
int i;
public:
__host__ __device__ exampleClass(int _i):i(_i){};
__host__ __device__ void increment(){i++;}

 __host__ string outputMessage(){ return "asdf";}


};

__global__ void testkernel (                        
    exampleClass *a,
    int IH, int IW)
{
    const int i = IMUL(blockIdx.x, blockDim.x) + threadIdx.x;
    const int j = IMUL(blockIdx.y, blockDim.y) + threadIdx.y;


    if (i<IW && j<IH) 
    {
        const int i_idx = i + IMUL(j, IW);  
        exampleClass* ptr = a+i_idx;
        ptr->increment();
    }
}

__host__ void test_function(exampleClass *a,
    int IH, int IW)
{
    for (int i = 0; i < IW; i++)
        for (int j = 0; j < IH; j++)
        {
            const int i_idx = i + j*IW;
            exampleClass* ptr = a+i_idx;
            cout << ptr->outputMessage();
        }
}

Обратите внимание, что вам придется переместить классы с устройства в память хоста, чтобы это «работало» правильно. Если вы попытаетесь сделать что-нибудь необычное с классами (например, полиморфизм), это, вероятно, взорвется.

person IdeaHat    schedule 28.03.2013
comment
Я думал, полиморфизм разрешен в CUDA5.0? Мой примерный класс — это базовый класс с несколькими производными. Кроме того, exampleClass содержит несколько точек, содержащих полиморфные классы. - person PaulD; 29.03.2013
comment
@ПолД. Да, это крутое изменение по сравнению с 4.0. CUDA — один из тех немногих программных пакетов, которые каждый год добавляют новые полезные функции! VTable этих классов должна иметь ссылку на оба указателя функций __host__ и __device__, поэтому размер класса будет расти довольно быстро. Обратите внимание, что виртуальное наследование по-прежнему не поддерживается. - person IdeaHat; 29.03.2013
comment
Я не знаком с VTable... Я более чем самоучка. Не могли бы вы немного объяснить это или кинуть ссылку? Кроме того, на веб-сайте nVidia говорится, что виртуальное наследование поддерживается начиная с Toolkit 4.0. developer.nvidia.com/cuda-toolkit-40 - person PaulD; 29.03.2013
comment
Стандарт кода 5 гласит: Не разрешено передавать аргумент глобальной функции; объект класса, производного от виртуальных базовых классов., поэтому виртуального наследования нет. В нем также указано, что таблица виртуальных функций помещается компилятором в глобальную или постоянную память. хотя я понятия не имею, как это происходит (статическая нагрузка?). [VTable в википедии](en.wikipedia.org/wiki/Virtual_method_table) - person IdeaHat; 29.03.2013
comment
У меня сложилось впечатление, что виртуальный базовый класс — это особый тип наследования: stackoverflow.com/questions/21558/ - person PaulD; 01.04.2013
comment
Да, это виртуальное наследование. en.wikipedia.org/wiki/Virtual_inheritance - person IdeaHat; 01.04.2013