1

I write some code like this:

void main(int argc, char **argv ) {

char message[20];
int i, rank, size, type=99;

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

if(rank == 0) {

    strcpy_s(message, "Hello, world");

    for (i=1; i<size; i++)
        MPI_Send(message, 13, MPI_CHAR, i, type, MPI_COMM_WORLD);

} else {
    MPI_Recv(message, 20, MPI_CHAR, 0, type, MPI_COMM_WORLD, &status);
}

printf( "Message from process =%d : %.13s\n", rank, message);

MPI_Finalize();
}

My output is random ordered. For example:

Message from process = 4 : Hello, world
Message from process = 2 : Hello, world
Message from process = 0 : Hello, world
Message from process = 1 : Hello, world
Message from process = 3 : Hello, world

But i want to do like this:

Message from process = 0 : Hello, world
Message from process = 1 : Hello, world
Message from process = 2 : Hello, world
Message from process = 3 : Hello, world
Message from process = 4 : Hello, world

I try some code, but still process random order.

I change my code. Now, every process wait its message from predecessor. But still processes outputs random ordered. I write MPI_Wait but it is not working.

if(rank == 0) {

    strcpy_s(message, "Hello, world");
    printf( "Message from process =%d : %.13s\n", rank, message);

    MPI_Isend(message, 13, MPI_CHAR, rank + 1, type, MPI_COMM_WORLD, &request);

    MPI_Wait(&request, &status);

} else {

    MPI_Recv(message, 20, MPI_CHAR, (rank - 1) % size, type, MPI_COMM_WORLD, &status);
    printf( "Message from process =%d : %.13s\n", rank, message);

    if(rank < (size - 1)){

        MPI_Isend(message, 13, MPI_CHAR, (rank + 1) % size, type, MPI_COMM_WORLD, &request);

        MPI_Wait(&request, &status);
    }
}

I hope some people help me. Thanks.

Abhineet
  • 5,320
  • 1
  • 25
  • 43
hkucuk
  • 345
  • 1
  • 4
  • 14

2 Answers2

3

By default, the printf statement will be evaluated by whichever processor happens to run into it first, not by order of rank. If you absolutely have to do it in order of rank, then you can try something like:

for(i = 0; i < size; i++) {
    if(i == rank) {
        printf("Message from process =%d : %.13s\n", rank, message);
    }

    MPI_Barrier(MPI_COMM_WORLD);
}

This loops through each rank and only allows the current rank to print, while everyone else hits MPI_Barrier and is forced to wait. Keep in mind, though, that this is not a scalable approach.

wolfPack88
  • 4,163
  • 4
  • 32
  • 47
1

I like the MPI_Barrier in a loop approach a lot! Another way would be to pass a token:

source = myrank -1;
dest = myrank + 1   
if (source < 0) source = MPI_PROC_NULL;
if (dest >= nprocs) dest = MPI_PROC_NULL;
MPI_Recv(NULL, 0, MPI_BYTE, source, 0, comm, MPI_STATUS_IGNORE);
printf("Message from process =%d : %.13s\n", rank, message);
MPI_Send(NULL, 0, MPI_BYTE, dest, 0, comm);

Another approach (should this be a separate answer?) is to prefix the lines with a rank, then sort. In MPICH this would be mpiexec -np 4 -prepend-rank ...

Rob Latham
  • 5,085
  • 3
  • 27
  • 44