0

I have a templated code, in which I want to choose between cuda or omp execution policies while calling thrust's algorithms. It seems that the compiler doesn't automatically detect the appropriate policy based on the container. I think a proper way to do select the policy (without using if else everywhere), would be to write a wrapper around thrust's algorithms with an integer template parameter. Here is an example of a minimal code for thrust::transform and it doesn't compile. However a similar wrapper for thrust::for_each compiles without any problem. What am I missing here?

#include <thrust/iterator/counting_iterator.h>
#include<thrust/transform.h>
#include<thrust/execution_policy.h>
#include<thrust/host_vector.h>
#include<thrust/device_vector.h>
#include <thrust/system/omp/execution_policy.h>

#include<iostream>

typedef thrust::device_vector<int> d_vec;
typedef thrust::host_vector<int> h_vec;

template<typename T>
struct myfunc{
    __host__ __device__
    T operator()(const T& i) const {
      return T(2)*i;
    }
};

template<int N, typename InputIter, typename OutputIter, typename Functor>
void transform(InputIter& begin1, InputIter& end1, OutputIter& begin2, Functor& func){
    switch (N){
        case 0:
            thrust::transform(thrust::device, begin1, end1, begin2, func);
            break;
        case 1:
            thrust::transform(thrust::omp::par, begin1, end1, begin2, func);
            break;
    }
}

int main(){
    int n = 4;

    thrust::counting_iterator<int> begin(0);
    thrust::counting_iterator<int> end = begin+n;

    d_vec device_vector(n);
    h_vec host_vector(n);

    transform<0>(begin, end, device_vector.begin(), myfunc<int>());
    transform<1>(begin, end, host_vector.begin(), myfunc<int>());

}

2
  • Can you post the compilation error message? Commented Mar 6, 2020 at 22:12
  • error: no instance of function template "transform" matches the argument list argument types are: (thrust::counting_iterator<int, thrust::use_default, thrust::use_default, thrust::use_default>, thrust::counting_iterator<int, thrust::use_default, thrust::use_default, thrust::use_default>, thrust::detail::normal_iterator<thrust::device_ptr<int>>, myfunc<int>) Commented Mar 7, 2020 at 17:09

1 Answer 1

1

The fix is to pass iterators and functors by value. If we wish to pass them by reference we have to declare that they are not modified by using the keyword const i.e.

void transform(InputIter begin1, InputIter end1, OutputIter begin2, Functor func)

or

void transform(const InputIter& begin1, const InputIter& end1, const OutputIter& begin2, const Functor& func)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.