как рассчитать среднее значение из массива int2 с помощью Thrust - PullRequest
5 голосов
/ 20 февраля 2012

Я пытаюсь вычислить среднее значение определенного массива, который содержит точки (x, y).
Можно ли использовать тягу, чтобы найти среднюю точку, представленную как точка (x, y)? я мог бы также представить массив как thrust::device_vector<int>, когда каждая ячейка содержит абсолютную позицию точки, что означает i*numColumns + j, хотя я не уверен, что среднее число представляет среднюю ячейку.
Спасибо!

Ответы [ 2 ]

8 голосов
/ 21 февраля 2012
#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 голосов
/ 21 февраля 2012

Ответ Кевемана верен, я просто хочу добавить полезный совет, который требует кода, поэтому я выложу его здесь, а не в комментариях.

Thrust 1.5 добавляет лямбда-заполнители, которые могут сделать подход @ keveman еще проще. Вместо функтора просто определите operator+ для int2, а затем замените создание экземпляра функтора на выражение-заполнитель _1 + _2 lambda. Вы также можете заменить явное объявление init вызовом make_int2() (предоставленным CUDA). Примечание: int2 operator+ определено в заголовке «vector_math.h» SDK-примера кода CUDA, но я опишу его ниже, чтобы прояснить его (поскольку этот файл не является стандартной частью 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;
}
...