transform - cuda thrust - transform_reduce several vectors build from the same data set at the same time -
i trying calculate several parameters depend on distances of system using cuda/thrust. have seen example in https://stackoverflow.com/a/29323246/3535786 (see below) calculate modified distance , sums everything. instead of using distance calculate single value, use them multiple operations (e.g. different exponent of distance). result should array/vector each element represents sum on different modification of distances (sum(sqrt(distance)), sum(distance), sum(distance^2) etc). have idea how can accomplished?
#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 2d point pair typedef thrust::tuple<float, float> point; // return 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 = n - 2 - floor(sqrt((double)(-8*k + 4*n*(n-1)-7))/2.0 - 0.5); const uint64_t j = k + + 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 random points in unit square on host thrust::host_vector<point> h_points(n); thrust::generate(h_points.begin(), h_points.end(), make_point); // transfer 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; }
edit clarify question:
the code above creates first n random 2d points p (here n=4) , saves on device.
points = { p1, p2, p3, p4};
then calculates (thrust::transform) possible distances (d). in these case there 6 possible distances (general (n-1)*n/2 possibilities):
distances = {d1, d2, d3, d4, d5, d6};
each distance used input same function f(d). in case f(d) -1/d. in end, result add (thrust::reduce). because of result single number depending on distances.
result = f(d1) + f(d2) + f(d3) + f(d4) + f(d5) + f(d6);
instead of that, want output vector or array, contains result r of different functions applied distances.
result = {r1, r2, r3, r4 ... } 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);
Comments
Post a Comment