我试图创造一个" Hello,world!"在(开放)MPI中应用,以便每个过程按顺序打印出来。
我的想法是让第一个进程在完成后向第二个进程发送消息,然后在第二个到第三个进程发送消息,等等:
#include <mpi.h>
#include <stdio.h>
int main(int argc,char **argv) {
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// See: http://mpitutorial.com/mpi-send-and-receive/
if (rank == 0) {
// This is the first process.
// Print out immediately.
printf("Hello, World! I am rank %d of %d.\n", rank, size);
MPI_Send(&rank, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);
} else {
// Wait until the previous one finishes.
int receivedData;
MPI_Recv(&receivedData, 1, MPI_INT, rank - 1, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
printf("Hello, World! I am rank %d of %d (message: %d).\n", rank, size, receivedData);
if (rank + 1 < size) {
// We're not the last one. Send out a message.
MPI_Send(&rank, 1, MPI_INT, rank + 1, 0, MPI_COMM_WORLD);
} else {
printf("Hello world completed!\n");
}
}
MPI_Finalize();
return 0;
}
当我在八核群集上运行它时,它每次运行都很完美。但是,当我在16核集群上运行它时,它有时会起作用,有时会输出如下内容:
Hello, world, I am rank 0 of 16.
Hello, world, I am rank 1 of 16 (message: 0).
Hello, world, I am rank 2 of 16 (message: 1).
Hello, world, I am rank 3 of 16 (message: 2).
Hello, world, I am rank 4 of 16 (message: 3).
Hello, world, I am rank 5 of 16 (message: 4).
Hello, world, I am rank 6 of 16 (message: 5).
Hello, world, I am rank 7 of 16 (message: 6).
Hello, world, I am rank 10 of 16 (message: 9).
Hello, world, I am rank 11 of 16 (message: 10).
Hello, world, I am rank 8 of 16 (message: 7).
Hello, world, I am rank 9 of 16 (message: 8).
Hello, world, I am rank 12 of 16 (message: 11).
Hello, world, I am rank 13 of 16 (message: 12).
Hello, world, I am rank 14 of 16 (message: 13).
Hello, world, I am rank 15 of 16 (message: 14).
Hello world completed!
也就是说,大部分输出都是有序的,但有些是不合适的。
为什么会这样?怎么可能呢?我该如何解决?
答案 0 :(得分:0)
不保证MPI代码以任何特定顺序完成。在多个节点上运行时尤其如此,但即使在一个节点上也是如此。
当您通过添加顺序发送和接收来强制执行某种排序时,输出消息仍会从应用程序进程转发到MPI层并返回到mpiexec
/ mpirun
进程要打印到屏幕上。此消息转发可以按任何顺序发生,并与其他通信交错(因为它使用完全不同的通信拓扑)。如果您确实必须确保按顺序打印消息,则必须确保相同的MPI等级打印出所有消息。