Saya baru-baru ini mencoba menggunakan penunjuk fungsi untuk secara dinamis menentukan beberapa tahap pemrosesan dalam aplikasi saya, yang berjalan pada sm_30.
Akan sulit untuk memposting kode di sini, karena ada banyak file dan fungsi berbeda yang terlibat, tetapi pada dasarnya, saya memulai dari contoh yang disertakan dalam Cuda Toolkit 5.0.
Saya mengalokasikan buffer fungsi perangkat tempat saya menyalin penunjuk fungsi perangkat, yang didefinisikan seperti dalam sampel berkat cudaMemcpyfromsymbolAsync yang digunakan dengan Jenis salinan DeviceToDevice.
Penunjuk perangkat saya didefinisikan seperti ini di .cu.h :
//device function pointer model
typedef void (*func)(structGpuArgument*);
//Declaring a function
__device__ void gpuFunc1(structGpuArgument* arg1);
di tempat lain saya punya .cu yang menyertakan deklarasi sebelumnya yang berisi kode berikut:
//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;
}
Faktanya, semuanya berfungsi dengan baik selama kernel global yang menggunakan buffer fungsi perangkat dalam argumen didefinisikan dalam file yang sama dengan fungsi dan penunjuknya. Kernel kemudian dapat mencetak alamat fungsi (0x4) dan menjalankan kodenya tanpa masalah. Saya tidak menggunakan kompilasi terpisah.
Ketika, dalam contoh program yang sama, kernel kedua, yang didefinisikan di tempat lain, menggunakan buffer penunjuk fungsi yang sama dalam argumen, ia dapat mencetak alamat memori yang sama untuk penunjuk fungsi (0x4) tetapi jika ia mencoba menjalankannya, itu akan terjadi. gagal mengeluarkan Instruksi ilegal pada 0x00000000 di cuda-memcheck. Panggilan API cuda lainnya terhenti setelahnya, saya perlu me-reboot komputer saya (reset melalui cuda-smi tidak didukung di GPU saya).
Saya ingin tahu apakah ada masalah umum dalam menggunakan penunjuk fungsi dengan cara ini, yaitu dengan menggunakan buffer penunjuk fungsi yang ditentukan dalam file lain, tetapi berbagi definisi penunjuk fungsi yang sama.
Juga jika ada latihan untuk menyetel ulang perangkat setelah segfault tanpa me-reboot seluruh sistem, ini dapat membantu saya menghemat waktu saat men-debug aplikasi saya.
Terima kasih untuk bantuannya