Receive Status

The status variable contains information about the message.

  • MPI_SOURCE The source rank of the message. This is a field of the status structure.

    • C++ status.MPI_SOURCE
    • Fortran status(MPI_SOURCE)
    • Python status.Get_Source()
  • MPI_TAG The tag. This is another field of the structure (or element of the array).

    • C++ status.MPI_TAG
    • Fortran status(MPI_TAG)
    • Python status.Get_tag()
  • MPI_Get_count(MPI_Status* status, MPI_Datatype datatype, int* count) The length (item count) of the message.

    • C++ MPI_Get_count(&status,MPI_TYPE,&item_count);
    • Fortran MPI_Get_count(status,MPI_TYPE,item_count,ierr)
    • Python status.Get_count(MPI.TYPE)
  • MPI_Error The error number. Not often needed.

    • C++ status.MPI_ERROR
    • Fortran status(MPI_ERROR)
    • Python status.Get_error()

The MPI_SOURCE and MPI_TAG items may be especially useful for the special dummy variables defined for source and tag.

Special Source and Tag Variables

MPI defines special variables that can be used in MPI_Recv

MPI_ANY_SOURCE
MPI_ANY_TAG

Either or both can be used in a receive if the MPI_Recv can accept a message from any source and/or any tag.

Example Status Usage

Add a status query to the exchange code to find the source, tag, and any error. Note that Python uses functions to retrieve all the members of the status structure, and must also initialize it with a constructor.

Although the status data structure can also return the item count, if the receiver does not know the number or size of the message, we recommend invoking MPI_PROBE, which allows the receiving process to determine the specifics of the message without actually receiving it. It can then set up an appropriate MPI_Recv.

C++

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

using namespace std;

int main(int argc, char *argv[]) {
    int rank, npes;
    MPI_Status status;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &npes);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    if ( npes != 2 ) {
	cout<<"This program runs only on two processes\n";
	MPI_Finalize();
	exit(1);
    }

    float baton=0;

    if ( rank == 0 ) {
	MPI_Recv(&baton,1,MPI_FLOAT,1,0,MPI_COMM_WORLD,&status);
	baton+=1.;
	MPI_Send(&baton,1,MPI_FLOAT,1,0,MPI_COMM_WORLD);
	int item_count;
	MPI_Get_count(&status,MPI_FLOAT,&item_count);
	cout<<"Source "<<status.MPI_SOURCE<<" Tag "<<status.MPI_TAG<<" Num Items "<<item_count<<" Error "<<status.MPI_ERROR<<"\n";
    }
    else if ( rank == 1) {
	baton=12.;
	MPI_Send(&baton,1,MPI_FLOAT,0,0,MPI_COMM_WORLD);
	MPI_Recv(&baton,1,MPI_FLOAT,0,0,MPI_COMM_WORLD,&status);
    }

    cout<<rank<<" "<<baton<<"\n";

    MPI_Finalize();

    exit(0);
}


Fortran

program send_receive
use mpi
implicit none

integer ::  rank, npes, ierr
integer, dimension(MPI_STATUS_SIZE) :: status
real    ::  baton
integer ::  item_count

   call MPI_Init(ierr)
   call MPI_Comm_size(MPI_COMM_WORLD, npes, ierr);
   call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr);

    if ( npes /= 2 ) then
        write(*,*) "This program runs only on two processes"
        call MPI_Finalize(ierr)
        stop
    endif

    baton=0;

    if ( rank == 0 ) then
        call MPI_Recv(baton,1,MPI_REAL,1,0,MPI_COMM_WORLD,status,ierr);
        baton=baton+1.
        call MPI_Send(baton,1,MPI_REAL,1,0,MPI_COMM_WORLD,ierr)
        call MPI_Get_count(status,MPI_REAL,item_count,ierr)
        write(*,*) "Source",status(MPI_SOURCE),"Tag",status(MPI_TAG),"Num items",item_count,"Error",status(MPI_ERROR)
    else if ( rank == 1 ) then
        baton=12.
        call MPI_Send(baton,1,MPI_REAL,0,0,MPI_COMM_WORLD,ierr)
        call MPI_Recv(baton,1,MPI_REAL,0,0,MPI_COMM_WORLD,status,ierr)
    endif

    write(*,*) rank,baton

    call MPI_Finalize(ierr)

end program


Python

import sys
import numpy as np
from mpi4py import MPI

comm=MPI.COMM_WORLD
nprocs=comm.Get_size()
rank=comm.Get_rank()

if nprocs !=2:
    print("This program works only for two processes.")
    sys.exit()

baton=np.empty(1)
status=MPI.Status()

if rank==0:
    comm.Recv([baton,MPI.DOUBLE],source=1,status=status)
    baton+=1.
    comm.Send([baton,MPI.DOUBLE],dest=1)
    print("Source",status.Get_source(),"Tag",status.Get_tag(),"Item count",status.Get_count(MPI.DOUBLE),"Error",status.Get_error())
elif rank==1:
    baton[:]=12.
    comm.Send([baton,MPI.DOUBLE],dest=0)
    comm.Recv([baton,MPI.DOUBLE],source=0,status=status)

print(rank,baton)

Previous
Next