为什么这个MPI代码执行不正常?

我正在努力创造一个“Hello,world!” 在(开放)MPI中应用,使每个过程按顺序打印出来。

我的想法是让第一个进程在完成时向第二个进程发送消息,然后在第二个到第三个进程发送消息,等等:

#include  #include  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! 

也就是说,大部分输出都是有序的,但有些是不合适的。

为什么会这样? 怎么可能呢? 我该如何解决?

MPI代码不保证以任何特定顺序完成。 在多个节点上运行时尤其如此,但即使在一个节点上也是如此。

当您通过添加顺序发送和接收来强制执行某种排序时,输出消息仍然从应用程序进程转发到MPI层并返回到mpiexec / mpirun进程以打印到屏幕上。 此消息转发可以按任何顺序发生,并与其他通信交错(因为它使用完全不同的通信拓扑)。 如果您确实必须确保按顺序打印消息,则必须确保相同的MPI等级打印出所有消息。