我正在計算使用OpenCL的n維點之間的歐幾里德距離。我得到了兩個n維點的列表,我應該返回一個數組,其中只包含第一個表中每個點到第二個表中每個點的距離。使用OpenCL的累積數組求和
我的做法是做正規多布爾循環(在表1的每一個點{於表2 {每一點...}},然後做使用並聯每對點的計算。
的歐幾里得然後將距離分爲3部分: 1.取點 中的每個尺寸之差2.平方差(仍針對每個尺寸) 3.將所有在2中獲得的值相加。 4.取平方根的值(在本例中省略了此步驟)。
一切都像一個魅力,直到我嘗試累積所有差異的總和(即,執行上述過程的第3步,下面代碼的第49行)。
作爲測試數據,我使用描述符列表,每個列表都有2個點: 描述符列表1: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);
}
}
}
我不得不說,首先,我是非常感激與灰熊的答案。我對OpenCL相當陌生,儘管我需要調整他給出的一些示例代碼,但它讓我直接朝着正確的方向發展。我注意到的重要事情(通過試驗和錯誤):無法處理陣列位置的線程需要丟棄; SCAN循環需要稍微調整,即使用輔助緩衝區累積部分結果並檢查邊界條件以找到要添加的項。再一次非常感謝你!我發佈了適用於我的代碼。 – SebastianP 2010-09-24 14:24:01