2015-04-21 47 views
1

我有一個數據矩陣,我應該使用GPU(和推力庫儘可能)進行一些細化。到目前爲止,我能夠將數據複製到GPU並編寫我自己的內核函數。現在,基於我的內核函數的輸出結果,我將利用推力庫來進行相同數據矩陣的其他細化,避免從GPU < - > CPU下載並重新上傳數據。推力:訪問使用cudaMallocPitch創建的設備變量

所以,我在使用功能使用cudaMallocPitch所述GPU創建設備變量:

float *d_M; 
size_t pitch; 
cudaStatus = cudaMallocPitch(&d_M, &pitch, sizeof(float)*(N), M+1); 
if (cudaStatus != cudaSuccess) 
{ 
    fprintf(stderr, "cudaMalloc Failed!"); 
    INFO; 
    return CUDA_MALLOC_ERROR; 
} 

這個變量表示與N×M個尺寸+ 1的矩陣。在使用ad-hoc cuda函數對GPU進行一些細化之後,我會使用推力庫對每行的元素進行求和,並將結果放在每行的M + 1列中。

對於這樣的操作,我會使用推力庫。 我的意圖應該是檢索使用cudaMallocPitch創建的原始指針,將其轉換爲thrust :: device_ptr,然後使用推力函數對其進行操作。所以,在代碼:

thrust::device_ptr<float> dd_M = thrust::device_pointer_cast(d_M); 

但是,當我嘗試打印兩個變量的地址,以確保該指針的地址相同:

printf("Address d_M: %p\n", &d_M); 
printf("Address dd_M: %p\n", &dd_M); 

我得到的地址不同的值。我不是我做錯了什麼。對於這樣的操作,我只是按照鏈接Thrust - Memory Management Functions上的推力手冊。

+0

我不相信有這樣做的簡單方法 – talonmies

+0

您將無法使用'cudaMallocPitch'方便地使用推力。改爲使用'cudaMalloc'。 –

+0

好吧,我會嘗試與cudaMalloc。謝謝 – Alek

回答

3

cudaMallocPitch將基本上無法使用推力。這是因爲它創造了一個這樣的分配:

D D D D D D D D D D D D D D X X 
D D D D D D D D D D D D D D X X 
D D D D D D D D D D D D D D X X 
D D D D D D D D D D D D D D X X 
D D D D D D D D D D D D D D X X 
... 

其中D項目代表您的實際數據和X項目代表附加在每一行,讓您的數據額外的空間寬度匹配所需的機器傾斜。

問題是推力沒有這個「未使用」區域的概念,代表X。當數據中存在「未使用」間隙時,沒有方便的方法來告訴推力函數分配線程(並生成適當的,連續的索引)。所以,如果我們把上面的推力矢量:

D D D D D D D D D D D D D D X X D D D D D D D D D D D D D D X X D D ... 

通過矢量散落不能方便的X地區推力算法和索引「跳過」。如果你真的想這樣做,有可能提出一個解決上述映射的thrust::permutation_iterator,但這將會產生與其相關的低效率,這將超過操作音調數據帶來的任何性能好處。

如果您使用cudaMalloc來代替,那麼您的數據將是連續的,這是推測所期望的方式。

+0

感謝您的詳細解答。 – Alek

+1

我在想,使用指針語義的自定義容器類可能是「最簡單」的方法。一個置換迭代器可能不會工作,因爲沒有保證(或要求)分配間距是數組類型大小的整數倍 – talonmies

+0

我同意你關於置換迭代器不是猶太潔食的觀點 - 至少對於非POD類型, t均勻分配到球場(甚至依賴於POD類型的球員不是猶太人)。所以,我在一般情況下並不知道如何去做。 –