Self-Assessment Quiz: MPI
Twenty questions to confirm the MPI model, the call arguments, and the halo-exchange pattern landed before you move on to GPUs in Chapter 35. Aim for 16 or more. Work the "what does this print?" and argument-order questions by hand; the answer key and a topic map are at the end.
Question 1
In the MPI model, the parallel workers are: - A. Threads sharing one address space - B. Processes, each with its own private memory - C. GPU cores - D. Coarray images sharing a global address space
Question 2
mpirun -np 4 ./prog launches:
- A. One process that spawns four threads
- B. Four copies of the same program, each with a different rank
- C. Four different programs
- D. One process, four times faster
Question 3
A rank is: - A. The speed of a process - B. A process's integer identity (0 … N−1) within a communicator - C. The number of processes - D. The amount of memory a process has
Question 4
Which call returns the total number of processes in MPI_COMM_WORLD?
- A. mpi_comm_rank
- B. mpi_comm_size
- C. mpi_init
- D. mpi_get_count
Question 5
What is wrong with call mpi_comm_rank(MPI_COMM_WORLD, rank) in the use mpi interface?
- A. Nothing
- B. It is missing the trailing ierr argument
- C. MPI_COMM_WORLD is not defined
- D. rank must be real
Question 6
The correct argument order for mpi_send is:
- A. buf, dest, count, tag, datatype, comm, ierr
- B. buf, count, datatype, dest, tag, comm, ierr
- C. dest, buf, count, datatype, tag, comm, ierr
- D. buf, count, dest, datatype, comm, tag, ierr
Question 7
Compared with mpi_send, an mpi_recv call additionally includes, before ierr:
- A. A root argument
- B. A status argument
- C. An op argument
- D. A second buffer
Question 8
You send an array of real(dp) but pass MPI_INTEGER as the datatype. The most likely result is:
- A. A compile error
- B. A runtime crash with a clear message
- C. No error — the receiver silently gets wrong data
- D. MPI converts the integers to reals automatically
Question 9
Two ranks each call mpi_send to the other first, then mpi_recv. This code:
- A. Always works correctly
- B. Can deadlock — it may pass for small messages and hang for large ones
- C. Always deadlocks immediately
- D. Is a compile error
Question 10
The cleanest single-call fix for the exchange in Question 9 is:
- A. mpi_bcast
- B. mpi_sendrecv
- C. mpi_reduce
- D. mpi_barrier
Question 11
mpi_bcast sends:
- A. Different pieces of an array, one per process
- B. One process's value to every process
- C. Every process's value combined onto one process
- D. A message between two named processes
Question 12
The difference between mpi_reduce and mpi_allreduce is:
- A. allreduce is slower
- B. reduce delivers the result to one root; allreduce delivers it to every process
- C. reduce only sums; allreduce only takes the max
- D. There is no difference
Question 13
Running example-03-collectives.f90 with -np 8, the "sum of (rank+1)" line prints:
- A. 8
- B. 28
- C. 36
- D. 64
Question 14
A ghost cell (halo cell) is: - A. A cell whose value is always zero - B. A stored copy of a neighbouring subdomain's boundary data that the process does not own - C. A cell that has been deallocated - D. The corner cell of the global grid
Question 15
Once a process's halo is filled each step, the interior stencil update it runs is: - A. A special distributed version of the stencil - B. The unmodified serial Chapter 24 stencil - C. Different for each process - D. Skipped for the edge rows
Question 16
MPI_PROC_NULL is used at the top and bottom strips because:
- A. It makes those processes run faster
- B. A send/recv to it is a no-op, so the same exchange code runs everywhere with no boundary if
- C. It fills the ghost cells with zeros
- D. It is required by mpi_init
Question 17
The solver stores its strip as u(nx, 0:nloc+1) — full width on the first index, decomposed direction on
the second — because:
- A. It looks tidier
- B. In column-major Fortran a whole row u(:,k) is then contiguous, so each halo message is a contiguous buffer
- C. MPI requires the second index to be the ghost
- D. It uses less memory
Question 18
True or false, with justification: a data race on the temperature field, the hazard you feared in OpenMP, is impossible between MPI processes.
Question 19
Non-blocking communication (mpi_isend/mpi_irecv + mpi_wait) is worth the extra complexity because it:
- A. Uses less memory
- B. Lets a process compute ghost-independent work while the exchange is in flight (overlap)
- C. Cannot deadlock while mpi_sendrecv can
- D. Automatically checks ierr
Question 20
What does this print, launched with -np 4? (Reason about the collective.)
mine = real(rank, dp) ! 0, 1, 2, 3
call mpi_allreduce(mine, s, 1, MPI_DOUBLE_PRECISION, MPI_SUM, MPI_COMM_WORLD, ierr)
if (rank == 0) print '(f4.1)', s
- A.
3.0 - B.
6.0 - C.
4.0 - D.
10.0
Answer Key
| Q | Ans | Why |
|---|---|---|
| 1 | B | MPI processes have private memory; they coordinate by messages, not shared variables. |
| 2 | B | SPMD: -np 4 runs four copies of the one program, each with a distinct rank. |
| 3 | B | A rank is a process's 0-based identity within a communicator. |
| 4 | B | mpi_comm_size returns the process count; mpi_comm_rank returns the caller's own rank. |
| 5 | B | Every mpi_* call in the use mpi interface needs the trailing ierr. |
| 6 | B | buf, count, datatype, dest, tag, comm, ierr — memorize it. |
| 7 | B | mpi_recv inserts a status argument before ierr (and names a source, not a dest). |
| 8 | C | MPI trusts your datatype; it copies the wrong bytes with no error — the dangerous kind of bug. |
| 9 | B | Standard-mode mpi_send may buffer small messages (works) but blocks on large ones (deadlock). |
| 10 | B | mpi_sendrecv does both in one deadlock-free call. |
| 11 | B | Broadcast: one process's value copied to all. |
| 12 | B | reduce → one root; allreduce → every process gets the combined result. |
| 13 | C | Sum of rank+1 for ranks 0..7 is $1+2+\dots+8 = N(N+1)/2 = 36$. |
| 14 | B | A ghost cell is a stored, unowned copy of a neighbour's boundary data. |
| 15 | B | With the halo filled, the stencil reads ghosts uniformly — the exact serial update runs. |
| 16 | B | Send/recv to MPI_PROC_NULL is a no-op, removing every boundary special-case. |
| 17 | B | Column-major makes u(:,k) contiguous, so the halo ships as a plain contiguous buffer. |
| 18 | True | Each process updates only its own rows in private memory; nothing is shared to race over. What replaces the worry is communication correctness — exchanging the right halo at the right time. |
| 19 | B | Non-blocking's payoff is overlap: compute the deep interior while the halo is in transit. |
| 20 | B | Sum of ranks 0+1+2+3 = 6; allreduce gives it to all, rank 0 prints 6.0. |
Topics to review by question
- Q1–5 → §34.1 (the MPI model: processes, ranks, communicators, the skeleton and
ierr). - Q6–10 → §34.2 (point-to-point: argument order, datatype, deadlock and
mpi_sendrecv). - Q11–13, Q20 → §34.3 (collectives: bcast, reduce vs allreduce, and what they compute).
- Q14–17 → §34.4 (domain decomposition, ghost cells,
MPI_PROC_NULL, column-major layout). - Q18–19 → §34.4 and the Spaced Review (distributed vs shared memory; non-blocking overlap).
Scored below 16? The two areas most worth rereading are the mpi_send/mpi_recv argument order and the
deadlock cure (Q6–10, §34.2), and the ghost-cell/halo-exchange pattern (Q14–17, §34.4) — they are the whole
of writing a distributed stencil code.