簡體   English   中英

CUDA Zeropadding 3D 矩陣

[英]CUDA Zeropadding 3D matrix

我有一個大小為 100x200x800 的 integer 矩陣,它以平面 100*200*800 向量的形式存儲在主機上,即,我有

int* h_data = (int*)malloc(sizeof(int)*100*200*800);

在設備 (GPU) 上,我想用零填充每個維度,以便獲得大小為 128x256x1024 的矩陣,分配如下:

int *d_data;
cudaMalloc((void**)&d_data, sizeof(int)*128*256*1024);

獲得零填充矩陣的最佳方法是什么? 我有兩個想法:

  1. 遍歷主機上的各個子矩陣並將它們直接復制到設備上的正確位置。
    • 這種方法需要多次cudaMemcpy調用,因此可能非常慢
  2. 在設備上,為 100x200x800 矩陣和 128x256x1024 矩陣分配 memory 並寫入 kernel 將樣本復制到正確的 memory 空間
    • 這種方法可能要快得多,但需要為設備上的兩個矩陣分配 memory

有沒有類似MATLAB的三維矩陣索引的可能? 在 MATLAB 中,我可以簡單地執行以下操作:

h_data = rand(100, 200, 800);
d_data = zeros(128, 256, 1024);
d_data(1:100, 1:200, 1:800) = h_data;

或者,如果我使用cudaMemcpy(d_data, h_data, sizeof(int)*100*200*800, cudaMemcpyHostToDevice); , 是否可以就地重新排序數據,這樣我就不必為第二個矩陣分配 memory ,可能使用cudaMemcpy3DcudaMemset3D

正如您假設的那樣,您可以使用cudaMemcpy3D進行此操作。 基本上:

  1. 正常分配您的設備陣列
  2. 使用cudaMemset將其cudaMemset
  3. 使用cudaMemcpy3D為選定的子陣列執行從主機到設備的線性內存復制,從主機源到設備目標陣列。

cudaMemcpy3D API 有點巴洛克式的、神秘的文檔,並且有一些適合初學者的常見陷阱。 基本上,線性內存傳輸需要一個指向源和目標的傾斜指針,以及一個表示傳輸大小的范圍。 令人困惑的部分是參數含義的變化取決於源和/或目標內存是 CUDA 數組還是傾斜線性內存。 在代碼中,你會想要這樣的東西:

int hw = 100, hh = 200, hd = 800; 
size_t hpitch = hw * sizeof(int);
int* h_data = (int*)malloc(hpitch * hh * hd);

int dw = 128, dh = 256, dd = 1024;
size_t dpitch = dw * sizeof(int);
int *d_data; 
cudaMalloc((void**)&d_data, dpitch * dh * dd);
cudaMemset(d_data, 0, dpitch * dh * dd);

cudaPitchedPtr src = make_cudaPitchedPtr(h_data, hpitch, hw, hh);    ​
​cudaPitchedPtr dst = make_cudaPitchedPtr(d_data, dpitch, dw, dh);

cudaExtent copyext = make_cudaExtent(hpitch, hh, hd);

​‎cudaMemcpy3DParms copyparms = {0};
​copyparms.srcPtr = src;
​copyparms.dstPtr = dest;
copyparms.extent = copyext;
copyparms.kind = cudaMemcpyHostToDevice;

cudaMemcpy3D(&copyparms);

【注:全部在瀏覽器中完成,切勿編譯或運行使用風險自負】

有沒有類似於 MATLAB 的三維矩陣索引的可能性?

這可以使用更高級別的庫,例如libtorch 例如,

    d_data(1:100, 1:200, 1:800) = h_data

libtorch變得像

    d_data.index_put_({Slice(0, 100), Slice(0, 200), Slice(0, 800)}, h_data)

(MATLAB 使用基於 1 的索引)。

可能還有其他 C++ 庫可以做到這一點,但這是我所知道的。


另一方面,如果創建一個 0 填充的 3D 數組是您唯一的目標,那么添加對另一個庫的依賴可能不值得。 這個狹窄的目標可以通過主機上的三重循環或設備上的等效內核來實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM