9

MPI_BarrierのOpenMPI実装を使用して同期の問題が発生しました。

int rank;
int nprocs;

int rc = MPI_Init(&argc, &argv);

if(rc != MPI_SUCCESS) {
    fprintf(stderr, "Unable to set up MPI");
    MPI_Abort(MPI_COMM_WORLD, rc);
}

MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);


printf("P%d\n", rank);
fflush(stdout);

MPI_Barrier(MPI_COMM_WORLD);

printf("P%d again\n", rank);

MPI_Finalize();

mpirun -n2./a.outの場合

出力は次のようになります:P0P1..。

出力は時々:P0P0再びP1P1再び

どうしたの?

4

4 に答える 4

15

印刷行が端末に表示される順序は、必ずしも物が印刷される順序ではありません。そのために共有リソース(stdout)を使用しているため、常に順序の問題が発生する必要があります。(そしてfflush、ここでは役に立ちませんstdout。とにかく行バッファリングされます。)

出力にタイムスタンプのプレフィックスを付けて、MPIプロセスごとに1つずつ、これらすべてを異なるファイルに保存することができます。

次に、ログを検査するために、2つのファイルをマージし、タイムスタンプに従って並べ替えることができます。

そうすれば、あなたの問題は消えるはずです。

于 2011-03-03T16:33:33.387 に答える
12

MPI_Barrier()に問題はありません。

Jensが述べたように、期待した出力が表示されない理由は、stdoutが各プロセスでバッファリングされているためです。複数のプロセスからの印刷が呼び出し元のプロセスに順番に表示されるという保証はありません。(各プロセスからの標準出力がリアルタイムで印刷するためにメインプロセスに転送されると、多くの不要な通信につながります!)

バリアが機能していることを確信したい場合は、代わりにファイルに書き込んでみてください。複数のプロセスが単一のファイルに書き込むと、さらに複雑になる可能性があるため、各procが1つのファイルに書き込み、バリアの後で、それらが書き込むファイルを交換することができます。例えば:

    Proc-0           Proc-1
      |                 |
 f0.write(..)     f1.write(...) 
      |                 |
      x  ~~ barrier ~~  x
      |                 |
 f1.write(..)     f0.write(...) 
      |                 |
     END               END

実装例:

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    char filename[20];
    int rank, size;
    FILE *fp;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    if (rank < 2) { /* proc 0 and 1 only */ 
        sprintf(filename, "file_%d.out", rank);
        fp = fopen(filename, "w");
        fprintf(fp, "P%d: before Barrier\n", rank);
        fclose(fp);
    }

    MPI_Barrier(MPI_COMM_WORLD);

    if (rank < 2) { /* proc 0 and 1 only */ 
        sprintf(filename, "file_%d.out", (rank==0)?1:0 );
        fp = fopen(filename, "a");
        fprintf(fp, "P%d: after Barrier\n", rank);
        fclose(fp);
    }

    MPI_Finalize();
    return 0;

}

コードを実行すると、次の結果が得られるはずです。

[me@home]$ cat file_0.out
P0: before Barrier
P1: after Barrier

[me@home]$ cat file_1.out
P1: before Barrier
P0: after Barrier

すべてのファイルについて、「afterBarrier」ステートメントは常に後で表示されます。

于 2011-03-03T17:38:34.517 に答える
3

MPIプログラムでは、出力の順序は保証されません。

これはMPI_Barrierとはまったく関係ありません。

また、MPIプログラムでの出力の順序について心配することにあまり時間をかけません。

これを実現する最も洗練された方法は、本当に必要な場合、プロセスにメッセージを1つのランク(ランク0など)に送信させ、ランク0に、受信した順序またはランク順に出力を出力させることです。

繰り返しになりますが、MPIプログラムからの出力を注文することにあまり時間をかけないでください。それは実用的ではなく、ほとんど役に立ちません。

于 2011-03-03T22:42:20.153 に答える
0

ここでの前の回答に加えて、MPI_BARRIERは正常に機能します。

ただし、動作を確認するだけの場合は、実行(SLEEP(1))を一時停止して、出力に追いつくことができます。

于 2020-07-29T20:27:14.083 に答える