2012-02-20 15 views
5

Estoy tratando de calcular el promedio de una cierta matriz que contiene puntos (x, y).
¿es posible usar el empuje para encontrar el punto promedio representado como un punto (x, y)? también podría representar la matriz como thrust::device_vector<int> cuando cada celda contiene la posición absoluta del punto, lo que significa i*numColumns + j aunque no estoy seguro de que el número promedio represente la celda promedio.
Gracias! respuestacómo calcular un promedio de una matriz int2 utilizando Thrust

+2

no puedes calcular definir un operador de adición para el 'tipo int2' (es decir.' A + b = {a.x + bx, a.y + por} '), a continuación, utilizar el estándar reducción para calcular la suma sobre la entrada, luego dividir a través de la cuenta del elemento? – talonmies

+0

Puede usar un operador si usa los marcadores de posición lambda de Thrust 1.5 + (consulte la respuesta de mi complemento a continuación). – harrism

Respuesta

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

de Keveman es correcta, sólo quiero añadir un consejo útil que requiere código, así que voy a poner aquí en vez de en los comentarios.

Thrust 1.5 agrega marcadores de posición lambda, lo que puede hacer que el enfoque de @ keveman sea aún más simple. En lugar de un funtor, simplemente defina operator+ para int2, y luego reemplace la creación de instancias del funtor con la expresión de marcador de posición _1 + _2 lambda. También puede reemplazar la declaración explícita de init con una llamada al make_int2() (proporcionada por CUDA). Nota: int2 operator+ se define en el encabezado "vector_math.h" del SDK de muestra del código CUDA, pero lo defino a continuación para dejarlo en claro (ya que ese archivo no es una parte estándar de 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; 
} 
Cuestiones relacionadas