Using MPI message passing to realize the sequential output of hello world

Posted by murdocsvan on Sat, 21 Dec 2019 21:36:56 +0100

MPI: hello world sequential output

When running MPI parallel programs, we don't know which core is moving fast, so it's unknown who executes the same code first without other controls.
For example, for a program that outputs "hello world", if multiple nodes are used to run, the printing order is uncertain. Here is a hello program:

/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
 *  (C) 2001 by Argonne National Laboratory.
 *      See COPYRIGHT in top-level directory.
 */

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

int main( int argc, char *argv[] )
{
    int rank;
    int size;
    
    MPI_Init( 0, 0 );
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    printf( "Hello world from process %d of %d\n", rank, size );
    MPI_Finalize();
    return 0;
}

We use several nodes to run:

lusongno1@ubuntu:~/Desktop$ mpirun -n 5 ./a.out
Hello world from process 3 of 5
Hello world from process 2 of 5
Hello world from process 4 of 5
Hello world from process 0 of 5
Hello world from process 1 of 5

It is found that the process order of printing results is uncertain, so how to modify the hello world program so that the output results of each screen printing are output in the sequence of process number from small to large? As follows:

/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
/*
*  (C) 2001 by Argonne National Laboratory.
*      See COPYRIGHT in top-level directory.
*/

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

int main(int argc, char *argv[]) {
	int myrank;
	int size;
	MPI_Status status;
	MPI_Init(0, 0);
	MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
	MPI_Comm_size(MPI_COMM_WORLD, &size);
	int data;
	data = 1;


	if(size==1) {
		printf("Hello world from process %d of %d\n", myrank, size);
		MPI_Finalize();//Enhance program robustness
		return 0;
	}


	if (myrank == 0) {
		printf("Hello world from process %d of %d\n", myrank, size);
		MPI_Send(&data, 1, MPI_INT, (myrank + 1) % size ,99, MPI_COMM_WORLD);
	}

	if (myrank >= 1) {
		MPI_Recv(&data, 1, MPI_INT, myrank - 1, 99, MPI_COMM_WORLD, &status);
		printf("Hello world from process %d of %d\n", myrank, size);
		MPI_Send(&data, 1, MPI_INT, (myrank + 1) % size, 99, MPI_COMM_WORLD);
	}
	MPI_Finalize();
	return 0;
}

The basic idea is to use point-to-point message communication. First, process 0 prints and sends a signal to process 1. After receiving the signal, process 1 prints and sends a signal to process 2 And so on until the last process prints. It's a very simple program, but there are many details to pay attention to

Topics: Ubuntu