cuda thrust - transform_reduce同时从同一数据集构建的几个向量

时间:2016-04-06 12:58:44

标签: cuda transform reduce thrust

我正在尝试计算几个参数,这些参数取决于使用cuda /推力的系统的所有距离。我在https://stackoverflow.com/a/29323246/3535786(见下文)中看到了一个例子,它计算了修改后的距离并总结了所有内容。我不想使用距离来计算单个值,而是将它们用于多个操作(例如距离的不同指数)。结果应该是数组/向量,其中每个元素表示距离的不同修改(总和(sqrt(距离)),总和(距离),总和(距离^ 2)等)的总和。有人知道如何实现这一目标吗?

#include <thrust/device_vector.h>
#include <thrust/generate.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/transform_reduce.h>
#include <thrust/random.h>
#include <math.h>
#include <iostream>
#include <stdio.h>
#include <stdint.h>

#define PRINT_DEBUG

typedef float Float;

// define a 2d point pair
typedef thrust::tuple<Float, Float> Point;

// return a random Point in [0,1)^2
Point make_point(void)
{
  static thrust::default_random_engine rng(12345);
  static thrust::uniform_real_distribution<Float> dist(0.0, 1.0);
  Float x = dist(rng);
  Float y = dist(rng);
  return Point(x,y);
}


struct sqrt_dis_new
{
  typedef thrust::device_ptr<Point> DevPtr;

  DevPtr points;
  const uint64_t n;

  __host__
  sqrt_dis_new(uint64_t n, DevPtr p) : n(n), points(p)
  {
  }

  __device__ 
  Float operator()(uint64_t k) const
  {
    // calculate indices in triangular matrix
    const uint64_t i = n - 2 - floor(sqrt((double)(-8*k + 4*n*(n-1)-7))/2.0 - 0.5);
    const uint64_t j = k + i + 1 - n*(n-1)/2 + (n-i)*((n-i)-1)/2;

    #ifdef PRINT_DEBUG
      printf("%llu -> (%llu, %llu)\n", k,i,j);
    #endif

    const Point& p1 = *(points.get()+j);
    const Point& p2 = *(points.get()+i);

    const Float xm = thrust::get<0>(p1)-thrust::get<0>(p2);
    const Float ym = thrust::get<1>(p1)-thrust::get<1>(p2);

    return 1.0/(-1.0 * sqrt(xm*xm + ym*ym));
  }
};


int main()
{
  const uint64_t N = 4;

  // allocate some random points in the unit square on the host
  thrust::host_vector<Point> h_points(N);
  thrust::generate(h_points.begin(), h_points.end(), make_point);

  // transfer to device
  thrust::device_vector<Point> d_points = h_points;

  const uint64_t count = (N-1)*N/2;

  std::cout << count << std::endl;


  thrust::plus<Float> binary_op;
  const Float init = 0.0;

  Float result =   thrust::transform_reduce(thrust::make_counting_iterator((uint64_t)0),
                                       thrust::make_counting_iterator(count),
                                        sqrt_dis_new(N, d_points.data()),
                                        init,
                                        binary_op);

  std::cout.precision(10);  
  std::cout<<"result: " << result << std::endl;

  return 0; 
}

修改以澄清问题:

上面的代码创建了前N个随机2D点p(此处N = 4),然后保存在设备上。

Points = { p1, p2, p3, p4};

然后它计算(thrust :: transform)所有可能的距离(d)。在这些情况下,有6种可能的距离(一般(N-1)* N / 2种可能性):

Distances = {d1, d2, d3, d4, d5, d6};

每个距离用作相同函数f(d)的输入。在这种情况下,f(d)是-1 / d。最后,所有结果都加起来(推力::减少)。因此,结果是一个数字取决于所有距离。

Result = f(d1) + f(d2) + f(d3) + f(d4) + f(d5) + f(d6);

而不是那样,我希望输出是一个矢量或数组,它包含应用于距离的不同函数的结果r。

Result = {r1, r2, r3, r4 ... } with
r1 =  f(d1) + f(d2) + f(d3) + f(d4) + f(d5) + f(d6);
r2 =  g(d1) + g(d2) + g(d3) + g(d4) + g(d5) + g(d6);
r3 =  h(d1) + h(d2) + h(d3) + h(d4) + h(d5) + h(d6);

0 个答案:

没有答案