2011-06-25 46 views
51

He estado buscando información sobre la codificación de CUDA (el lenguaje nvidia gpu) con C#. He visto algunas de las bibliotecas, pero parece que agregarían un poco de sobrecarga (debido a las p/invocaciones, etc.).Codificando CUDA con C#?

  • ¿Cómo debo usar CUDA en mis aplicaciones de C#? ¿Sería mejor codificarlo en decir C++ y compilarlo en un dll?
  • ¿Disminuiría este gasto de usar un contenedor las ventajas que obtendría de usar CUDA?
  • ¿Y hay algún buen ejemplo de cómo usar CUDA con C#?

Respuesta

39

Existe una envoltura de cuda 4.2 tan bonita como ManagedCuda. Simplemente añada proyecto CUDA C++ para su solución, que contiene el suyo C#, a continuación, que acaba de añadir

call "%VS100COMNTOOLS%vsvars32.bat" 
for /f %%a IN ('dir /b "$(ProjectDir)Kernels\*.cu"') do nvcc -ptx -arch sm_21 -m 64 -o "$(ProjectDir)bin\Debug\%%~na_64.ptx" "$(ProjectDir)Kernels\%%~na.cu" 
for /f %%a IN ('dir /b "$(ProjectDir)Kernels\*.cu"') do nvcc -ptx -arch sm_21 -m 32 -o "$(ProjectDir)bin\Debug\%%~na.ptx" "$(ProjectDir)Kernels\%%~na.cu" 

a posterior a la generación de eventos en las propiedades de proyecto de C#, esta compila archivo .ptx * y lo copia en su directorio de salida del proyecto C#.

Luego, simplemente necesita crear un nuevo contexto, cargar el módulo desde el archivo, cargar la función y trabajar con el dispositivo.

//NewContext creation 
CudaContext cntxt = new CudaContext(); 

//Module loading from precompiled .ptx in a project output folder 
CUmodule cumodule = cntxt.LoadModule("kernel.ptx"); 

//_Z9addKernelPf - function name, can be found in *.ptx file 
CudaKernel addWithCuda = new CudaKernel("_Z9addKernelPf", cumodule, cntxt); 

//Create device array for data 
CudaDeviceVariable<cData2> vec1_device = new CudaDeviceVariable<cData2>(num);    

//Create arrays with data 
cData2[] vec1 = new cData2[num]; 

//Copy data to device 
vec1_device.CopyToDevice(vec1); 

//Set grid and block dimensions      
addWithCuda.GridDimensions = new dim3(8, 1, 1); 
addWithCuda.BlockDimensions = new dim3(512, 1, 1); 

//Run the kernel 
addWithCuda.Run(
    vec1_device.DevicePointer, 
    vec2_device.DevicePointer, 
    vec3_device.DevicePointer); 

//Copy data from device 
vec1_device.CopyToHost(vec1); 
11

Esto se ha comentado en la lista de nvidia en el pasado:

http://forums.nvidia.com/index.php?showtopic=97729

que sería fácil de utilizar P/Invoke para usarlo en las asambleas de este modo:

[DllImport("nvcuda")] 
    public static extern CUResult cuMemAlloc(ref CUdeviceptr dptr, uint bytesize); 
+1

eliminado el enlace. no hay necesidad de mostrar un muerto enlace más. sería muy amable si elimina su comentario. La gente podría ser irreparable de esto. –

+0

No me di cuenta de que solo podías invocar las llamadas CUDA. Es una pena que tengas que comprar en NVidia para que esto funcione. –

2

Existen varias alternativas que puede utilizar para usar CUDA en sus aplicaciones C#.

  • Escriba una biblioteca C++/CUDA en un proyecto separado, y use P/Invoke. La sobrecarga de P/invocaciones sobre llamadas nativas probablemente será insignificante.
  • Utilice un contenedor CUDA como ManagedCuda (que expondrá toda la API de CUDA). No tendrá que escribir su DLLIports a mano para la API completa de tiempo de ejecución CUDA (que es conveniente). Desafortunadamente, aún tendrá que escribir su propio código CUDA en un proyecto separado.
  • (recomendada) Puede utilizar libre/código abierto/compiladores de propiedad (que generará CUDA (fuente o binario) de su código C#

puede encontrar varios de ellos en línea:. Echar un vistazo en this answer por ejemplo.

2

supongo Hybridizer, explicó here como un blog el Nvidia es también vale la pena mencionar. Here es su relacionada GitHub reporto que parece.