Я вычисляю евклидово расстояние между n-мерными точками с помощью OpenCL. Я получаю два списка n-мерных точек и должен вернуть массив, содержащий только расстояния от каждой точки в первой таблице до каждой точки во второй таблице. 1. возьмите разницу между каждым измерением в точках 2. возвести эту разницу в квадрат (по-прежнему для каждого измерения) 3. просуммируйте все значения, полученные в 2. 4. Извлеките квадратный корень из значения, полученного в 3. (этот шаг был опущен в этом примере.)
Все работает как чудо, пока я не попытаюсь накопить сумму всех различий (а именно, выполняя шаг 3 из процедура, описанная выше, строка 49 кода ниже).
В качестве тестовых данных я использую DescriptorLists с двумя точками в каждом: 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)
Итак, результирующий вектор должен иметь значения: 128, 2064512, 2130048, 128 Прямо сейчас я получаю случайные числа, которые меняются с каждым запуском.
Я ценю любую помощь или подсказки в том, что я делаю неправильно. Надеюсь, в сценарии, над которым я работаю, все ясно.
#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);
}
}
}