web-dev-qa-db-ja.com

C#でCUDAをコーディングしますか?

C#を使用したCUDA(nvidia gpu言語)のコーディングに関する情報を探しています。私はいくつかのライブラリを見てきましたが、それらは少しのオーバーヘッドを追加するようです(p/invokesなどのため)。

  • C#アプリケーションでCUDAを使用するにはどうすればよいですか?たとえばC++でコーディングし、それをdllにコンパイルする方が良いでしょうか?
  • ラッパーを使用するこのオーバーヘッドは、CUDAを使用することで得られる利点を損なうでしょうか?
  • そして、C#でCUDAを使用する良い例はありますか?
56
Ben

ManagedCuda のようなニースの完全なcuda 4.2ラッパーがあります。 C++プロジェクトをソリューションに追加するだけで、C#プロジェクトが含まれます。その後、追加するだけです。

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"

c#プロジェクトのプロパティでイベントをポストビルドするには、これにより* .ptxファイルがコンパイルされ、C#プロジェクトの出力ディレクトリにコピーされます。

次に、新しいコンテキストを作成し、ファイルからモジュールをロードし、関数をロードしてデバイスを操作するだけです。

//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);
44
Insomnious

これは、過去にnvidiaリストでコメントされています。

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

p/Invokeを使用すると、次のようなアセンブリで簡単に使用できます。

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

Nvidiaのブログ投稿として here も説明する価値があると説明されていると思います。 ここ は関連するGitHubリポジトリです。

5
Ebrahim Byagowi

C#アプリケーションでCUDAを使用するために使用できる代替方法がいくつかあります。

  • 別のプロジェクトでC++/CUDAライブラリを作成し、P/Invokeを使用します。ネイティブコールに対するP/invokeのオーバーヘッドは、おそらく無視できるでしょう。
  • ManagedCuda (CUDA API全体を公開する)などのCUDAラッパーを使用します。 CUDAランタイムAPI全体に対してDLLImportsを手動で記述する必要はありません(便利です)。幸いなことに、別のプロジェクトで独自のCUDAコードを記述する必要があります。
  • recommended)free/opensource/proprietaryコンパイラ(c#コードからcuda(ソースまたはバイナリ)を生成します)を使用できます。

それらのいくつかをオンラインで見つけることができます: this answer を見てください。

2
Regis Portalez