Вопрос довольно прост, но позвольте мне дать обзор моей структуры. У меня есть абстрактный класс 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__
функции.
РЕДАКТИРОВАТЬ: часть вопроса, которую я начертал неправильно. Пожалуйста, ознакомьтесь с комментариями, чтобы понять, почему.
Функция '__device__' может быть виртуальной: http://docs.nvidia.com/cuda/cuda-c-programming-guide/#virtual-functions –
' __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 # виртуальной-функция). –
Справа. То, что у вас нет, - это объект, который живет как на хосте, так и на устройстве и имеет виртуальные функции. Или вы не можете иметь виртуальные функции, которые являются как '__device__', так и' __host__'. Но я, возможно, ошибаюсь, поэтому не стесняйтесь (и поощряйте) исправить меня. – Spiros