从 CUDA 中的主机访问设备上的类成员数组指针

Posted

技术标签:

【中文标题】从 CUDA 中的主机访问设备上的类成员数组指针【英文标题】:Accessing Class Member Array Pointer on Device from Host in CUDA 【发布时间】:2012-12-25 02:02:30 【问题描述】:

我已经被这个问题难住了一段时间了。这涉及到 CUDA 设备指针。我的设备上有一个自定义类的实例,它有一个成员变量,它是指向数组(在设备上)的指针。

class MyClass 
public:
    int* array;
    // Other variables and functions, etc.
;

它需要是一个动态分配的数组,因为数组的大小取决于程序开始时的一些输入。在程序执行期间,我正在使用内核函数修改类,但最终我想在主机上获取此类的副本以输出到文件。但是我似乎无法让 cudaMemCpy 为我工作。

我可以使用以下代码获取该类的副本(其中 dc 是指向设备上的类的指针):

MyClass hc;
cudaMemcpy(&hc, dc, sizeof(dc), cudaMemcpyDeviceToHost);

但这只会获取类中不是指针的信息,这是有道理的,因为在 hc 中检索到的指针仍将指向设备上的数据。所以我想我可以使用这段代码来实际获取数组。

int* h_array;
cudaMemcpy(h_array, dc->array, sizeof(dc->array), cudaMemcpyDeviceToHost);

这仅返回一个空数组,而且我得到一个 cudaFree 错误(“Cuda 错误:cuda 空闲操作:无效参数”)。我已经尝试了很多这样的变体,包括使用 hc->array,但没有成功。有没有什么方法可以让我得到这个数组,而不必编写一个内核函数来复制每个单独的条目?我正在使用 CUDA 5.0。

【问题讨论】:

类中的设备指针(即MyClass.array的值)是使用主机API还是使用设备内核内部的malloc/new分配的? 指针是使用主机 API 分配的。在我读入输入后,我在主机上分配了一个数组,在设备上分配了另一个数组(使用 cudaMalloc)。我将一些初始值存储到主机数组,然后使用 cudaMemCpy 将此信息复制到设备数组上。然后我使用一个简单的 >> 内核将 MyClass.array 的值设置为设备数组。之后我释放了主机阵列,因为我不再需要它了。 dc 是指向设备内存的指针。你不能像这样在主机上尊重它dc->array 考虑到这一点,我建议您重新考虑解决问题的方式。首先,使用结构/类的数组比使用数组的结构/类更简单(但不一定更有效)(在这种情况下,数组无论如何都必须具有固定的大小)。 【参考方案1】:

我认为您以错误的方式使用 sizeof 和指针。

您的代码中的sizeof(dc)sizeof(dc->array) 可以替换为sizeof(MyClass)ArraySize * sizeof(int)

对于指针,您必须执行两次cudaMemcpy 才能获取您的数组。

    首先获取对象hc,它存储了你的数组的addr。

    cudaMemcpy(&hc, dc, sizeof(MyClass), cudaMemcpyDeviceToHost);
    

    然后获取数组本身。

    cudaMemcpy(h_array, hc.array, ArraySize*sizeof(int),D2H);
    

另外,dc 是指向设备内存的指针。你不能像这样在主机上取消引用它dc->array

【讨论】:

这种帮助!虽然您的方法不适用于我的原始代码,但它确实让我想到更改 MyClass 对象的初始化方式。最初它被设置为在我将其复制到设备后接收设备指针,但我将其更改为在将其复制到设备之前给它指针。无论出于何种原因,虽然我在拥有类的原始主机副本时仍然可以访问该数组,但是当我将它从设备复制回来时,指针不再起作用(导致相同的错误)。 @C.G.真奇怪。存储在array 中的值(在本例中为地址)在复制到设备内存并从设备内存复制回来后不应更改。 @C.G.我认为您的代码中的sizeof(dc)sizeof(dc->array) 也可能是一个问题。改用sizeof(MyClass) & ArraySize*sizeof(int) 是的,这就是问题所在。从 sizeof(dc) 切换到 sizeof(MyClass) 解决了它。感谢您的帮助!

以上是关于从 CUDA 中的主机访问设备上的类成员数组指针的主要内容,如果未能解决你的问题,请参考以下文章

访问不同 CUDA 内核中的类成员

通过“指向类成员的指针”访问作为数组的类成员

CUDA中的一个简单的缩减程序

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

为啥我不能访问指向数组中成员函数的指针?

访问包含在数组中的指向类对象的类成员函数的正确语法是啥?