ACENET Summer School - MPI

Blocking and buffering

Overview

Teaching: 10 min
Exercises: 15 min
Questions
Objectives

Different versions of SEND

Buffering is dangerous!

Without using new MPI routines, how can we fix this?

Re-arranging communications to avoid deadlock

program fourthmessage
use mpi
implicit none

    integer :: ierr, rank, comsize
    integer :: left, right
    integer :: tag
    integer :: status(MPI_STATUS_SIZE)
    double precision :: msgsent, msgrcvd
    
    call MPI_Init(ierr)
    call MPI_Comm_size(MPI_COMM_WORLD, comsize, ierr)
    call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)

    left = rank-1
    if (left <0) left = comsize-1
    right = rank+1
    if (right >=comsize) right = 0

    msgsent= rank*rank
    msgrcvd= -999.
    tag=1

    if (mod(rank,2) == 0) then
        call MPI_Ssend(msgsent, 1, MPI_DOUBLE_PRECISION,right, &
                      tag, MPI_COMM_WORLD,ierr)  
        call MPI_Recv(msgrcvd, 1, MPI_DOUBLE_PRECISION,left, &
                      tag, MPI_COMM_WORLD,status,ierr)
     else 
        call MPI_Recv(msgrcvd, 1, MPI_DOUBLE_PRECISION,left, &
                      tag, MPI_COMM_WORLD,status,ierr)	    
        call MPI_Ssend(msgsent, 1, MPI_DOUBLE_PRECISION,right, &
                      tag, MPI_COMM_WORLD,ierr)
    end if
 
    print *, rank, 'Sent ', msgsent, 'and recvd ', msgrcvd
    call MPI_Finalize(ierr)
end program fourthmessage

Following is a C program for fourth message

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

int main(int argc, char **argv) {
    int rank, size, ierr;
    int left, right;
    int tag=1;
    double msgsent, msgrcvd;
    MPI_Status rstatus;

    ierr = MPI_Init(&argc, &argv);
    ierr = MPI_Comm_size(MPI_COMM_WORLD, &size);
    ierr = MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    left = rank-1;
    if (left < 0) left =size-1;
    right = rank+1;
    if (right == size) right = 0;
    msgsent = rank*rank;
    msgrcvd = -999.;

    if(rank % 2 ==0) {
	ierr = MPI_Ssend(&msgsent, 1, MPI_DOUBLE, right,tag, MPI_COMM_WORLD); 
        ierr = MPI_Recv(&msgrcvd, 1, MPI_DOUBLE, left,tag, MPI_COMM_WORLD, &rstatus); 
	}
    else {
	ierr = MPI_Recv(&msgrcvd, 1, MPI_DOUBLE, left,tag, MPI_COMM_WORLD, &rstatus); 
	ierr = MPI_Ssend(&msgsent, 1, MPI_DOUBLE, right,tag, MPI_COMM_WORLD); 
	}
    printf("%d: Sent %lf and got %lf\n", rank, msgsent, msgrcvd);

    ierr = MPI_Finalize();
    return 0;
}

Something new: Sendrecv

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

int main(int argc, char **argv) {
    int rank, size, ierr;
    int left, right;
    int tag = 1;
    double msgsent, msgrcvd;
    MPI_Status rstatus;

    ierr = MPI_Init(&argc, &argv);
    ierr = MPI_Comm_size(MPI_COMM_WORLD, &size);
    ierr = MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    left = rank-1;
    if (left < 0) left = size-1;
    right = rank+1;
    if (right == size) right = 0;

    msgsent = rank*rank;
    msgrcvd = -999.;

    ierr=MPI_Sendrecv(&msgsent, 1, MPI_DOUBLE, right, tag, &msgrcvd, 1,
                      MPI_DOUBLE, left, tag, MPI_COMM_WORLD, &rstatus );
	
    printf("%d: Sent %lf and got %lf\n", rank, msgsent, msgrcvd);

    ierr = MPI_Finalize();
    return 0;
}

Following is a fortran program for sendrecieve.

program fifthmessage
use mpi
implicit none

    integer :: ierr, rank, comsize
    integer :: left, right
    integer :: tag
    integer :: status(MPI_STATUS_SIZE)
    double precision :: msgsent, msgrcvd
    
    call MPI_Init(ierr)
    call MPI_Comm_size(MPI_COMM_WORLD, comsize, ierr)
    call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)

    left = rank-1
    if (left <0) left = comsize-1
    right= rank+1
    if (right >=comsize) right = 0

    msgsent= rank*rank
    msgrcvd= -999.
    tag=1
    
    call MPI_Sendrecv(msgsent, 1, MPI_DOUBLE_PRECISION, right, tag, &
                      msgrcvd, 1, MPI_DOUBLE_PRECISION, left,  tag, &
                      MPI_COMM_WORLD, status, ierr)
 
    print *, rank, 'Sent ', msgsent, 'and recvd ', msgrcvd
    call MPI_Finalize(ierr)
end program fifthmessage

Sendrecv = Send + Recv

C syntax

send recieve

FORTRAN syntax send reciev

Why are there two different tags/types/counts?

Key Points