【问题标题】:passing cuda device pointer to host function将 cuda 设备指针传递给主机函数
【发布时间】:2013-03-21 19:10:47
【问题描述】:

我正在开发一个程序。我是 CUDA 和 C 的新手,所以这对我来说真的是一段坎坷的旅程。我正在尝试将结构复制到设备中。然后我试图通过将结构复制到设备来将其返回到主机。下面是代码:

typedef struct {
    int row;
    int col;
    float *arr;
    int numElements;
} Matrix;

Matrix *RMatrix = //definition here

Matrix *d_RMatrix;

    copyMatrix(d_RMatrix, RMatrix, hostToDevice);

    Matrix *check = createMatrix(0, 0, NULL, 0);

    copyMatrix(check, d_RMatrix, deviceToHost);

以及copyMatrix的定义:

void copyMatrix (Matrix *copyTo, Matrix *copyFrom, Copy_type type) 
{

    if(type == hostToDevice) {

        // create temporary host matrix and array
        Matrix *copyFrom_h = createMatrix(copyFrom->row, copyFrom->col, NULL, copyFrom->numElements);

        // allocate device memory, pointing to array in host. Copy array to device memory
        cudaMalloc((void**) &copyFrom_h->arr, sizeof(float) * copyFrom_h->numElements);
        cudaMemcpy(copyFrom_h->arr, copyFrom->arr, sizeof(float) * copyFrom_h->numElements, cudaMemcpyHostToDevice);

        // copy the temporary memory to device
        cudaMalloc((void**) &copyTo, sizeof(Matrix));
        cudaMemcpy(copyTo, copyFrom_h, sizeof(Matrix), cudaMemcpyHostToDevice);

        copyFrom_h = NULL;
        free(copyFrom_h);

    }

    else if(type == deviceToHost) {

        cudaMemcpy(copyTo, copyFrom, sizeof(Matrix), cudaMemcpyDeviceToHost);

        // allocate space for array in the copy to matrix
        copyTo->arr = makeArray(copyTo->col, copyTo->row);
        cudaMemcpy(copyTo->arr, copyFrom->arr, sizeof(float) * copyTo->numElements, cudaMemcpyDeviceToHost);

    }
}

错误表示第一次调用 cudaMemcpy 时在 0x3(d_RMatrix 的值)处的内存访问无效,并导致第二次出现段错误。

这里有什么我遗漏的吗?谢谢你的帮助:)

【问题讨论】:

    标签: c pointers cuda gpgpu


    【解决方案1】:

    在 C 中,指针是指向对象的实体(在这种情况下)。创建指针不会创建对象,也不会为其分配空间。

    您创建了一个指针Matrix *d_RMatrix;,但它没有指向任何有效对象。你很幸运它崩溃了,因为它可能会意外地将数据实际复制到内存中的某个随机位置。

    Matrix TheMatrix();
    Matrix *PointerToTheMatrix = &TheMatrix;
    

    或者

    Matrix *PointerToTheMatrix = createMatrix(...);//remember you will have to delete it eventually!
    

    函数参数是一种方式。如果您在函数内部为copyTo 分配了某些内容,则更改将在函数外部不可见。

    /编辑: 我有个主意:

    Matrix* CreateMatrixInDevice(Matrix* copyFrom)
    {
        Matrix* copyTo = NULL;
        cudaMalloc((void**) &copyTo, sizeof(Matrix));//create outer struct
        cudaMemcpy(copyTo, copyFrom, sizeof(Matrix), cudaMemcpyHostToDevice);//copy data from outer struct
        //the arr element in the device is now INVALID (pointing to host)
    
        cudaMalloc((void**) &copyTo->arr, sizeof(float) * copyFrom->numElements);//create inner array
        cudaMemcpy(copyTo->arr, copyFrom->arr, sizeof(float) * copyFrom->numElements, cudaMemcpyHostToDevice);//copy matrix data
    
        return copyTo;
    }
    

    【讨论】:

    • 我使用设备全局内存中copyMatrix 内的 cudaMalloc 函数为一个空间分配了空间。这算作一个对象吗?我知道存在不使用设备内存中定义的变量值的限制,但我不确定这是不是这种情况......
    • @AnugerahErlaut 我认为您对函数参数也有疑问,我已经更新了答案。我认为您应该尝试在一个函数中制作工作副本。
    • 是的,如果我将代码全部放在函数之外,它似乎可以工作。绝对变量范围问题。将不得不重新考虑该方法(不想将所有代码都放在 main 中)。谢谢你的回答:)
    • @AnugerahErlaut 现在检查一下,也许你会喜欢这个
    • 最后,我决定先把所有东西都展平,然后看看能不能把东西组合成函数。感谢您的跟进 :)
    猜你喜欢
    • 2021-07-03
    • 2015-09-12
    • 2017-12-08
    • 2020-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多