Assessment 2 on Message Passing

This assessment tests your knowledge of the history of different message passing systems. The final section test your understanding of how they work and the differences in function and semmantics.

Theory

10 points

For each only give a brief answer.

receivers address, data buffer, size of data, message tags, status of operation or handle for non-blocking operations.

Blocking returns after completing some operation, while non-blocking returns immediately and the user has to check when the operation has completed. The main point here is, the data buffer associated with the operation is unsafe to use on non-blocking calls when they return but safe to use on blocking calls.

Local blocking generally block until the message/data has been handed to some lower level sub-system (i.e. no delivered yet)

Global blocking is where the data has been received before the sending call returns.

As they have not completed the operation yet, the system usually returns a handle, which the user can check. Supported operations include, a wait, test and maybe a cancel.

On Caltech HyperCube there were only a few send and receive operations, on moden systems there are upward of two hundred. Many more would be needed, but these are secified as arguments. There are also status, async handles and other arguments.

History and particular systems

10 points

For each question give only a brief answer.

Sync send and receive operations of only 8 bytes.

Distributed Process Environment on the Hypercube.

Interrupt driven send and recv calls as well as better tagging of message.

CMMD on the Thinking Machines CM5. Allowed swapping of data values without having to make copies of data to prevent the system overwriting it. It was good for stencil operations.

The IBM EUI had good collective operations for a vendor system. MPI does now, but these were modelled on the IBM system.

PVM. Its better suited to Heterogeneous systems and is able to handle failures of processes, hosts and network links.

Shared memory abstraction, which some message passing semmantics.

out = send and in = recv

Operational understanding (i.e. in practice)

10 points

For the following sample of code:

Task 1

send ( task2, data, data-length )

receive ( task2, new-data, new-data-length )

Task 2

send ( task1, data, data-length )

receive ( task1, new-data, new-data-length )

It relies on both sides buffering the sending data. Neither recv can complete until after the sends which can't happen unless their is some form of 'local buffering'.

PVM, as it always buffers sends for you.

Swap one of the send, recv pairs

    (4) To work under MPI without changing the order of any calls? (2)

Use the buffered send MPI_Bsend() and buffer attach semmantic. The buffer must be at least new-data-length + any headers MPI adds!

    (5) If using either CMMD or MPI, how could it be shortened and still work? (1)

Use a send and recv call (sendrec())

    (6) If a code is performing an exchange of boundrary conditions on a 2-D grid (i.e. 4 exchanges), how could you use four non-blocking calls instead of four blocking calls? Why might it be faster? (2)

Use 4 non-blocking sends and 4 non-blocking recvs

If using just one wait, you should make copies of the sending data to prevent the receives from overwriting them.

Fixing a message passing application

20 points

An application that has a master-slave structure is made from two pieces of source code (master.c and slave.c). To prevent errors from coding mistakes between the two codes all constansts are kept in a single header file (cons.h).

The application solves a problem by domain decomposition. The communication pattern used is:

  1. The master sends initial data to the slaves
  2. The slaves do a computation to generate changes in their values (delta values)
  3. The slaves pass partial results to all other slaves (a complete exchange)
  4. The slaves then calculate their own current values
  5. The slaves then pass these new values to the master for logging / plotting etc

At random times the code appears to produce a wrong result which then goes away. It is suspected that the code has a race condition in it (see additional diagram).

The form of the code is:

cons.h

master.c

slave.c

    start

    recv (master, init-data, data)

    for (iterations)

    end

    (1) Write a short paragraph using the additional diagram on why a race occurs. (6)

The slaves echange data with each other, without checking which iteration the senders are on, and without forcing the receives to receive from each other slave just the once per iteration.

    (2) Is it due to the programming style? (2)

Yes, using just the tags in headerfile has restricted the way receive is used.

    (3) Or the choice of semmantics? (2)

Yes, this is the real cause. The receive should be more specific.

    (4) What should be changed to fix it? Give 3 methods including the actual changes to the code. One of the methods should involve a collective operation. (7)

3 Methods

(1) Receive from each task once per iteration

(2) Receive from each slave once per iteration by keeping count of the iterations...

(3) Force all slaves to stay on the same iteration by using a barrier after all the receives (or before all the sends)

Debugging tools like xpvm help.

Keep a CRC of all the messages senders and tags per iteration so you know when the communication patten has changed.

Use Promela (SPIN model)

Marking

All answers should be emailed to me at fagg@cs.utk.edu by Tuesday the 2nd of Feburary, 1999. I will cover the answers to this assessment on the 3rd of Feburary.

The numbers in brackets (2) at the end of the line, denote the number of marks per question, the maximum score is 50.