Ich berechne den Euklidischen Abstand zwischen n-dimensionalen Punkten mit OpenCL. Ich bekomme zwei Listen von n-dimensionalen Punkten und ich sollte ein Array zurückgeben, das nur die Abstände von jedem Punkt in der ersten Tabelle zu jedem Punkt in der zweiten Tabelle enthält.Kumulative Array-Summierung mit OpenCL
Mein Ansatz ist die regelmäßige doble Schleife zu tun (für jeden Punkt in Tabelle 1 {für jeden Punkt in Tabelle 2 {...}} und führen Sie dann die Berechnung für jedes Paar von Punkten in paralell.
Die euklidischen Der Abstand wird dann in 3 Teile geteilt: 1. nehmen Sie den Unterschied zwischen den einzelnen Punkten in den Punkten 2. Quadrat dieser Unterschied (immer noch für jede Dimension) 3. addieren Sie alle Werte in 2. 4. Nehmen Sie die Quadratwurzel des Wertes, der in 3 erhalten wurde. (Dieser Schritt wurde in diesem Beispiel weggelassen.)
Alles funktioniert wie ein Zauber bis ich versuche, die Summe aller Differenzen zu akkumulieren (d. h. Ausführung von Schritt 3. des oben beschriebenen Verfahrens, Zeile 49 des folgenden Codes).
Als Testdaten verwende ich DescriptorLists mit je 2 Punkten: DescriptorList1: 001,002,003, ..., 127,128; (p1) 129,130,131, ..., 255,256; (p2)
Deskriptorliste2: 000,001,002, ..., 126,127; (p1) 128,129,130, ..., 254,255; (P2)
So ist der resultierende Vektor sollte die Werte: 128, 2064512, 2130048, 128 Im Moment bin ich immer Zufallszahlen, die mit jedem Lauf variieren.
Ich freue mich über jede Hilfe oder führt, was ich falsch mache. Hoffentlich ist alles klar über das Szenario in arbeite ich
#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);
}
}
}
ich zu sagen habe, vor allem, dass ich mit Antwort des Grizzly sehr dankbar bin. Ich bin ziemlich neu in OpenCL, und obwohl ich den Beispielcode, den er ein bisschen gegeben hat, anpassen musste, führte es mich direkt in die richtige Richtung.Wichtige Dinge, die mir aufgefallen sind (durch Versuch und Irrtum): Threads, die die Array-Positionen nicht adressieren, müssen verworfen werden; Die SCAN-Schleife erforderte ein wenig Feinabstimmung, nämlich die Verwendung eines Hilfspuffers, um Teilergebnisse zu akkumulieren und nach Randbedingungen zu suchen, um die hinzuzufügenden Terme zu finden. Danke dir nochmal! Ich poste den Code, der für mich funktioniert hat. – SebastianP