我正在使用 OpenCL 计算 n 维点之间的欧几里得距离。我得到两个 n 维点列表,我应该返回一个数组,其中只包含从第一个表中的每个点到第二个表中的每个点的距离。
我的方法是进行常规的双循环(对于 Table1 中的每个点{对于 Table2 中的每个点 {...} },然后对并行中的每一对点进行计算。
然后将欧几里得距离分成 3 部分: 1. 取点中每个维度之间的差 2. 平方差(仍然是每个维度) 3. 将 2 中获得的所有值相加。 4. 取点的平方根3中得到的值。(本例中省略了这一步。)
在我尝试累积所有差异的总和之前,一切都像魅力一样工作(即执行上述过程的第 3 步,下面代码的第 49 行)。
作为测试数据,我使用的是 DescriptorLists,每个点有 2 个点: DescriptorList1: 001,002,003,...,127,128; (p1) 129,130,131,...,255,256; (p2)
描述符列表2: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);
}
}
}