我有一个带指针的数据结构(想想链表)。在启动读取输入数据的内核之前无法确定其大小。所以我在输入处理期间在设备上分配数据。
但是,尝试将该数据复制回主机失败。据我所知,这是因为 CUDA 中存在限制,不允许运行时 API 访问设备分配的内存。然而,该信息是针对 CUDA 4 的,“即将修复”。有谁知道该修复程序或解决方法是否出现过?我似乎找不到任何关于此的最新信息。
这是一个可重现的例子:
#include <cstdio>
__device__ int *devData;
__global__ void initKernel()
{
devData = new int[6];
devData[0] = 0;
devData[1] = 1;
devData[2] = 2;
devData[3] = 3;
devData[4] = 4;
devData[5] = 5;
}
__global__ void printKernel()
{
printf("Testing device: %d\n", devData[3]);
}
int main()
{
initKernel<<<1,1>>>();
cudaDeviceSynchronize();
printKernel<<<1,1>>>();
cudaDeviceSynchronize();
int *devAddr;
cudaGetSymbolAddress((void **)&devAddr, devData);
int *hostData = new int[6];
cudaMemcpy(hostData, devAddr, 6*sizeof(int), cudaMemcpyDeviceToHost)); //cudaErrorInvalidValue (invalid argument)
//same error with: cudaMemcpyFromSymbol(hostData, devData, 6*sizeof(int));
printf("Testing host: %d\n", testHost[3]);
return 0;
}
这会为 cudaMemcpy 抛出一个 cudaErrorInvalidValue(与 cudaMemcpyFromSymbol 相同)。当我使用 __device__ int devData[6];
而不是 __device__ int *devData;
并按预期打印 3 时,这不会引发错误。
最佳答案
还是不行
这记录在 the programming guide 中.
In addition, device malloc() memory cannot be used in any runtime or driver API calls (i.e. cudaMemcpy, cudaMemset, etc).
如果您在内核 malloc()
创建的分配中有数据要传输到主机,则需要先将该数据传输到设备内存分配(或托管分配),然后复制到主机或在主机代码中使用。
内核内 malloc
的相同注释和用法的所有方面同样适用于内核内 new
以及内核内 cudaMalloc
.
关于c++ - cudaMemcpy 来托管设备分配的内存仍然不可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58402487/