Skip to content
Copyright (C) 2018 CSC - IT Center for Science Ltd.
Licensed under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
Code is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Copy of the GNU General Public License can be obtained from
<http://www.gnu.org/licenses/>.
## Message chain
Write a simple program where every processor sends data to the next
one. Let ntasks be the number of the tasks, and myid the rank of the
current process. Your program should work as follows:
- Every task with a rank less than ntasks-1 sends a message to task
myid+1. For example, task 0 sends a message to task 1.
- The message content is an integer array where each element is
initialized to myid.
- The message tag is the receiver’s id number.
- The sender prints out the number of elements it sends and the tag
number. All tasks with rank &ge; 1 receive messages.
- Each receiver prints out their myid, and the first element in the
received array.
a) Implement the program described above using `MPI_Send` and
`MPI_Recv`. You may start from scratch or use as a starting point
[c/skeleton.c](c/skeleton.c), [fortran/skeleton.F90](fortran/skeleton.F90) or
[python/skeleton.py](c/skeleton.py). Investigate the timings with different
numbers of MPI tasks (e.g. 2, 4, 8, 16, ...), and pay attention especially to
rank 0. Can you explain the behaviour?
b) Rewrite the program using `MPI_Sendrecv` instead of `MPI_Send` and
`MPI_Recv`. Investigate again timings with different numbers of MPI
tasks (e.g. 2, 4, 8, 16, ...). Can you explain the differences to case a)?
c) Try to simplify the code by employing the `MPI_PROC_NULL` in treating the
special cases of the first and last task in the chain.
d) Rewrite the program using non-blocking communication (`MPI_Isend` and
`MPI_Irecv`).
c) Rewrite the program using persistent communication operations
(`MPI_Send_init`, `MPI_Recv_init`, etc.).
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
int i, myid, ntasks;
int size = 10000000;
int *message;
int *receiveBuffer;
MPI_Status status;
double t0, t1;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &ntasks);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
/* Allocate message buffers */
message = malloc(sizeof(int) * size);
receiveBuffer = malloc(sizeof(int) * size);
/* Initialize message */
for (i = 0; i < size; i++) {
message[i] = myid;
}
/* Start measuring the time spent in communication */
MPI_Barrier(MPI_COMM_WORLD);
t0 = MPI_Wtime();
/* TODO start */
/* Send and receive messages as defined in exercise */
if (myid < ntasks - 1) {
printf("Sender: %d. Sent elements: %d. Tag: %d. Receiver: %d\n",
myid, size, myid + 1, myid + 1);
}
if (myid > 0) {
printf("Receiver: %d. first element %d.\n",
myid, receiveBuffer[0]);
}
/* TODO end */
/* Finalize measuring the time and print it out */
t1 = MPI_Wtime();
MPI_Barrier(MPI_COMM_WORLD);
fflush(stdout);
if (myid == 0) {
printf("\n");
printf("Timings:\n");
printf("Time elapsed in rank %2d: %6.3f\n", myid, t1 - t0);
}
MPI_Barrier(MPI_COMM_WORLD);
fflush(stdout);
if (myid == ntasks - 1) {
printf("Time elapsed in rank %2d: %6.3f\n", myid, t1 - t0);
}
free(message);
free(receiveBuffer);
MPI_Finalize();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
int i, myid, ntasks;
int size = 10000000;
int *message;
int *receiveBuffer;
MPI_Status statuses[2];
MPI_Request requests[2];
double t0, t1;
int source, destination;
int count;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &ntasks);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
/* Allocate message buffers */
message = malloc(sizeof(int) * size);
receiveBuffer = malloc(sizeof(int) * size);
/* Initialize message */
for (i = 0; i < size; i++) {
message[i] = myid;
}
/* Set source and destination ranks */
if (myid < ntasks - 1) {
destination = myid + 1;
} else {
destination = MPI_PROC_NULL;
}
if (myid > 0) {
source = myid - 1;
} else {
source = MPI_PROC_NULL;
}
/* Start measuring the time spend in communication */
MPI_Barrier(MPI_COMM_WORLD);
t0 = MPI_Wtime();
/* Receive messages in the back ground */
MPI_Irecv(receiveBuffer, size, MPI_INT, source, MPI_ANY_TAG,
MPI_COMM_WORLD, &requests[0]);
/* Send messages in the back ground */
MPI_Isend(message, size, MPI_INT, destination, myid + 1,
MPI_COMM_WORLD, &requests[1]);
/* Blocking wait for messages */
MPI_Waitall(2, requests, statuses);
/* Use status parameter to find out the no. of elements received */
MPI_Get_count(&statuses[0], MPI_INT, &count);
printf("Sender: %d. Sent elements: %d. Tag: %d. Receiver: %d\n",
myid, size, myid + 1, destination);
printf("Receiver: %d. Received elements: %d. Tag %d. Sender: %d.\n",
myid, count, statuses[0].MPI_TAG, statuses[0].MPI_SOURCE);
/* Finalize measuring the time and print it out */
t1 = MPI_Wtime();
MPI_Barrier(MPI_COMM_WORLD);
fflush(stdout);
if (myid == 0) {
printf("\n");
printf("Timings:\n");
printf("Time elapsed in rank %2d: %6.3f\n", myid, t1 - t0);
}
MPI_Barrier(MPI_COMM_WORLD);
fflush(stdout);
if (myid == ntasks - 1) {
printf("Time elapsed in rank %2d: %6.3f\n", myid, t1 - t0);
}
free(message);
free(receiveBuffer);
MPI_Finalize();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
int i, myid, ntasks;
int size = 10000000;
int *message;
int *receiveBuffer;
MPI_Status statuses[2];
MPI_Request requests[2];
double t0, t1;
int source, destination;
int count;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &ntasks);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
/* Allocate message buffers */
message = malloc(sizeof(int) * size);
receiveBuffer = malloc(sizeof(int) * size);
/* Initialize message */
for (i = 0; i < size; i++) {
message[i] = myid;
}
/* Set source and destination ranks */
if (myid < ntasks - 1) {
destination = myid + 1;
} else {
destination = MPI_PROC_NULL;
}
if (myid > 0) {
source = myid - 1;
} else {
source = MPI_PROC_NULL;
}
/* Start measuring the time spend in communication */
MPI_Barrier(MPI_COMM_WORLD);
t0 = MPI_Wtime();
/* Describe the receiving requests */
MPI_Recv_init(receiveBuffer, size, MPI_INT, source, MPI_ANY_TAG,
MPI_COMM_WORLD, &requests[0]);
/* Describe the sending requests */
MPI_Send_init(message, size, MPI_INT, destination, myid + 1,
MPI_COMM_WORLD, &requests[1]);
/* Start communication */
MPI_Startall(2, requests);
/* Blocking wait for messages */
MPI_Waitall(2, requests, statuses);
/* Finalize measuring the time and print it out */
t1 = MPI_Wtime();
/* Use status parameter to find out the no. of elements received */
MPI_Get_count(&statuses[0], MPI_INT, &count);
printf("Sender: %d. Sent elements: %d. Tag: %d. Receiver: %d\n",
myid, size, myid + 1, destination);
printf("Receiver: %d. Received elements: %d. Tag %d. Sender: %d.\n",
myid, count, statuses[0].MPI_TAG, statuses[0].MPI_SOURCE);
MPI_Barrier(MPI_COMM_WORLD);
fflush(stdout);
if (myid == 0) {
printf("\n");
printf("Timings:\n");
printf("Time elapsed in rank %2d: %6.3f\n", myid, t1 - t0);
}
MPI_Barrier(MPI_COMM_WORLD);
fflush(stdout);
if (myid == ntasks - 1) {
printf("Time elapsed in rank %2d: %6.3f\n", myid, t1 - t0);
}
free(message);
free(receiveBuffer);
MPI_Finalize();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
int i, myid, ntasks;
int size = 10000000;
int *message;
int *receiveBuffer;
MPI_Status status;
double t0, t1;
int source, destination;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &ntasks);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
/* Allocate message buffers */
message = malloc(sizeof(int) * size);
receiveBuffer = malloc(sizeof(int) * size);
/* Initialize message */
for (i = 0; i < size; i++) {
message[i] = myid;
}
/* Set source and destination ranks */
if (myid < ntasks - 1) {
destination = myid + 1;
} else {
destination = MPI_PROC_NULL;
}
if (myid > 0) {
source = myid - 1;
} else {
source = MPI_PROC_NULL;
}
/* Start measuring the time spent in communication */
MPI_Barrier(MPI_COMM_WORLD);
t0 = MPI_Wtime();
/* Send and receive messages */
MPI_Sendrecv(message, size, MPI_INT, destination, myid + 1,
receiveBuffer, size, MPI_INT, source, MPI_ANY_TAG,
MPI_COMM_WORLD, &status);
printf("Sender: %d. Sent elements: %d. Tag: %d. Receiver: %d\n",
myid, size, myid + 1, destination);
/* Finalize measuring the time and print it out */
t1 = MPI_Wtime();
MPI_Barrier(MPI_COMM_WORLD);
fflush(stdout);
if (myid == 0) {
printf("\n");
printf("Timings:\n");
printf("Time elapsed in rank %2d: %6.3f\n", myid, t1 - t0);
}
MPI_Barrier(MPI_COMM_WORLD);
fflush(stdout);
if (myid == ntasks - 1) {
printf("Time elapsed in rank %2d: %6.3f\n", myid, t1 - t0);
}
free(message);
free(receiveBuffer);
MPI_Finalize();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
int i, myid, ntasks;
int size = 10000000;
int *message;
int *receiveBuffer;
MPI_Status status;
double t0, t1;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &ntasks);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
/* Allocate message buffers */
message = malloc(sizeof(int) * size);
receiveBuffer = malloc(sizeof(int) * size);
/* Initialize message */
for (i = 0; i < size; i++) {
message[i] = myid;
}
/* Start measuring the time spent in communication */
MPI_Barrier(MPI_COMM_WORLD);
t0 = MPI_Wtime();
/* Send messages */
if (myid < ntasks - 1) {
MPI_Send(message, size, MPI_INT, myid + 1, myid + 1,
MPI_COMM_WORLD);
printf("Sender: %d. Sent elements: %d. Tag: %d. Receiver: %d\n",
myid, size, myid + 1, myid + 1);
}
/* Receive messages */
if (myid > 0) {
MPI_Recv(receiveBuffer, size, MPI_INT, myid - 1, myid,
MPI_COMM_WORLD, &status);
printf("Receiver: %d. first element %d.\n",
myid, receiveBuffer[0]);
}
/* Finalize measuring the time and print it out */
t1 = MPI_Wtime();
MPI_Barrier(MPI_COMM_WORLD);
fflush(stdout);
if (myid == 0) {
printf("\n");
printf("Timings:\n");
printf("Time elapsed in rank %2d: %6.3f\n", myid, t1 - t0);
}
MPI_Barrier(MPI_COMM_WORLD);
fflush(stdout);
if (myid == ntasks - 1) {
printf("Time elapsed in rank %2d: %6.3f\n", myid, t1 - t0);
}
free(message);
free(receiveBuffer);
MPI_Finalize();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
int i, myid, ntasks;
int size = 10000000;
int *message;
int *receiveBuffer;
MPI_Status status;
double t0, t1;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &ntasks);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
/* Allocate message buffers */
message = malloc(sizeof(int) * size);
receiveBuffer = malloc(sizeof(int) * size);
/* Initialize message */
for (i = 0; i < size; i++) {
message[i] = myid;
}
/* Start measuring the time spent in communication */
MPI_Barrier(MPI_COMM_WORLD);
t0 = MPI_Wtime();
/* Send and receive messages */
if ((myid > 0) && (myid < ntasks - 1)) {
MPI_Sendrecv(message, size, MPI_INT, myid + 1, myid + 1,
receiveBuffer, size, MPI_INT, myid - 1, MPI_ANY_TAG,
MPI_COMM_WORLD, &status);
printf("Sender: %d. Sent elements: %d. Tag: %d. Receiver: %d\n",
myid, size, myid + 1, myid + 1);
}
/* Only send a message */
else if (myid < ntasks - 1) {
MPI_Send(message, size, MPI_INT, myid + 1, myid + 1,
MPI_COMM_WORLD);
printf("Sender: %d. Sent elements: %d. Tag: %d. Receiver: %d\n",
myid, size, myid + 1, myid + 1);
}
/* Only receive a message */
else if (myid > 0) {
MPI_Recv(receiveBuffer, size, MPI_INT, myid - 1, myid,
MPI_COMM_WORLD, &status);
printf("Receiver: %d. first element %d.\n",
myid, receiveBuffer[0]);
}
/* Finalize measuring the time and print it out */
t1 = MPI_Wtime();
MPI_Barrier(MPI_COMM_WORLD);
fflush(stdout);
if (myid == 0) {
printf("\n");
printf("Timings:\n");
printf("Time elapsed in rank %2d: %6.3f\n", myid, t1 - t0);
}
MPI_Barrier(MPI_COMM_WORLD);
fflush(stdout);
if (myid == ntasks - 1) {
printf("Time elapsed in rank %2d: %6.3f\n", myid, t1 - t0);
}
free(message);
free(receiveBuffer);
MPI_Finalize();
return 0;
}
program basic
use mpi
use iso_fortran_env, only : REAL64
implicit none
integer, parameter :: size = 10000000
integer :: rc, myid, ntasks
integer :: message(size)
integer :: receiveBuffer(size)
integer :: status(MPI_STATUS_SIZE)
real(REAL64) :: t0, t1
call mpi_init(rc)
call mpi_comm_rank(MPI_COMM_WORLD, myid, rc)
call mpi_comm_size(MPI_COMM_WORLD, ntasks, rc)
message = myid
! Start measuring the time spent in communication
call mpi_barrier(mpi_comm_world, rc)
t0 = mpi_wtime()
! TODO: Send and receive as defined in the assignment
if ( myid < ntasks-1 ) then
write(*,'(A10,I3,A20,I8,A,I3,A,I3)') 'Sender: ', myid, &
' Sent elements: ',size, &
'. Tag: ', myid+1, '. Receiver: ', myid+1
end if
if ( myid > 0 ) then
write(*,'(A10,I3,A,I3)') 'Receiver: ', myid, &
' First element: ', receiveBuffer(1)
end if
! Finalize measuring the time and print it out
t1 = mpi_wtime()
call mpi_barrier(mpi_comm_world, rc)
call flush(6)
if (myid == 0) then
write(*,*)
write(*,*) 'Timings:'
write(*, '(A20, I3, A, F6.3)') 'Time elapsed in rank', myid, ':', t1-t0
endif
call mpi_barrier(mpi_comm_world, rc)
call flush(6)
if (myid == ntasks - 1) then
write(*, '(A20, I3, A, F6.3)') 'Time elapsed in rank', myid, ':', t1-t0
endif
call mpi_finalize(rc)
end program basic
program chain
use mpi
use iso_fortran_env, only : REAL64
implicit none
integer, parameter :: size = 10000000
integer :: rc, myid, ntasks
integer :: message(size)
integer :: receiveBuffer(size)
integer :: status(MPI_STATUS_SIZE,2)
real(REAL64) :: t0, t1
integer :: source, destination
integer :: count
integer :: requests(2)
call mpi_init(rc)
call mpi_comm_rank(MPI_COMM_WORLD, myid, rc)
call mpi_comm_size(MPI_COMM_WORLD, ntasks, rc)
message = myid
! Set source and destination ranks
if (myid < ntasks-1) then
destination = myid + 1
else
destination = MPI_PROC_NULL
end if
if (myid > 0) then
source = myid - 1
else
source = MPI_PROC_NULL
end if
! Start measuring the time spent in communication
call mpi_barrier(mpi_comm_world, rc)
t0 = mpi_wtime()
! Receive messages in the back ground
call mpi_irecv(receiveBuffer, size, MPI_INTEGER, source, &
MPI_ANY_TAG, MPI_COMM_WORLD, requests(1), rc)
! Send messages in the back ground
call mpi_isend(message, size, MPI_INTEGER, destination, &
myid + 1, MPI_COMM_WORLD, requests(2), rc)
! Blocking wait for messages
call mpi_waitall(2, requests, status, rc)
! Use status parameter to find out the no. of elements received
call mpi_get_count(status(:,1), MPI_INTEGER, count, rc)
write(*,'(A10,I3,A20,I8,A,I3,A,I3)') 'Sender: ', myid, &
' Sent elements: ', size, &
'. Tag: ', myid + 1, &
'. Receiver: ', destination
write(*,'(A10,I3,A20,I8,A,I3,A,I3)') 'Receiver: ', myid, &
'received elements: ', count, &
'. Tag: ', status(MPI_TAG, 1), &
'. Sender: ', status(MPI_SOURCE, 1)
! Finalize measuring the time and print it out
t1 = mpi_wtime()
call mpi_barrier(mpi_comm_world, rc)
call flush(6)
if (myid == 0) then
write(*,*)
write(*,*) 'Timings:'
write(*, '(A20, I3, A, F6.3)') 'Time elapsed in rank', myid, ':', t1-t0
endif
call mpi_barrier(mpi_comm_world, rc)
call flush(6)
if (myid == ntasks - 1) then
write(*, '(A20, I3, A, F6.3)') 'Time elapsed in rank', myid, ':', t1-t0
endif
call mpi_finalize(rc)
end program chain
program chain
use mpi
use iso_fortran_env, only : REAL64
implicit none
integer, parameter :: size = 10000000
integer :: rc, myid, ntasks
integer :: message(size)
integer :: receiveBuffer(size)
integer :: status(MPI_STATUS_SIZE,2)
real(REAL64) :: t0, t1
integer :: source, destination
integer :: count
integer :: requests(2)
call mpi_init(rc)
call mpi_comm_rank(MPI_COMM_WORLD, myid, rc)
call mpi_comm_size(MPI_COMM_WORLD, ntasks, rc)
message = myid
! Set source and destination ranks
if (myid < ntasks-1) then
destination = myid + 1
else
destination = MPI_PROC_NULL
end if
if (myid > 0) then
source = myid - 1
else
source = MPI_PROC_NULL
end if
! Start measuring the time spent in communication
call mpi_barrier(mpi_comm_world, rc)
t0 = mpi_wtime()
! Describe the receiving request
call mpi_recv_init(receiveBuffer, size, MPI_INTEGER, source, &
MPI_ANY_TAG, MPI_COMM_WORLD, requests(1), rc)
! Describe the sending request
call mpi_send_init(message, size, MPI_INTEGER, destination, &
myid + 1, MPI_COMM_WORLD, requests(2), rc)
! Start communication
call mpi_startall(2, requests, rc)
! Blocking wait for messages
call mpi_waitall(2, requests, status, rc)
t1 = mpi_wtime()
! Use status parameter to find out the no. of elements received
call mpi_get_count(status(:,1), MPI_INTEGER, count, rc)
write(*,'(A10,I3,A20,I8,A,I3,A,I3)') 'Sender: ', myid, &
' Sent elements: ', size, &
'. Tag: ', myid + 1, &
'. Receiver: ', destination
write(*,'(A10,I3,A20,I8,A,I3,A,I3)') 'Receiver: ', myid, &
'received elements: ', count, &
'. Tag: ', status(MPI_TAG, 1), &
'. Sender: ', status(MPI_SOURCE, 1)
call mpi_barrier(mpi_comm_world, rc)
call flush(6)
if (myid == 0) then
write(*,*)
write(*,*) 'Timings:'
write(*, '(A20, I3, A, F6.3)') 'Time elapsed in rank', myid, ':', t1-t0
endif
call mpi_barrier(mpi_comm_world, rc)
call flush(6)
if (myid == ntasks - 1) then
write(*, '(A20, I3, A, F6.3)') 'Time elapsed in rank', myid, ':', t1-t0
endif
call mpi_finalize(rc)
end program chain
program basic
use mpi
use iso_fortran_env, only : REAL64
implicit none
integer, parameter :: size = 10000000
integer :: rc, myid, ntasks
integer :: message(size)
integer :: receiveBuffer(size)
integer :: status(MPI_STATUS_SIZE)
real(REAL64) :: t0, t1
integer :: source, destination
call mpi_init(rc)
call mpi_comm_rank(MPI_COMM_WORLD, myid, rc)
call mpi_comm_size(MPI_COMM_WORLD, ntasks, rc)
message = myid
! Set source and destination ranks
if (myid < ntasks-1) then
destination = myid + 1
else
destination = MPI_PROC_NULL
end if
if (myid > 0) then
source = myid - 1
else
source = MPI_PROC_NULL
end if
! Start measuring the time spent in communication
call mpi_barrier(mpi_comm_world, rc)
t0 = mpi_wtime()
! Send and receive messages
call mpi_sendrecv(message, size, MPI_INTEGER, destination, myid + 1, &
receiveBuffer, size, MPI_INTEGER, source, MPI_ANY_TAG, &
MPI_COMM_WORLD, status, rc)
write(*,'(A10,I3,A20,I8,A,I3,A,I3)') 'Sender: ', myid, &
' Sent elements: ', size, &
'. Tag: ', myid + 1, &
'. Receiver: ', destination
! Finalize measuring the time and print it out
t1 = mpi_wtime()
call mpi_barrier(mpi_comm_world, rc)
call flush(6)
if (myid == 0) then
write(*,*)
write(*,*) 'Timings:'
write(*, '(A20, I3, A, F6.3)') 'Time elapsed in rank', myid, ':', t1-t0
endif
call mpi_barrier(mpi_comm_world, rc)
call flush(6)
if (myid == ntasks - 1) then
write(*, '(A20, I3, A, F6.3)') 'Time elapsed in rank', myid, ':', t1-t0
endif
call mpi_finalize(rc)
end program basic
program basic
use mpi
use iso_fortran_env, only : REAL64
implicit none
integer, parameter :: size = 10000000
integer :: rc, myid, ntasks
integer :: message(size)
integer :: receiveBuffer(size)
integer :: status(MPI_STATUS_SIZE)
real(REAL64) :: t0, t1
call mpi_init(rc)
call mpi_comm_rank(MPI_COMM_WORLD, myid, rc)
call mpi_comm_size(MPI_COMM_WORLD, ntasks, rc)
message = myid
! Start measuring the time spent in communication
call mpi_barrier(mpi_comm_world, rc)
t0 = mpi_wtime()
! Send messages
if ( myid < ntasks-1 ) then
call mpi_send(message, size, MPI_INTEGER, myid+1, &
myid+1, MPI_COMM_WORLD, rc)
write(*,'(A10,I3,A20,I8,A,I3,A,I3)') 'Sender: ', myid, &
' Sent elements: ',size, &
'. Tag: ', myid+1, '. Receiver: ', myid+1
end if
! Receive messages
if ( myid > 0 ) then
call mpi_recv(receiveBuffer, size, MPI_INTEGER, myid-1, &
myid, MPI_COMM_WORLD, status, rc)
write(*,'(A10,I3,A,I3)') 'Receiver: ', myid, &
' First element: ', receiveBuffer(1)
end if
! Finalize measuring the time and print it out
t1 = mpi_wtime()
call mpi_barrier(mpi_comm_world, rc)
call flush(6)
if (myid == 0) then
write(*,*)
write(*,*) 'Timings:'
write(*, '(A20, I3, A, F6.3)') 'Time elapsed in rank', myid, ':', t1-t0
endif
call mpi_barrier(mpi_comm_world, rc)
call flush(6)
if (myid == ntasks - 1) then
write(*, '(A20, I3, A, F6.3)') 'Time elapsed in rank', myid, ':', t1-t0
endif
call mpi_finalize(rc)
end program basic
program basic
use mpi
use iso_fortran_env, only : REAL64
implicit none
integer, parameter :: size = 10000000
integer :: rc, myid, ntasks
integer :: message(size)
integer :: receiveBuffer(size)
integer :: status(MPI_STATUS_SIZE)
real(REAL64) :: t0, t1
call mpi_init(rc)
call mpi_comm_rank(MPI_COMM_WORLD, myid, rc)
call mpi_comm_size(MPI_COMM_WORLD, ntasks, rc)
message = myid
! Start measuring the time spent in communication
call mpi_barrier(mpi_comm_world, rc)
t0 = mpi_wtime()
if ( (myid > 0) .and. (myid < ntasks-1) ) then
! Send and receive messages
call mpi_sendrecv(message, size, MPI_INTEGER, myid + 1, myid + 1, &
receiveBuffer, size, MPI_INTEGER, myid - 1, MPI_ANY_TAG, &
MPI_COMM_WORLD, status, rc)
write(*,'(A10,I3,A20,I8,A,I3,A,I3)') 'Sender: ', myid, &
' Sent elements: ', size, &
'. Tag: ', myid + 1, '. Receiver: ', myid + 1
else if (myid < ntasks-1) then
! Only send a message
call mpi_send(message, size, MPI_INTEGER, myid+1, &
myid+1, MPI_COMM_WORLD, rc)
write(*,'(A10,I3,A20,I8,A,I3,A,I3)') 'Sender: ', myid, &
' Sent elements: ', size, &
'. Tag: ', myid + 1, '. Receiver: ', myid + 1
else if (myid > 0) then
! Only receive a message
call mpi_recv(receiveBuffer, size, MPI_INTEGER, myid - 1, &
myid, MPI_COMM_WORLD, status, rc)
write(*,'(A10,I3,A,I3)') 'Receiver: ', myid, &
' First element: ', receiveBuffer(1)
end if
! Finalize measuring the time and print it out
t1 = mpi_wtime()
call mpi_barrier(mpi_comm_world, rc)
call flush(6)
if (myid == 0) then
write(*,*)
write(*,*) 'Timings:'
write(*, '(A20, I3, A, F6.3)') 'Time elapsed in rank', myid, ':', t1-t0
endif
call mpi_barrier(mpi_comm_world, rc)
call flush(6)
if (myid == ntasks - 1) then
write(*, '(A20, I3, A, F6.3)') 'Time elapsed in rank', myid, ':', t1-t0
endif
call mpi_finalize(rc)
end program basic
from __future__ import print_function
from mpi4py import MPI
import numpy
from sys import stdout
comm = MPI.COMM_WORLD
myid = comm.Get_rank()
ntasks = comm.Get_size()
# Send and receive buffers
n = 10000000
data = numpy.zeros(n, int) + myid
buff = numpy.zeros(n, int)
# Message chain using Send and Recv
# Start measuring the time spent in communication
comm.barrier()
t0 = MPI.Wtime()
# TODO start
# Send and receive messages as defined in exercise
if myid < ntasks - 1:
pass
print(" Rank {0:d}: sent {1:d} elements to rank {2:d}.".format(myid,
len(data),
myid+1))
if myid > 0:
pass
print(" Rank {0:d}: received an array filled with {1:d}s.".format(myid,
buff[0]))
# TODO end
t1 = MPI.Wtime()
# ... wait for every rank to finish ...
stdout.flush()
comm.barrier()
if myid == 0:
print("")
print("Timings")
print("Time elapsed in rank {0} {1:6.3f}".format(myid, t1 - t0))
stdout.flush()
comm.barrier()
if myid == ntasks - 1:
print("Time elapsed in rank {0} {1:6.3f}".format(myid, t1 - t0))
from __future__ import print_function
from mpi4py import MPI
import numpy
from sys import stdout
comm = MPI.COMM_WORLD
myid = comm.Get_rank()
ntasks = comm.Get_size()
# Send and receive buffers
n = 10000000
data = numpy.zeros(n, int) + myid
buff = numpy.zeros(n, int)
# Message chain using Sendrecv and MPI.PROC_NULL
tgt = myid + 1
src = myid - 1
if myid == 0:
src = MPI.PROC_NULL
elif myid == ntasks - 1:
tgt = MPI.PROC_NULL
# Start measuring the time spent in communication
comm.barrier()
t0 = MPI.Wtime()
req_recv = comm.Irecv(buff, source=src)
req_send = comm.Isend(data, dest=tgt)
MPI.Request.Waitall((req_recv, req_send))
print(" Rank {0}: sent {1} elements to myid {2}.".format(myid, len(data), tgt))
print(" Rank {0}: received a message from myid {1}.".format(myid, src))
print(" Rank {0}: received an array filled with {1}s.".format(myid, buff[0]))
t1 = MPI.Wtime()
# ... wait for every myid to finish ...
stdout.flush()
comm.barrier()
if myid == 0:
print("")
print("Timings")
print("Time elapsed in myid {0} {1:6.3f}".format(myid, t1 - t0))
stdout.flush()
comm.barrier()
if myid == ntasks - 1:
print("Time elapsed in myid {0} {1:6.3f}".format(myid, t1 - t0))
from __future__ import print_function
from mpi4py import MPI
import numpy
from sys import stdout
comm = MPI.COMM_WORLD
myid = comm.Get_rank()
ntasks = comm.Get_size()
# Send and receive buffers
n = 10000000
data = numpy.zeros(n, int) + myid
buff = numpy.zeros(n, int)
# Message chain using Sendrecv and MPI.PROC_NULL
tgt = myid + 1
src = myid - 1
if myid == 0:
src = MPI.PROC_NULL
elif myid == ntasks - 1:
tgt = MPI.PROC_NULL
# Start measuring the time spent in communication
comm.barrier()
t0 = MPI.Wtime()
req_recv = comm.Recv_init(buff, source=src)
req_send = comm.Send_init(data, dest=tgt)
MPI.Prequest.Startall((req_recv, req_send))
MPI.Request.Waitall((req_recv, req_send))
print(" Rank {0}: sent {1} elements to myid {2}.".format(myid, len(data), tgt))
print(" Rank {0}: received a message from myid {1}.".format(myid, src))
print(" Rank {0}: received an array filled with {1}s.".format(myid, buff[0]))
t1 = MPI.Wtime()
# ... wait for every myid to finish ...
stdout.flush()
comm.barrier()
if myid == 0:
print("")
print("Timings")
print("Time elapsed in myid {0} {1:6.3f}".format(myid, t1 - t0))
stdout.flush()
comm.barrier()
if myid == ntasks - 1:
print("Time elapsed in myid {0} {1:6.3f}".format(myid, t1 - t0))
from __future__ import print_function
from mpi4py import MPI
import numpy
from sys import stdout
comm = MPI.COMM_WORLD
myid = comm.Get_rank()
ntasks = comm.Get_size()
# Send and receive buffers
n = 10000000
data = numpy.zeros(n, int) + myid
buff = numpy.zeros(n, int)
# Message chain using Sendrecv and MPI.PROC_NULL
tgt = myid + 1
src = myid - 1
if myid == 0:
src = MPI.PROC_NULL
elif myid == ntasks - 1:
tgt = MPI.PROC_NULL
# Start measuring the time spent in communication
comm.barrier()
t0 = MPI.Wtime()
# use the same MPI call to do all communication
comm.Sendrecv(data, dest=tgt, recvbuf=buff, source=src)
print(" Rank {0}: sent {1} elements to myid {2}.".format(myid, len(data), tgt))
print(" Rank {0}: received a message from myid {1}.".format(myid, src))
print(" Rank {0}: received an array filled with {1}s.".format(myid, buff[0]))
t1 = MPI.Wtime()
# ... wait for every myid to finish ...
stdout.flush()
comm.barrier()
if myid == 0:
print("")
print("Timings")
print("Time elapsed in myid {0} {1:6.3f}".format(myid, t1 - t0))
stdout.flush()
comm.barrier()
if myid == ntasks - 1:
print("Time elapsed in myid {0} {1:6.3f}".format(myid, t1 - t0))
from __future__ import print_function
from mpi4py import MPI
import numpy
from sys import stdout
comm = MPI.COMM_WORLD
myid = comm.Get_rank()
ntasks = comm.Get_size()
# Send and receive buffers
n = 10000000
data = numpy.zeros(n, int) + myid
buff = numpy.zeros(n, int)
# Message chain using Send and Recv
# Start measuring the time spent in communication
comm.barrier()
t0 = MPI.Wtime()
tgt = myid + 1
src = myid - 1
if myid < ntasks - 1:
comm.Send(data, dest=tgt, tag=tgt)
print(" Rank {0:d}: sent {1:d} elements to rank {2:d}.".format(myid,
len(data),
tgt))
if myid > 0:
comm.Recv(buff, source=src, tag=myid)
print(" Rank {0:d}: received an array filled with {1:d}s.".format(myid,
buff[0]))
t1 = MPI.Wtime()
# ... wait for every rank to finish ...
stdout.flush()
comm.barrier()
if myid == 0:
print("")
print("Timings")
print("Time elapsed in rank {0} {1:6.3f}".format(myid, t1 - t0))
stdout.flush()
comm.barrier()
if myid == ntasks - 1:
print("Time elapsed in rank {0} {1:6.3f}".format(myid, t1 - t0))
from __future__ import print_function
from mpi4py import MPI
import numpy
from sys import stdout
comm = MPI.COMM_WORLD
myid = comm.Get_rank()
ntasks = comm.Get_size()
# Send and receive buffers
n = 10000000
data = numpy.zeros(n, int) + myid
buff = numpy.zeros(n, int)
# Message chain using Sendrecv
# Start measuring the time spent in communication
comm.barrier()
t0 = MPI.Wtime()
tgt = myid + 1
src = myid - 1
if myid > 0 and myid < ntasks -1: # middle of chain; send and receive
comm.Sendrecv(data, dest=tgt, sendtag=tgt,
recvbuf=buff, source=src, recvtag=myid)
print(" Rank {0}: sent {1} elements to myid {2}.".format(myid, len(data), tgt))
print(" Rank {0}: received a message from myid {1}.".format(myid, src))
print(" Rank {0}: received an array filled with {1}s.".format(myid, buff[0]))
elif myid == 0: # start of chain; only send
comm.Send(data, dest=tgt, tag=tgt)
print(" Rank {0}: sent {1} elements to myid {2}.".format(myid,
len(data), tgt))
elif myid == ntasks - 1: # end of chain; only receive
comm.Recv(buff, source=src, tag=myid)
print(" Rank {0}: received a message from myid {1}.".format(myid, src))
print(" Rank {1}: received an array filled with {1}s.".format(myid, buff[0]))
t1 = MPI.Wtime()
# ... wait for every myid to finish ...
stdout.flush()
comm.barrier()
if myid == 0:
print("")
print("Timings")
print("Time elapsed in myid {0} {1:6.3f}".format(myid, t1 - t0))
stdout.flush()
comm.barrier()
if myid == ntasks - 1:
print("Time elapsed in myid {0} {1:6.3f}".format(myid, t1 - t0))