использование шаблона в тяге для переключения между политиками выполнения - PullRequest
0 голосов
/ 06 марта 2020

У меня есть шаблонный код, в котором я хочу выбирать между политиками выполнения cuda или omp при вызове алгоритмов Thrust. Похоже, что компилятор не определяет автоматически соответствующую политику на основе контейнера. Я думаю, что правильный способ выбора политики (без использования везде, где бы то ни было) - написать обертку вокруг алгоритмов тяги с целочисленным параметром шаблона. Вот пример минимального кода для thrust :: transform, и он не компилируется. Однако подобная оболочка для thrust :: for_each компилируется без проблем. Что мне здесь не хватает?

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

}

1 Ответ

1 голос
/ 07 марта 2020

Исправление - передавать итераторы и функторы по значению. Если мы хотим sh передать их по ссылке, мы должны объявить, что они не изменены, используя ключевое слово const, т.е.

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

или

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