2013-01-10 48 views
3

我一直在這個問題上相當難住了一段時間。這涉及CUDA設備指針。我有一個坐在我的設備上的自定義類的實例,它有一個成員變量,它是指向數組(位於設備上)的指針。從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。

+0

設備指針是否在設備內核中使用主機API或使用'malloc/new'分配的類中的設備指針(所以MyClass.array的值) ? – talonmies

+0

指針使用主機API分配。在我讀入輸入後,我在主機和設備上的另一個陣列(使用cudaMalloc)上分配一個數組。我將一些初始值存儲到主機陣列,然後使用cudaMemCpy將這些信息複製到設備陣列上。然後,我使用一個簡單的<<<1,1> >>內核將MyClass.array的值設置爲設備陣列。之後我釋放了主機陣列,因爲我不再需要它了。 –

+0

'dc'是一個指向設備內存的指針。你不能在主機上尊重這個'dc-> array' – kangshiyin

回答

1

我認爲你用錯誤的方式使用sizeof和指針。

sizeof(dc)sizeof(dc->array)在你的代碼可以通過sizeof(MyClass) & ArraySize * sizeof(int)所取代。

對於指針,你必須做cudaMemcpy兩次才能得到你的數組。

  1. 首先獲取對象hc,它存儲數組的addr。

    cudaMemcpy(&hc, dc, sizeof(MyClass), cudaMemcpyDeviceToHost); 
    
  2. 然後獲取數組本身。

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

另外,dc是一個指向裝置MEM中。你不能在這樣的主機上解除引用dc->array

+0

這種幫助!雖然你的方法不適合我的原代碼,但它確實讓我想到改變MyClass對象的初始化方式。最初,它被設置爲在將設備指針複製到設備後收到設備指針,但是我在將設備指針複製到設備之前將其更改爲指針。不管什麼原因,雖然我仍然可以訪問數組,但我有該類的原始主機副本,但是當我將其從設備中複製回來時,指針不再工作(導致相同的錯誤)。 –

+0

@ C.G。真奇怪。存儲在'array'中的值(在這種情況下爲addr)不應該在從設備內存複製到設備內存後更改。 – kangshiyin

+0

@ C.G。我認爲代碼中的sizeof(dc)'和sizeof(dc-> array)'也可能是個問題。改爲使用'sizeof(MyClass)'&'ArraySize * sizeof(int)'。 – kangshiyin