Overview
Teaching: 10 min
Exercises: 15 minQuestions
Objectives
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;
}
#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
C syntax
FORTRAN syntax
Why are there two different tags/types/counts?
Key Points
There are advanced MPI routines that solve most common problems. Don’t reinvent the wheel.