因此,我看到一个parent问题,该问题涉及如何使用cudaMemcpyToSymbol
从主机复制到GPU上的恒定内存。
我的问题是如何执行相反的操作,使用cudaMemcpyFromSymbol
从设备常量内存复制到主机。
在下面的最小可重复示例中,我要么
invalid device symbol
的{{1}}错误,或cudaMemcpyFromSymbol(const_d_a, b, size);
,则会得到segmentation fault
。我咨询过manual,建议我按照1)进行编码,而this SO question则建议我按照2)进行编码。他们都不在这里工作。
有人可以帮忙建议一个解决方法吗?我一定是不正确地理解了一些东西……谢谢!
代码如下:
cudaMemcpyFromSymbol(&b, const_d_a, size, cudaMemcpyDeviceToHost)
答案 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);
您的代码将正确运行,并且最终结果将匹配。
在这些函数中,无需在a
或b
指针中使用与号。 a
和b
已经是指针。在您链接的示例中,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];
无论如何保持原样不会对您发布的代码造成问题。