Sto provando a separare un programma CUDA in due file separati .cu nel tentativo di avvicinarmi di più alla scrittura di un'app reale in C++. Ho un piccolo programma semplice che:Come separare il codice CUDA in più file
Assegna una memoria sull'host e sul dispositivo.
Inizializza l'array host su una serie di numeri. Copie l'array ospita una matrice dispositivo ritrovamenti quadrati di tutti gli elementi della matrice usando un kernel dispositivo Copie la matrice dispositivo torna alla matrice ospitante Stampa i risultati
Questo funziona se metto tutto in un file .cu ed eseguirlo. Quando lo divido in due file separati comincio a ricevere errori di collegamento. Come tutte le mie ultime domande, so che questo è qualcosa di piccolo, ma che cos'è?
KernelSupport.cu
#ifndef _KERNEL_SUPPORT_
#define _KERNEL_SUPPORT_
#include <iostream>
#include <MyKernel.cu>
int main(int argc, char** argv)
{
int* hostArray;
int* deviceArray;
const int arrayLength = 16;
const unsigned int memSize = sizeof(int) * arrayLength;
hostArray = (int*)malloc(memSize);
cudaMalloc((void**) &deviceArray, memSize);
std::cout << "Before device\n";
for(int i=0;i<arrayLength;i++)
{
hostArray[i] = i+1;
std::cout << hostArray[i] << "\n";
}
std::cout << "\n";
cudaMemcpy(deviceArray, hostArray, memSize, cudaMemcpyHostToDevice);
TestDevice <<< 4, 4 >>> (deviceArray);
cudaMemcpy(hostArray, deviceArray, memSize, cudaMemcpyDeviceToHost);
std::cout << "After device\n";
for(int i=0;i<arrayLength;i++)
{
std::cout << hostArray[i] << "\n";
}
cudaFree(deviceArray);
free(hostArray);
std::cout << "Done\n";
}
#endif
MyKernel.cu
#ifndef _MY_KERNEL_
#define _MY_KERNEL_
__global__ void TestDevice(int *deviceArray)
{
int idx = blockIdx.x*blockDim.x + threadIdx.x;
deviceArray[idx] = deviceArray[idx]*deviceArray[idx];
}
#endif
Costruire Log:
1>------ Build started: Project: CUDASandbox, Configuration: Debug x64 ------
1>Compiling with CUDA Build Rule...
1>"C:\CUDA\bin64\nvcc.exe" -arch sm_10 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin" -Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MT " -maxrregcount=32 --compile -o "x64\Debug\KernelSupport.cu.obj" "d:\Stuff\Programming\Visual Studio 2008\Projects\CUDASandbox\CUDASandbox\KernelSupport.cu"
1>KernelSupport.cu
1>tmpxft_000016f4_00000000-3_KernelSupport.cudafe1.gpu
1>tmpxft_000016f4_00000000-8_KernelSupport.cudafe2.gpu
1>tmpxft_000016f4_00000000-3_KernelSupport.cudafe1.cpp
1>tmpxft_000016f4_00000000-12_KernelSupport.ii
1>Linking...
1>KernelSupport.cu.obj : error LNK2005: __device_stub__Z10TestDevicePi already defined in MyKernel.cu.obj
1>KernelSupport.cu.obj : error LNK2005: "void __cdecl TestDevice__entry(int *)" ([email protected]@[email protected]) already defined in MyKernel.cu.obj
1>D:\Stuff\Programming\Visual Studio 2008\Projects\CUDASandbox\x64\Debug\CUDASandbox.exe : fatal error LNK1169: one or more multiply defined symbols found
1>Build log was saved at "file://d:\Stuff\Programming\Visual Studio 2008\Projects\CUDASandbox\CUDASandbox\x64\Debug\BuildLog.htm"
1>CUDASandbox - 3 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Sono in esecuzione Visual Studio 2008 su Windows 7 a 64 bit.
Edit:
penso di aver bisogno di elaborare su questo un po '. Il risultato finale che sto cercando qui è di avere una normale applicazione C++ con qualcosa come Main.cpp con l'evento int main()
e le cose vanno da lì. A un certo punto nel mio codice .cpp voglio essere in grado di fare riferimento ai bit CUDA. Quindi il mio pensiero (e correggimi se c'è una convenzione più standard qui) è che inserirò il codice Kernel CUDA nei loro file .cu, e poi avrò un file .cu di supporto che si occuperà di parlare al dispositivo e di chiamare funzioni del kernel e cosa no.
Si prega di elaborare con un semplice esempio di codice –
tuo MyKernel.h dovrebbe avere 'TestDeviceWrapper void (DIM3 griglia, blocco DIM3, int * devicearray)' da quando il KernelSupport.cu diventa KernelSupport.cpp cl.exe non capirà la __global__ sintassi. Quindi in MyKernel.cu, 'TestDeviceWrapper()' chiama semplicemente 'TestDevice <<<> >>'. – Tom
Sembra ragionevole, il codice fornito presuppone che verrà incluso in un file cuda, come indicato nella domanda. –