2013-10-02 325 views
1

我正在使用CUDA,但似乎我無法將STL向量作爲參數傳遞,因此我需要將這些向量矩陣轉換爲動態數組。如何將stl向量矩陣轉換爲2d陣列矩陣(或1d陣列)

std::vector< std::vector<float> > some_matrix;float **f;

我試圖用memcpy函數,但由於某種原因,如期望的那樣,如果我嘗試複製內容的簡化版,工作,有的在原有的矩陣值的改變垃圾。 我避免使用循環,因爲那會降低效率。

+0

你以前是怎麼做的?您可以顯示您的代碼,並讓其他人幫助修復這些錯誤(如果有的話)。 – kangshiyin

+0

std :: vector僅供主機使用。我會推薦使用推力庫。 – JackOLantern

+0

好吧,我要試一試。 –

回答

2

正如您發現的那樣,不可能將std::vector傳遞給CUDA內核並在內核代碼中使用它,並且不可能將您可能構建的簡單的主機指針數組傳遞給也可以將CUDA內核編號爲std::vector< std::vector<float> >

你需要做的是首先創建一個設備指針的主機數組(這樣你複製到設備的每一行就有一個條目),並且複製指向設備的指針數組。這意味着您需要爲複製到設備的每個矩陣行或列調用cudaMalloc和cudaMemcpy調用。你可以做這樣的:

std::vector< std::vector<float> > some_matrix; 

float** f = new float*[some_matrix.size()]; 
for (int i = 0; i < some_matrix.size(); ++i) { 
    size_t szp = sizeof(float) * some_matrix[i].size(); 
    float* p; 
    cudaMalloc((void **)&p, sz); 
    cudaMemcpy(p, &some_matrix[i][0], szp, cudaMemcpyHostToDevice); 
    f[i] = p; 
} 

float** f_dev; 
size_t szf = sizeof(float*) * some_matrix.size(); 
cudaMalloc((void **)&f_dev, szf); 
cudaMemcpy(f_dev, f, szf, cudaMemcpyHostToDevice); 

[免責聲明:寫在瀏覽器中,從來沒有編譯或測試,使用風險自擔]

在此之後f_dev可以安全地傳遞到CUDA內核和所使用的設備。

希望你能從上面的代碼中看到爲什麼這種數據結構在GPU上不太容易使用。有很多API開銷來設置並傳輸它,然後在設備上存在延遲懲罰,因爲要將值提取到內存所需的雙指針間接尋址。

對於源數據不是「鋸齒狀數組」的情況(即矩陣中所有行都是相同長度的情況),存儲在線性存儲器中的扁平列主要或行主要數組是更好的解決方案。如果源數組鋸齒狀,請考慮使用類似於CSR或CSC稀疏矩陣格式的結構。這些在設備上並沒有提供太多的性能改進,但是它們減少了主機端API開銷來管理它們。