2011-06-25 50 views
51

Tôi đã tìm kiếm một số thông tin về mã hóa CUDA (ngôn ngữ gpu nvidia) với C#. Tôi đã thấy một vài trong số các thư viện, nhưng có vẻ như họ sẽ thêm một chút chi phí (vì p/invokes, vv).Mã hóa CUDA bằng C#?

  • Tôi nên sử dụng CUDA như thế nào trong các ứng dụng C# của mình? Nó sẽ được tốt hơn để mã nó trong nói C + + và biên dịch mà thành một dll?
  • Chi phí này có sử dụng trình bao bọc để loại bỏ mọi lợi thế mà tôi có được từ việc sử dụng CUDA không?
  • Và có bất kỳ ví dụ hay về việc sử dụng CUDA với C# không?

Trả lời

39

Có một bao bì cuda 4.2 hoàn chỉnh đẹp như ManagedCuda. Bạn chỉ cần thêm dự án CUDA C++ để giải pháp của bạn, trong đó có bạn C# dự án, sau đó bạn chỉ cần thêm

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" 

để gửi-xây dựng các sự kiện trong C# thuộc tính dự án của bạn, điều này biên dịch file * .ptx và sao chép nó vào bạn C# thư mục đầu ra của dự án.

Sau đó, bạn chỉ cần tạo ngữ cảnh mới, tải mô-đun từ tệp, chức năng tải và làm việc với thiết bị.

//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

này đã được nhận xét về danh sách nvidia trong quá khứ:

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

nó sẽ được dễ dàng để sử dụng P/Invoke để sử dụng nó trong hội đồng như vậy:

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

loại bỏ các liên kết. không cần để hiển thị một chết liên kết thêm. sẽ rất tử tế nếu bạn xóa nhận xét của mình. Mọi người có thể không được giải thích về điều này. –

+0

Tôi đã không nhận ra rằng bạn chỉ có thể PInvoke các cuộc gọi CUDA. Xấu hổ mà bạn cần phải mua vào NVidia để làm việc này. –

2

Có một số lựa chọn thay thế mà bạn có thể sử dụng để sử dụng CUDA trong các ứng dụng C# của mình.

  • Viết thư viện C++/CUDA trong một dự án riêng biệt và sử dụng P/Invoke. Các chi phí của P/gọi trên các cuộc gọi bản địa có thể sẽ không đáng kể.
  • Sử dụng trình bao bọc CUDA chẳng hạn như ManagedCuda (sẽ hiển thị toàn bộ API CUDA). Bạn sẽ không phải viết DLLImports của bạn bằng tay cho toàn bộ API thời gian chạy CUDA (thuận tiện). Thật không may, bạn sẽ vẫn phải viết mã CUDA của riêng bạn trong một dự án riêng biệt.
  • (khuyến) Bạn có thể sử dụng miễn phí/mã nguồn mở/biên dịch độc quyền (mà sẽ tạo ra CUDA (hoặc nguồn hoặc nhị phân) từ # mã c của bạn

Bạn có thể tìm thấy một số trong số họ trực tuyến:. Có một cái nhìn tại this answer ví dụ.

2

tôi đoán Hybridizer, giải thích here như một bài đăng blog trên Nvidia cũng đáng kể. Here là GitHub liên quan của nó repo vẻ bề ngoài.