Dejar p
ser una matriz del primer conjunto de ubicaciones donde cada fila proporciona las coordenadas de un punto en particular. Del mismo modo, vamos q
ser una matriz del segundo conjunto de ubicaciones donde cada fila proporciona las coordenadas de un punto en particular.
Entonces la fórmula para la distancia euclidiana al cuadrado pareado es:
k(i,j) = (p(i,:) - q(j,:))*(p(i,:) - q(j,:))",
dónde p(i,:)
denota i
-th fila de matriz p
y p"
denota la transposición de p
.
Me gustaría calcular la matriz k
en GPU habilitada para CUDA (NVidia Tesla) en C ++. Tengo OpenCV v.2.4.1 con soporte de GPU pero estoy abierto a otras alternativas, como la biblioteca de Thrust. Sin embargo, no estoy muy familiarizado con la programación de GPU. ¿Puede sugerir una forma eficiente de realizar esta tarea? ¿Qué bibliotecas de C ++ debo usar?
Respuestas
3 para la respuesta № 1El problema parece lo suficientemente simple como para hacer una exageración de la biblioteca.
Sin saber el rango de i
y j
, Te sugiero particionar k
en bloques de un múltiplo de 32 hilos cada uno y en cada bloque, calcule
float sum, myp[d];
int i = blockIdx.x*blockDim.x + threadIdx.x;
for ( int kk = 0 ; kk < d ; kk++ )
myp[kk] = p(i,kk);
for ( j = blockIdx.y*blockDim.y ; j < (blockIdx.y+1)*blockDim ; j++ ) {
#pragma unroll
for ( sum = 0.0f , int kk = 0 ; kk < d ; kk++ ) {
temp = myp[kk] - q(j,kk);
sum += temp*temp;
}
k(i,j) = sum;
}
donde estoy asumiendo que sus datos tienen d
dimensiones y escritura p(i,k)
, q(j,k)
y k( to mean an access to a two-dimensional array. I also took the liberty in assuming that your data is of type
flotar
Tenga en cuenta que dependiendo de cómo k
se almacena, por ejemplo, row-major o column-major, es posible que desee realizar un bucle i
por hilo en lugar de obtener escrituras unidas a k
.