2013-03-21 96 views
0

我有一個我正在開發的程序。我是CUDA和C的新手,所以對我來說這真的是一次顛簸。我試圖將一個結構複製到設備中。然後我試圖通過將結構複製到設備來將結構返回到主機。下面是代碼:將cuda設備指針傳遞給主機功能

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值)第2位。

有什麼我在這裏失蹤?感謝您的幫助:)

回答

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

我使用的設備全局內存的'copyMatrix'內cudaMalloc功能分配的空間之一。這算作爲一個對象嗎? 我知道有沒有使用設備內存中定義的變量值的限制,但我不知道這是一種情況... – 2013-03-21 19:30:00

+0

@AnugerahErlaut我認爲你也有一個功能的問題參數,我已經更新了答案。我認爲你應該嘗試在一個函數中創建一個工作副本。 – 2013-03-21 19:31:56

+0

Yups,它似乎工作,如果我把代碼都放在函數之外。絕對可變的範圍問題。將不得不重新考慮這種方法(不要把所有的代碼放在主要位置)。 感謝您的回答:) – 2013-03-21 19:44:42