1
votes

I am trying to partition an array with the thrust library's partition_copy function.

I have seen examples where pointers are passed, but I need to know how many elements are in each partition.

What I have tried is to pass device vectors as the OutputIterator parameters, something like this:

#include <thrust/device_vector.h>
#include <thrust/device_ptr.h>
#include <thrust/partition.h>

struct is_even {
    __host__ __device__ bool operator()(const int &x) {
        return (x % 2) == 0;
    }
};

int N;
int *d_data;
cudaMalloc(&d_data, N*sizeof(int));

//... Some data is put in the d_data array

thrust::device_ptr<int> dptr_data(d_data);

thrust::device_vector<int> out_true(N);
thrust::device_vector<int> out_false(N);

thrust::partition_copy(dptr_data, dptr_data + N, out_true, out_false, is_even());

When I try to compile I get this error:

error: class "thrust::iterator_system<thrust::device_vector<int, thrust::device_allocator<int>>>" has no member "type"
      detected during instantiation of "thrust::pair<OutputIterator1, OutputIterator2> thrust::partition_copy(InputIterator, InputIterator, OutputIterator1, OutputIterator2, Predicate) [with InputIterator=thrust::device_ptr<int>, OutputIterator1=thrust::device_vector<int, thrust::device_allocator<int>>, OutputIterator2=thrust::device_vector<int, thrust::device_allocator<int>>, Predicate=leq]"

So my question is: How can you use either thrust::partition or thrust::partition_copy and know how many elements you ended up with in each partition?

1

1 Answers

5
votes

Your compile error is due to the fact that you are passing vectors instead of iterators here:

thrust::partition_copy(dptr_data, dptr_data + N, out_true, out_false, is_even());
                                                 ^^^^^^^^^^^^^^^^^^^

Instead you should pass iterators based on those containers:

thrust::partition_copy(dptr_data, dptr_data + N, out_true.begin(), out_false.begin(), is_even());

In order to get the lengths of the results, we must use the return value of thrust::partition copy():

Returns A pair p such that p.first is the end of the output range beginning at out_true and p.second is the end of the output range beginning at out_false.

Something like this:

auto r = thrust::partition_copy(dptr_data, dptr_data + N, out_true.begin(), out_false.begin(), is_even());
int length_true = r.first - out_true.begin();
int length_false = r.second - out_false.begin();

Note that a similar method can be used with other thrust algorithms. Those that don't return a tuple will be even easier to work with.

For example:

auto length = (thrust::remove_if(A.begin(), A.end(), ...) - A.begin());