在 GPU 上计算欧几里得距离矩阵的平方

Calculate squared Euclidean distance matrix on GPU

本文关键字:距离 几里 计算 GPU      更新时间:2023-10-16

p第一组位置的矩阵,其中每行给出特定点的坐标。类似地,让我们q第二组位置的矩阵,其中每行给出特定点的坐标。

那么成对平方欧几里得距离的公式为:

k(i,j) = (p(i,:) - q(j,:))*(p(i,:) - q(j,:))', 

其中p(i,:)表示矩阵p的第i行,p'表示p的转置。

我想在C++中在支持 CUDA 的 GPU(NVidia Tesla)上计算矩阵k。我有支持 GPU 的 OpenCV v.2.4.1,但我对其他替代方案持开放态度,例如 Thrust 库。但是,我对GPU编程不太熟悉。您能建议一种有效的方法来完成这项任务吗?我应该使用哪些C++库?

这个问题看起来很简单,足以使库矫枉过正。

在不知道ij的范围的情况下,我建议您k划分为每个块 32 个线程的倍数,并在每个块中

计算
float sum, myp[d];
int i = blockIdx.x*blockDim.x + threadIdx.x;
for ( int kk = 0 ; kk < d ; kk++ )
    myp[kk] = p(i,kk);
for ( j = blockIdx.y*blockDim.y ; j < (blockIdx.y+1)*blockDim ; j++ ) {
    sum = 0.0f;
    #pragma unroll
    for ( int kk = 0 ; kk < d ; kk++ ) {
        temp = myp[kk] - q(j,kk);
        sum += temp*temp;
        }
    k(i,j) = sum;
    }

我假设您的数据具有d维度,并写入p(i,k)q(j,k)k(i,j)表示对二维数组的访问。我也冒昧地假设您的数据属于 float 型。

请注意,根据k的存储方式,例如行主或列主,您可能希望遍历每个线程i,而不是将合并的写入k