2012-02-20 9 views
5

Tôi đang cố tính giá trị trung bình của một mảng nhất định có chứa điểm (x, y).
có thể sử dụng lực đẩy để tìm điểm trung bình được biểu thị dưới dạng điểm (x, y) không? tôi cũng có thể biểu diễn mảng dưới dạng thrust::device_vector<int> khi mỗi ô chứa vị trí tuyệt đối của điểm, nghĩa là i*numColumns + j mặc dù tôi không chắc chắn rằng số trung bình thể hiện ô trung bình.
Cảm ơn! câu trả lờicách tính trung bình từ mảng int2 sử dụng Thrust

+2

Bạn không thể tính toán xác định toán tử bổ sung cho loại 'int2' (ví dụ:' a + b = {a.x + bx, a.y + by} '), sau đó sử dụng tiêu chuẩn giảm để tính tổng trên đầu vào, sau đó chia cho số phần tử? – talonmies

+0

Bạn có thể sử dụng toán tử nếu bạn sử dụng trình giữ chỗ lambda của Thrust 1.5 + (xem câu trả lời bổ sung của tôi bên dưới). – harrism

Trả lời

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 là đúng, tôi chỉ muốn thêm một mẹo hữu ích mà đòi hỏi mã, vì vậy tôi sẽ đặt nó ở đây chứ không phải là trong các ý kiến.

Lực đẩy 1.5 thêm trình giữ chỗ lambda, có thể làm cho cách tiếp cận của @ keveman trở nên đơn giản hơn. Thay vì functor, chỉ cần định nghĩa operator+ cho int2, và sau đó thay thế instantiation của functor bằng biểu thức giữ chỗ lambda _1 + _2. Bạn cũng có thể thay thế tuyên bố rõ ràng của init bằng một cuộc gọi đến make_int2() (do CUDA cung cấp). Lưu ý: int2 operator+ được định nghĩa trong tiêu đề "vector_math.h" của mẫu mã CUDA, nhưng tôi xác định nó dưới đây để làm rõ nó (vì tệp đó không phải là một phần tiêu chuẩn của 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; 
}