cudaMemcpy 仍然无法托管设备分配的内存?

Posted

技术标签:

【中文标题】cudaMemcpy 仍然无法托管设备分配的内存?【英文标题】:cudaMemcpy to host for device-allocated memory still not possible? 【发布时间】:2021-12-28 00:50:06 【问题描述】:

我有一个带有指针的数据结构(想想链表)。在启动读取输入数据的内核之前无法确定其大小。所以我在输入处理期间在设备上分配数据。 但是,尝试将该数据复制回主机失败。据我所知,这是因为 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 时,这不会引发错误。

【问题讨论】:

【参考方案1】:

还是不行。

这在the programming guide中有记录。

此外,设备 malloc() 内存不能用于任何运行时或驱动程序 API 调用(即 cudaMemcpy、cudaMemset 等)。

如果您希望传输到由内核malloc() 创建的分配中的数据到主机,则需要先将该数据传输到设备内存分配(或托管分配),然后再复制到主机或在主机代码中使用。

内核内malloc 的相同cmets 和使用的所有方面同样适用于内核内new 和内核内cudaMalloc

【讨论】:

以上是关于cudaMemcpy 仍然无法托管设备分配的内存?的主要内容,如果未能解决你的问题,请参考以下文章

当“cudaMemcpy”从设备到主机时,我是不是必须设置正确的设备?

cuda实践2

CUDA-将二维数组从主机传输到设备

CUDA程序优化之数据传输

CUDA程序优化之数据传输

CUDA程序优化之数据传输