Anugerah Erlaut
Anugerah Erlaut

Reputation: 1120

passing cuda device pointer to host function

I have a program I'm working on. I'm new with CUDA and C,so it really has been a bumpy ride for me. I'm trying to copy a struct into the device. And then I'm trying to get the struct back to host by copying it to the device. Below is the code :

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);

and the definition of 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);

    }
}

The error says invalid memory access at 0x3 (value of d_RMatrix) for the 1st call to cudaMemcpy and results in segfault on the 2nd.

Is there anything I'm missing here? Thanks for your help :)

Upvotes: 0

Views: 2087

Answers (1)

Agent_L
Agent_L

Reputation: 5411

In C a pointer is an entity pointing to an object (in this case). Creating a pointer DOES NOT create the object nor allocate space for it.

You have created a pointer Matrix *d_RMatrix; but it doesn't point to any valid object. You got lucky it crashed, because by accident it could manage to actually copy the data into some random place in the memory.

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

Or

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

Function parameters are one way. If you assign something to copyTo inside function, the change will not be visible outside the function.

/edit: I have an idea:

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;
}

Upvotes: 1

Related Questions