Sto calcolando la distanza euclidea tra i punti n-dimensionali usando OpenCL. Ottengo due liste di punti n-dimensionali e dovrei restituire un array che contenga solo le distanze da ogni punto della prima tabella a ogni punto della seconda tabella.Sommatoria dell'array cummulativo usando OpenCL
Il mio approccio è quello di fare il loop doble regolare (per ogni punto in Table1 {per ogni punto in Table2 {...}} e poi fare il calcolo per ogni coppia di punti in paralell.
euclidea la distanza viene quindi divisa in 3 parti: 1. prendere la differenza tra ogni dimensione nei punti 2. quadrare tale differenza (sempre per ogni dimensione) 3. sommare tutti i valori ottenuti in 2. 4. Prendere la radice quadrata del valore ottenuto in 3. (questo passaggio è stato omesso in questo esempio.)
Tutto funziona come un fascino finché io prova ad accumulare la somma di tutte le differenze (ovvero, eseguendo il passaggio 3. della procedura descritta sopra, riga 49 del codice seguente).
Come dati di test sto utilizzando le DescriptorList con 2 punti ciascuna: DescriptorList1: 001,002,003, ..., 127,128; (p1) 129,130,131, ..., 255,256; (P2)
DescriptorList2: 000.001.002, ..., 126.127; (p1) 128,129,130, ..., 254,255; (p2)
Quindi il vettore risultante dovrebbe avere i valori: 128, 2064512, 2130048, 128 Al momento sto ottenendo numeri casuali che variano ad ogni corsa.
Apprezzo qualsiasi aiuto o indizio su ciò che sto facendo male. Speriamo che tutto è chiaro sullo scenario sto lavorando in
#define BLOCK_SIZE 128
typedef struct
{
//How large each point is
int length;
//How many points in every list
int num_elements;
//Pointer to the elements of the descriptor (stored as a raw array)
__global float *elements;
} DescriptorList;
__kernel void CompareDescriptors_deb(__global float *C, DescriptorList A, DescriptorList B, int elements, __local float As[BLOCK_SIZE])
{
int gpidA = get_global_id(0);
int featA = get_local_id(0);
//temporary array to store the difference between each dimension of 2 points
float dif_acum[BLOCK_SIZE];
//counter to track the iterations of the inner loop
int loop = 0;
//loop over all descriptors in A
for (int i = 0; i < A.num_elements/BLOCK_SIZE; i++){
//take the i-th descriptor. Returns a DescriptorList with just the i-th
//descriptor in DescriptorList A
DescriptorList tmpA = GetDescriptor(A, i);
//copy the current descriptor to local memory.
//returns one element of the only descriptor in DescriptorList tmpA
//and index featA
As[featA] = GetElement(tmpA, 0, featA);
//wait for all the threads to finish copying before continuing
barrier(CLK_LOCAL_MEM_FENCE);
//loop over all the descriptors in B
for (int k = 0; k < B.num_elements/BLOCK_SIZE; k++){
//take the difference of both current points
dif_acum[featA] = As[featA]-B.elements[k*BLOCK_SIZE + featA];
//wait again
barrier(CLK_LOCAL_MEM_FENCE);
//square value of the difference in dif_acum and store in C
//which is where the results should be stored at the end.
C[loop] = 0;
C[loop] += dif_acum[featA]*dif_acum[featA];
loop += 1;
barrier(CLK_LOCAL_MEM_FENCE);
}
}
}
che ho da dire, prima di tutto, che sono molto grato con la risposta di Grizzly. Sono piuttosto nuovo di OpenCL e, anche se avevo bisogno di modificare il codice di esempio che ha dato un po ', mi ha portato dritto nella giusta direzione.Cose importanti che ho notato (per tentativi ed errori): thread che non indirizzano le posizioni dell'array necessario per essere scartati; il ciclo SCAN ha richiesto un piccolo ritocco, ovvero l'utilizzo di un buffer ausiliario per accumulare risultati parziali e il controllo delle condizioni al contorno per trovare i termini da aggiungere. Grazie mille ancora! Sto postando il codice che ha funzionato per me. – SebastianP