Parallel Programming With MPI

William Gropp
Argonne National Laboratory Mathematics and Computer Science Division

1

Overview
• Introduction to MPI
♦ What it is ♦ Where it came from ♦ Basic MPI communication • Some simple example ♦ Some simple exercises ♦ More advanced MPI communication ♦ A non-trivial exercise ♦ Looking to the future: some features from MPI-2

• Building programs using MPI libraries
♦ PETSc • Poisson solver with no MPI ♦ pnetCDF • High performance parallel I/O
2
University of Chicago Department of Energy

Models for Parallel Computation
• Shared memory (load, store, lock, unlock) • Message Passing (send, receive, broadcast, ...) • Transparent (compiler works magic) • Directive-based (compiler needs help) • Others (BSP, OpenMP, ...) • Task farming (scientific term for large transaction processing)
3
University of Chicago Department of Energy

Why Yet Another Parallel Programming Approach?
• Distributed memory (shared nothing) systems
♦ Common, easier to build, dominate high-

end computing (over 329 of top 500; all 1998 Gordon Bell Prize finalists; most highest-performing applications)

• Performance depends on managing memory use
♦ Goal of many parallel programming models

is to simplify programming by hiding details of memory locality and management (parallel programming for the masses)
4
Department of Energy

• Support for modular programming
University of Chicago

Message Passing Features • Parallel programs consist of separate processes. each with its own address space ♦ Programmer manages memory by placing data in a particular process • Data sent explicitly between processes ♦ Programmer manages memory motion • Collective operations ♦ On arbitrary set of processes • Data distribution ♦ Also managed by programmer • Message passing model doesn’t get in the way • It doesn’t help either 5 University of Chicago Department of Energy .

