【问题标题】:CUDA memcpy not working when copying back to host复制回主机时 CUDA memcpy 不起作用
【发布时间】:2014-12-22 18:56:27
【问题描述】:

我的问题是 CUDA memcpy 从设备复制回主机。我的程序使用用 C# + CUDA 包装类编写的 GUI 和用 cudaC 编写的核心 cuda 逻辑。

这是c#中负责启动一切的主要代码:

int[] imgData = srcImg.RgbData8bitInt;
int[] patData = pattern.PatternData;
int[] maskData = pattern.MaskData;
int[] Accumulator = new int[srcImg.Width * srcImg.Height];

IntPtr A_dev = CUDA.MallocInt(srcImg.Width * srcImg.Height);

IntPtr Img_dev = CUDA.MallocInt(imgData.Length);
CUDA.MemcpyToDevice(imgData, Img_dev, imgData.Length);

IntPtr Pat_dev = CUDA.MallocInt(patData.Length);
CUDA.MemcpyToDevice(patData, Pat_dev, patData.Length);

IntPtr Mask_dev = CUDA.MallocInt(maskData.Length);
CUDA.MemcpyToDevice(maskData, Mask_dev, maskData.Length);

int gridSizeX = (srcImg.Width - pattern.Image.Width) / 256 + 1;
int gridSizeY = srcImg.Height - pattern.Image.Width;
int imageWidth = srcImg.Width;

CUDA.Execute(status, gridSizeX, gridSizeY, A_dev, Img_dev, Pat_dev, Mask_dev, imageWidth);
CUDA.SynchronizeContext();

CUDA.MemcpyToHost(Accumulator, A_dev, Accumulator.Length);

顺便说一句。 CUDA.SynchronizeContext() 是 cudaThreadSynchronize() 的包装器;

有问题的部分是最后一行,负责将值从设备复制回主机。

[DllImport(dllPath, CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
private static extern int memcpyToHost(int[] srcPtr, IntPtr devPtr, int size);
extern "C" int __declspec(dllexport) __stdcall memcpyToHost(int* host, int* dev, int size)
{
    if (dev == 0) return 1;
    cudaError_t status = cudaMemcpy(host, dev, size * sizeof(int), cudaMemcpyDeviceToHost);
    if (status == cudaSuccess)
        return 0;
    else
        return 1;
}

我在调试时得到的错误状态是:cudaErrorInvalidValue

分配内存并复制到设备似乎没问题,我已经调试过了。我完全不知所措,也许有人遇到过类似的问题?

编辑:已解决参见 cmets

【问题讨论】:

  • 错误可能是由先前的 CUDA 调用或内核调用引起的。您是否在cudaThreadSynchronize() 周围的包装函数中进行了适当的内核错误检查和/或错误检查?请注意,对于此类问题(“为什么我的代码不起作用?”),SO expects 需要提供 MCVE。另请注意,cudaThreadSynchronize() 已被弃用,取而代之的是 cudaDeviceSynchronize(),但这肯定不会造成问题。
  • 感谢您的评论。 Acutally我已经为这个问题苦苦挣扎了几天,但我刚刚解决了它。问题是 cudaDeviceReset();放置在内核调用之后... ... ...
  • 如果您提供了一个答案来解释问题是什么以及您如何解决它,那么我们可以将此问题从未回答列表中删除。 (是的,您可以回答自己的问题。)

标签: c# cuda


【解决方案1】:

问题是 cudaDeviceReset();放置在内核调用之后。

【讨论】:

    猜你喜欢
    • 2014-04-21
    • 2016-02-09
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 2011-11-30
    • 2012-09-29
    • 2020-08-20
    相关资源
    最近更新 更多