2017-04-04 39 views
-1

我有p.ntp測試粒子,每個粒子都有笛卡爾座標tp.rh[i].x,tp.rh[i].y,tp.rh[i].z。在這個集合中,我需要找到CLUSTERS。這意味着,我正在尋找更接近i的粒子,該粒子小於hill2 (tp.D_rel < hill2)。這樣的成員的數量存儲在N_conv中。在CUDA內核中查找三元組

我使用這個週期for (int i = 0; i < p.ntp; i++),它通過數據集。對於每個i第個粒子,我計算相對於集合中其他成員的平方距離tp.D_rel[idx]。然後,我使用第一個線程(idx == 0)來查找滿足我的條件的案例數量。最後,如果有多於一個(N_conv > 1)的正例,我需要寫出所有可能聚集在一起的粒子(三胞胎,...)。

我的代碼只適用於案件,其中i < blockDim.x。爲什麼?有沒有一種通用的方法,如何在一組數據中查找集羣,但只寫出三元組或更多?

注:我知道,有些情況下會發現兩次。

__global__ void check_conv_system(double t, struct s_tp tp, struct s_mp mp, struct s_param p, double *time_step) 
{ 
const uint bid = blockIdx.y * gridDim.x + blockIdx.x; 
const uint tid = threadIdx.x; 
const uint idx = bid * blockDim.x + tid; 
double hill2 = 1.0e+6; 

__shared__ double D[200]; 
__shared__ int ID1[200]; 
__shared__ int ID2[200]; 

if (idx >= p.ntp) return; 
int N_conv; 

for (int i = 0; i < p.ntp; i++) 
{ 

    tp.D_rel[idx] = (double)((tp.rh[i].x - tp.rh[idx].x)*(tp.rh[i].x - tp.rh[idx].x) + 
          (tp.rh[i].y - tp.rh[idx].y)*(tp.rh[i].y - tp.rh[idx].y) + 
          (tp.rh[i].z - tp.rh[idx].z)*(tp.rh[i].z - tp.rh[idx].z)); 
    __syncthreads(); 
    N_conv = 0; 

    if (idx == 0) 
    { 

     for (int n = 0; n < p.ntp; n++) { 
     if ((tp.D_rel[n] < hill2) && (i != n)) { 

     N_conv = N_conv + 1; 
     D[N_conv] = tp.D_rel[n]; 
     ID1[N_conv] = i; 
     ID2[N_conv] = n; 

     } 
     } 

     if (N_conv > 0) { 
     for(int k = 1; k < N_conv; k++) { 
      printf("%lf %lf %d %d \n",t/365.2422, D[k], ID1[k], ID2[k]); 
      } 
     } 

     } //end idx == 0 

    } //end for cycle for i   

} 
+1

問題:「爲什麼這段代碼不工作?」你應該提供[mcve]。內核本身並不是一個MCVE。 –

回答

1

正如RobertCrovella所說,沒有MCV的例子,很難說。

然而,tp.D_del陣列似乎要被寫入到與idx指數,和回讀全範圍索引n一個__syncthreads()之後。請注意,__syncthreads()的調用將僅在一個塊內執行同步,而不是跨整個設備。因此,某個線程/塊將訪問尚未計算的數據,因此失敗。

您想檢查您的代碼,以便塊計算的值不依賴於彼此。