【问题标题】:Calculate squared Euclidean distance matrix on GPU在 GPU 上计算平方欧几里得距离矩阵
【发布时间】:2012-06-27 03:30:23
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 顺便说一句,您正在计算欧几里得距离的平方...
  • @Pedro:我想这就是为什么它被描述为“成对平方欧几里得距离”(强调我的)......
  • @talonmies:是的,从编辑的时间戳来看,它只是与我的评论重叠。
  • 是的平方.. 我昨天更新了我的问题

标签: c++ cuda gpu euclidean-distance


【解决方案1】:

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

在不知道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

【讨论】:

  • 感谢 cuda c 代码!我有一个支持 GPU 矩阵运算的 OpenCV 库(无论如何我都在使用),所以可以先尝试一下。
猜你喜欢
  • 2013-04-07
  • 2020-06-16
  • 2016-08-02
  • 2015-01-13
  • 2014-05-08
  • 2018-03-28
  • 1970-01-01
  • 2014-11-18
相关资源
最近更新 更多