我有i
个测试粒子,每个tp.rh[i].x
粒子都有笛卡尔坐标tp.rh[i].y
,tp.rh[i].z
,i
。在这个集合中,我需要找到CLUSTERS。这意味着,我正在寻找更接近hill2 (tp.D_rel < hill2)
粒子的粒子,而不是N_conv
。此类成员的数量存储在for (int i = 0; i < p.ntp; i++)
。
我使用这个循环i
,它遍历数据集。对于每个tp.D_rel[idx]
粒子,我计算相对于集合中其他成员的平方距离(idx == 0)
。然后我使用第一个线程N_conv > 1
来查找满足我条件的案例数。最后,如果有超过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
}
的情况。为什么?有一般的方法,如何在一组数据中找到集群,但只写出三元组以及更多?
注意:我知道,有些案例会被发现两次。
private
答案 0 :(得分:1)
正如RobertCrovella所提到的,没有MCV的例子,很难说清楚。
但是,tp.D_del
数组似乎是使用idx
索引写入的,并且在__syncthreads()
之后使用全范围索引n
进行回读。请注意,对__syncthreads()
的调用只会在一个块内执行同步,而不是在整个设备中执行。因此,某些线程/块将访问尚未计算的数据,因此失败。
您想要检查您的代码,以便由块计算的值不会彼此依赖。