MPI Tutorial
MPI Tutorial
ch
@spcl_eth
S. DI GIROLAMO [DIGIROLS@[Link]]
MPI Tutorial – Part 1
Design of Parallel and High-Performance Computing – Recitation Session
Basic Info
First DPHPC lecture: 09/25
Assignments
are an important part of the course.
You will not learn this material from listening to a lecture alone -- you have to do the assignments.
They are not graded, but feedbacks are provided if handend-in
2
[Link]
@spcl_eth
3
[Link]
@spcl_eth
4
[Link]
@spcl_eth
MPI
Process Process
MPI
5
[Link]
@spcl_eth
Process1
O(N log N) 8 23 19 67 45 35 1 24 13 30 3 5
Process1 Process2
8 19 23 35 45 67 1 3 5 13 24 30
O(N/2 log N/2) O(N/2 log N/2)
1 3 5 8 13 19 23 24 30 35 45 67 O(N)
Process1
6
[Link]
@spcl_eth
Early vendor systems (Intel’s NX, IBM’s EUI, TMC’s CMMD) were
not portable (or very capable)
Early portable systems (PVM, p4, TCGMSG, Chameleon) were mainly research efforts
– Did not address the full spectrum of message-passing issues
– Lacked vendor support
– Were not implemented at the most efficient level
The MPI Forum was a collection of vendors, portability writersand
users that wanted to standardize all these efforts
7
[Link]
@spcl_eth
What is MPI?
MPI: Message Passing Interface
– The MPI Forum organized in 1992 with broad participation by:
• Vendors: IBM, Intel, TMC, SGI, Convex, Meiko
• Portability library writers: PVM, p4
• Users: application scientists and library writers
• MPI-1 finished in 18 months
– Incorporates the best ideas in a “standard” way
• Each function takes fixed arguments
• Each function has fixed semantics
– Standardizes what the MPI implementation provides and what the application can and cannot expect
– Each system can implement it differently as long as the semantics match
MPI is not…
– a language or compiler specification
– a specific implementation or product
8
[Link]
@spcl_eth
9
[Link]
@spcl_eth
10
[Link]
@spcl_eth
11
[Link]
@spcl_eth
Process Identification
12
[Link]
@spcl_eth
Communicators
mpiexec -np 16 ./test
Communicators do not
need to contain all 0 01 12 3
processes in the system When you start an MPI
program, there is one
04 215 326 37 predefined communicator
MPI_COMM_WORLD
Communicators can be created “by hand” or using tools provided by MPI (not discussed in this tutorial)
Simple programs typically only use the predefined communicator MPI_COMM_WORLD
13
[Link]
@spcl_eth
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
printf("I am %d of %d\n", rank, size);
MPI_Finalize();
return 0;
}
14
[Link]
@spcl_eth
Data Communication
Data communication in MPI is like email exchange
– One process sends a copy of the data to another process (or a group of processes), and the other process
receives it
Communication requires the following information:
– Sender has to know:
• Whom to send the data to (receiver’s process rank)
• What kind of data to send (100 integers or 200 characters, etc)
• A user-defined “tag” for the message (think of it as an email subject; allows the receiver to understand what
type of data is being received)
– Receiver “might” have to know:
• Who is sending the data (OK if the receiver does not know; in this case sender rank will be MPI_ANY_SOURCE,
meaning anyone can send)
• What kind of data is being received (partial information is OK: I might receive up to 1000 integers)
• What the user-defined “tag” of the message is (OK if the receiver does not know; in this case tag will be
MPI_ANY_TAG)
15
[Link]
@spcl_eth
16
[Link]
@spcl_eth
17
[Link]
@spcl_eth
Messages are sent with an accompanying user-defined integer tag, to assist the
receiving process in identifying the message
For example, if an application is expecting two types of messages from a peer, tags
can help distinguish these two types
Messages can be screened at the receiving end by specifying a specific tag
MPI_ANY_TAG is a special “wild-card” tag that can be used by the receiver to match any
tag
18
[Link]
@spcl_eth
When this function returns, the data has been delivered to the system and the buffer can
be reused.
– The message may not have been received by the target process.
19
[Link]
@spcl_eth
20
[Link]
@spcl_eth
Waits until a matching (on source, tag, comm) message is received from the system, and
the buffer can be used.
source is rank in communicator comm, or MPI_ANY_SOURCE.
Receiving fewer than count occurrences of datatype is OK, but receiving more is an
error.
status contains further information:
– Who sent the message (can be used if you used MPI_ANY_SOURCE)
– How much data was actually received
– What tag was used with the message (can be used if you used MPI_ANY_TAG)
– MPI_STATUS_IGNORE can be used if we don’t need any additional information
21
[Link]
@spcl_eth
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0)
MPI_Send(data, 100, MPI_INT, 1, 0, MPI_COMM_WORLD);
else if (rank == 1)
MPI_Recv(data, 100, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Finalize();
return 0;
}
22
[Link]
@spcl_eth
Rank 0
8 23 19 67 45 35 1 24 13 30 3 5
8 19 23 35 45 67 1 3 5 13 24 30
Rank 0
8 19 23 35 45 67 1 3 5 13 24 30
Rank 0
1 3 5 8 13 19 23 24 30 35 45 67
23
[Link]
@spcl_eth
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0) {
MPI_Send(&a[500], 500, MPI_INT, 1, 0, MPI_COMM_WORLD);
sort(a, 500);
MPI_Recv(b, 500, MPI_INT, 1, 0, MPI_COMM_WORLD, &status);
MPI_Finalize(); return 0;
} 24
[Link]
@spcl_eth
Status Object
The status object is used after completion of a receive to findthe actual length, source, and tag of
a message
Status object is MPI-defined type and provides information about:
– The source process for the message (status.MPI_SOURCE)
– The message tag (status.MPI_TAG)
– Error status (status.MPI_ERROR)
The number of elements received is given by:
25
[Link]
@spcl_eth
Task 1 Task 2
Each “worker process” computes some task (maximum 100 elements) and sends it to the
“master” process together with its group number: the “tag” field can be used to represent
the task
– Data count is not fixed (maximum 100 elements)
– Order in which workers send output to master is not fixed (different workers = different src ranks, and
different tasks = different tags)
26
[Link]
@spcl_eth
if (rank != 0)
MPI_Send(data, rand() % 100, MPI_INT, 0, group_id, MPI_COMM_WORLD);
else {
for (i = 0; i < size – 1 ; i++) {
MPI_Recv(data, 100, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
MPI_Get_count(&status, MPI_INT, &count);
printf(“worker ID: %d; task ID: %d; count: %d\n”, [Link], [Link], count);
}
}
[...snip...]
}
27
[Link]
@spcl_eth
MPI is Simple
Many parallel programs can be written using just these six functions, only two of which are non-trivial:
– MPI_INIT – initialize the MPI library (must be the
first routine called)
– MPI_COMM_SIZE - get the size of a communicator
– MPI_COMM_RANK – get the rank of the calling process
in the communicator
– MPI_SEND – send a message to another process
– MPI_RECV – send a message to another process
– MPI_FINALIZE – clean up all MPI state (must be the last MPI function
called by a process)
For performance, however, you need to use other MPI features
28
[Link]
@spcl_eth
29
[Link]
@spcl_eth
30
[Link]
@spcl_eth
31
[Link]
@spcl_eth
32
[Link]
@spcl_eth
Blocking Communication
In blocking communication.
– MPI_SEND does not return until buffer is empty (available for reuse)
– MPI_RECV does not return until buffer is full (available for use)
A process sending data will be blocked until data in the send buffer is emptied
A process receiving data will be blocked until the receive buffer is filled
Exact completion semantics of communication generally depends on the
message size and the system buffer size
Blocking communication is simple to use but can be prone to deadlocks
If (rank == 0) Then
Call mpi_send(..)
Call mpi_recv(..)
Usually deadlocks Else
Call mpi_send(..) UNLESS you reverse send/recv
Call mpi_recv(..)
Endif
33
[Link]
@spcl_eth
time
34
[Link]
@spcl_eth
Non-Blocking Communication
Non-blocking (asynchronous) operations return (immediately) ‘‘request handles” that can be waited on and
queried
– MPI_ISEND(start, count, datatype, dest, tag, comm, request)
– MPI_IRECV(start, count, datatype, src, tag, comm, request)
– MPI_WAIT(request, status)
Non-blocking operations allow overlapping computation and communication
One can also test without waiting using MPI_TEST
– MPI_TEST(request, flag, status)
Anywhere you use MPI_SEND or MPI_RECV, you can use the pair of
MPI_ISEND/MPI_WAIT or MPI_IRECV/MPI_WAIT
Combinations of blocking and non-blocking sends/receives can be used to synchronize execution instead of
barriers
35
[Link]
@spcl_eth
Multiple Completions
36
[Link]
@spcl_eth
time
37
[Link]
@spcl_eth
Just because the send completes does not mean that the receive has completed
– Message may be buffered by the system
– Message may still be in transit
38
[Link]
@spcl_eth
39
[Link]
@spcl_eth
MPI_REDUCE combines data from all processes in the communicator and returns it to one
process.
In many numerical algorithms, SEND/RECV can be replaced by BCAST/REDUCE, improving
both simplicity and efficiency.
40
[Link]
@spcl_eth
41
[Link]
@spcl_eth
Synchronization
MPI_BARRIER(comm)
– Blocks until all processes in the group of the communicator comm call it
– A process cannot get out of the barrier until all other processes have reached barrier
42
[Link]
@spcl_eth
P0 A A
P1 Broadcast A
P2 A
P3 A
int MPI_Scatter(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount,
MPI_Datatype recvtype, int root, MPI_Comm comm)
P0 A B C D Scatter A
P1
B
P2
C
Gather
P3
D
int MPI_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount,
MPI_Datatype recvtype, int root, MPI_Comm comm)
43
[Link]
@spcl_eth
int MPI_Allgather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount,
MPI_Datatype recvtype, MPI_Comm comm)
P0 A A B C D
P1 B Allgather A B C D
P2 C A B C D
P3 D A B C D
int MPI_Alltoall(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount,
MPI_Datatype recvtype, MPI_Comm comm)
P0 A0 A1 A2 A3 A0 B0 C0 D0
P1
B0 B1 B2 B3 Alltoall A1 B1 C1 D1
P2
C0 C1 C2 C3 A2 B2 C2 D2
P3
D0 D1 D2 D3 A3 B3 C3 D3
44
[Link]
@spcl_eth
Collective Computation
int MPI_Reduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root,
MPI_Comm comm)
P0 A A+B+C+D
P1 B Reduce
P2 C
P3 D
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op,
MPI_Comm comm)
P0 A A+B+C+D
P1 B AllReduce A+B+C+D
P2 C A+B+C+D
P3 D A+B+C+D
45
[Link]
@spcl_eth
int MPI_Scan(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op,
MPI_Comm comm)
P0 A A
P1 B AB
Scan
P2 C ABC
P3 D ABCD
MPI_ALLREDUCE, MPI_REDUCE, MPI_REDUCESCATTER, and MPI_SCAN take both built-in and user-
defined combiner functions
46
[Link]
@spcl_eth
MPI_MAX Maximum
MPI_MIN Minimum
MPI_PROD Product
MPI_SUM Sum
MPI_LAND Logical and
MPI_LOR Logical or
MPI_LXOR Logical exclusive or
MPI_BAND Bitwise and
MPI_BOR Bitwise or
MPI_BXOR Bitwise exclusive or
MPI_MAXLOC Maximum and location
MPI_MINLOC Minimum and location
47
[Link]
@spcl_eth
48
[Link]
@spcl_eth
Homework
Find an iterative method to calculate Pi (if you cannot find one read
[Link]
Write a sequential version in C
Write a parallel version using MPI (based on seq. Code)
49