ManagedCuda:IllegalAddress;在执行内核时

时间:2014-12-16 21:47:47

标签: c# cuda

我正在使用C#项目中的ManagedCuda库来利用GPU,目前我正在跟随这个tutorial关于如何在使用OpenCV实现它之后编写C#和C ++之间兼容的代码。

我的代码似乎一切正常,内核被发现,构建并执行方法调用但是我收到错误:

An unhandled exception of type 'ManagedCuda.CudaException' occurred in ManagedCuda.dll

Additional information: ErrorIllegalAddress: While executing a kernel, the device 
encountered a load or store instruction on an invalid memory address.

The context cannot be used, so it must be destroyed (and a new one should be created).

我知道C#抱怨在尝试将设备指针传递给内核时找不到有效地址,我在代码和引用教程中的帖子之间可以区分的唯一区别是ManagedCuda似乎最近有一个改版,允许用户使用Lambdas,我已经做了一些阅读,并没有找到任何东西来澄清这是否是导致我的问题:

static Func<int, int, int> cudaAdd = (a, b) =>
{
    // init output parameters
    CudaDeviceVariable<int> result_dev = 0;
    int result_host = 0;
    // run CUDA method
    addWithCuda.Run(a, b, result_dev.DevicePointer);   <--- Code throws error here
    // copy return to host
    result_dev.CopyToHost(ref result_host);
    return result_host;
};

在原始教程代码中,OP使用CudaDeviceVariable result_dev = 0;。这可能是问题吗?我不明白为什么会这样,但也许我的演员是错的?

为了清楚起见,这里是被调用的内核:

__global__ void kernel(int a, int b, int *c)
{
    *c = (a + b)*(a + b);
}

3 个答案:

答案 0 :(得分:6)

TL; DR:异常与C#项目中的32/64位设置有关。将平台目标设置为x86,或者如果你在任何CPU上都有它,请确保选择首选32位。

enter image description here enter image description here

我如何发现:

根据https://algoslaves.wordpress.com/2013/08/25/nvidia-cuda-hello-world-in-managed-c-and-f-with-use-of-managedcuda/在.NET 4.5中提供解决方案(与OP相同) 使用NuGet添加ManagedCuda 6.5 - Standalone

工作正常

备用点A.

将.NET版本更改为4.0,使用NuGet删除并添加ManagedCuda 6.5 - Standalone:

抛出异常:附加信息:ErrorIllegalAddress:执行内核时,设备遇到无效内存地址的加载或存储指令。

将.NET版本切换为4.5,使用NuGet删除并添加ManagedCuda 6.5 - Standalone:

抛出异常:与上述相同。

清洁解决方案,重建解决方案,构建解决方案:

抛出异常:与上述相同。

手动删除Visual Studio生成的每个文件/文件夹:

抛出异常:与上述相同。

重新打开从A点备份的项目:

工作得很好。

在工作和不工作项目中手动删除Visual Studio生成的每个文件/文件夹。

直观地比较所有文件。

每个文件都是相同的,除了:不工作的版本在MangedCudaTest.csproj中有额外的<Prefer32Bit>false</Prefer32Bit>

已删除包含<Prefer32Bit>false</Prefer32Bit>的行。

不工作版本终于工作得很好。

在我的主项目中进行了相同的更改,最终工作得很好。

答案 1 :(得分:2)

从评论看来,抛出的异常似乎是由于在不同的线程上运行。在单线程环境中,示例代码运行正常,返回正确的结果。为了在多线程应用程序中使用Cuda,必须正确同步线程并将cuda上下文绑定到当前活动的线程。

答案 2 :(得分:0)

我有同样的问题,我的解决方案是将.NET项目设置为64位,而不是像aeroson的回答中建议的32位。我想这可能是因为我使用的是CUDA SDK 7.5而且我读到的某个地方大约有32位被淘汰。