MPI
Distributed-memory parallelism across processes/nodes using the Message Passing Interface.
Distributed-memory parallelism across processes/nodes using the Message Passing Interface.
29.1 Hello MPI
program hello_mpi
use mpi_f08 ! modern Fortran binding (type-safe)
implicit none
integer :: rank, nprocs
call MPI_Init()
call MPI_Comm_rank(MPI_COMM_WORLD, rank)
call MPI_Comm_size(MPI_COMM_WORLD, nprocs)
print '(a, i0, a, i0)', "Hello from rank ", rank, " of ", nprocs
call MPI_Finalize()
end program hello_mpimpifort hello_mpi.f90 -o hello_mpi # Open MPI / MPICH / Intel MPI wrapper
mpirun -np 4 ./hello_mpi29.2 Point-to-point & collectives
real(8) :: local_sum, global_sum, buf(100)
type(MPI_Status) :: status
type(MPI_Request) :: req
! Send / receive
if (rank == 0) then
call MPI_Send(buf, 100, MPI_DOUBLE_PRECISION, 1, 0, MPI_COMM_WORLD)
else if (rank == 1) then
call MPI_Recv(buf, 100, MPI_DOUBLE_PRECISION, 0, 0, MPI_COMM_WORLD, status)
end if
! Non-blocking
call MPI_Isend(buf, 100, MPI_DOUBLE_PRECISION, dest, tag, MPI_COMM_WORLD, req)
call MPI_Wait(req, status)
! Collectives
call MPI_Bcast(params, 10, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD)
call MPI_Reduce(local_sum, global_sum, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD)
call MPI_Allreduce(local_sum, global_sum, 1, MPI_DOUBLE_PRECISION, MPI_SUM, MPI_COMM_WORLD)
call MPI_Scatter(full, nloc, MPI_DOUBLE_PRECISION, part, nloc, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD)
call MPI_Gather(part, nloc, MPI_DOUBLE_PRECISION, full, nloc, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD)
call MPI_Barrier(MPI_COMM_WORLD)
t = MPI_Wtime()29.3 Parallel π example
program mpi_pi
use mpi_f08
implicit none
integer, parameter :: n = 100000000
integer :: rank, nprocs, i
real(8) :: h, x, local, pi
call MPI_Init()
call MPI_Comm_rank(MPI_COMM_WORLD, rank)
call MPI_Comm_size(MPI_COMM_WORLD, nprocs)
h = 1.0d0 / n
local = 0.0d0
do i = rank + 1, n, nprocs ! cyclic distribution of work
x = h * (i - 0.5d0)
local = local + 4.0d0 / (1.0d0 + x * x)
end do
local = local * h
call MPI_Reduce(local, pi, 1, MPI_DOUBLE_PRECISION, MPI_SUM, 0, MPI_COMM_WORLD)
if (rank == 0) print '(a, f18.15)', "pi = ", pi
call MPI_Finalize()
end program mpi_pi29.4 Advanced MPI topics
Domain decomposition & halo exchange (MPI_Sendrecv), Cartesian topologies (MPI_Cart_create, MPI_Cart_shift), derived datatypes (MPI_Type_vector for strided columns), one-sided communication (RMA), parallel I/O (MPI-IO, parallel HDF5/NetCDF), hybrid MPI+OpenMP, communicators/groups, profiling tools (Score-P, TAU, Intel Trace Analyzer).