如何使用Thrust从int2数组计算平均值

5

我想计算一个包含点(x,y)的数组的平均值。
是否可以使用Thrust找到表示为(x,y)点的平均点?
我也可以将数组表示为thrust :: device_vector<int>,其中每个单元格包含点的绝对位置,即i * numColumns + j,但我不确定平均数是否代表平均单元格。
谢谢!


2
你不能只是为 int2 类型计算定义一个加法运算符(即 a+b={a.x+b.x,a.y+b.y}),然后使用标准缩减方法计算输入的总和,最后通过元素数量进行除法运算吗? - talonmies
如果您使用Thrust 1.5+的lambda占位符(请参见下面我的附加答案),则可以使用运算符。 - harrism
2个回答

8
#include <iostream>
#include <thrust/device_vector.h>
#include <thrust/reduce.h>

struct add_int2 {
  __device__
  int2 operator()(const int2& a, const int2& b) const {
    int2 r;
    r.x = a.x + b.x;
    r.y = a.y + b.y;
    return r;
  }
};

#define N 20

int main()
{
  thrust::host_vector<int2> a(N);
  for (unsigned i=0; i<N; ++i) {
    a[i].x = i;
    a[i].y = i+1;
  }

  thrust::device_vector<int2> b = a;

  int2 init;
  init.x = init.y = 0;

  int2 ave = thrust::reduce(b.begin(), b.end(), init, add_int2());
  ave.x /= N;
  ave.y /= N;

  std::cout << ave.x << " " << ave.y << std::endl;
  return 0;
}

6
Keveman的回答是正确的,我只想补充一个有用的提示,需要代码支持,所以我会在这里放置它,而不是在评论中。
Thrust 1.5添加了lambda占位符,可以使@keveman的方法更加简单。不需要使用functor,只需为int2定义operator+,然后用_1 + _2 lambda占位符表达式替换functor的实例化。您还可以将显式声明的init替换为对make_int2()函数的调用(由CUDA提供)。注意:int2 operator+在CUDA代码示例SDK的“vector_math.h”头文件中定义,但我下面定义它以使其清晰明了(因为该文件不是CUDA的标准部分)。
#include <iostream>
#include <thrust/device_vector.h>
#include <thrust/reduce.h>

using namespace thrust::placeholders;

__device__
int2 operator+(const int2& a, const int2& b) {
  return make_int2(a.x+b.x, a.y+b.y);
}

#define N 20

int main()
{
  thrust::host_vector<int2> a(N);
  for (unsigned i=0; i<N; ++i) {
    a[i].x = i;
    a[i].y = i+1;
  }

  thrust::device_vector<int2> b = a;

  int2 ave = thrust::reduce(b.begin(), b.end(), make_int2(0, 0), _1 + _2);
  ave.x /= N;
  ave.y /= N;

  std::cout << ave.x << " " << ave.y << std::endl;
  return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接