2015-06-29 3 views
3

Вопрос довольно прост, но позвольте мне дать обзор моей структуры. У меня есть абстрактный класс AbstractScheme, представляющий тип вычисления (своего рода дискретизация для уравнения, но это не важно). Каждая реализация должна предоставить метод для возврата имени схемы и должна реализовать защищенную функцию, которая является ядром CUDA. Базовый абстрактный класс предоставляет открытый метод, который вызывает ядро ​​CUDA и возвращает время, необходимое для завершения ядра.Могут ли ядра CUDA быть виртуальными функциями?

class AbstractScheme 
{ 
public: 
    /** 
    * @return The name of the scheme is returned 
    */ 
    virtual std::string name() const =0; 

    /** 
    * Copies the input to the device, 
    * computes the number of blocks and threads, 
    * launches the kernel, 
    * copies the output to the host, 
    * and measures the time to do all of this. 
    * 
    * @return The number of milliseconds to perform the whole operation 
    *   is returned 
    */ 
    double doComputation(const float* input, float* output, int nElements) 
    { 
     // Does a lot of things and calls this->kernel(). 
    } 

protected: 
    /** 
    * CUDA kernel which does the computation. 
    * Must be implemented. 
    */ 
    virtual __global__ void kernel(const float*, float*, int) =0; 
}; 

У меня также есть несколько реализаций этого базового класса. Но когда я пытаюсь скомпилировать с NVCC 7.0, я получаю сообщение об ошибке со ссылкой на строку, в которой я определяю функцию kernel в AbstractScheme (в последней строке в листинге выше):

myfile.cu(60): error: illegal combination of memory qualifiers 

Я не мог найти какой-либо ресурс говоря, что ядра не могут быть виртуальными функциями, но я чувствую, что это проблема. Можете ли вы объяснить причину этого? Я четко понимаю, как и почему функции __device__ не могут быть виртуальными (виртуальные функции являются указателями на фактические [хост] функции, хранящиеся в объекте, и вы не можете вызывать такую ​​функцию из кода устройства), но я не уверен насчет __global__ функции.

РЕДАКТИРОВАТЬ: часть вопроса, которую я начертал неправильно. Пожалуйста, ознакомьтесь с комментариями, чтобы понять, почему.

+1

Функция '__device__' может быть виртуальной: http://docs.nvidia.com/cuda/cuda-c-programming-guide/#virtual-functions –

+1

' __device__' функции могут быть 'virtual'. Руководство по программированию даже [дает несколько примеров] (http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#derived-class). Я думаю, возможно, что вы имеете в виду, что объект, созданный на хосте, с 'виртуальными' функциями, [не может быть передан устройству] (http://docs.nvidia.com/cuda/cuda-c-programming -руководство/index.html # виртуальной-функция). –

+0

Справа. То, что у вас нет, - это объект, который живет как на хосте, так и на устройстве и имеет виртуальные функции. Или вы не можете иметь виртуальные функции, которые являются как '__device__', так и' __host__'. Но я, возможно, ошибаюсь, поэтому не стесняйтесь (и поощряйте) исправить меня. – Spiros

ответ

4

Ядра не могут быть членами классов в объектной модели CUDA, будь то виртуальные или нет. Это является причиной ошибки компиляции, даже если это не особенно очевидно из сообщения об ошибке, выпущенного компилятором.