2012-09-04 2 views
3

내가 같은 길이 의 장치에 정수 dmapdflag의 두 배열을 가지고 있고 추력 장치 포인터로 포장 한 dmaptdflagt추력의 반환 값의 종류 :: remove_if

있습니다 값이 -1 인 dmap 배열의 일부 요소 이 -1과 해당 값을 에서 dflag 배열로 제거하고 싶습니다.

이 작업을 수행하려면 remove_if 함수를 사용하고 있지만이 호출의 반환 값 또는 반환 값을 얻으려면 반환 값을 알아낼 수 없습니다.

는 (나는 dflagt이 열쇠로 사용되는 reduce_by_key 기능 이러한 감소 배열을 전달하려는.) 내가 감소를 수행하는 다음 호출을 사용하고

. 제가 변수에 반환 값을 저장할 수있는 방법을 알고 하자 개별 배열을 해결하기 위해 사용하십시오 위에서 사용 된 술어 펑터가

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); 
    } 
} 

답변

6

으로 정의된다 dflagdmap

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() 
); 

반환 값은 zip_iterator입니다.이 zip_iterator는 remove_if 호출 중에 functor가 true를 반환 한 튜플 시퀀스의 새로운 끝을 표시합니다. 기본 배열의 새로운 end 반복기에 액세스하려면 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 

을 tuple의 첫 번째 요소의 내용이 단락 된 경우 두 번째 항목은 동일한 방식으로 액세스됩니다. 벡터의 새 끝을 표시하는 반복자는 thrust::get<1>(Tend)입니다.