【问题标题】:Call of boost::compute::sort() with zip iterators delivers build errors使用 zip 迭代器调用 boost::compute::sort() 会导致构建错误
【发布时间】:2017-04-01 10:00:12
【问题描述】:

我在构建使用 Boost.Compute 库的程序时遇到问题。 我使用了两个zip_iterators,每个都由一个包含两个浮点迭代器的元组组成 使用boost::compute::sort() 函数对两个浮点向量进行排序。 我的代码(compute::vectors 之前都填充了浮点值):

typedef compute::vector<float>::iterator Float_Iterator;
typedef boost::tuple<Float_Iterator, Float_Iterator> Sort_Tuple;
typedef compute::zip_iterator<Sort_Tuple> Sort_Iterator;

Sort_Iterator first_sort = compute::make_zip_iterator
(boost::make_tuple(d_x.begin(), d_y.begin()));
Sort_Iterator last_sort = compute::make_zip_iterator
(boost::make_tuple(d_x.end(), d_y.end()));

BOOST_COMPUTE_FUNCTION(bool, compare, (const boost::tuple<float, float> p1, const boost::tuple<float, float> p2),
{
    return boost_tuple_get(p1, 0) < boost_tuple_get(p2, 0);
}
);

compute::sort(first_sort, last_sort, compare, queue);

编译时,我收到:

error C2782: 'void   boost::compute::detail::dispatch_merge_blocks(Iterator,Iterator,Compare,size_t,c onst size_t,const size_t,const size_t,boost::compute::command_queue &)' :   **template parameter 'Iterator' is ambiguous**
          c:\local\boost_1_62_0\boost\compute\algorithm\detail\merge_sort_on_cpu.hpp(129)     : see declaration of 'boost::compute::detail::dispatch_merge_blocks'
          could be **'Sort_Iterator'
 or       'boost::compute::buffer_iterator<T>'**
          with
          [
              T=value_type
          ]

正如您在我的代码中看到的,我使用之前声明的两个Sort_Iterators 调用该函数。两个参数具有相同的类型,那么编译器为什么要假设任何歧义呢?我不明白。

但是,如果我尝试显式类型转换函数参数,例如

compute::sort((Sort_Iterator)first_sort, (Sort_Iterator)last_sort, compare,    queue);

错误信息后半部分改为:

could be **'boost::compute::zip_iterator<Sort_Tuple>'
or       'boost::compute::buffer_iterator<T>'**
with
[
     T=value_type
]

【问题讨论】:

    标签: c++ boost boost-compute


    【解决方案1】:

    即使您的代码已编译,您也无法对 zip 迭代器进行排序:它们是只读的。您必须改为对元组向量进行排序。

    关于Iterator 的歧义,编译器不是指 正在传递的类型,而是指调用链中更深层次的某个函数的Iterator

    template<class Iterator, class Compare>
    inline void dispatch_merge_blocks(Iterator first, Iterator result, /* ... /);
    

    这样称呼:

    dispatch_merge_blocks(first, temp.begin(), /* ... */);
    dispatch_merge_blocks(temp.begin(), first, /* ... */);
    

    这里,first 是您传入的Iterator,类型为:

    zip_iterator<tuple<buffer_iterator<float>, buffer_iterator<float>>>
    

    temp.begin() 是……

    typedef typename std::iterator_traits<Iterator>::value_type value_type;
    
    // temporary buffer for merge result
    vector<value_type> temp(count, context);
    

    vector&lt;tuple&lt;float, float&gt;&gt;::iterator(1)。编译器看到同一个模板参数有两种不同的类型,因此推导失败。

    此外,在调用链中进一步出现以下函数:

    template<class Iterator, class Compare>
    inline void merge_blocks(Iterator first, Iterator result, /* ... */)
    {
        // dummy iterator as it's not sort by key
        Iterator dummy;
        merge_blocks(first, dummy, result, dummy, /* ... */);
    }
    

    注意这一行:Iterator dummy;。编译失败是因为zip_iterator没有默认构造函数,所以模板实例化失败,整个编译失败。

    (1):我不完全确定value_type 最终是如何被推导出为tuple&lt;float, float&gt; 的,并且通过层层的模板让我有点头疼,但这是基本上发生了什么。

    【讨论】:

    • 谢谢!但是还有一个问题:为什么传递只读的 zip_iterators 会有问题?我不想让 zip_iterators 排序,而是他们指向的浮点向量(通过 iteratos 构造的元组)。所以 zip_iterators 本身的值不应该在 sort() 期间被改变,不是吗?
    • Boost Compute 中OpenCL codegen for zip iterators is currently implemented 的方式只是阻止分配工作,令人遗憾。我想知道这是否可以解决,费用是多少。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 2017-01-09
    • 2012-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多