Thrust reduce with tuple accumulator

耗尽温柔 提交于 2021-02-10 06:18:27

问题


I want to use thrust::reduce on a thrust::host_vector of thrust::tuple<double,double>. Because there is no predefined thrust::plus<thrust::tuple<double,double>> I wrote my own and used the variant of thrust::reduce with four arguments.

Since I'm a good citizen I put my custom version of plus in my own namespace where I left the primary template simply undefined and specialized it for thrust::tuple<T...>.

#include <iostream>
#include <tuple>

#include <thrust/host_vector.h>
#include <thrust/reduce.h>
#include <thrust/tuple.h>

namespace thrust_ext {

namespace detail {

// https://stackoverflow.com/a/24481400
template <size_t ...I>
struct index_sequence {};

template <size_t N, size_t ...I>
struct make_index_sequence : public make_index_sequence<N - 1, N - 1, I...> {};

template <size_t ...I>
struct make_index_sequence<0, I...> : public index_sequence<I...> {};

template < typename... T, size_t... I >
__host__ __device__ thrust::tuple<T...> plus(thrust::tuple<T...> const &lhs,
                                             thrust::tuple<T...> const &rhs,
                                             index_sequence<I...>) {
    return {thrust::get<I>(lhs) + thrust::get<I>(rhs) ...};
}

} // namespace detail

template < typename T >
struct plus;

template < typename... T >
struct plus < thrust::tuple<T...> > {
    __host__ __device__ thrust::tuple<T...> operator()(thrust::tuple<T...> const &lhs,
                                                       thrust::tuple<T...> const &rhs) const {
        return detail::plus(lhs,rhs,detail::make_index_sequence<sizeof...(T)>{});
    }
};

} //namespace thrust_ext

int main() {
    thrust::host_vector<thrust::tuple<double,double>> v(10, thrust::make_tuple(1.0,2.0));

    auto r = thrust::reduce(v.begin(), v.end(),
                            thrust::make_tuple(0.0,0.0),
                            thrust_ext::plus<thrust::tuple<double,double>>{});

    std::cout << thrust::get<0>(r) << ' ' << thrust::get<1>(r) << '\n';
}

However, this does not compile. The error message is horribly long, see this Gist. The error message indicates that the problem is in some implementation detail of thrust::reduce. Also, if I substitute thrust::tuple with std::tuple it compiles and runs as expected.

I'm using Thrust 1.8.1 with Clang 6.


回答1:


As you can see in your error message, thrust::tuple<double,double> is actually thrust::tuple<double, double, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type>

This is a C++03-style "variadic template" based on default template arguments, which means that sizeof...(T) will count all the null_types and produce the wrong size (always 10).

You'll need to use thrust::tuple_size to retrieve the actual size.



来源:https://stackoverflow.com/questions/48981446/thrust-reduce-with-tuple-accumulator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!