CUDA cudaMemcpyFromSymbol“无效的设备符号”错误?

时间:2018-12-02 03:43:41

标签: cuda

因此,我看到一个parent问题,该问题涉及如何使用cudaMemcpyToSymbol从主机复制到GPU上的恒定内存。

我的问题是如何执行相反的操作,使用cudaMemcpyFromSymbol从设备常量内存复制到主机。

在下面的最小可重复示例中,我要么

  • 1)使用invalid device symbol的{​​{1}}错误,或
  • 2)如果我使用cudaMemcpyFromSymbol(const_d_a, b, size);,则会得到segmentation fault

我咨询过manual,建议我按照1)进行编码,而this SO question则建议我按照2)进行编码。他们都不在这里工作。

有人可以帮忙建议一个解决方法吗?我一定是不正确地理解了一些东西……谢谢!

代码如下:

cudaMemcpyFromSymbol(&b, const_d_a, size, cudaMemcpyDeviceToHost)

1 个答案:

答案 0 :(得分:1)

在CUDA中,各种cudaMemcpy*操作都是在C标准库memcpy例程之后建模的。在该函数中,第一个指针总是始终,第二个指针总是始终。所有cudaMemcpy*函数也是如此。

因此,如果要执行cudaMemcpyToSymbol,则符号最好是传递给该函数的第一个(目标)参数(第二个参数将是主机指针)。如果要执行cudaMemcpyFromSymbol,则符号必须是第二个参数(源位置),而主机指针是第一个参数。那不是你在这里的东西:

cudaError_t err2 = cudaMemcpyFromSymbol(const_d_a, b, size);
                                          ^        ^
                                          |       This should be the symbol.
                                          |  
                                   This is supposed to be the host destination pointer.

您可以通过查看API documentation来发现这一点。

如果我们在代码行中反转这两个参数的顺序:

cudaError_t err2 = cudaMemcpyFromSymbol(b, const_d_a, size);

您的代码将正确运行,并且最终结果将匹配。

在这些函数中,无需在ab指针中使用与号。 ab已经是指针。在您链接的示例中,pi_gpu_h不是指针。它是一个普通变量。要使用cudaMemcpyFromSymbol向其复制内容,必须获取该普通变量的地址,因为该函数需要一个(目标)指针。

顺便说一句,这看起来不正确:

__constant__ float const_d_a[N * sizeof(float)];  

这实际上是一个静态数组声明,除__constant__装饰器之外,它的等效处理方式与在C或C ++中的处理方式相同。如果要存储N sizeof(float)个数量,则此处不必将N乘以float。只需N自己就能做到:

__constant__ float const_d_a[N];

无论如何保持原样不会对您发布的代码造成问题。