2015-12-18 63 views
0

我花了2天試圖找出這一點,並獲得無處不在。說我有一個結構,看起來像這樣:如何將C++數組結構傳遞給CUDA設備?

struct Thing { 
    bool is_solid; 
    double matrix[9]; 
} 

我想創建一個結構數組稱爲things,然後處理GPU上的數組。喜歡的東西:

Thing *things; 
int num_of_things = 100; 
cudaMallocManaged((void **)&things, num_of_things * sizeof(Thing)); 

// Something missing here? Malloc individual structs? Everything I try doesn't work. 

things[10].is_solid = true; // Segfaults 

它甚至最好的做法去做這種方式,而不是通過與被num_of_things大陣列的單個結構?這似乎對我來說,能得到非常討厭尤其是當你已經陣列(如matrix,這將需要9 * num_of_things

任何信息,將不勝感激!

+2

你的代碼適合我。 [這是我的完整測試用例](http://pastebin.com/tBXqFF1C)(你應該提供這樣的東西)。你的方法沒有錯;對於如何在受管方案中執行此操作通常會很常見。很可能你正在犯下幾個錯誤之一:1.你不是爲cc3.0 +設備編譯。 2.您沒有在cc3.0 +設備上運行。 3.您的環境[不支持管理內存的使用情況(http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#um-requirements)。 –

+1

在任何情況下,最好的建議是採用[適當CUDA錯誤檢查(http://stackoverflow.com/questions/14038589/what-is-the-canonical-way-to-check-for-errors-using- cuda-runtime-api)任何時候你遇到一個cuda代碼的問題,我已經在我的測試用例中演示過了。嘗試在我的測試用例中運行代碼,看看你得到了什麼樣的輸出;我認爲這會對發生的事情有所啓發。 –

+0

非常感謝!原來我做錯了,因爲編譯器沒有足夠的參數,所以我傳遞了第三個參數'0'到'cudaMallocManaged'。我不認爲這是相關的,所以我把它放在了問題之外。它需要的是'cudaMemAttachGlobal'或'cudaMemAttachHost'作爲一個非常善良單獨指出在freenode /#CUDA。 –

回答

2

在評論一些對話框後,似乎該OP公司發佈的代碼有沒有問題,我是能夠成功地編譯和運行圍繞代碼構建這個測試用例,等於是OP:

$ cat t1005.cu 
#include <iostream> 

struct Thing { 
    bool is_solid; 
    double matrix[9]; 
}; 

int main(){ 

    Thing *things; 
    int num_of_things = 100; 
    cudaError_t ret = cudaMallocManaged((void **)&things, num_of_things * sizeof(Thing)); 
    if (ret != cudaSuccess) { 
    std::cout << cudaGetErrorString(ret) << std::endl; 
    return 1;} 
    else { 
    things[10].is_solid = true; 
    std::cout << "Success!" << std::endl; 
    return 0;} 
} 
$ nvcc -arch=sm_30 -o t1005 t1005.cu 
$ ./t1005 
Success! 
$ 

對於這個問題:

這樣做是否最好的做法,而不是傳遞一個num_of_things大的數組的單個結構?

是的,這是一個明智的做法,無論是否使用託管內存都可用。可以使用單個cudaMemcpy調用(例如,如果未使用託管內存)以簡單方式將不包含嵌入指針的其他任何結構的數組轉移到GPU。

解決對第3(flags)參數的問題cudaMallocManaged

  1. 如果指定了它,它是不正確的傳遞零(儘管OP公司發佈的代碼沒有給出這方面的證據。)你應該使用一個the documented choices
  2. 如果未指定,則此參數仍然有效,並提供缺省參數cudaMemAttachGlobal。這可以通過查看cuda_runtime.h文件或僅僅編譯/運行上面的測試代碼來確認。這一點似乎是文檔中的疏忽,我在NVIDIA提交了一個內部問題來看看這個問題。因此,有關這方面的文檔可能會在未來發生變化。

最後,proper cuda error checking總是爲了您有一個CUDA代碼的麻煩任何時間,使用這種可以透露這是由任何錯誤的一些情況。 OP在代碼註釋中報告的seg故障幾乎可以肯定是由於cudaMallocManaged調用失敗(可能是因爲零參數提供不正確),因此所述指針(things)沒有實際分配。隨後使用該指針會導致seg錯誤。我的測試代碼演示瞭如何避免seg故障,即使cudaMallocManaged調用由於某種原因而失敗,並且密鑰是正確的錯誤檢查。