Question

I have this following function to test out thrust but it doesn't compile. It appears my predicate is not valid and my knowledge of C/C++ is not strong enough to know what I need to do correct the compilation issue. Please could someone explain what's going on here and how I can fix it.

void filter(device_vector<int>& x, 
                device_vector<int>& y,
                thrust::unary_function<int,bool> f) {

    thrust::copy_if(x.begin(), x.end(), y.end(), f);
}


nvcc -o test test.cu -O2
/usr/lib/nvidia-cuda-toolkit/include/thrust/detail/internal_functional.h(102): error: call of an object of a class type without appropriate operator() or conversion functions to pointer-to-function type
          detected during:
            instantiation of "__nv_bool thrust::detail::predicate_to_integral<Predicate, IntegralType>::operator()(const T &) [with Predicate=thrust::unary_function<__nv_bool, int>, IntegralType=std::ptrdiff_t, T=int]" 
/usr/lib/nvidia-cuda-toolkit/include/thrust/detail/function.h(187): here
            instantiation of "Result thrust::detail::host_device_function<Function, Result>::operator()(const Argument &) const [with Function=thrust::detail::predicate_to_integral<thrust::unary_function<__nv_bool, int>, std::ptrdiff_t>, Result=std::ptrdiff_t, Argument=thrust::device_reference<int>]" 
/usr/lib/nvidia-cuda-toolkit/include/thrust/iterator/transform_iterator.h(306): here
            instantiation of "thrust::detail::transform_iterator_base<AdaptableUnaryFunction, Iterator, Reference, Value>::type::reference thrust::transform_iterator<AdaptableUnaryFunction, Iterator, Reference, Value>::dereference() const [with AdaptableUnaryFunction=thrust::detail::predicate_to_integral<thrust::unary_function<__nv_bool, int>, std::ptrdiff_t>, Iterator=thrust::detail::normal_iterator<thrust::device_ptr<int>>, Reference=std::ptrdiff_t, Value=thrust::use_default]" 
/usr/lib/nvidia-cuda-toolkit/include/thrust/iterator/iterator_facade.h(128): here
            instantiation of "Facade::reference thrust::iterator_core_access::dereference(const Facade &) [with Facade=thrust::transform_iterator<thrust::detail::predicate_to_integral<thrust::unary_function<__nv_bool, int>, std::ptrdiff_t>, thrust::detail::normal_iterator<thrust::device_ptr<int>>, std::ptrdiff_t, thrust::use_default>]" 
/usr/lib/nvidia-cuda-toolkit/include/thrust/iterator/iterator_facade.h(305): here
Was it helpful?

Solution

Let's look at some reference first:

The function object pred shall not apply any non-constant function through the dereferenced iterator. This function object may be a pointer to function or an object of a type with an appropriate function call operator.

From "Predicate".

Thus, you shouldn't limit the choices of the caller to unary_function. In a case like this, any object, function, whatever that can be used in the context of copy_if should be allowed to pass. Actually, in vanilla C++ unary_function is deprecated (in favor of std::function, which shouldn't be used here anyway for exactly the same reasons).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top