but not in practical sense.) Message passing (and MPI) is for MIMD/SPMD parallelism.the same instructions are carried out simultaneously on multiple data items (SIMD) • Task Parallel .Types of Parallel Computing Models • Data Parallel . University of Chicago 6 Department of Energy . multiple data) not synchronized at individual operation level • SPMD is equivalent to MIMD since each MIMD program can be made SPMD (similarly for SIMD. HPF is an example of an SIMD interface.different instructions on different data (MIMD) • SPMD (single program.

Comparison with Other Models • Single process (address space) model ♦ OpenMP and threads in general ♦ Fortran 90/95 and compiler-discovered parallelism ♦ System manages memory and (usually) thread scheduling ♦ Named variables refer to the same storage • Single name space model ♦ HPF ♦ Data distribution part of the language. but programs still written as if there is a single name space 7 Department of Energy University of Chicago .

.. A University of Chicago • Integer A(10) do i=1.The Distributed Memory or “Shared-Nothing” Model Process 0 Address Space Process 1 A(10) A(10) Different Variables! • Integer A(10) … print *. 8 Department of Energy .10 A(i) = i enddo .

The Message-Passing Model • A process is (traditionally) a program counter and address space • Processes may have multiple threads (program counters and associated stacks) sharing a single address space • Message passing is for communication among processes. which have separate address spaces • Interprocess communication consists of ♦ synchronization ♦ movement of data from one process’s address space to another’s 9 Department of Energy University of Chicago .

What is MPI? • A message-passing library specification ♦ extended message-passing model ♦ not a language or compiler specification ♦ not a specific implementation or product • For parallel computers. and tool developers 10 University of Chicago Department of Energy . and heterogeneous networks • Full-featured • Designed to provide access to advanced parallel hardware for end users. library writers. clusters.

Where Did MPI Come From? • Early vendor systems (Intel’s NX. IBM’s EUI. Convex. Intel. p4 ♦ users: application scientists and library writers ♦ finished in 18 months University of Chicago 11 Department of Energy . TCGMSG. Chameleon) were mainly research efforts ♦ Did not address the full spectrum of issues ♦ Lacked vendor support ♦ Were not implemented at the most efficient level • The MPI Forum organized in 1992 with broad participation by: ♦ vendors: IBM. p4. Meiko ♦ portability library writers: PVM. SGI. TMC. TMC’s CMMD) were not portable (or very capable) • Early portable systems (PVM.

user views of process layout • Profiling interface encourages portable tools 12 University of Chicago Department of Energy .Novel Features of MPI • Communicators encapsulate communication spaces for library safety • Datatypes reduce copying costs and permit heterogeneity • Multiple communication modes allow precise buffer management • Extensive collective operations for scalable global communication • Process topologies permit efficient process placement.

mpi-forum.MPI References • The Standard itself: ♦ at http://www.anl. in both postscript and HTML • Other information on Web: ♦ at http://www.gov/mpi ♦ pointers to lots of stuff.mcs. other MPI pages 13 Department of Energy University of Chicago . a FAQ. including other talks and tutorials.org ♦ All MPI official releases.

• Designing and Building Parallel Programs. 1999. by Gropp. Saphir. MIT Press. by Snir. MIT Press. and Dongarra.Vol 1 The MPI Core. • MPI: The Complete Reference . 1995. Otto. Lusk. Addison-Wesley. Lusk.Vol 2 The MPI Extensions. 14 University of Chicago Department of Energy . Huss-Lederman. by Gropp. Nitzberg. and Snir. and Skjellum. 1998. Walker. MIT Press. • MPI: The Complete Reference . 1997. Huss-Lederman. • Parallel Programming with MPI. Lumsdaine.Books on MPI • Using MPI: Portable Parallel Programming with the Message-Passing Interface (2nd edition). 1998. by Ian Foster. Morgan-Kaufmann. by Peter Pacheco.

h for C • mpif.Programming With MPI • MPI is a library ♦ All operations are performed with routine calls ♦ Basic definitions in • mpi.h for Fortran 77 and 90 • MPI module for Fortran 90 (optional) • First Program: ♦ Create 4 processes in a simple MPI job ♦ Write out process number ♦ Write out some variables (illustrate separate name space) 15 University of Chicago Department of Energy .

♦ MPI_Comm_rank reports the rank. a number between 0 and size-1.Finding Out About the Environment • Two important questions that arise early in a parallel program are: ♦ How many processes are participating in this computation? ♦ Which one am I? • MPI provides functions to answer these questions: ♦ MPI_Comm_size reports the number of processes. identifying the calling process University of Chicago 16 Department of Energy .

MPI_Comm_size( MPI_COMM_WORLD.h> int main( int argc.Hello (C) #include "mpi. size ).h" #include <stdio. size. &rank ). char *argv[] ) { int rank. return 0. MPI_Init( &argc. rank. MPI_Finalize(). &argv ). &size ). printf( "I am %d of %d\n". MPI_Comm_rank( MPI_COMM_WORLD. } 17 University of Chicago Department of Energy .

ierr ) call MPI_COMM_SIZE( MPI_COMM_WORLD. ierr ) print *. rank. size call MPI_INIT( ierr ) call MPI_COMM_RANK( MPI_COMM_WORLD. 'I am '. ' of '. size.h' integer ierr. rank. size call MPI_FINALIZE( ierr ) end 18 University of Chicago Department of Energy .Hello (Fortran) program main include 'mpif. rank.

MPI::Finalize().h> int main( int argc.Get_size().h" #include <iostream. size = MPI_COMM_WORLD. size. &argv ). MPI::Init( &argc. } 19 University of Chicago Department of Energy . return 0.Get_rank(). cout << "I am " << rank << " of " << size << endl. rank = MPI_COMM_WORLD. char *argv[] ) { int rank.Hello (C++) #include "mpi.

h (in C) or mpif. • A consequence of the requirement that non-MPI statements execute independently University of Chicago 20 Department of Energy . line.h (in Fortran) and designates all processes in the MPI “job” • Each statement executes independently in each process ♦ including the printf/print statements • I/O not part of MPI-1 ♦ print and write to standard output or error not part of either MPI-1 or MPI-2 ♦ output order is undefined (may be interleaved by character. or blocks of characters).Notes on Hello World • All MPI programs begin with MPI_Init and end with MPI_Finalize • MPI_COMM_WORLD is defined by mpi.

starting an MPI program is dependent on the implementation of MPI you are using. and might require various scripts. program arguments. as a recommendation.out to run an MPI program • In general. and/or environment variables. but not a requirement.Running MPI Programs • The MPI-1 Standard does not specify how to run an MPI program. Many parallel systems use a batch environment to share resources among users ♦ The specific commands to run a program on a parallel system are • • defined by the environment installed on the parallel computer 21 University of Chicago Department of Energy . ♦ Many implementations provided mpirun –np 4 a. mpiexec <args> is part of MPI-2. just as the Fortran standard does not specify how to run a Fortran program. for implementors.

MPI Basic Send/Receive • We need to fill in the details in Process 0 Send(data) Receive(data) Process 1 • Things that need specifying: ♦ How will “data” be described? ♦ How will processes be identified? ♦ How will the receiver recognize/screen messages? ♦ What will it mean for these operations to complete? University of Chicago 22 Department of Energy .

and must be received in the same context ♦ Provides necessary support for libraries • A group and context together form a communicator • A process is identified by its rank in the group associated with a communicator • There is a default communicator whose group contains all initial processes.Some Basic Concepts • Processes can be collected into groups • Each message is sent in a context. called MPI_COMM_WORLD 23 University of Chicago Department of Energy .

MPI_INT. in particular ones for subarrays 24 University of Chicago Department of Energy .. where • An MPI datatype is recursively defined as: ♦ predefined. MPI_DOUBLE) a contiguous array of MPI datatypes a strided block of datatypes an indexed array of blocks of datatypes an arbitrary structure of datatypes • There are MPI functions to construct custom datatypes. count.g. corresponding to a data type from the ♦ ♦ ♦ ♦ language (e. datatype).MPI Datatypes • The data in a message to send or receive is described by a triple (address.

to assist the receiving process in identifying the message • Messages can be screened at the receiving end by specifying a specific tag. MPI calls them tags to avoid confusion with datatypes 25 University of Chicago Department of Energy . or not screened by specifying MPI_ANY_TAG as the tag in a receive • Some non-MPI message-passing systems have called tags “message types”.MPI Tags • Messages are sent with an accompanying user-defined integer tag.

MPI Basic (Blocking) Send MPI_SEND(start. which is the rank of the target process in the communicator specified by comm. datatype). tag. • The target process is specified by dest. datatype. the data has been delivered to the system and the buffer can be reused. count. comm) • The message buffer is described by (start. • When this function returns. dest. 26 University of Chicago Department of Energy . count. The message may not have been received by the target process.

size of message) 27 University of Chicago Department of Energy . tag. but receiving more is an error • status contains further information (e.g. status) • Waits until a matching (both source and tag) message is received from the system. and the buffer can be used • source is rank in communicator specified by comm. datatype.MPI Basic (Blocking) Receive MPI_RECV(start. or MPI_ANY_SOURCE • tag is a tag to be matched on or MPI_ANY_TAG • receiving fewer than count occurrences of datatype is OK. comm. count. source.

… ) • Datatype • Contexts ♦ Basic for heterogeneity ♦ Derived for non-contiguous ♦ Message safety for libraries ♦ Robustness and correctness 28 Department of Energy • Buffering University of Chicago . 10. MPI_DOUBLE. MPI_DOUBLE. 1.Send-Receive Summary • Send to matching Receive A(10) B(20) MPI_Send( A. …) MPI_Recv( B. 0. 20.

comm. 0. MPI_Status status. &argc). buf. MPI_Send( &buf. &rank ). comm). MPI_INT. char *argv[]) { int rank.h” int main( int argc. 0. } University of Chicago 29 Department of Energy .A Simple MPI Program #include “mpi. 1. 0. MPI_Comm_rank( MPI_COMM_WORLD. buf ). } MPI_Finalize(). &status ). } else if (rank == 1) { MPI_Recv( &buf. 1. return 0. MPI_Init(&argv. printf( “Received %d\n”. /* Process 0 sends and Process 1 receives */ if (rank == 0) { buf = 123456. 1. MPI_INT.

h’ integer rank.eq.eq. rank. 1) then call MPI_Recv( buf. ierr ) C Process 0 sends and Process 1 receives if (rank . 1. * ierr ) else if (rank . 1. 0. 0) then buf = 123456 call MPI_Send( buf. buf. buf endif call MPI_Finalize(ierr) end 30 University of Chicago Department of Energy . comm. 0. * status. comm. 1. status(MPI_STATUS_SIZE) call MPI_Init(ierr) call MPI_Comm_rank( MPI_COMM_WORLD. 0. MPI_INTEGER. ierr ) print *.A Simple MPI Program (Fortran) program main include ‘mpif. “Received “. ierr. MPI_INTEGER.

1.Send( &buf. MPI_INT.Recv( &buf. char *argv[]) { int rank. 0 ). cout << “Received “ << buf << endl. } MPI::Finalize(). MPI::Init(&argv. rank = MPI_COMM_WORLD. MPI_INT. buf.Get_rank(). 1. 0 ).A Simple MPI Program (C++) #include “mpi. } else if (rank == 1) { comm. 1. return 0. // Process 0 sends and Process 1 receives if (rank == 0) { buf = 123456. } 31 University of Chicago Department of Energy . comm.h” int main( int argc. 0. &argc).

ierr) tag_recvd = status(MPI_TAG) recvd_from = status(MPI_SOURCE) call MPI_GET_COUNT(status. datatype. recvd_count..Retrieving Further Information • Status is a data structure allocated in the user’s program. status. recvd_count. . . &recvd_count ).. • In C: int recvd_tag. recvd_count integer status(MPI_STATUS_SIZE) call MPI_RECV(. MPI_Recv(. MPI_ANY_TAG. MPI_ANY_SOURCE.. recvd_from = status. datatype. MPI_ANY_SOURCE. MPI_Get_count( &status. ierr) 32 University of Chicago Department of Energy .. &status ) recvd_tag = status. recvd_from. MPI_ANY_TAG.... MPI_Status status.MPI_TAG..MPI_SOURCE. recvd_from. • In Fortran: integer recvd_tag...

♦ this can be defeated by use of “wild card” tags. • User-defined tags still provided in MPI for user convenience in organizing 33 University of Chicago Department of Energy application . • Contexts are different from tags ♦ no wild cards allowed ♦ allocated dynamically by the system when a library sets up a communicator for its own use. but ♦ this requires libraries to be aware of tags used by other libraries.Tags and Contexts • Separation of messages used to be accomplished by use of tags.

as a recommendation. • Use mpirun –np # -nolocal a.g. • In general. mpirun –np 3 –nolocal cpi 34 University of Chicago Department of Energy . starting an MPI program is dependent on the implementation of MPI you are using. and/or environment variables. and might require various scripts. but not a requirement. • mpiexec <args> is part of MPI-2. program arguments. for implementors. just as the Fortran standard does not specify how to run a Fortran program.Running MPI Programs • The MPI-1 Standard does not specify how to run an MPI program.out for your clusters. e.

MPI is Simple • Many parallel programs can be written using just these six functions. only two of which are non-trivial: ♦ MPI_INIT ♦ MPI_FINALIZE ♦ MPI_COMM_SIZE ♦ MPI_COMM_RANK ♦ MPI_SEND ♦ MPI_RECV 35 University of Chicago Department of Energy .

Another Approach to Parallelism • Collective routines provide a higher-level way to organize a parallel program • Each process executes the same communication operations • MPI provides a rich set of collective operations… 36 University of Chicago Department of Energy .

SEND/RECEIVE can be replaced by BCAST/REDUCE. improving both simplicity and efficiency University of Chicago 37 Department of Energy .Collective Operations in MPI • Collective operations are called by all processes in a communicator • MPI_BCAST distributes data from one process (the root) to all others in a communicator • MPI_REDUCE combines data from all processes in communicator and returns it to one process • In many numerical algorithms.

Example: PI in C . MPI_Comm_size(MPI_COMM_WORLD.&argv). double mypi. scanf("%d". h. myid. MPI_INT. } MPI_Bcast(&n.&myid).1 #include "mpi.h" #include <math.141592653589793238462643.h> int main(int argc. rc. MPI_COMM_WORLD). i. x. MPI_Comm_rank(MPI_COMM_WORLD. sum.&n). while (!done) { if (myid == 0) { printf("Enter the number of intervals: (0 quits) "). 0.&numprocs). pi. double PI25DT = 3. numprocs. 1. n. a. if (n == 0) break. MPI_Init(&argc. char *argv[]) { int done = 0. 38 University of Chicago Department of Energy .

for (i = myid + 1. Error is .5). MPI_SUM.2 h = 1. fabs(pi . } MPI_Finalize(). } 39 University of Chicago Department of Energy .0 + x*x).16f\n". i <= n. } mypi = h * sum.0 / (1.0 / (double) n.PI25DT)). MPI_COMM_WORLD). MPI_Reduce(&mypi. sum = 0. 0. &pi. MPI_DOUBLE.16f.0.Example: PI in C .0. sum += 4. if (myid == 0) printf("pi is approximately %. i += numprocs) { x = h * ((double)i . return 0. pi. 1.

numprocs.myid.1 program main include ‘mpif. MPI_INTEGER. n endif call MPI_Bcast(n.eq. mypi. 1. myid.false. z data done/. x. rc double pi25dt. done) if (myid . ierr ) call MPI_Comm_rank(MPI_COMM_WORLD.141592653589793238462643/ call MPI_Init(ierr) call MPI_Comm_size(MPI_COMM_WORLD. 0. h. pi.h’ integer done. 0) then print *.”Enter the number of intervals: (0 quits)“ read *.numprocs. sum.not. ierr ) if (n . 0) goto 10 40 University of Chicago Department of Energy . ierr) do while (.eq.Example: PI in Fortran . i. n./ data PI25DT/3. * MPI_COMM_WORLD.

MPI_DOUBLE_PRECISION.0 do i=myid+1.0. 0. MPI_COMM_WORLD.2 = 1. "pi is approximately “.0 + x*x).eq.Example: PI in Fortran . abs(pi .PI25DT) enddo 10 continue call MPI_Finalize( ierr ) end 41 University of Chicago Department of Energy h . enddo mypi = h * sum call MPI_Reduce(mypi.n. Error is “. * MPI_SUM.numprocs x = h * (i . * “. sum += 4. pi.0 / (1.5). 0) then print *. ierr ) if (myid .0 / n sum = 0. 1. pi.

MPI_INT. n. double mypi.Get_rank(). while (!done) { if (myid == 0) { printf("Enter the number of intervals: (0 quits) "). i.141592653589793238462643.&argv). myid.1 #include "mpi. } MPI_COMM_WORLD. rc. numprocs = MPI_COMM_WORLD.Bcast(&n. if (n == 0) break. sum. x. a. double PI25DT = 3.&n). scanf("%d".Example: PI in C++ . 1. MPI::Init(&argc. char *argv[]) { int done = 0.h> int main(int argc. pi.h" #include <math.Get_size(). 0 ). 42 University of Chicago Department of Energy . h. myid = MPI_COMM_WORLD. numprocs.

0 + x*x).2 h = 1. } mypi = h * sum. 0).5). &pi. sum += 4.0 / (double) n. MPI_DOUBLE. } 43 University of Chicago Department of Energy . if (myid == 0) printf("pi is approximately %. pi.0 / (1. Error is . i <= n.PI25DT)).Reduce(&mypi. MPI_COMM_WORLD.16f.0. sum = 0. MPI_SUM. } MPI::Finalize(). for (i = myid + 1. return 0.16f\n". i += numprocs) { x = h * ((double)i . 1. fabs(pi .Example: PI in C++ .0.

. and Fortran-90 issues.Notes on C and Fortran • C and Fortran bindings correspond closely • In C: ♦ mpi. • C++ bindings.h must be included. are 44 University of Chicago Department of Energy part of MPI-2. with a place for the return code in the last argument.h must be #included ♦ MPI functions return error codes or MPI_SUCCESS • In Fortran: ♦ mpif. or use MPI module ♦ All MPI calls are to subroutines.

Alternative Set of 6 Functions • Using collectives: ♦ MPI_INIT ♦ MPI_FINALIZE ♦ MPI_COMM_SIZE ♦ MPI_COMM_RANK ♦ MPI_BCAST ♦ MPI_REDUCE 45 University of Chicago Department of Energy .

which prints it.Exercises • Modify hello program so that each process sends the name of the machine it is running on to process 0. ♦ See source of cpi or fpi in mpich2/examples or mpich2/examples/f77 for how to use MPI_Get_processor_name • Do this in such a way that the hosts are printed in rank order University of Chicago 46 Department of Energy .

More on Message Passing • Message passing is a simple programming model. but there are some special issues ♦ Buffering and deadlock ♦ Deterministic execution ♦ Performance 47 University of Chicago Department of Energy .

Buffers • When you send data. where does it go? One possibility is: Process 0 User data Local buffer the network Local buffer User data 48 University of Chicago Department of Energy Process 1 .

and we wait later. University of Chicago Process 1 49 Department of Energy . or that MPI_Send return before transfer is complete.Avoiding Buffering • It is better to avoid copies: Process 0 User data the network User data This requires that MPI_Send wait on delivery.

Blocking and Non-blocking Communication • So far we have been using blocking communication: ♦ MPI_Recv does not complete until the buffer is full (available for use). ♦ MPI_Send does not complete until the buffer is empty (available for use). • Completion depends on size of message and amount of system buffering. 50 University of Chicago Department of Energy .

Sources of Deadlocks • Send a large message from process 0 to process 1 ♦ If there is insufficient storage at the destination. the send must wait for the user to provide the memory space (through a receive) • What happens with this code? Process 0 Process 1 Send(1) Send(0) Recv(1) Recv(0) • This is called “unsafe” because it depends on the availability of system buffers in which to store the data sent until it can be received University of Chicago 51 Department of Energy .

Some Solutions to the “unsafe” Problem • Order the operations more carefully: Process 0 Send(1) Recv(1) Process 1 Recv(0) Send(0) • Supply receive buffer at same time as send: Process 0 Sendrecv(1) Process 1 Sendrecv(0) 52 University of Chicago Department of Energy .

More Solutions to the “unsafe” Problem • Supply own space as buffer for send Process 0 Bsend(1) Recv(1) Process 1 Bsend(0) Recv(0) • Use non-blocking operations: Process 0 Isend(1) Irecv(1) Waitall University of Chicago Process 1 Isend(0) Irecv(0) Waitall 53 Department of Energy .

tag.MPI’s Non-blocking Operations • Non-blocking operations return (immediately) “request handles” that can be tested and waited on: MPI_Request request. MPI_Isend(start. MPI_Status status. MPI_Irecv(start. dest. count. &status). count. &request). &flag. tag. comm. &request). University of Chicago 54 Department of Energy . &status). (each request must be Waited on) • One can also test without waiting: MPI_Test(&request. datatype. dest. comm. datatype. MPI_Wait(&request.

status. ierr) call MPI_Wait(request. ierr) University of Chicago 55 Department of Energy . dest. status. count.MPI’s Non-blocking Operations (Fortran) • Non-blocking operations return (immediately) “request handles” that can be tested and waited on: integer request integer status(MPI_STATUS_SIZE) call MPI_Isend(start. request. request. tag. comm. ierr) (Each request must be waited on) • One can also test without waiting: call MPI_Test(request. count. dest. comm. flag. datatype. tag. datatype.ierr) call MPI_Irecv(start.

array_of indices. &status) MPI_Waitsome(count. 56 University of Chicago Department of Energy . array_of_requests. array_of_statuses) MPI_Waitany(count. array_of_requests.Multiple Completions • It is sometimes desirable to wait on multiple requests: MPI_Waitall(count. array_of_requests. &index. array_of_statuses) • There are corresponding versions of test for each of these.

index. ierr) call MPI_Waitany(count. status. array_of_statuses. array_of_statuses. array_of_requests. 57 University of Chicago Department of Energy . ierr) call MPI_Waitsome(count.Multiple Completions (Fortran) • It is sometimes desirable to wait on multiple requests: call MPI_Waitall(count. array_of_requests. ierr) • There are corresponding versions of test for each of these. array_of_requests. array_of indices.

58 University of Chicago Department of Energy . (Unsafe programs deadlock.Communication Modes • MPI provides multiple modes for sending messages: ♦ Synchronous mode (MPI_Ssend): the send does not complete until a matching receive has begun.) • MPI_Recv receives messages sent in any mode.) ♦ Buffered mode (MPI_Bsend): the user supplies a buffer to the system for its use. • Allows access to fast protocols • undefined behavior if matching receive not posted • Non-blocking versions (MPI_Issend. (User allocates enough memory to make an unsafe program safe. ♦ Ready mode (MPI_Rsend): user guarantees that a matching receive has been posted. etc.

Other Point-to Point Features • MPI_Sendrecv • MPI_Sendrecv_replace • MPI_Cancel ♦ Useful for multibuffering • Persistent requests ♦ Useful for repeated communication patterns ♦ Some systems can exploit to reduce latency and increase performance University of Chicago 59 Department of Energy .

MPI_Sendrecv • Allows simultaneous send and receive • Everything else is general. …) ♦ More general than “send left” Process 0 Process 1 SendRecv(1) SendRecv(0) 60 University of Chicago Department of Energy . ♦ Send and receive datatypes (even type signatures) may be different ♦ Can use Sendrecv with plain Send or Recv (or Irecv or Ssend_init.

• Groups and communicators can be constructed “by hand” or using topology routines. • No non-blocking collective operations. different communicators deliver similar functionality.MPI Collective Communication • Communication and computation is coordinated among a group of processes in a communicator. data movement. 61 University of Chicago Department of Energy . collective computation. • Three classes of operations: synchronization. • Tags are not used.

• Almost never required in a parallel program ♦ Occasionally useful in measuring performance and load balancing 62 University of Chicago Department of Energy .Synchronization • MPI_Barrier( comm ) • Blocks until all processes in the group of the communicator comm call it.

ierr ) • Blocks until all processes in the group of the communicator comm call it. 63 University of Chicago Department of Energy .Synchronization (Fortran) • MPI_Barrier( comm.

• Blocks until all processes in the group of the communicator comm call it.Barrier().Synchronization (C++) • comm. 64 University of Chicago Department of Energy .

Collective Data Movement A Broadcast P0 P1 P2 P3 A A A A P0 P1 P2 P3 ABCD Scatter Gather A B C D 65 Department of Energy University of Chicago .

this tells MPI which process originates the broadcast and which receive • Example of orthogonallity of the MPI design: MPI_Recv need not test for “multisend” 66 University of Chicago Department of Energy .Comments on Broadcast • All collective operations must be called by all processes in the communicator • MPI_Bcast is called by both the sender (called the root process) and the processes that are to receive the broadcast ♦ MPI_Bcast is not a “multi-send” ♦ “root” argument is the rank of the sender.

More Collective Data Movement P0 P1 P2 P3 A B C D Allgather AB AB AB AB C C C C D D D D P0 P1 P2 P3 A0 A1 A2 A3 B0 B1 B2 B3 C0 C1 C2 C3 D0 D1 D2 D3 A0 B0 C0 D0 Alltoall A1 B1 C1 D1 A2 B2 C2 D2 A3 B3 C3 D3 67 University of Chicago Department of Energy .

Collective Computation P0 P1 P2 P3 A B C D ABCD Reduce P0 P1 P2 P3 A B C D Scan A AB ABC ABCD 68 Department of Energy University of Chicago .

69 University of Chicago Department of Energy . Reduce_scatter. Reduce. Reduce. Reduce_scatter. • V versions allow the hunks to have different sizes. Scatterv • All versions deliver results to all participating processes. Scan.MPI Collective Routines • Many Routines: Allgather. Gather. Alltoall. Allreduce. Allgatherv. and Scan take both built-in and user-defined combiner functions. Alltoallv. Scatter. • Allreduce. Gatherv. Bcast.

MPI Built-in Collective Computation Operations • • • • • • • • • • • • MPI_MAX MPI_MIN MPI_PROD MPI_SUM MPI_LAND MPI_LOR MPI_LXOR MPI_BAND MPI_BOR MPI_BXOR MPI_MAXLOC MPI_MINLOC Maximum Minimum Product Sum Logical and Logical or Logical exclusive or Binary and Binary or Binary exclusive or Maximum and location Minimum and location 70 University of Chicago Department of Energy .

The Collective Programming Model • One style of higher level programming is to use only collective routines • Provides a “data parallel” style of programming ♦ Easy to follow program flow 71 University of Chicago Department of Energy .

MPI_Finalize ♦ Information on the processes • MPI_Comm_rank.What MPI Functions are in Use? • For simple applications. MPI_Wait. MPI_Send. MPI_Get_processor_name ♦ Collective communication • MPI_Allreduce. these are common: ♦ Point-to-point communication • MPI_Irecv. MPI_Recv ♦ Startup • MPI_Init. MPI_Comm_size. MPI_Allgather 72 University of Chicago Department of Energy . MPI_Bcast. MPI_Isend.

Understanding and Predicting Performance • Not all programs will run faster in parallel ♦ The benefit of additional processors may be outweighed by the cost of moving data between them T = Tp + Ts +Tc • A typical cost model is p Tc = communicat ion overhead Tp = parallel fraction 73 University of Chicago Department of Energy This term is zero for p=1 Ts = serial (non .parallizable) fraction .

Latency and Bandwidth • Simplest model s + r n • s includes both hardware (gate delays) and software (context switch. setup) • r includes both hardware (raw bandwidth of interconnection and memory system) and software (packetization. copies between user and system) • Head-to-head and pingpong values may differ University of Chicago Department of Energy .

The number quoted is sometimes misleading. Time to Send Message Latency Not latency University of Chicago 1/slope=Bandwidth Message Size Department of Energy . This is true only for the simple model. latency is the limit(n→0) of the time to send n bytes • Latency is sometimes described as “time to send a message of zero bytes”.Interpreting Latency and Bandwidth • Bandwidth is the inverse of the slope of the line time = latency + (1/rate) size_of_message • For performance estimation purposes.

Timing MPI Programs (C)
• The elapsed (wall-clock) time between two points in an MPI program can be computed using MPI_Wtime: double t1, t2; t1 = MPI_Wtime(); ... t2 = MPI_Wtime(); printf( “time is %d\n”, t2 - t1 ); • The value returned by a single call to MPI_Wtime has little value. • Times in general are local, but an implementation might offer synchronized times. See attribute MPI_WTIME_IS_GLOBAL.
University of Chicago Department of Energy

Timing MPI Programs
• The elapsed (wall-clock) time between two points in an MPI program can be computed using MPI_Wtime: double precision t1, t2
t1 = MPI_Wtime() ... t2 = MPI_Wtime() print *, ‘time is ‘, t2 - t1

• The value returned by a single call to MPI_Wtime has little value. • Times in general are local, but an implementation might offer synchronized times. See attribute MPI_WTIME_IS_GLOBAL.
University of Chicago Department of Energy

Measuring Performance
• Using MPI_Wtime
♦ timers are not continuous — MPI_Wtick

• MPI_Wtime is local unless the MPI_WTIME_IS_GLOBAL attribute is true
♦ MPI attributes are an advanced topic – ask

me this afternoon if you are interested

• MPI Profiling interface provides a way to easily instrument the MPI calls in an application • Performance measurement tools for MPI
University of Chicago Department of Energy

Sample Timing Harness (C)
• Average times, make several trials
for (k=0; k<nloop; k++) { t1 = MPI_Wtime(); for (i=0; i<maxloop; i++) { <operation to be timed> } time = MPI_Wtime() - t1; if (time < tfinal) tfinal = time; }

• Use MPI_Wtick to discover clock resolution • Use getrusage to get other effects (e.g., context switches, paging)
University of Chicago Department of Energy

paging) University of Chicago Department of Energy . nloop t1 = MPI_Wtime() do i=1.t1)/maxloop if (time . context switches.maxloop <operation to be timed> enddo time = (MPI_Wtime() .g. make several trials tfinal=1000.lt.0 do k=1.. tfinal) tfinal = time enddo • Use MPI_Wtick to discover clock resolution • Use getrusage to get other effects (e.Sample Timing Harness (Fortran) • Average times.

t. MPI_Send(…). pingpong give 130 MB/sec for 2 but 75 MB/sec for 4 (for MPI_Ssend) University of Chicago Department of Energy .Pitfalls in timing (C) • Time too short: t = MPI_Wtime(). over by cost of calling MPI_Wtime • “Correcting” MPI_Wtime by subtracting average of MPI_Wtime calls overestimates MPI_Wtime • Code not paged in (always run at least twice) • Minimums not what users see • Tests with 2 processors may not be representative ♦ T3D has processors in pairs. • Underestimates by MPI_Wtick. time = MPI_Wtime() .

Pitfalls in timing (Fortran) • Time too short: t = MPI_Wtime() call MPI_Send(…) time = MPI_Wtime() .t • Underestimates by MPI_Wtick. pingpong give 130 MB/sec for 2 but 75 MB/sec for 4 (for MPI_Ssend) University of Chicago Department of Energy . over by cost of calling MPI_Wtime • “Correcting” MPI_Wtime by subtracting average of MPI_Wtime calls overestimates MPI_Wtime • Code not paged in (always run at least twice) • Minimums not what users see • Tests with 2 processors may not be representative ♦ T3D has processors in pairs.

Example of Paging Problem • Black area is identical setup computation 83 University of Chicago Department of Energy .

.g. Ssend/Irecv-Wait) ♦ Make sure all processes are ready before starting the test ♦ How repeatable are your measurements? ♦ How does the performance compare to the performance of other operations (e.Exercise: Timing MPI Operations • Estimate the latency and bandwidth for some MPI operation (e. floating multiply)? 84 University of Chicago Department of Energy . Bcast. Send/Recv..g. memcpy.

Processes Logfile Jumpshot Display 85 University of Chicago Department of Energy . • A separate display program (Jumpshot) aids the user in conducting a post mortem analysis of program behavior.Performance Visualization with Jumpshot • For detailed analysis of parallel program behavior. timestamped events are collected into a log file during the run.

Using Jumpshot to look at FLASH at multiple Scales 1000 x Each line represents 1000’s of messages University of Chicago Detailed view shows opportunities for optimization 86 Department of Energy .

the master can become a bottleneck University of Chicago Department of Energy .Implementing Master/Worker Algorithms • Many algorithms have one or more master processes that send tasks and receive results from worker processes • Because there is one (or a few) controlling processes.

ierr ) ! If this is the last data item.not. ! Else send more work to them call MPI_Send(b.true. ierr ) enddo • Not included: ♦ Sending initial work to all processes ♦ Deciding when to set done 88 University of Chicago Department of Energy . ! set done to . status.….& … .status(MPI_SOURCE).Skeleton Master Process • do while(.…. Done) ! Get results from anyone call MPI_Recv( a.

not. …. Done) ! Receive work from master call MPI_Recv( a. ….Skeleton Worker Process • Do while (. ierr ) enddo • Not included: ♦ Detection of termination (probably message from master) ♦ An alternative would be a test for a nonblocking barrier (which MPI doesn’t have) 89 University of Chicago Department of Energy . status. ierr ) … compute for task ! Return result to master call MPI_Send( b.

master may not evenly respond 90 University of Chicago Department of Energy .Problems With Master/Worker • Worker processes have nothing to do while waiting for the next task • Many workers may try to send data to the master at the same time ♦ Could be a problem if data size is very large. such as 20-100 MB • Master may fall behind in servicing requests for work if many processes ask in a very short interval • Presented with many requests.

Spreading out communication • Use double buffering to overlap request for more work with work Do while (. remove it with MPI_Cancel ♦ MPI_Test_cancelled required on IBM (!). Done) ! Receive work from master call MPI_Wait( request. ierr ) enddo • MPI_Cancel ♦ Last Irecv may never match. send_work. …. then MPI_Request_free 91 Department of Energy University of Chicago .not. ierr ) … compute for task ! Return result to master (could also be nb) call MPI_Send( b. …. ierr ) call MPI_IRecv( a2. request. ierr ) ! Request MORE work call MPI_Send( …. …. status.

Limiting Memory Demands on Master • Using MPI_Ssend and MPI_Issend to encourage limits on memory demands ♦ MPI_Ssend and MPI_Issend do not specify that the data itself doesn’t move until the matching receive is issued. but that is the easiest way to implement the synchronous send operations ♦ Replace MPI_Send in worker with • MPI_Ssend for blocking • MPI_Issend for nonblocking (even less synchronization) 92 University of Chicago Department of Energy .

workers select a master to request work from at random • Keep more work locally • Use threads to implement work stealing (but you must be use a thread-safe implementation of MPI) 93 University of Chicago Department of Energy .Distributing work further • Use multiple masters.

Mesh-Based Computations in MPI • First step: decompose the problem • Second step: arrange for the communication of data • Example: “Jacobi” iteration ♦ Represents the communication in many mesh-based computations ♦ Not a good algorithm (we’ll see better ways later) ♦ Not the best decomposition (more scalable decompositions are more complex to program — unless you use higher-level libraries) 94 University of Chicago Department of Energy .

Jacobi Iteration (C Ordering) • Simple parallel data structure • Processes exchange rows with neighbors 95 University of Chicago Department of Energy .

Jacobi Iteration (Fortran Ordering) • Simple parallel data structure Process 0 Process 1 Process 2 Process 3 Boundary Point Interior Node University of Chicago • Processes exchange columns with neighbors • Local part declared as xlocal(m.0:n+1) 96 Department of Energy .

up_nbr. 1. maxm. maxm. down_nbr. ring_comm. 1. MPI_DOUBLE. MPI_Comm ring_comm = mesh->ring_comm. } 97 University of Chicago Department of Energy . MPI_Recv( xlocal. then receive from above */ MPI_Send( xlocal + maxm. 0. down_nbr. MPI_DOUBLE. MPI_Recv( xlocal + maxm * (lrow + 1). 0. &status ). /* Send up. up_nbr. then receive from below */ MPI_Send( xlocal + maxm * lrow. ring_comm. maxm. MPI_DOUBLE. maxm.Send and Recv (C) • Simplest use of send and recv { MPI_Status status. &status ). ring_comm ). /* Send down. ring_comm ). MPI_DOUBLE.

ierr ) call MPI_Send( xlocal(1. m.1). m. ring_comm. & left_nbr. ierr ) call MPI_Recv( xlocal(1. ring_comm. MPI_DOUBLE_PRECISION. status. m. 0. m.n+1). 0. status. MPI_DOUBLE_PRECISION. & right_nbr.n). & left_nbr. ring_comm. ring_comm. ierr ) 98 University of Chicago Department of Energy . 0. ierr ) call MPI_Recv( xlocal(1. 0. MPI_DOUBLE_PRECISION.0). & right_nbr. MPI_DOUBLE_PRECISION.Send and Recv (Fortran) • Simplest use of send and recv integer status(MPI_STATUS_SIZE) call MPI_Send( xlocal(1.

Performance of Simplest Code • Very poor performance on SP2 ♦ Rendezvous sequentializes sends/receives • OK performance on T3D (implementation tends to buffer operations) 99 University of Chicago Department of Energy .

MPI_Irecv( xlocal + maxm * (lrow + 1). MPI_Request r[4]. up_nbr. 1. MPI_Comm ring_comm. maxm. maxm. down_nbr. MPI_DOUBLE. 1. r. ring_comm. Isend. 0. MPI_DOUBLE.ok performance MPI_Status statuses[4]. &r[0] ). then receive from below */ MPI_Irecv( xlocal. } 100 University of Chicago Department of Energy . ring_comm. maxm. statuses ). MPI_Isend( xlocal + maxm * lrow. maxm. MPI_Waitall( 4. ring_comm. &r[1] ). Waitall . MPI_DOUBLE. /* Send up. MPI_DOUBLE. then receive from above */ MPI_Isend( xlocal + maxm.Better to start receives first (C) • Irecv. &r[3] ). &r[2] ). ring_comm. 0. down_nbr. /* Send down. up_nbr.

MPI_DOUBLE_PRECISION. requests(1). m. MPI_DOUBLE_PRECISION.n).0). ierr ) 101 University of Chicago Department of Energy . MPI_DOUBLE_PRECISION. ring_comm. m. m. Isend. & right_nbr. requests(4). m. ierr ) call MPI_Waitall( 4. requests(2).n+1). & left_nbr.1). statuses.& left_nbr. MPI_DOUBLE_PRECISION.Better to start receives first (Fortran) • Irecv. requests(3). ierr ) call MPI_Isend( xlocal(1.ok performance integer statuses(MPI_STATUS_SIZE. ierr ) call MPI_Isend( xlocal(1. ierr ) call MPI_Irecv( xlocal(1. ring_comm.4).& right_nbr. ring_comm. requests(4) call MPI_Irecv( xlocal(1. requests. Waitall . ring_comm.

MPI and Threads • Symmetric Multiprocessors (SMPs) are a common building block of many parallel machines • The preferred programming model for SMPs with threads ♦ POSIX (“pthreads”) ♦ OpenMP ♦ sproc (SGI) ♦ compiler-managed parallelism University of Chicago Department of Energy .

openmp.Thread Interfaces • POSIX “pthreads” • Windows ♦ Kernel threads ♦ User threads called “fibers” Library-based Invoke a routine in a separate thread • Java ♦ First major language with threads ♦ Provides memory synchronization model: methods (procedures) declared “synchronized” executed by one thread at a time ♦ (don’t mention Ada. which has tasks) • OpenMP ♦ Mostly directive-based parallel loops ♦ Some thread features (lock/unlock) ♦ http://www.org 103 University of Chicago Department of Energy .

Threads and MPI • MPI_Init_thread(&argc. and MPICH will do this through attributes) 104 University of Chicago Department of Energy .&argv.required.&provided) ♦ Thread modes: • MPI_THREAD_SINGLE — One thread (MPI_Init) • MPI_THREAD_FUNNELED — One thread making MPI calls – most common case when MPI combined with OpenMP • MPI_THREAD_SERIALIZED — One thread at a time making MPI calls • MPI_THREAD_MULTIPLE — Free for all • Coexist with compiler (thread) parallelism for SMPs • MPI could have defined the same modes on a communicator basis (more natural.

What’s in MPI-2 • Extensions to the message-passing model ♦ Dynamic process management ♦ One-sided operations (remote memory access) ♦ Parallel I/O ♦ Thread support • Making MPI more robust and convenient ♦ C++ and Fortran 90 bindings ♦ External interfaces. handlers ♦ Extended collective operations ♦ Language interoperability 105 University of Chicago Department of Energy .

MPI as a Setting for Parallel I/O • Writing is like sending and reading is like receiving • Any parallel I/O system will need: ♦ collective operations ♦ user-defined datatypes to describe both memory and file layout ♦ communicators to separate application-level message passing from I/O-related message passing ♦ non-blocking operations • I.. lots of MPI-like machinery • We will discuss a high-level approach to using MPI-IO University of Chicago 106 Department of Energy .e.

sequential consistency University of Chicago 107 Department of Energy . clusters ♦ Workstation networks • Retaining “look and feel” of MPI-1 • Dealing with subtle memory behavior issues: cache coherence. • Balancing efficiency and portability across a wide class of architectures ♦ shared-memory multiprocessors ♦ NUMA architectures ♦ distributed-memory MPP’s.One-Sided Operations in MPI-2 (also called Remote Memory Access) • Synchronization is separate from data movement.

Remote Memory Access Windows and Window Objects Process 0 Process 1 Get Put window Process 2 Process 3 = address spaces University of Chicago = window object 108 Department of Energy .

Why Use RMA? • Performance • May allow more dynamic. asynchronous algorithms • But Get/Put is not Load/Store ♦ Synchronization is exposed in MPI one-sided operations 109 University of Chicago Department of Energy .

Basic RMA Functions for Communication • MPI_Win_create exposes local memory to RMA operation by other processes in a communicator Collective operation ♦ Creates window object ♦ • MPI_Win_free deallocates window object • MPI_Put moves data from local memory to remote memory • MPI_Get retrieves data from remote memory into local memory • MPI_Accumulate updates remote memory using local values • Data movement operations are non-blocking • Subsequent synchronization on window object needed to ensure operation is complete 110 University of Chicago Department of Energy .

post.RMA Functions for Synchronization • Multiple ways to synchronize: • MPI_Win_fence – barrier across all processes participating in window. complete. unlock} – involves single other process ♦ Not to be confused with lock. such as nearest neighbors in grid • MPI_Win_{lock. wait} –involves groups of processes.unlock University of Chicago 111 Department of Energy . allows BSP-like model • MPI_Win_{start.

not an example of where to use RMA 112 University of Chicago Department of Energy .Comparing RMA and Point-to-Point Communication • The following example shows how to achieve the same communication pattern using point-to-point and remote memory access communication • Illustrates the issues.

comm. n. } /* Allow other operations to proceed (communication or computation) */ … /* Complete the operation */ MPI_Wait( &request. 0. MPI_INT. comm. rank. &request ). } else if (rank == 1) { MPI_Irecv( inbuf. 1. &comm ). MPI_Comm_split( MPI_COMM_WORLD. /* Only processes 0 and 1 execute the rest of this */ if (rank > 1) return. &status ). 0. &rank ). MPI_INT. /* Free communicator */ MPI_Comm_free( &comm ). rank <= 1. n. /* Process 0 sends and Process 1 receives */ if (rank == 0) { MPI_Isend( outbuf. &request ). 113 University of Chicago Department of Energy .Point-to-point /* Create communicator for separate context for processes 0 and 1 */ MPI_Comm_rank( MPI_COMM_WORLD. 0.

sizeof(int). &comm ). &win ). &rank ). n. MPI_INFO_NULL. comm. 0. win ). /* Free the window */ MPI_Win_free( &win ). MPI_INFO_NULL. n * sizeof(int). University of Chicago 114 Department of Energy . n. MPI_INT. rank <= 1. 1.RMA /* Create memory window for separate context for processes 0 and 1 */ MPI_Comm_rank( MPI_COMM_WORLD. /* Process 0 puts into process 1 */ MPI_Win_fence( 0. if (rank == 0) MPI_Put( outbuf. if (rank == 0) MPI_Win_create( NULL. 0. /* Allow other operations to proceed (communication or computation) */ … /* Complete the operation */ MPI_Win_fence( 0. comm. win ). win ). MPI_INT. rank. MPI_Comm_split( MPI_COMM_WORLD. else if (rank == 1 ) MPI_Win_create( inbuf. &win ). sizeof(int). /* Only processes 0 and 1 execute the rest of this */ if (rank > 1) return.

. win ). . if (rank == 0) { /* Process 0 puts data into many local windows */ MPI_Put( ..Using MPI_Win_fence MPI_Win_create( A. .... &win ). win ). win ). win ). win ). win ).. processes can load and store into A. printf( "A[%d] = %d\n". MPI_Win_fence( 0.. .. /* The following fence completes the MPI_Get operations */ MPI_Win_fence( 0... /* After the fence. . /* We need a fence between stores and RMA operations */ MPI_Put( . 0. win ). } /* This fence completes the MPI_Put operations initiated by process 0 */ MPI_Win_fence( 0. A[0] ). /* The following fence completes the preceding Put */ MPI_Win_fence( 0.. /* All processes initiate access to some window to extract data */ MPI_Get( . win ). 115 University of Chicago Department of Energy . MPI_Put( . MPI_Win_fence( 0.. the local window */ A[rank] = 4. win ).

Example of MPI RMA: Ghost Point Exchange • Multiparty data exchange • Jacobi iteration in 2 dimensions ♦ Model for PDEs. and algorithms with surface/volume behavior ♦ Issues are similar to unstructured grid problems (but harder to illustrate) 116 University of Chicago Department of Energy . Sparse matrix-vector products.

Jacobi Iteration (Fortran Ordering) • Simple parallel data structure Process 0 Process 1 Process 2 Process 3 Boundary Point Interior Node • Processes exchange columns with neighbors • Local part declared as xlocal(m.0:n+1) University of Chicago 117 Department of Energy .

right_nbr ) use mpi integer nx. e double precision a(0:nx+1. right_ghost_disp call MPI_WIN_FENCE( 0. win. ierr ) return end 118 University of Chicago Department of Energy . nx. win. s. e. left_nbr. ierr ) ! Put left edge into left neighbor's right ghost cells ! See text about right_ghost_disp right_ghost_disp = 1 + (nx+2)*(e-s+2) call MPI_PUT( a(1. win. ierr ) ! Put bottom edge into right neighbor's left ghost cells left_ghost_disp = 1 call MPI_PUT( a(1. right_ghost_disp.Ghostpoint Exchange with RMA subroutine exchng1( a. left_ghost_disp.e). ierr ) call MPI_WIN_FENCE( 0. left_nbr. win. win. & MPI_DOUBLE_PRECISION. nx. MPI_DOUBLE_PRECISION.s-1:e+1) integer win.s). MPI_DOUBLE_PRECISION. nx. & right_nbr. & left_nbr. & MPI_DOUBLE_PRECISION. s. nx. right_nbr integer ierr integer(kind=MPI_ADDRESS_KIND) left_ghost_disp. nx.

LAM) support heterogeneous workstation networks. Free implementations (MPICH. ♦ Multiple complete MPI-2 implementations available • MPI-2 implementations appearing piecemeal. parts coming soon from IBM) ♦ MPI RMA an important part of the spectacular results on the Earth Simulator ♦ Most of dynamic and one sided in LAM. • MPI-2 implementations are being undertaken now by all vendors. parts from SGI and HP. with I/O first. ♦ I/O available in most MPI implementations ♦ One-sided available in some (e.NEC and Fujitsu. MPICH2 University of Chicago 119 Department of Energy .MPI-2 Status Assessment • All MPP vendors now have MPI-1. WMPI.g .

MPICH Goals • Complete MPI implementation • Portable to all platforms supporting the messagepassing model • High performance on high-performance hardware • As a research project: ♦ exploring tradeoff between portability and performance ♦ removal of performance gap between user level (MPI) and hardware capabilities • As a software project: ♦ a useful free implementation for most machines ♦ a starting point for vendor proprietary implementations 120 University of Chicago Department of Energy .

MPICH2 • All-new implementation is our vehicle for research in ♦ ♦ ♦ ♦ ♦ ♦ Thread safety and efficiency (e. optimized MPI’s 121 Department of Energy • Parallel Environments ♦ ♦ ♦ ♦ ♦ ♦ University of Chicago .g. parallel I/O. avoid thread locks) Optimized MPI datatypes Optimized Remote Memory Access (RMA) High Scalability (64K MPI processes and more) Exploiting Remote Direct Memory Access (RDMA) capable networks (Myrinet) All of MPI-2. RMA Clusters IBM BG/L New interconnect technologies (Myrinet) Cray Red Storm (under discussion) Others Many vendors start with MPICH in crafting custom.. including dynamic process management.

dynamic processes. passivetarget RMA on many platforms • Improved performance • New algorithms for collective operations • Improved robustness • Process manager interface Supports multiple process managers ♦ Includes the MPD-based manager (provides scalable startup) ♦ • Multiple devices implemented Sockets. active-target RMA. shared memory. Infiniband ♦ Many groups already using MPICH2 for their MPI implementations ♦ 122 University of Chicago Department of Energy .MPICH-2 Status and Schedule • Supports all of MPI-1 and most of MPI-2. including all of MPI-IO.

mcs.gov/mpi/mpich • MPICH2: ♦ www.anl.mcs.anl.Getting MPICH for Your Cluster • MPICH1: ♦ www.gov/mpi/mpich2 123 University of Chicago Department of Energy .

both open source and commercial • Sophisticated numerical programs can be built using libraries ♦ Scalable I/O of data to a community standard file format ♦ Solve a PDE (e.g.. PETSc) University of Chicago 124 Department of Energy .High-Level Programming With MPI • MPI was designed from the beginning to support libraries • Many libraries exist.

these should be built on top of MPI-IO 125 University of Chicago Department of Energy . portable file formats ♦ Include metadata describing contents • For parallel machines.Higher Level I/O Libraries • Scientific applications work with structured data and desire more selfdescribing file formats • netCDF and HDF5 are two popular “higher level” I/O libraries ♦ Abstract away details of file layout ♦ Provide standard.

Parallel netCDF (PnetCDF) • Collaboration between NWU and ANL as part of the Scientific Data Management SciDAC • netCDF ♦ API for accessing multi-dimensional data sets ♦ Portable file format • Popular in both fusion and climate communities • Parallel netCDF is an effort to ♦ Very similar API to netCDF ♦ Tuned for better performance in today’s computing environments ♦ Retains the file format so netCDF and PnetCDF applications can share files 126 University of Chicago Department of Energy .

I/O in netCDF • Original netCDF ♦ Parallel read • All processes read the file independently • No possibility of collective optimizations P0 P1 P2 P3 ♦ Sequential write • Parallel writes are carried out by shipping data to a single process netCDF • PnetCDF Parallel read/write to shared netCDF file ♦ Built on top of MPI-IO which utilizes optimal I/O facilities of the parallel file system and MPI-IO implementation ♦ Allows for MPI-IO hints and datatypes for further optimization ♦ University of Chicago Parallel File System P0 P1 P2 P3 Parallel netCDF Parallel File System 127 Department of Energy .

2. “latitude”. temp_id. dim_off[2]. “temp”. lon_id. dim_id[2]. 512. &lat_id). dim_size[2]. status = ncmpi_def_dim(file_id. dim_id. 512. &temp_id). “foo”.PnetCDF Example Part 1 int main(int argc. NC_CLOBBER. “longitude”. status = ncmpi_def_dim(file_id. dim_id[1] = lat_id. status = ncmpi_create(MPI_COMM_WORLD. 128 University of Chicago Department of Energy . status = ncmpi_def_var(file_id. lat_id. int status. dim_id[0] = lon_id. NC_DOUBLE. char *argv[]) { double temps[512*512/NR_PROCS]. &lon_id). MPI_INFO_NULL. &file_id).

partition_problem_space(dim_off. temps). writes its part. collectively */ status = ncmpi_put_vara_double_all(file_id. /* perform calculations until time to write */ /* each proc. } 129 University of Chicago Department of Energy .PnetCDF Example Part 2 /* leave define mode. dim_size). enter coll. temp_id. dim_size. dim_off. status = ncmpi_close(file_id). data mode */ status = ncmpi_enddef(file_id).

More Information on PnetCDF
• Parallel netCDF web site:
http://www.mcs.anl.gov/parallel-netcdf/

• Parallel netCDF mailing list:
Mail to majordomo@mcs.anl.gov with the body “subscribe parallel-netcdf”

• Jianwei Li’s PnetCDF talk at SC2003:
Thursday at 4:00 in room 36-37

• The SDM SciDAC web site:
http://sdm.lbl.gov/sdmcenter/
130
University of Chicago Department of Energy

The PETSc Library
• PETSc provides routines for the parallel solution of systems of equations that arise from the discretization of PDEs
♦ Linear systems ♦ Nonlinear systems ♦ Time evolution

• PETSc also provides routines for
♦ Sparse matrix assembly ♦ Distributed arrays ♦ General scatter/gather (e.g., for

unstructured grids)

131
University of Chicago Department of Energy

Hello World in PETSc
#include "petsc.h" int main( int argc, char *argv[] ) { int rank; PetscInitialize( &argc, &argv, 0, 0 ); MPI_Comm_rank( PETSC_COMM_WORLD, &rank ); PetscSynchronizedPrintf( PETSC_COMM_WORLD, "Hello World from rank %d\n", rank ); PetscSynchronizedFlush( PETSC_COMM_WORLD ); PetscFinalize( ); return 0; }
132
University of Chicago Department of Energy

Structure of PETSc
PETSc PDE Application Codes ODE Integrators

Visualization

Nonlinear Solvers, Interface Unconstrained Minimization Linear Solvers Preconditioners + Krylov Methods Object-Oriented Grid Matrices, Vectors, Indices Management Profiling Interface Computation and Communication Kernels MPI, MPI-IO, BLAS, LAPACK

133
University of Chicago Department of Energy

PETSc Numerical Components Nonlinear Solvers Newton-based Methods Line Search Trust Region Other Euler Time Steppers Backward Pseudo Time Euler Stepping Other Krylov Subspace Methods GMRES CG CGS Bi-CG-STAB TFQMR Richardson Chebychev Other Preconditioners Additive Schwartz Block Jacobi Jacobi ILU ICC LU (Sequential only) Others Matrices Compressed Sparse Row (AIJ) Blocked Compressed Sparse Row (BAIJ) Block Diagonal (BDIAG) Dense Matrix-free Other Distributed Arrays Indices Index Sets Block Indices Stride Other Vectors 134 University of Chicago Department of Energy .

Flow of Control for PDE Solution Main Routine Timestepping Solvers (TS) Nonlinear Solvers (SNES) Linear Solvers (SLES) PETSc PC Application Initialization KSP Function Evaluation User code Jacobian Evaluation PETSc code PostProcessing 135 Department of Energy University of Chicago .

BiCGstab with Additive Schwarz. including GMRES with ILU. Features of this solver: ♦ Fully parallel ♦ 2-d decomposition of the 2-d mesh ♦ Linear system described as a sparse matrix.Poisson Solver in PETSc • The following 7 slides show a complete 2-d Poisson solver in PETSc. user can select many different sparse data structures ♦ Linear system solved with any user-selected Krylov iterative method and preconditioner provided by PETSc. ♦ Complete performance analysis built-in • Only 7 slides of code! 136 University of Chicago Department of Energy . etc.

h> #include "petscsles.double) ). Vec b. px.*/ #include <math. 0.h" extern Mat FormLaplacianDA2d( DA. int ). n. PETSC “objects” hide details of distributed data structures and function parameters . int its. char *argv[] ) { SLES sles.Mode: C.h" #include "petscda. int. &argv. PetscInitialize( &argc. c-basic-offset:4 . 0 ). double (*)(double. double y ) { return sin(x*M_PI)*sin(y*M_PI). x. /* This function is used to define the right-hand side of the Poisson equation to be solved */ double func( double x. DA grid. -*. Mat A. } int main( int argc. extern Vec FormVecFromFunctionDA2d( DA. py. worldSize.Solve a Poisson Problem with Preconditioned GMRES /* -*.

MPI_Comm_size( PETSC_COMM_WORLD. px. 1. &px. func ). 1. allocate. &x ). &n. Use 10 by default */ n = 10. PetscOptionsGetInt( PETSC_NULL. "-px". &worldSize ). &grid ). /* Form the matrix and the vector corresponding to the DA */ A = FormLaplacianDA2d( grid. DA_STENCIL_STAR. DA_NONPERIODIC. Default it the same as without DAs */ px = 1. n ). and manage distributed data structures . /* Get the process decomposition. PETSc provides routines to access parameters and defaults /* Create a distributed array */ DACreate2d( PETSC_COMM_WORLD. 0. PetscOptionsGetInt( PETSC_NULL./* Get the mesh size. PETSc provides routines to create. 0 ). py. VecDuplicate( b. 0 ). b = FormVecFromFunctionDA2d( grid. n. py = worldSize / px. "-n". n. 0. n.

SLESSetFromOptions( sles ). PETSc provides SLESSolve( sles. b. PETSC_VIEWER_STDOUT_WORLD ). return 0. PetscPrintf( PETSC_COMM_WORLD. A. DADestroy( grid ). VecView( x. its ). PetscFinalize( ). VecDestroy( b ). including the output of the distributed “vec” object . "Solution is:\n" ). VecDestroy( x ). MatDestroy( A ). x. A. SLESSetOperators( sles. DIFFERENT_NONZERO_PATTERN ). &its ). routines that solve PetscPrintf( PETSC_COMM_WORLD. } systems of sparse linear (and nonlinear) equations PETSc provides coordinated I/O (behavior is as-if a single process). SLESDestroy( sles ).SLESCreate( PETSC_COMM_WORLD. "Required %d iterations\n". &sles ).

int n. h = 1. DACreateGlobalVector( grid. c-basic-offset:4 . je. int is. double (*f)( double. i./* -*. j. &V ). ie. (void **)&vval ).*/ #include "petsc. DAVecGetArray( grid. V. -*. double h. in. double **vval.h" #include "petscda. .0 / (n + 1).h" #include "petscvec.h" /* Form a vector based on a function for a 2-d regular mesh on the unit square */ Vec FormVecFromFunctionDA2d( DA grid. jn. double ) ) { Vec V.Mode: C. js.

return V. ie = is + in ./* Get global coordinates of this patch in the DA grid */ DAGetCorners( grid. } Almost the uniprocess code . for (i=is . &js. 0 ). 0.1. (void **)&vval ). } } DAVecRestoreArray( grid. i<=ie . V. i++) { for (j=js . &in. &jn. (j + 1) * h ). je = js + jn . j<=je .1. &is. j++){ vval[j][i] = (*f)( (i + 1) * h.

&is. Creates a parallel MatStencil cols[5]. &jn. ie. in. je. int n ) { Mat A. ie = is + in . &js. vals[5]. i. Distributed Across All Processes /* -*.h" /* Form the matrix for the 5-point finite difference 2d Laplacian on the unit square. &A ). je = js + jn .h" #include "petscda.1. 0 ). int r. /* Get global coordinates of this patch in the DA grid */ DAGetCorners( grid.Mode: C. using compressed sparse row format .Creating a Sparse Matrix. &in. oneByh2. oneByh2 = 1. is. distributed matrix h = 1. -*. j. MATMPIAIJ.0 / (n + 1). jn. 0. js. row. DAGetMatrix( grid.*/ #include "petscsles. c-basic-offset:4 . double h. nelm. n is the number of interior points along a side */ Mat FormLaplacianDA2d( DA grid.0 / (h*h).1.

if (j . cols[nelm++]. nelm. cols[nelm]. return A. as it often does. i++) { for (j=js. cols[nelm]. MatAssemblyEnd(A.1 > 0) { vals[nelm] = oneByh2. cols[nelm].i = i. vals. if (i + 1 < n . MAT_FINAL_ASSEMBLY).i = i.4 * oneByh2. row. nelm = 0. cols[nelm++]. from the boundary conditions .for (i=is. cols. i<=ie.j = j. } Just the usual code for setting the elements of the sparse matrix (the complexity comes.i = i.i = i + 1.1. cols[nelm++].} vals[nelm] = .1) { vals[nelm] = oneByh2.j = j + 1.j = j . &row. } } MatAssemblyBegin(A.} if (j + 1 < n .1 > 0) { vals[nelm] = oneByh2.j = j.} if (i .j = j. j<=je.1) { vals[nelm] = oneByh2. cols[nelm]. cols[nelm].i = i.} MatSetValuesStencil( A. cols[nelm++].1.i = i .j = j. 1. cols[nelm++]. j++){ row. MAT_FINAL_ASSEMBLY). INSERT_VALUES ).

Full-Featured PDE Solver • Command-line control of Krylov iterative method (choice of algorithms and parameters) • Integrated performance analysis • Optimized parallel sparse-matrix operations • Question: How many MPI calls used in example? 144 University of Chicago Department of Energy .

bcgs. 145 University of Chicago Department of Energy .restrict.interpolate.jacobi.sor.ilu.tfqmr.asm.gmres..…] • • • • • -ksp_max_it <max_iters> -ksp_gmres_restart <restart> -pc_asm_overlap <overlap> -pc_asm_type [basic..…] • -pc_type [lu.none] etc .Setting Solver Options at Runtime • -ksp_type [cg.

Global and Local Representations Local node Ghost node 5 0 1 2 3 4 9 Global: each process stores a unique local set of vertices (and each vertex is owned by exactly one process) Local: each process stores a unique local set of vertices as well as ghost nodes from neighboring processes 146 University of Chicago Department of Energy .

Global and Local Representations (cont.) Proc 1 9 10 11 6 7 8 3 4 5 0 1 2 Global Representation: 0 1 2 3 4 5 Proc 0 Proc 0 6 7 8 9 10 11 Proc 1 Proc 1 6 7 8 3 4 5 0 1 2 6 7 8 3 4 5 0 1 2 Local Representations: Proc 1 3 4 5 6 7 8 9 10 11 0 1 2 3 4 5 6 7 8 Proc 0 Proc 0 0 1 2 3 4 0 1 2 3 4 5 6 7 8 5 6 7 8 147 University of Chicago Department of Energy .

including ghost points) ♦ DAGlobalToLocalBegin(DA..DA *) ♦ DACreate3d(…..Logically Regular Meshes • DA .DA *) ♦ DACreate2d(…. Vec *) or ♦ DACreateLocalVector( DA. Vec *) • Update ghostpoints (scatter global vector into local parts. …) ♦ DAGlobalToLocalEnd(DA.…) University of Chicago 148 Department of Energy .Distributed Array: object containing information about vector layout across the processes and communication of ghost values • Form a DA ♦ DACreate1d(….DA *) • Create the corresponding PETSc vectors ♦ DACreateGlobalVector( DA..

Distributed Arrays Data layout and ghost values Proc 10 Proc 10 Proc 0 Proc 1 Proc 0 Proc 1 Box-type stencil Star-type stencil 149 University of Chicago Department of Energy .

which is contained in PETSc vectors • Global vector: parallel ♦ each process stores a unique local portion ♦ DACreateGlobalVector(DA da. but not the actual field data.1.…nlocal- 1) 150 University of Chicago Department of Energy .Vec *lvec). • Local work vector: sequential ♦ each process stores its local portion plus ghost values ♦ DACreateLocalVector(DA da.Vectors and DAs • The DA object contains information about the data layout and ghost values. ♦ uses “natural” local numbering of indices (0.Vec *gvec).

DAPeriodicType wrap. int s. int M.const int ly[].DACreate2d(…. DAStencilType stencil_type.int m.and y-directions ♦ processes in x.int n.and y-directions ♦ degrees of freedom per node ♦ stencil width ♦ Number of nodes for each cell (use PETSC_NULL for the default) as tensor-product And similarly for DACreate1d() and DACreate3d() 151 University of Chicago Department of Energy .BOX] ♦ number of grid points in x.Y. DA *inra) ♦ DA_[NON.int N.XY]PERIODIC ♦ DA_STENCIL_[STAR.int dof.X.*DA) • DACreate2d(MPI_Comm comm.const int lx[].

Vec global_vec.…) ♦ Takes same arguments 152 University of Chicago Department of Energy . Vec local_vec ) ♦ global_vec provides data ♦ Insert is either INSERT_VALUES or ADD_VALUES and specifies how to update values in the local vector. local_vec (a pre-existing local vector) • DAGlobalToLocal End(DA.Updating the Local Representation Two-step process that enables overlapping computation and communication • DAGlobalToLocalBegin(DA. insert.

uv.u_global.f.ierr) 153 University of Chicago Department of Energy . ierr ) call DALocalToGlobal(da.2. i=1.INSERT_VALUES. ui.u_global.0*u(i) + u(i-1)) 10 continue call VecRestoreArray( ulocal.ulocal.INSERT_VALUES. ui.ulocal.5/h)*u(i)*(u(i+1)-u(i-1)) + (e/(h*h))*(u(i+1) . ierr ) #define u(i) uv(ui+i) C Do local computations (here u and f are local vectors) do 10.localsize f(i) = (.ierr) call VecGetArray( ulocal.ierr) call DAGlobalToLocalEnd(da. uv.Ghost Point Scatters: Burger’s Equation Example call DAGlobalToLocalBegin(da.INSERT_VALUES.f_global.

corresponding to the entire problem domain University of Chicago PETSc numbering used by DAs 154 Department of Energy .Global Numbering used by DAs Proc 2 Proc 3 Proc 2 Proc 3 26 27 28 21 22 23 16 17 18 11 12 13 6 7 8 1 2 3 Proc 0 29 30 24 25 19 20 14 15 9 10 4 5 Proc1 22 23 24 19 20 21 16 17 18 7 8 9 4 5 6 1 2 3 Proc 0 29 30 27 28 25 26 14 15 12 13 10 11 Proc1 Natural numbering.

AO *ao)..Mapping Between Global Numberings • Natural global numbering ♦ convenient for visualization of global problem. etc. ♦ AO usage explained in next section • Some utilities (e. • Can convert between various global numbering schemes using AO (Application Orderings) ♦ DAGetAO(DA da. specification of certain boundary conditions. VecView()) automatically handle this mapping for global vectors attained from DAs 155 University of Chicago Department of Energy .g.

html • These provide the building blocks for building large. HDF5. IMSL. Prometheus. ScaLAPACK. TCGMSG-MPI. … ♦ Commercially supported libraries • E. Trilinos.Other Libraries • Many libraries exist ♦ Freely available libraries • PETSc. PLAPACK. SPRNG.. PSPASES.anl. … ♦ More at www.g. FFTW. and efficient programs 156 University of Chicago Department of Energy .gov/mpi/libraries. S+. ParMETIS. MP_SOLVE. MpCCI. GeoFEM.mcs. NAG. DOUG. complex. PARASOL. IBM PESSL. TAO.

Some Final Comments • It isn’t how fast you can program something easy • It is how fast you can program what you need • Libraries give MPI an advantage over other parallel programming models • Libraries provide a way to build custom high-level programming environments ♦ Many exist — use them if possible ♦ Otherwise. create your own! 157 University of Chicago Department of Energy .

Conclusion • MPI provides a well-developed. using component-oriented design can simplify the process of writing and debugging an application with MPI. 158 University of Chicago Department of Energy . efficient and portable model for programming parallel computers • Just as important. • Parallel applications can often be quickly built using these components • Even when no available component meets your needs. MPI provides features that enable and encourage the construction of software components.

Suggestions for Exercises • Compile and run: ♦ Examples in /opt/mpich/ethernet/gcc/examples cp –r /opt/mpich/ethernet/gcc/examples .html ♦ Or on the CD: mpi-exercises/index.top500.org) ♦ Build PETSc and try the examples (including those with graphics) ♦ University of Chicago 159 Department of Energy . make cpi mpirun –np 3 –nolocal .anl.f) to use MPI_Send and MPI_Recv instead of MPI_Bcast and MPI_Reduce ♦ • Visit www./cpi • Write some programs: Hello world ♦ Modify cpi.html ♦ • For the adventurous Build HPLinpack and find the year that your cluster would have been the fastest machine in the world (see www.c (or pi3.gov/mpi/tutorials/mpiexmpl/index.mcs.

including: • Send modes in MPI • Collectives and pipelining • Defining collective combiner operations • Parallel netCDF details • Fairness in master-worker programs • Why contexts? • Using the MPI profiling interface 160 University of Chicago Department of Energy .Appendix • The following slides provide more information about some features of MPI.

Buffered Mode • When MPI_Isend is awkward to use (e. ) ... 161 University of Chicago Department of Energy . • MPI_Buffer_detach waits for completion. MPI_Buffer_detach( &buf.. the user can provide a buffer for the system to store messages that cannot immediately be sent. MPI_Buffer_attach( buf.. bufsize ).. • Performance depends on MPI implementation and size of message. MPI_Bsend( . same as MPI_Send . .. char *buf = malloc( bufsize ). int bufsize.. lots of small messages).g.. &bufsize ).

lots of small messages).g. 162 University of Chicago Department of Energy ..Buffered Mode (Fortran) • When MPI_Isend is awkward to use (e. integer bufsize. call MPI_Buffer_detach( buf. • Performance depends on MPI implementation and size of message. ) .. bufsize.. buf(10000) call MPI_Buffer_attach( buf.. ierr ) . the user can provide a buffer for the system to store messages that cannot immediately be sent... bufsize. same as MPI_Send . ierr ) • MPI_Buffer_detach waits for completion. call MPI_Bsend( ...

n ... call MPI_Bsend( bufsize bytes . & bufsize+MPI_BSEND_OVERHEAD. ierr ) do i=1. & ierr ) 163 University of Chicago Department of Energy . bufsize.Test Your Understanding of Buffered Sends • What is wrong with this code? call MPI_Buffer_attach( buf.. Enough MPI_Recvs( ) enddo call MPI_Buffer_detach( buf. ) ....

. MPI_Recv 164 Department of Energy ... process scheduling.Buffering is limited • Processor 0 i=1 MPI_Bsend MPI_Recv i=2 MPI_Bsend • i=2 Bsend fails because first Bsend has not been able to deliver the data University of Chicago • Processor 1 i=1 MPI_Bsend … delay due to computing.

Correct Use of MPI_Bsend • Fix: Attach and detach buffer in loop • do i=1.n call MPI_Buffer_attach( buf.. call MPI_Bsend( bufsize bytes ) ... Enough MPI_Recvs( ) call MPI_Buffer_detach( buf. ierr ) enddo Buffer detach will wait until messages have been delivered 165 University of Chicago Department of Energy .ierr ) . & bufsize+MPI_BSEND_OVERHEAD.. bufsize.

When not to use Collective Operations
• Sequences of collective communication can be pipelined for better efficiency • Example: Processor 0 reads data from a file and broadcasts it to all other processes.
♦ do i=1,m

if (rank .eq. 0) read *, a call mpi_bcast( a, n, MPI_INTEGER, 0, & comm, ierr ) enddo ♦ Assume that Bcast takes nlogp time. Then this takes m n log p time (see Tuesday for a better way to bcast).

• It can be done in (m+p) n time!
166
University of Chicago Department of Energy

Pipeline the Messages
• Processor 0 reads data from a file and sends it to the next process. Other forward the data.
♦ do i=1,m

if (rank .eq. 0) then read *, a call mpi_send(a, n, type, 1, 0, comm,ierr) else call mpi_recv(a,n,type,rank-1, 0, comm,status,ierr) call mpi_send(a,n,type,next, 0, comm,ierr) endif enddo

167
University of Chicago Department of Energy

Concurrency between Steps
• Broadcast:
Time Each broadcast takes less time then pipeline version, but total time is longer

• Pipeline

Another example of deferring synchronization
168
University of Chicago Department of Energy

Notes on Pipelining Example
• Use MPI_File_read_all
♦ Even more optimizations possible • Multiple disk reads • Pipeline the individual reads • Block transfers

• Sometimes called “digital orrery”
♦ Circular particles in n-body problem ♦ Even better performance if pipeline never

stops

• “Elegance” of collective routines can lead to fine-grain synchronization
♦ performance penalty
169
University of Chicago Department of Energy

you always get the same results ♦ but roundoff error. truncation can happen • MPI does not require that the same input give the same output ♦ Implementations are encouraged but not required to provide exactly the same output given the same input ♦ Round-off error may cause slight differences • Allreduce does guarantee that the same value is received by all processes for each call • Why didn’t MPI mandate determinism? ♦ Not all applications need it ♦ Implementations can use “deferred synchronization” ideas to provide better performance 170 Department of Energy University of Chicago .How Deterministic are Collective Computations? • In exact arithmetic.

• The user function should perform: inoutvec[i] = invec[i] op inoutvec[i]. inoutvec. datatype ). len. 171 University of Chicago Department of Energy . • The user function can be non-commutative.Defining your own Collective Operations • Create your own collective computations with: MPI_Op_create( user_fcn. user_fcn( invec. commutes. MPI_Op_free( &op ). for i from 0 to len-1. &op ).

len. & datatype ) • The user function should perform: inoutvec(i) = invec(i) op inoutvec(i) for i from 1 to len. commutes. • The user function can be non-commutative. ierr ) MPI_Op_free( op. 172 University of Chicago Department of Energy . inoutvec.Defining your own Collective Operations (Fortran) • Create your own collective computations with: call MPI_Op_create( user_fcn. ierr ) subroutine user_fcn( invec. op.

PnetCDF Development Activity Lots of help coming from the community: • John Tannahill at LLNL really pushing on the Fortran side of things • Tyce Mclarty helping knock out build problems on the IBM SP platform • Brad Gallagher at UofC examining performance with FLASH • Rene Redler (PRISM project in Europe) is testing on the NEC SX platform 173 University of Chicago Department of Energy .

FLASH • FLASH is an astrophysics simulation code from the University of Chicago ASCI Center • Fluid dynamics code using adaptive mesh refinement (AMR) • Runs on systems with thousands of nodes • Has been using HDF5 for checkpointing and other output 174 University of Chicago Department of Energy .

HDF5 • Results using FLASH I/O benchmark on ASCI Frost at LLNL ♦ IBM’s MPI ♦ GPFS parallel file system 8x8x8 Blocks University of Chicago 16x16x16 Blocks 175 Department of Energy .Performance Comparison vs.

FLASH and PnetCDF in Practice
• The amount of time FLASH spends in I/O varies widely between platforms • For some platforms, the change in I/O performance has resulted in 2-3 times speedup for the application as a whole!

176
University of Chicago Department of Energy

Under the Hood of PnetCDF
• PnetCDF builds on top of any MPI-IO implementation • Can be used with our components:
♦ ROMIO MPI-IO implementation ♦ PVFS parallel file system

• Has also been tested on IBM SP and NEC S Cluster PnetCDF PnetCDF ROMIO ROMIO PVFS PVFS
University of Chicago

NEC SX PnetCDF PnetCDF MPI/SX MPI/SX SX Local FS SX Local FS

IBM SP PnetCDF PnetCDF IBM MPI IBM MPI GPFS GPFS
177

Department of Energy

Parallel netCDF Operators
• The netCDF Operators (NCO) are a suite of tools for manipulating netCDF files • Used for postprocessing netCDF files in the climate community • We are in the process of porting a subset of these to run in parallel using PnetCDF • Performance gains with no effort to the user! • This is another example of high-level programming with MPI — At the shell level, using programs (filters) enabled by MPI

178
University of Chicago Department of Energy

MPICH2
• Complete redesign! • Same goals as for MPICH:
♦ Complete implementation (this time with

MPI-2) ♦ Portable ♦ Making best use of hardware (highperformance when possible) ♦ Starting point for vendors

• Also:
♦ Enhanced fault handling

• Implementation in progress, betas available
University of Chicago

179
Department of Energy

Some Research Areas • MPI-2 RMA interface ♦ Can we get high performance? • Fault Tolerance and MPI ♦ Are intercommunicators enough? • MPI on 64K processors ♦ Umm…how do we make this work :)? ♦ Reinterpreting the MPI “process” • MPI as system software infrastructure ♦ With dynamic processes and fault tolerance. can we build services on MPI? 180 University of Chicago Department of Energy .

n). preconditioners.PETSC_DECIDE.&b).. A.Basic Linear Solver Code (C/C++) SLES Mat Vec int sles. This default works with all VecDuplicate(x. solving only one system SLESSetFromOptions(sles). number of iterations */ MatCreate(PETSC_COMM_WORLD. preconditioners. x.n. SLESSolve(sles. RHS vectors */ problem dimension. VecSetFromOptions (x). /* /* /* /* linear solver context */ matrix */ solution.A.PETSC_DECIDE.n.g.&sles). n.&A). 181 University of Chicago Department of Energy .&its).PETSC_DECIDE . SLESDestroy(sles).A. matrix each time a system is solved. b.&x).b. has the same nonzero pattern as the VecSetSizes(x. its. MatSetFromOptions(A). Other values (e.DIFFERENT_NONZERO_PATTERN). /* (code to assemble matrix not shown) */ Indicate whether the preconditioner VecCreate(PETSC_COMM_WORLD.x. Ignored when SLESSetOperators(sles. /* (code to assemble RHS vector not shown)*/ SAME_NONZERO_PATTERN) can be used for particular SLESCreate(PETSC_COMM_WORLD .

its.b.x. ierr ) VecCreate( PETSC_COMM_WORLD.ierr) SLESDestroy(sles.A.A.Basic Linear Solver Code (Fortran) SLES Mat Vec integer call call call call call call sles A x.sles.b. PETSC_DECIDE.PETSC_DECIDE. ierr MatCreate( PETSC_COMM_WORLD.A. n.n.ierr ) C then assemble matrix and right-hand-side vector call call call call call SLESCreate(PETSC_COMM_WORLD.x. ierr ) VecSetFromOptions( x.its. ierr ) VecDuplicate( x.n.ierr ) MatSetFromOptions( A. DIFFERENT_NONZERO_PATTERN.ierr) 182 Department of Energy University of Chicago .ierr) SLESSetFromOptions(sles. b n.ierr) SLESSolve(sles.ierr) SLESSetOperators(sles.ierr ) VecSetSizes( x.

interpolate.jacobi.none] -sub_pc_type <pctype> -sub_ksp_type <ksptype> -sub_ksp_rtol <rtol> And many more options.SLES: Selected Preconditioner Options Functionality Procedural Interface Runtime Option -pc_type [lu. restrict.. 183 University of Chicago Department of Energy .asm. sor..…] Set preconditioner type PCSetType( ) Set level of fill for ILU Set SOR iterations Set SOR parameter Set additive Schwarz variant Set subdomain solver options PCILUSetLevels( ) PCSORSetIterations( ) PCSORSetOmega( ) PCASMSetType( ) PCGetSubSLES( ) -pc_ilu_levels <levels> -pc_sor_its <its> -pc_sor_omega <omega> -pc_asm_type [basic.ilu.

tfqmr..cgs.bcgs. -ksp_truemonitor. 184 University of Chicago Department of Energy .gmres..…] -ksp_monitor. –ksp_xmonitor.SLES: Selected Krylov Method Options Functionality Set Krylov method Set monitoring routine Procedural Interface KSPSetType( ) KSPSetMonitor( ) Runtime Option -ksp_type [cg. ksp_xtruemonitor KSPSetTolerances( ) -ksp_rtol <rt> -ksp_atol <at> Set convergence -ksp_max_its <its> tolerances KSPGMRESSetRestart( ) -ksp_gmres_restart <restart> Set GMRES restart parameter Set orthogonalization KSPGMRESSet -ksp_unmodifiedgramschmidt Orthogonalization( ) -ksp_irorthog routine for GMRES And many more options.

SAEQSBAIJ 8 block diagonal: MPIBDIAG. SEQBDIAG 8 dense: MPIDENSE.Matrices • What are PETSc matrices? ♦ Fundamental objects for storing linear operators (e. SEQDENSE 8 matrix-free 8 etc. • MatSetFromOptions(Mat) lets you set the MatType at runtime. SEQAIJ 8 symmetric block sparse AIJ: MPISBAIJ.MatType) • where MatType is one of 8 default sparse AIJ: MPIAIJ..processes that share the matrix • number of local/global rows and columns • Create matrices via ♦ ♦ MatSetType(Mat.g. 185 University of Chicago Department of Energy .Mat *) • MPI_Comm . SEQAIJ 8 block sparse AIJ (for multi-component PDEs): MPIAIJ. Jacobians) MatCreate(….

block AIJ. dense. ♦ Matrix assembly • MatSetValues() ♦ Matrix-vector multiplication • MatMult() ♦ Matrix viewing • MatView() • Multiple underlying implementations ♦ AIJ.. ♦ Not by its data structures 186 University of Chicago Department of Energy . block diagonal. etc. e. matrix-free. symmetric block AIJ.g.Matrices and Polymorphism • Single user interface. the operations that you can perform with it. • A matrix is defined by its properties.

Matrix Assembly • Same form as for PETSc Vectors: • MatSetValues(Mat.…) ♦ number of rows to insert/add ♦ indices of rows and columns ♦ number of columns to insert/add ♦ values to add ♦ mode: [INSERT_VALUES.ADD_VALUES] • MatAssemblyBegin(Mat) • MatAssemblyEnd(Mat) 187 University of Chicago Department of Energy .

to allocate matrix if (rank == 0) { /* Only one process creates matrix */ for (i=1.1. double value[3]. column[1] = i.column. int column[3].0. i<n-2.PETSC_DECIDE. … MatCreate(PETSC_COMM_WORLD.n. /* mesh interior */ Let PETSc decide value[0] = -1. how 188 University of Chicago Department of Energy . i++) { across processes column[0] = i-1.MAT_FINAL_ASSEMBLY).n.value. Choose the global Size of the matrix MatSetFromOptions(A). } } /* also must set boundary points (code for global row 0 and n-1 omitted) */ MatAssemblyBegin(A.Matrix Assembly Example simple 3-point stencil for 1D discretization Mat A.INSERT_VALUES).MAT_FINAL_ASSEMBLY).0.&i. MatSetValues(A. i.&A). PETSC_DECIDE. MatAssemblyEnd(A. value[2] = -1.0. value[1] = 2.3. column[2] = i+1.

proc 0 proc 1 proc 2 proc 3 proc 4 } proc 3: locally owned rows MatGetOwnershipRange(Mat A. int *rend) ♦ rstart: first locally owned row of global matrix ♦ rend -1: last locally owned row of global matrix 189 University of Chicago Department of Energy .Parallel Matrix Distribution Each process locally owns a submatrix of contiguously numbered global rows. int *rstart.

i.3.0.0.istart. … MatCreate(PETSC_COMM_WORLD. Let PETSc decide /* mesh interior */ to allocate matrix istart = start.&i.n. if (start == 0) istart = 1. if (iend == n-1) iend = n-2.INSERT_VALUES). } /* also must set boundary points (code for global row 0 and n-1 omitted) */ MatAssemblyBegin(A.column.n.&start. double value[3]. value[1] = 2. MatAssemblyEnd(A. i<iend. start. MatSetValues(A. int column[3].MAT_FINAL_ASSEMBLY). end. iend = end.0. column[1] = i.MAT_FINAL_ASSEMBLY). column[2] = i+1.&end).value.iend. PETSC_DECIDE. value[2] = -1. across processes value[0] = -1.Matrix Assembly Example With Parallel Assembly simple 3-point stencil for 1D discretization Mat A. for (i=istart. MatGetOwnershipRange(A.1.&A). Choose the global Size of the matrix MatSetFromOptions(A). University of Chicago how 190 Department of Energy .PETSC_DECIDE. i++) { column[0] = i-1.

J.K indices DAGlobalToLocal( ) structured meshes 191 University of Chicago Department of Energy .Communication and Physical Discretization: Structured Meshes Communication Geometric Data stencil [implicit] Data Structure Ghost Point Creation Data Structures DACreate( ) DA Ghost Point Updates Local Numerical Computation Loops over I.

ierr ) print *. & comm.status(MPI_SOURCE) enddo else do i=1.’ Received from’. n.& MPI_ANY_SOURCE. ierr ) enddo endif • In what order are messages received? 192 University of Chicago Department of Energy .& status. n. comm. 0. MPI_INTEGER.1000 call MPI_Send( a.eq. MPI_ANY_TAG. i.1000*(size-1) call MPI_Recv( a. 0) then do i=1. MPI_INTEGER.Fairness in Message Passing • What happens in this code: if (rank .

Fairness • MPI makes no guarantee. • The program could ♦ Receive all from process 1. then all from process 2. etc. ♦ That order would starve processes 2 and higher of work in a master/worker method • How can we encourage or enforce fairness? 193 University of Chicago Department of Energy . other than that all messages will be received eventually.

ierr) enddo • Process all completed receives (wait guarantees at least one): call MPI_Waitsome( size-1.MPI Multiple Completion • Provide one Irecv for each process: do i=1. count.req(array_of_indices(j)).count ! Source of completed message is … array_of_statuses(MPI_SOURCE. req.i.& array_of_indices.… req(i).) enddo 194 University of Chicago Department of Energy . ierr ) do j=1. array_of_statuses.j) ! Repost request call MPI_Irecv( ….size-1 call MPI_Irecv(….

have each worker process receive 10 work requests and send 10 responses.Test Yourself: Providing Fairness • Write a program with one master.g. Make the workers’ computation trivial (e. just return a counter) Use the simple algorithm (MPI_Send/MPI_Recv) ♦ Is the MPI implementation fair? • Write a new version using MPI_Irecv/MPI_Waitall ♦ Be careful of uncancelled Irecv requests ♦ Be careful of the meaning of array_of_indices (zero versus one origin) 195 University of Chicago Department of Energy ..

University of Chicago Department of Energy . Sub1b().Why Contexts? • Parallel libraries require isolation of messages from one another and from the user that cannot be adequately handled by tags. Sub2(). ♦ Sub1 and Sub2 are from different libraries Sub1(). • The following examples are due to Marc Snir. ♦ Sub1a and Sub1b are from the same library Sub1a(). Sub2().

Correct Execution of Library Calls Process 0 Process 1 Process 2 Recv(any) Sub1 Recv(any) Send(1) Send(0) Recv(1) Sub2 Send(2) Send(0) Recv(2) Send(1) Recv(0) 197 University of Chicago Department of Energy .

Incorrect Execution of Library Calls Process 0 Process 1 Process 2 Recv(any) Sub1 Recv(any) Send(1) Send(0) Recv(1) Sub2 Send(2) ? Send(0) Recv(2) Send(1) Recv(0) 198 Department of Energy University of Chicago Program hangs (Recv(1) never satisfied) .

Correct Execution of Library Calls with Pending Communication Recv(any) Sub1a Send(0) Send(1) Recv(2) Sub2 Send(1) Send(2) Recv(0) Send(0) Recv(1) Recv(any) Sub1b 199 University of Chicago Department of Energy .

Incorrect Execution of Library Calls with Pending Communication Recv(any) Sub1a Send(0) Send(1) Recv(2) Sub2 Send(1) Send(2) Recv(0) Send(0) Recv(1) Recv(any) Sub1b Program Runs—but with wrong data! 200 Department of Energy University of Chicago .

Using PMPI routines • PMPI allows selective replacement of MPI routines at link time (no need to recompile) • Some libraries already make use of PMPI • Some MPI implementations have PMPI bugs ♦ PMPI_Wtime() returns 0 ♦ PMPI in a separate library that some installations have not installed University of Chicago Department of Energy .

Profiling Interface Call MPI_Send MPI_Send MPI_Send PMPI_Send Call MPI_Bcast User Program Profiling Library MPI_Bcast MPI Library 202 University of Chicago Department of Energy .

datatype. return PMPI_send(start. MPI_Datatype datatype. } 203 University of Chicago Department of Energy . tag.Using the Profiling Interface From C static int nsend = 0. int MPI_Send( void *start. MPI_Comm comm ) { nsend++. count. int dest. int tag. int count. dest. comm).

datatype. dest. datatype. comm.Using the Profiling Interface from Fortran Block data common /mycounters/ nsend data nsend/0/ end subroutine MPI_Send( start. count. & dest. comm common /mycounters/ nsend save /mycounters/ nsend = nsend + 1 call PMPI_send(start. tag. count. tag. datatype. comm. count.& tag. ierr ) end University of Chicago 204 Department of Energy . ierr ) integer start(*). dest.

Test Yourself: Find Unsafe Uses of MPI_Send • Assume that you have a debugger that will tell you where a program is stopped (most will). How can you find unsafe uses of MPI_Send (calls that assume that data will be buffered) by running the program without making assumptions about the amount of buffering ♦ Hint: Use MPI_Ssend 205 University of Chicago Department of Energy .

comm call PMPI_Ssend(start. dest. count. comm. datatype. comm. count. tag. dest. datatype. count. ierr ) integer start(*). tag. MPI_Send will act like MPI_Ssend (or fail) 206 University of Chicago Department of Energy . dest.Finding Unsafe uses of MPI_Send subroutine MPI_Send( start. tag. datatype. ierr ) end • MPI_Ssend will not complete until the matching receive starts • MPI_Send can be implemented as MPI_Ssend • At some value of count.

Finding Unsafe Uses of MPI_Send II • Have the application generate a message about unsafe uses of MPI_Send ♦ Hint: use MPI_Issend ♦ C users can use __FILE__ and __LINE__ • sometimes possible in Fortran (.F files) 207 University of Chicago Department of Energy .

dest. MPI_Wtime()) call PMPI_Test( request. 1. dest. ierr ) endif 208 end University of Chicago Department of Energy . comm. dest. flag. ’MPI_Send appears to be hanging’ call MPI_Abort( MPI_COMM_WORLD. count.not. flag . status(MPI_STATUS_SIZE) double precision tend. t1 . ierr ) Enddo if (.gt. comm.false.Reporting on Unsafe MPI_Send subroutine MPI_Send( start. datatype. flag) then print *. count.& ierr ) integer start(*). & request. count. datatype.not.h’ integer request. tag. delay parameter (delay=10. tend = MPI_Wtime()+ delay Do while (. tag. status. ierr ) flag = . comm include ’mpif.0d0) logical flag call PMPI_Issend(start. tag. datatype.and.

anl.Logging and Visualization Tools • Upshot.uiuc.cs.wisc.rs6000/ibm.edu/Projects/Pablo/pablo. Jumpshot.com/ http://www.uiuc. and MPE tools http://www.gov/mpi/mpich http://www.mcs.edu/~paradyn University • Chicago of Many other vendor tools exist Department of Energy .ncsa.html http://www.com/software/sp_products/pe.html • Pallas VAMPIR • IBM VT • Pablo • Paragraph • Paradyn http://www.edu/Apps/MCS/ParaGraph/ParaGr aph.pallas.cs. html http://wwwpablo.

Sign up to vote on this title
UsefulNot useful