Caleb Johnson
Caleb Johnson

Reputation: 410

How to invoke CUDA from C#

I've built a program using Hybridizer to write CUDA code in C# and call the functions. The program is functional but I noticed that the overhead of setting up the GPU and calling the function to it is extremely high. For example, a job which took 3000 ticks when run on the CPU took about 50 million ticks to set up the GPU wrapper then another 50 million ticks to run when doing it on the GPU. I'm trying to figure out if this lag is due to Hybridizer itself or is simply unavoidable when calling GPU code from my C# program.

So I'm looking for alternative methods. My searches have found some mentions of something called P/invoke, but I can't really find a good guide on how to use it and all of those threads are 9+ years old so I don't know if their information is still relevant. I also found something about ManagedCuda but it seems that is no longer in development.

Upvotes: 4

Views: 3841

Answers (1)

Denis Gladkiy
Denis Gladkiy

Reputation: 2174

You can try CppSharp to generate C# bindings to CUDA. We were able to initialize CUDA with this approach and call it's simple hardware info functions (GetDeviceProperties, CudaSetDevice, CudaGetDeviceCount, CudaDriverGetVersion, CudaRuntimeGetVersion).

Usage of the other parts of CUDA API seems to be possible but we did not try: CppSharp generated bindings for the whole CUDA runtime API. We use CUDA indirectly via NVIDIA's Flex library. All the Flex functions are usable via CppSharp without considerable penalties.

The example usage of classes generated via CppSharp looks like this:

int driverVersion = 0;
CudaRuntimeApi.CudaDriverGetVersion(ref driverVersion);

int runtimeVersion = 0;
CudaRuntimeApi.CudaRuntimeGetVersion(ref runtimeVersion);

int deviceCount = 0;
var errorCode = CudaRuntimeApi.CudaGetDeviceCount(ref deviceCount);

if (errorCode != CudaError.CudaSuccess)
{
    Console.Error.WriteLine("'cudaGetDeviceCount' returned " + errorCode + ": " + CudaRuntimeApi.CudaGetErrorString(errorCode));
    return;
}

for (var device = 0; device < deviceCount; ++device)
{
    using (var deviceProperties = new CudaDeviceProp()) 
    {
        CudaRuntimeApi.CudaGetDeviceProperties(deviceProperties, device);
    }
}
         

CudaRuntimeApi and CudaDeviceProp are the classes generated by CppSharp.

Upvotes: 6

Related Questions