2013-12-10 6 views
-1

Я пытаюсь скомпилировать программу, включающую ядро ​​с MSVS 2012 и CUDA. Я использую общую память, но в отличие от this question по той же самой проблеме, я использую только мои имя переменной для общей памяти этого ядра один раз, так что нет никакой проблемы переопределения с помощью следующего кода:.Ошибка объявления CUDA "несовместима с предыдущим" variable_name "

template<typename T> 
__global__ void mykernel(
    const T* __restrict__ data, 
    T*  __restrict__ results) 
{ 
    extern __shared__ T warp_partial_results[]; 
    /* ... */ 
    warp_partial_results[lane_id] = something; 
    /* ... */ 
    results[something_else] = warp_partial_results[something_else]; 
    /* ... */ 
} 

который конкретизируется для нескольких типов (например, с плавающей точкой, INT, неподписанных INT), я получаю страшный

declaration is incompatible with previous "warp_partial_results" 

сообщение. Что может быть причиной этого?

+1

голосование, чтобы закрыть, вы не указали код SSCCE.org. SO ожидает: «Вопросы, касающиеся проблем с кодом, который вы написали, должны описывать конкретную проблему - и включать в себя действительный код для ее воспроизведения - в самом вопросе. См. SSCCE.org для руководства». Исключить «концептуальные вопросы о проблемах с мой код "или" что может вызвать этот "тип вопросов. Предоставьте полный, компилируемый код, который демонстрирует проблему, вместе с командой компиляции, которую вы используете с ней. –

+0

Добавить код за пару минут. – einpoklum

+1

Код, который вы показали до сих пор, не является полным. Когда я пытаюсь взломать его в компилируемый код, он не дает компиляции для меня. Изучите веб-страницу [SSCCE.org] (http://sscce.org) и укажите * полный *, * компилируемый * код, демонстрирующий ошибку. –

ответ

2

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

Обходной путь доступен в виде специализированной специализации через классы. См:

http://www.ecse.rpi.edu/~wrf/wiki/ParallelComputingSpring2015/cuda/nvidia/samples/0_Simple/simpleTemplates/sharedmem.cuh

Вы можете использовать обходной путь следующим образом:

template<class T> __global__ void foo(T* g_idata, T* g_odata) 
{ 
    // shared memory 
    // the size is determined by the host application 

    SharedMem<T> shared; 
    T* sdata = shared.getPointer(); 

    // .. the rest of the code remains unchanged! 
} 

getPointer() имеет * специализированная реализация для каждого типа, который возвращает другой указатель, например, extern __shared__ float* shared_mem_float или extern __shared__ int* shared_mem_int и т.д.

(*) - Не совсем. в поставляемом в NVidia заголовочном файле они специализируются на некоторых базовых типах, и все.