簡體   English   中英

如何有效地將數據從 2D 主機陣列(帶填充)復制到 1D 設備陣列並刪除 CUDA 中的原始填充?

[英]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.

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