0

MPI_Sendwithoutの効果をテストしようとしていMPI_Recvます。openmpi-1.4.5 および mvapich2-1.9 を使用してコンパイルおよび実行する次のプログラムがあります。これらの実装が MPI 標準の 2 つの異なるバージョン用であることは承知していますが、これらの標準全体で同じだMPI_Sendと思います。MPI_Recv

#include <mpi.h>
#include <iostream>
#include <assert.h>

using namespace std;

MPI_Comm ping_world;
int mpi_size, mpi_rank;

void* ping(void* args)
{
    int ctr = 0;
    while(1)
    {
            char buff[6] = "PING";
            ++ctr;
            for(int i=0; i<mpi_size; ++i)
            {
                    cout << "[" << ctr << "] Rank " << mpi_rank << " sending " << buff << " to rank " << i << endl;
                    MPI_Send(buff, 6, MPI_CHAR, i, 0, ping_world);
            }
    }
}

int main(int argc, char *argv[])
{
int provided;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
assert(provided == MPI_THREAD_MULTIPLE);

MPI_Comm_rank (MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size (MPI_COMM_WORLD, &mpi_size);

    {
            MPI_Group orig_group;
            MPI_Comm_group(MPI_COMM_WORLD, &orig_group);
            int ranks[mpi_size];
            for(int i=0; i<mpi_size; ++i)
                    ranks[i] = i;

            MPI_Group new_group;
            MPI_Group_incl(orig_group, mpi_size, ranks, &new_group);
            MPI_Comm_create(MPI_COMM_WORLD, new_group, &ping_world);
    }

pthread_t th_ping;
pthread_create(&th_ping, NULL, ping, (void *) NULL);

pthread_join(th_ping, NULL);

return 0;
}

mvapich2 を使用すると、常に次の出力が得られます (これ以上のものはありません)。基本的に、プログラムは次の 3 行でハングしたようです。

[1] Rank 0 sending PING to rank 0
[1] Rank 1 sending PING to rank 0
[1] Rank 1 sending PING to rank 1

openmpi を使用すると、次の出力が得られます (終わりがありません)。

[1] Rank 1 sending PING to rank 0
[1] Rank 1 sending PING to rank 1
[1] Rank 0 sending PING to rank 0
[1] Rank 0 sending PING to rank 1
[2] Rank 0 sending PING to rank 0
[2] Rank 0 sending PING to rank 1
[3] Rank 0 sending PING to rank 0
[3] Rank 0 sending PING to rank 1
[4] Rank 0 sending PING to rank 0
[4] Rank 0 sending PING to rank 1
[5] Rank 0 sending PING to rank 0
[2] Rank 1 sending PING to rank 0
[2] Rank 1 sending PING to rank 1
[3] Rank 1 sending PING to rank 0
[3] Rank 1 sending PING to rank 1
[4] Rank 1 sending PING to rank 0
[4] Rank 1 sending PING to rank 1
[5] Rank 1 sending PING to rank 0
[5] Rank 1 sending PING to rank 1
[6] Rank 1 sending PING to rank 0

質問:

  1. なぜこのような違いがあるのですか?
  2. mvapich2 を使用して openmpi (unending) に似た動作を実現するにはどうすればよいですか?
4

3 に答える 3

1

MPI_Send は、呼び出し側プログラムがバッファーを安全に再利用できる場合に戻ることができます。他に何も保証されていませんが、多くの異なる実装依存の動作があります。実装が異なれば、メッセージのバッファリングも異なる方法で処理できます。Eager プロトコルでは、一致する MPI_Recv を送信する必要なく、いくつかの短い (より短い) メッセージを受信ランクに転送することもできます。

ブロッキング送信が返される前にメッセージの受信を強制するために MPI が必要な場合は、MPI_Ssend を参照してください。

于 2013-09-01T04:42:25.707 に答える
0

データを受信せずに送信するのは不適切な MPI プログラムです。あなたが見ている問題は、送信が受信と一致しないことです。実装によってはMPI_SEND、メッセージが実際に相手側で受信されるまでブロックされる場合があります。実際、私が知っているすべての実装は、十分に大きなメッセージに対してこれを行います (ただし、6 バイトのメッセージはおそらくどこにもそのしきい値に達していません)。

ブロックせずにメッセージを送信したい場合は、 を使用する必要がありますMPI_ISEND。ただし、この場合でも、データがローカルにバッファリングされるだけでなく、最終的に呼び出すMPI_TESTか、データが実際に送信されたことを確認する必要があります。MPI_WAIT

MVAPICH2 がハングするのに Open MPI がハングしない理由の詳細についてはよくわかりませんが、最終的にはそれほど重要ではありません。プログラムを変更する必要があるか、実際には使用すべきではないケースをテストしているだけです。

于 2013-08-30T14:50:27.900 に答える
0

MVAPICH2 (および MPICH) の実装では、対応する MPI_Recv が見つかるまで、セルフ ブロッキング送信がブロックされます (バッファリングされません)。それが、「ランク 1 が PING をランク 0 に送信する」でハングしなかった理由です。これは単なる実装上の選択です。

于 2013-09-03T23:40:10.867 に答える