我正在尝试计算几个参数,这些参数取决于使用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);