4

各行pが特定の点の座標を与える最初の場所のセットの行列とします。同様に、q各行が特定の点の座標を与える2番目の場所のセットの行列とします。

次に、ペアワイズ二乗ユークリッド距離の式は次のとおりです。

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

ここで、は行列の-番目の行をp(i,:)示し、はの転置を示します。ipp'p

kC ++のCUDA対応GPU(NVidia Tesla)で行列を計算したいと思います。GPUをサポートするOpenCVv.2.4.1を使用していますが、Thrustライブラリなどの他の代替手段を利用できます。しかし、私はGPUプログラミングにあまり精通していません。このタスクを実行するための効率的な方法を提案できますか?どのC++ライブラリを使用する必要がありますか?

4

1 に答える 1

4

問題は、ライブラリをやり過ぎにするほど単純に見えます。

iとの範囲がわからない場合は、それぞれ32スレッドの倍数のブロックに分割し、各ブロックで計算するjことをお勧めします。k

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)、2次元配列へのアクセスを意味すると仮定しています。私はまた、あなたのデータがタイプであると仮定することに自由を取りましたfloat

保存方法によっては、たとえば行メジャーや列メジャーなど、スレッドごとにループして、への合体書き込みを取得しkたい場合があることに注意してください。ik

于 2012-06-25T20:35:13.540 に答える