3

整数の 2 つの配列がdmap ありdflag 、同じ長さのデバイス上にあり、それらをスラスト デバイス ポインターでラップしましたdmaptdflagt

dmap 配列に値が -1 の要素がいくつかあります。これらの -1 と対応する値を dflag 配列から削除したいと考えています。

これを行うために remove_if 関数を使用していますが、この呼び出しの戻り値が何であるか、またはこの戻り値を使用して get を取得する方法がわかりません。

reduce_by_key(これらの縮小された配列を、 dflagt がキーとして使用される関数に渡したいと思います。)

削減を行うために次の呼び出しを使用しています。dflag戻り値を変数に格納し、それを使用して個々の配列をアドレス指定する方法を教えてください。dmap

thrust::remove_if( 
    thrust::make_zip_iterator(thrust::make_tuple(dmapt, dflagt)), 
    thrust::make_zip_iterator(thrust::make_tuple(dmapt+numindices, dflagt+numindices)), 
    minus_one_equality_test() 
); 

ここで、上で使用された述語ファンクターは次のように定義されます

struct minus_one_equality_test
{ 
    typedef typename thrust::tuple<int,int> Tuple; 
    __host__ __device__ 
    bool operator()(const Tuple& a ) 
    { 
        return  thrust::get<0>(a) ==  (-1); 
    } 
} 
4

1 に答える 1

6

戻り値は、remove_if 呼び出し中にファンクターが true を返した一連のタプルの新しい終了を示す zip_iterator です。基になる配列の新しい終了反復子にアクセスするには、zip_iterator からタプル反復子を取得する必要があります。そのタプルの内容は、zip_iterator を構築するために使用した元の配列の新しい終了イテレータです。コードよりも言葉の方がはるかに複雑です。

#include <thrust/tuple.h>
#include <thrust/device_vector.h>
#include <thrust/device_ptr.h>
#include <thrust/remove.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/copy.h>

#include <iostream>

struct minus_one_equality_test
{ 
    typedef thrust::tuple<int,int> Tuple; 
    __host__ __device__ 
    bool operator()(const Tuple& a ) 
    { 
        return  thrust::get<0>(a) ==  (-1); 
    }; 
}; 


int main(void)
{
    const int numindices = 10;

    int mapt[numindices] = { 1, 2, -1, 4, 5, -1, 7, 8, -1, 10 };
    int flagt[numindices] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

    thrust::device_vector<int> vmapt(10);
    thrust::device_vector<int> vflagt(10);

    thrust::copy(mapt, mapt+numindices, vmapt.begin());
    thrust::copy(flagt, flagt+numindices, vflagt.begin());

    thrust::device_ptr<int> dmapt = vmapt.data();
    thrust::device_ptr<int> dflagt = vflagt.data();

    typedef thrust::device_vector< int >::iterator  VIt;
    typedef thrust::tuple< VIt, VIt > TupleIt;
    typedef thrust::zip_iterator< TupleIt >  ZipIt;

    ZipIt Zend = thrust::remove_if(  
        thrust::make_zip_iterator(thrust::make_tuple(dmapt, dflagt)), 
        thrust::make_zip_iterator(thrust::make_tuple(dmapt+numindices, dflagt+numindices)), 
        minus_one_equality_test() 
    ); 

    TupleIt Tend = Zend.get_iterator_tuple();
    VIt vmapt_end = thrust::get<0>(Tend);

    for(VIt x = vmapt.begin(); x != vmapt_end; x++) {
        std::cout << *x << std::endl;
    }

    return 0;
}

これをコンパイルして実行すると、次のように表示されます。

$ nvcc -arch=sm_12 remove_if.cu 
$ ./a.out
1
2
4
5
7
8
10

この例では、タプルの最初の要素の短縮されたコンテンツのみを「取得」します。2 番目の要素は同じ方法でアクセスされます。ベクトルの新しい終点を示す反復子は ですthrust::get<1>(Tend)

于 2012-09-04T20:28:04.757 に答える