# Section III Exercises Exercises TDD Reminder Exercise 1

• Slides: 21

Section III - Exercises

Exercises • • TDD Reminder Exercise 1: Simple function Exercise 2: MPI Halo Exercise 3: Interpolation p. FUnit Tutorial 2

TDD Reminder Add test Write Test code Yes Passes? No Passes? Write application code No Yes Successful and done p. FUnit Tutorial 3

Exercise 1

Exercise 1 • Develop unit tests and implementation for a function that computes the sum inverse of a sequence of floating point numbers: Possible tests? – If n=1 and A 1=1, then f = 1 – If n=3 and A 1 =½, A 2=⅓, A 3=⅕, then f = 2+3+5=10 p. FUnit Tutorial 5

Exercise 1 (cont’d) • Copy the exercise material into your own home directory % cp –r /discover/nobackup/tclune/TDD_Exercises. • Use the pre-installed version of p. FUnit % export PFUNIT=/usr/local/other/p. FUnit/Intel-11. 1. 038 -serial • Detailed instructions are located in TDD_Exercises/Exercise_1/README • Do not allow yourself to get stuck – ask for assistance. p. FUnit Tutorial 6

Exercise 2

Tests with MPI • Tests which use MPI accept an extra argument – Used by framework to pass a subcommunicator – Provides access to rank and npes for convenience • Test interface looks like: subroutine test_parallel(info) type (Test. Info_type) : : info • Other useful interfaces: rank = process. Rank(info) npes = num. Processes(info) comm = mpi. Communicator(info) • Very important NOT to use MPI_COMM_WORLD p. FUnit Tutorial 8

MPI cont’d • Registration of MPI tests requires an extra parameter specifying the number of processes to use: call add(suite, & & Mpi. Test. Case('test. MPI', test. MPI, num. Processes=3)) • p. FUnit creates a new subcommunicator for each MPI test when it is run – Serial tests are only run on the root process. • Must use configuration of PFUNIT compiled with MPI=YES • Must launch p. FUnit driver with “mpirun” p. FUnit Tutorial 9

MPI & Halo Fill PE 7 PE 6 PE 5 PE 4 PE 3 PE 2 PE 1 PE 0 Domain Decomposition p. FUnit Tutorial 10

Halo’s Close-up PE 2 Northern Halo Interior Southern Halo PE 3 Northern Halo Interior Southern Halo p. FUnit Tutorial Processes exchange data via MPI 11

Halo Fill Possible Tests • Key insight: use synthetic data – Make fill predictable • Interior unchanged? • Southern Halo has expected values? • Northern Halo has expected values? p. FUnit Tutorial 12

Exercise 2 • Change directory into Exercise_2 • Use MPI configuration of p. FUnit % export PFUNIT= /usr/local/other/p. FUnit/Intel-11. 1. 069 -Openmpi-1. 4. 2 • Detailed instructions are located in TDD_Exercises/Exercise_2/README p. FUnit Tutorial 13

Exercise 3

Example: Linear Interpolation Nodes: {xi} Data: {yi} (xi, yi) y x 1 x 2 x x 3 xn p. FUnit Tutorial x 15

Potential Tests • • Bracketing: find i such that Trap out-of-bounds values of x? Interpolation: Computing node weights: p. FUnit Tutorial 16

When Assert Isn’t Enough • Failing p. FUnit calls to Assert* actually call another routine throw(<exception>). E. g. call throw(‘mass is not conserved’) • Throw() accumulates exceptions on a stack. If the stack is not empty when a test completes, p. FUnit considers the test to have failed. • Developers can directly use throw() to have complete control over messages. – This is mostly useful in application code when trapping unsupported conditions. – Test routines can be used to verify the implementation of the trapping logic by using the routine catch() p. FUnit Tutorial 17

Catch() • catch() has two forms: – catch(<message>): returns true if <message> is on the stack of exceptions if (catch(‘mass is not conserved’) then … – catch(): returns true if stack is non-empty if (catch()) then … • By default catch() deletes the exception from the task. – Optional argument overrides the default: if (catch(preserve=. true. )) then p. FUnit Tutorial 18

Example: throw/catch • Application code: subroutine foo(…, x, …) if (x < 0. ) then call throw(‘x must be positive’) return end if • Note that use in application creates dependency on p. FUnit • Test code: … call foo(…, -1. , …) ! Trigger ‘bad’ case if (. not. catch(‘x must be positive’)) then call throw(‘failed to trap negative x’) end if p. FUnit Tutorial 19

Throw/catch (cont’d) • The combination if (. not. catch(<msg>)) call throw(…) is common enough that p. FUnit has a shortcut • assert. Failed. Assert() call assert. Failed. Assert(‘x must be positive’) • You will use this technique for part of the interpolation exercise p. FUnit Tutorial 20

Exercise 3: Interpolation • Change directory into Exercise_3 % cp –r /discover/nobackup/tclune/TDD_Exercises. • Use the serial version of p. FUnit % export PFUNIT=/usr/local/other/p. FUnit/Intel-11. 1. 038 -serial • Detailed instructions are located in TDD_Exercises/Exercise_3/README p. FUnit Tutorial 21