![](/img/trans.png)
[英]CUDA: Allocating 1d device memory to copy 2d pointer-to-pointer host array to and from GPU
[英]How to effectively copy data from 2D host array (with padding) to 1D device array and remove the original padding in CUDA?
我在主機上有一個帶有填充的二維列主數組,例如:
|1 4 7|
|2 5 8|
A_h = |3 6 9|
|x x x|
|x x x|
我想將數據復制到設備 memory 作為一維數組:
{1, 2, 3, 4, 5, 6, 7, 8, 9} //preferred
或者
{1, 2, 3, 4, 5, 6, 7, 8, 9, x, x, x, x, x, x}
使用 CUDA 和/或推力實現這一目標的最快和有效方法是什么?
編輯:我按照羅伯特的評論在使用推力時刪除了循環,但代碼只能復制第一列。 如何在不使用循環的情況下使其適用於整個陣列?
thrust::counting_iterator<int> first(0);
thrust::counting_iterator<int> last = first + rows;
thrust::device_vector<real_type> A_d(rows * cols);
thrust::copy(thrust::make_permutation_iterator(A_h, first),
thrust::make_permutation_iterator(A_h, last), A_d.begin());
如果用例只是將較大源的子集復制到不跨步(如此連續)的較小目標中,那么帶有謂詞的條件副本可能是最簡單的方法(我猜收集也可以)。 像這樣的東西:
#include <vector>
#include <iostream>
#include <thrust/device_vector.h>
#include <thrust/copy.h>
#include <thrust/iterator/counting_iterator.h>
struct indexer
{
int lda0;
int lda1;
indexer() = default;
__device__ __host__
indexer(int l0, int l1) : lda0(l0), lda1(l1) {};
__device__ __host__
bool operator()(int x) {
int r = x % lda0;
return (r < lda1);
};
};
int main()
{
const int M0 = 5, N=3;
const int M1 = 3;
const int len1 = M1*N;
{
std::vector<int> data{ 1, 2, 3, -1, -1, 4, 5, 6, -1, -1, 7, 8, 9, -1, -1 };
thrust::device_vector<int> ddata = data;
thrust::device_vector<int> doutput(len1);
indexer pred(M0, M1);
thrust::counting_iterator<int> idx(0);
thrust::copy_if(ddata.begin(), ddata.end(), idx, doutput.begin(), pred);
for(int i=0; i<len1; i++) {
int val = doutput[i];
std::cout << i << " " << val << std::endl;
}
}
return 0;
}
這里的謂詞只會 select 的每個列的一個子集,並將它們復制到一個連續的 output 范圍內:
$ nvcc -arch=sm_52 -std=c++11 -o subset subset.cu
$ ./subset
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
如果您想要更通用的東西(如此跨步的輸入和輸出),那么您可能可以對scatter_if
使用相同的想法。 如評論中所述,這可以通過cudaMemcpy2D
或副本 kernel 輕松完成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.