Недавно я пытался использовать указатель функции для динамического определения нескольких этапов обработки в моем приложении, работающем на sm_30.
Было бы сложно опубликовать код здесь, так как задействовано много разных файлов и функций, но в основном я начал с образца, который был включен в Cuda Toolkit 5.0.
Я выделяю буфер функции устройства, куда копирую указатель функции устройства, определенный так же, как в примере, благодаря cudaMemcpyfromsymbolAsync, используемому с типом копии DeviceToDevice.
Указатель моего устройства определяется следующим образом в .cu.h :
//device function pointer model
typedef void (*func)(structGpuArgument*);
//Declaring a function
__device__ void gpuFunc1(structGpuArgument* arg1);
в другом месте у меня есть .cu, который включает предыдущее объявление, содержащее следующий код:
//get the actual function pointer
__device__ func gpuFuncPtr = gpuFunc1;
//Buffer to store a list of function pointer
func* pFuncDevBuffer;
cudaMalloc(&pFuncDevBuffer,NB_FUNC*sizeof(func));
//copy the actual function pointer (symbol) to the list buffer
cudaMemcpyFromSymbolAsync( pFuncDevBuffer+i ,gpuFuncPtr,sizeof(func),0,cudaMemcpyDeviceToDevice,stream)
//Launch the kernel that will use the functions
kernel_test<<<1,10,0,stream>>>(pFuncDevBuffer)
...
//defining the kernel that uses pointer buffer
__global__ void kernel_test(func* pFuncDevBuffer)
{
printf("func address : %p\n",pFuncDevBuffer[0]);
pFuncDevBuffer[0](NULL);
}
//defining the function pointed by the function pointer
__device__ void gpuFunc1(structGpuArgument* arg1)
{
do_something;
}
На самом деле все работает нормально, пока глобальное ядро, принимающее в качестве аргумента буфер функции device, определено в том же файле, что и функция и ее указатель. Затем ядро может распечатать адрес функции (0x4) и выполнить ее код без проблем. Я не использую отдельную компиляцию.
Когда в том же экземпляре программы второе ядро, определенное в другом месте, принимает в качестве аргумента тот же самый буфер указателя функции, оно может распечатать тот же самый адрес памяти для указателя функции (0x4), но если оно попытается выполнить его, оно не удается выдать недопустимую инструкцию по адресу 0x00000000 в cuda-memcheck. Любой другой вызов API cuda зависает после этого, мне нужно перезагрузить компьютер (сброс через cuda-smi не поддерживается на моем графическом процессоре).
Я хотел бы знать, существует ли известная проблема с использованием указателя функции таким образом, т.е. с использованием буфера указателя функции, определенного в другом файле, но с использованием одного и того же определения указателя функции.
Кроме того, если есть тренировка по сбросу устройства после ошибки сегментации без перезагрузки всей системы, это может помочь мне сэкономить время при отладке моего приложения.
спасибо за помощь