0

I have a device_vector A. I have a Map M. I want to erase the elements of A using Map M. I try the following way but it gives compilation error "no instance of overloaded function..."

#include <thrust/sequence.h>
#include <thrust/execution_policy.h>
#include <thrust/iterator/permutation_iterator.h>
#include <thrust/fill.h>

void erase_value_using_map( thrust::device_vector<int>& A, thrust::device_vector<int> Map)
{

A.erase(thrust::make_permutation_iterator(A.begin(), Map.begin()),
        thrust::make_permutation_iterator(A.begin(), Map.end()));

}

int main(int argc, char * argv[])
{
thrust::device_vector<int> A(20);
thrust::sequence(thrust::device, A.begin(), A.end(),0);  // x components of the 'A' vectors

thrust::device_vector<int> Map(10);
Map[0]=2;Map[1]=4;Map[2]=8;Map[3]=10;Map[4]=11;Map[5]=13;Map[6]=15;Map[7]=17;Map[8]=19;Map[9]=6;

erase_value_using_map(A, Map);

return 0;
}

Error message:

error: no instance of overloaded function "thrust::device_vector<T, Alloc>::erase [with T=int, Alloc=thrust::device_malloc_allocator<int>]" matches the argument list
            argument types are: (thrust::permutation_iterator<thrust::detail::normal_iterator<thrust::device_ptr<int>>, thrust::detail::normal_iterator<thrust::device_ptr<int>>>, thrust::permutation_iterator<thrust::detail::normal_iterator<thrust::device_ptr<int>>, thrust::detail::normal_iterator<thrust::device_ptr<int>>>)
            object type is: thrust::device_vector<int, thrust::device_malloc_allocator<int>>
user27665
  • 673
  • 7
  • 27
  • 1
    It obviously isn't supported, and makes no sense even if it compiled. A permutation iterator is a construct whose values, when dereferenced, return values from a source vector in a prescribed order. But it is illogical to imagine that the iterator values are valid iterators in the source vector. Further, your attempt at a begin/end iterator are clearly broken. The semantics of a permutation iterator are clearly described in the documentation and this is obvious not a use case for it – talonmies Dec 17 '18 at 09:13
  • Then how can I selectively delete some members of a device_vector? It has to use erase, but some other algorithm is needed. Any hints plz? (without using a separate device_vector) – user27665 Dec 17 '18 at 10:10
  • I doubt there is a way Typically, this would be done as a gather operation (so the complete opposite sense -- copy the values you want, rather than delete the values you don't want) – talonmies Dec 17 '18 at 12:40
  • https://stackoverflow.com/a/17595078/681865 might be another alternative – talonmies Dec 17 '18 at 13:59
  • 1
    Use `thrust::partition` to move the values you want to keep to the beginning of the vector. Then use the vector erase method itself. – Robert Crovella Dec 17 '18 at 14:24

1 Answers1

1

I found solution using gather(as adviced by talonmies) and resize.

#include <thrust/gather.h>
#include <thrust/device_vector.h>
#include <thrust/execution_policy.h>

int main()
{

thrust::device_vector<int> d_values(10);
d_values[0]=0;d_values[1]=10;d_values[2]=20;d_values[3]=30;d_values[4]=40;
d_values[5]=50;d_values[6]=60;d_values[7]=70;d_values[8]=80;d_values[9]=90;

thrust::device_vector<int> d_map(7);
d_map[0]=0;d_map[1]=2;d_map[2]=4;d_map[3]=6;d_map[4]=8;d_map[5]=1;d_map[6]=3;

thrust::device_vector<int> d_output(10);
thrust::gather(thrust::device,
               d_map.begin(), d_map.end(),
               d_values.begin(),
               d_output.begin());

d_output.resize(d_map.size());

return 0;
}
user27665
  • 673
  • 7
  • 27