在MPI中,如何制作以下程序等到所有计算完成

D P*_* P. 6 c mpi wait

我是MPI的新手,这个程序是用C语言编写的.在以下程序中,我要求其他处理器打印消息.但是我想在所有其他进程完成后在进程/等级0打印"END"消息.要运行此程序,我使用4个处理器并执行以下命令mpicc file.c -o objfile,mpirun -np 4 objfile
如果可能,请向我显示示例.

#include <mpi.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char** argv) 
{
    MPI_Init(&argc, &argv);
    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    int i;
    double centroid[3];/*ignore this array*/

    if (world_rank == 0) 
    {
        int destination;
        for (i=0; i<3; i++)
        {
            /*Ignore centroid buffer been sent for now*/

            destination = i+1;/*destination rank or process*/
            MPI_Send(&centroid, 3, MPI_DOUBLE, destination, 0, MPI_COMM_WORLD);
        }

        printf("\nEND: This need to print after all MPI_Send/MPI_Recv has been completed\n\n");
    } 
    else
    {   
        MPI_Recv(&centroid, 3, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);        
        sleep(1); /*This represent many calculations that will happen here later, instead of sleep*/
        printf("Printing at Rank/Process number: %d\n", world_rank);
    }


    MPI_Finalize();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果:

END: This need to print after all MPI_Send/MPI_Recv has been completed Printing at Rank/Process number: 2 Printing at Rank/Process number: 3 Printing at Rank/Process number: 1

请修改此代码或向我展示如何等待所有其他处理器完成的示例

Gil*_*les 6

好吧,你快到了.所有缺失都是MPI_Barrier()对所有进程的调用.这可以这样做:

#include <mpi.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char** argv) 
{
    MPI_Init(&argc, &argv);
    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    int i;
    double centroid[3];/*ignore this array*/

    if (world_rank == 0) 
    {
        int destination;
        for (i=0; i<3; i++)
        {
            /*Ignore centroid buffer been sent for now*/

            destination = i+1;/*destination rank or process*/
            MPI_Send(&centroid, 3, MPI_DOUBLE, destination, 0, MPI_COMM_WORLD);
        }
        MPI_Barrier(MPI_COMM_WORLD);
        printf("\nEND: This need to print after all MPI_Send/MPI_Recv has been completed\n\n");
    } 
    else
    {   
        MPI_Recv(&centroid, 3, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);        
        sleep(1); /*This represent many calculations that will happen here later, instead of sleep*/
        printf("Printing at Rank/Process number: %d\n", world_rank);
        MPI_Barrier(MPI_COMM_WORLD);
    }


    MPI_Finalize();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

添加此屏障后,代码会在我的笔记本电脑上显示:

~/tmp$ mpirun -n 4 ./a.out 
Printing at Rank/Process number: 1
Printing at Rank/Process number: 2
Printing at Rank/Process number: 3

END: This need to print after all MPI_Send/MPI_Recv has been completed
Run Code Online (Sandbox Code Playgroud)

注意:在这种情况下,排名1到3的打印是有序的,但这只是偶然的,因为这可以以任何顺序发生.实际上,上面的代码将保证在printf()进程#0和其他进程之间调用的顺序,但它不能保证打印到屏幕的顺序,因为缓冲等可能发生并搞砸了.
公平地说,它应该适用于大多数环境(大多数时候).但严格来说,这并不能保证.