MPIと並行して正方行列を乗算しようとしています。
MPI_Type_vector を使用して正方部分行列 (float の配列) をプロセスに送信し、部分積を計算できるようにします。次に、次の反復で、これらの部分行列は MPI_Type_contiguous として隣接プロセスに送信されます (部分行列全体が送信されます)。この部分は期待どおりに機能しており、ローカルの結果は正しいです。
次に、連続した型で MPI_Gather を使用して、すべてのローカル結果をルート プロセスに送り返します。問題は、最終的なマトリックスが、サブマトリックスごとではなく、行ごとに (明らかに、この方法で) 作成されることです。
最終的な行列を再配置する醜い手順を書きましたが、MPI_Type_vectors を送信する「逆」操作 (つまり、値の配列を送信し、それをサブ配列形式で直接配置する) を実行する直接的な方法があるかどうかを知りたいです。受信配列)。
私の長いテキストを明確にするための例:
A[16] と B[16]
これらは実際には 2D 配列、A[4][4] と B[4][4] です。
乗算する 4x4 行列です。C[4][4] には結果が含まれます。4 つのプロセスが使用されます (0 から 3 までの i を持つ Pi) :
Pi は、subAi[4] と subBi[4] の 2 つの 2x2 サブマトリックスを取得します。それらの製品はローカルに subCi[4] に保存されます。
たとえば、P0 は次のようになります。
A[0]、A[1]、A[4]、および A[5] を含む subA0[4] ;
B[0]、B[1]、B[4]、および B[5] を含む subB0[4]。
すべてが計算された後、ルート プロセスはすべての subCi[4] を収集します。
次に、C[4][4] には以下が含まれます。
[
subC 0 [0]、subC 0 [1]、subC 0 [2]、subC 0 [3]、
subC1[0]、subC1[1]、subC1[2]、subC1[3]、
subC2[0]、 subC2[1]、subC2[2]、subC2[3]、
subC3[0]、subC3[1]、subC3[2]、subC3[3]]
そして、私はそれが欲しいです:
[
subC 0 [0]、subC 0 [1]、subC1[0]、subC1[1]、
subC 0 [2]、subC 0 [3]、subC1[2]、subC1[3]、
subC2[0]、 subC2[1]、subC3[0]、subC3[1]、
subC2[2]、subC2[3]、subC3[2]、subC3[3]]
それ以上の操作なし。誰かが方法を知っていますか?
アドバイスありがとうございます。
「高性能マーク」への回答に情報を追加:
1 さて、私の最初の行列は 2D 配列です (A[4][4] の形をしています)。質問を書きながら短くしたかったのですが、今ではそれは悪い考えでした...
例として、MPI_Type_vector を次のように定義しました。
MPI_Type_vector(2, 2, 4, MPI_FLOAT, &subMatrix);
(ちなみに、フラット化された配列の違いはわかりません)。
2 私は MPI の専門家ではないので、おかしなことをするかもしれません。これは、例に適用された私のコードの一部です(Aのみが処理され、Bは非常に似ています):
ルートからスレーブプロセスへの部分行列の送信:
Master {
for (i = 0 ; i < 2 ; i++)
for (j = 0 ; j < 2 ; j++)
MPI_Send(&A[j * 2][(i + j) % 2 * 2], 1, subMatrix, i + j * 2, 42, MPI_COMM_WORLD);
}
スレーブが受け取る:
MPI_Recv(subA, 4, MPI_FLOAT, 0, 42, MPI_COMM_WORLD, &status);
次に、プロセス間の交換は、次の subMatrixLocal の MPI_Send および MPI_Recv を介して行われます。
MPI_Type_contiguous(4, MPI_FLOAT, &subMatrixLocal);
すべてのローカル操作が完了したら、すべての subC 行列を C に集めます。
MPI_Gather(subC, 1, subMatrixLocal, C, 1, subMatrixLocal, 0, MPI_COMM_WORLD);
前述の結果が得られましたが、これを並べ替える必要があります...
提案されたアルゴリズムについて: 次のステップは、正方行列の積が効率的な GPU で行列の乗算を行うことです。MPI は、行列を CPU から CPU に転送するためにのみ使用されます。もちろん、グローバルな効率性がテストされます。
0 「逆演算も同じ型定義でいい」とおっしゃいましたね。ただし、私の MPI_Vector_type は「大きな」行列では正常に機能していますが、サブ行列で直接使用することはできません (2x2 行列で MPI_Vector_type(2, 2, 4) を適用すると、間違った結果が得られます。定義された配列の「外側」にある最後の 2 つの値...)。別の MPI_Vector_type を作成して送受信する必要があるということですか?