首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >推力: reduce_by_key将zip_iterator(元组)传递给自定义函子以按键检索平均值

推力: reduce_by_key将zip_iterator(元组)传递给自定义函子以按键检索平均值
EN

Stack Overflow用户
提问于 2016-06-17 21:50:16
回答 1查看 1.1K关注 0票数 0

我要做的是通过thrust::reduce_by_key按键求出平均值。我首先使用sort_by_key,这很好地按照reduce_by_key的连续键进行分组。我用this来帮助我走到这一步。但是,我得到了许多我无法理解的错误(这也是我第一次使用reduce_by_key),如果不使用大量临时分配,我想不出更好的方法来做到这一点:(1)按键求值之和,然后按键计数,(2)将两者除以平均值。

代码语言:javascript
运行
复制
input keys:   1,   1,   1,  2,   3,   5,  5,  2
input values: 120, 477, 42, 106, 143, 53, 83, 24

expected output values: 213, 65, 143, 68

我有以下自定义函式:

代码语言:javascript
运行
复制
struct GetAverage
{
    template<typename Tuple>
    __host__ __device__
    int operator()(const Tuple& t)
    {
        //SumByKey / CountByKey
        return thrust::get<0>(t) / thrust::get<1>(t);
    }
};

函子从下面的代码中调用,位于main()

代码语言:javascript
运行
复制
thrust::device_vector<unsigned int> tempKey(8);
thrust::device_vector<unsigned int> tempValue(8);

tempKey[0] = 1;
tempKey[1] = 1;
tempKey[2] = 1;
tempKey[3] = 2;
tempKey[4] = 3;
tempKey[5] = 5;
tempKey[6] = 5;
tempKey[7] = 2;

tempValue[0] = 120;
tempValue[1] = 477;
tempValue[2] = 42;
tempValue[3] = 106;
tempValue[4] = 143;
tempValue[5] = 53;
tempValue[6] = 83;
tempValue[7] = 24;

thrust::sort_by_key(tempKey.begin(), tempKey.end(), tempValue.begin());

thrust::equal_to<int> binary_pred;
thrust::reduce_by_key(
    tempKey.begin(),
    tempKey.end(),
    thrust::make_zip_iterator(
        thrust::make_tuple(
            tempValue.begin(),
            thrust::make_constant_iterator(1)
        )
    ), //values_first; Should go into GetAverage() custom functor as a zipped tuple <tempValue, 1>
    tempKey.begin(), //keys_output; Should be returning the unique keys
    tempValue.begin(), //values_output; Should be returning the average by key 
    binary_pred,
    GetAverage()
);

示例错误:

-no instance of function template "GetAverage::operator()" matches the argument list

-no operator "=" matches these operands

-no suitable conversion function from "InputValueType" to "TemporaryType" exists

-no suitable conversion function from "thrust::detail::tuple_of_iterator_references<thrust::device_reference<int>, int, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type, thrust::null_type>" to "TemporaryType" exists

有谁想过如何解决这个问题吗?还是链接?我阅读了这里使用的所有东西的文档,并尽可能仔细地试图理解它,但没有解决问题。谢谢!

更新

看看埃里克的答案。结合他所说的,这是新的源代码。为元组创建了一个用来处理加号的操作。这段代码唯一没有做的事情就是在reduce_by_key调用之后,应该对结果使用一个thrust::transform,通过将和除以计数来得到平均值。

代码语言:javascript
运行
复制
// --- Defining key tuple type
typedef thrust::tuple<int, int> Tuple;

/* PLUS OPERATOR BETWEEN TUPLES */
struct TuplePlus
{
    __host__ __device__
    Tuple operator ()(const Tuple& lhs, const Tuple& rhs)
    {
        return thrust::make_tuple(
            thrust::get<0>(lhs) + thrust::get<0>(rhs),
            thrust::get<1>(lhs) + thrust::get<1>(rhs)
        );
    }
};

main()内部,我现在有以下内容。

代码语言:javascript
运行
复制
thrust::equal_to<int> binary_pred;
thrust::reduce_by_key(
    tempKey.begin(),
    tempKey.end(),
    thrust::make_zip_iterator(
        thrust::make_tuple(
            tempValue.begin(),
            thrust::make_constant_iterator(1)
        )
    ), //values_first; goes in as a zipped up tuple <value, 1>
    tempKey.begin(), //keys_output
    thrust::make_zip_iterator(
        thrust::make_tuple(
            tempValue.begin(),
            tempCount.begin()
        )
    ), //values_output; ZipIterator<Sum, Count> by key
    binary_pred,
    TuplePlus()
);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-17 22:40:55

有两个问题。

元组序列约简的结果应该是元组,而不是int。根据文件

reductions.html#ga633d78d4cb2650624ec354c9abd0c97f

最后一个参数binary_op应该是类型

BinaryFunction是二元函数的模型,二进制函数的result_type可转换为OutputIterator2 2的value_type。

这意味着你的减缩手术应该是

代码语言:javascript
运行
复制
struct GetSum
{
  template<typename Tuple>
  __host__ __device__
  Tuple operator()(const Tuple& a, construction Tuple& b)
  {
    ...
  }
}

另一方面,在缩减阶段,你只能计算和,而不能有效地计算平均值。这意味着您的values_output也应该是一个具有与values_first相同类型的zip迭代器。

OutputIterator2是输出迭代器的模型,InputIterator2 2的value_type可转换为OutputIterator2 2的value_type。

因此,您需要两个结果数组,一个用于按键和,另一个用于按键计数。应该将它们拉链在一起,并用作values_output

然后,您需要另一个thrust::transform来计算最终结果--按键计算平均值。

您还可以尝试@RobertCrovella提出的方法,它使用单个thrust::reduce_by_key来计算平均值。

key() as a function of two reduced vectors

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37890860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档