Software for the course will be placed in a public directory, which you may access from your home directory as ~/../public. The software for this assignment lives in various subdirectories of ~/../public/examples.
Also see two other web pages with links to software available in the course as well as references and other valuable on-line sources of information.. These are found at:
This Assignment consists of 3 parts. In the first two parts you'll compile and run code supplied to you, and in part 3 you'll make modifications to some code.
This part will help acquaint you with process of running an MPI program. Copy the directory ~/../public/examples/Basic to your home area. Compile and run the two programs in the subdirectory called Basic. Be sure to use the Makefile that we've supplied so you'll get the correct compiler and loader flags. The Makefile includes an "arch" file that defines appropriate command line flags for the compiler. You currently have arch.valkyrie which provides the appropriate settings needed for Valkyrie.
Your first program is a parallel "hello world" program. This program prints "Hello World'' from each processor, along with the process ID. It also reports the total number of processors in the run. Run the program on 2 processors.Here is some sample output:
# processes: 2 Hello world from node 0 Hello world from node 1
Do the node ID's come in any particular order? Why is this?
In the second program 'message' each processor sends two integers to node 0, which prints out the values. A common convention is to call node 0 the manager or boss. Run program 2 several times on 4 processors. Do the node ID's come in any particular order? Why is this the case? Modify the program so that the nodes report to the manager in increasing order of node rank.
The purpose of this part is to show you how to set up the nodes to communicate as if they were connected in a ring, and to measure some aspects of communication performance.
The program we've supplied you, ring.C, is found in ~/../public/examples/Ring. This program treats the processors as if connected in a ring. Node 0 sends a message to successor node 1, and so on until node P-1, which then sends the message back to node 0, which is P-1's successor in mod P arithmetic. The cycle then repeats. Messages of various sizes are passed around the ring, starting with 2 byte long messages and progressing in powers of two up to a user-specified limit.
Ring extracts up to 2 arguments from the command line, which must appear in the order specified
By default NNN=1024,TTT=5.
Under default settings Ring passes messages of 2, 4, 8, ..., 1K,
..., 256K five times around the processor ring. Ring measures the total time
taken to pass messages around the ring, and reports the statistics based on
these times as a function of increasing message length. (See below for how
Ring collects timing information.)
Run Ring on 4 processors, and experiment with messages into the megabyte range. Note any differences in message passing times on differing numbers of processors, and attempt to explain them. Run several times and report the best timings. Did you notice any variations in the timings?
To get accurate timings, you may need to increase the repetitions parameter for short messages below about 1KB in length. Use the message size parameter to restrict the maximum message length to 1KB, and successively double the repetitions parameter until the timings stabilize. For longer lengths (1KB to 16KB) you may be able to use a smaller repetition factor.
Prior to collecting timings, Ring "warms up" the machine by passing messages around the ring once before it turns on the timer. This helps to eliminate transient program behavior from your timing runs. Ring divides the timings by the number of repetitions around the ring, and reports three quantities: message length, bandwidth( x106 bytes/sec), and message time in microseconds (ms). Using this information
You may have noticed that some of the output in the Ring program is
garbled. In particular, one or more node names appear later in the output
than is consistent with their appearance in the code. What do you think is
causing this behavior?
Ring calls MPI's timer function MPI_Wtime() to measure message passing times (as wall clock times), Your timings will reflect interference from other jobs. On a dedicated run, such interference will be minimal; running times will be shorter and reproducible. We aren't yet able to make dedicated runs, however. So run the program several times until you see consistent results. If you are still having difficulties getting consistent results, try running on other nodes. You should use no more than 4 nodes for this experiment.
To get an absolute time take the difference in times sampled by two successive calls to MPI_Wtime:
double t0 = MPI_Wtime();
// some code....
double t1 = MPI_Wtime();
double time = (t1-t0);
The man-page for MPI_Wtime() is found on line. Note,
however, that all times are reported in seconds, and there is no need to
divide by MPI_Wtick() to convert to seconds. (You can
obtain the resolution of MPI_Wtime using
MPI_Wtick())
We are providing you with a working serial program that solves a mathematical equation known as the advection equation. The provided code solves the advection equation on a two-dimensional mesh and sends the output to the gnuplot plotting program. You'll modify this code to run the equation solver and the plotter within separate MPI processes. Message passing will enable the processes to communicate in a producer-consumer relationship.
The code we are providing is found in the public directory mentioned bove, which you may access from your home directory as valkyrie:~/../public/examples/padv. As with the other codes, the Makefile includes an "arch" file that defines appropriate command line flags for the compiler.
The advection equation is a first order differential equation which describes how a spatial feature, say a hump, moves in space as a function of time. In our example, this feature is a gaussian (hump) which translates (moves) across space as time progresses.
The solver discretizes the equation by representing continuous quantities at discrete points in space and time. A two dimensional mesh will be used to represent space, and the mesh will be updated over a series of timesteps in order to take account of time.
A first order differential equation can usually be solved for a set of timesteps using a technique that uses current mesh values to compute new ones. The values of the mesh points at t=0 describe the initial state of the system. One round of computing updates for each mesh point results in a new mesh representing the state at t=1. Successive rounds of updates result in mesh values that change in time. The special thing about the advection equation is that if these mesh values are plotted at each timestep, any spatial features present at the initial state, are seen to move across the mesh.
The code provided to you is a serial implementation of a two dimensional advection simulation. The simulation begins with a gaussian (hump) evaluated on the initial mesh, which extends from 0 to 1 in real world co-ordinates. Updates are performed at each iteration step. At each iteration, a 3D plot of the mesh is displayed (along with contours) using the 'splot' function of gnuplot .
Compile the serial program provided to you as
gcc -lm padv.c -o
padv
The program can then be run from the command prompt as follows:
padv [-nx <x meshpoints>] [-ny <y meshpoints>] [-vx <x speed>] [-vy <y speed>] [-x0 <center x>] [-y0 <center y>]
[-h <height>] [-nt <timesteps>]
With the arguments interpreted as shown:
-nx <integer> Number of mesh points in the x dimension
-ny <integer> Number of mesh points in the y dimension
-vx <float> Advection speed in x direction
-vy <float> Advection speed in y direction
-x0 <float> X co-ordinate of the center of the gaussian feature
-y0 <float> Y co-ordinate of the center of the gaussian feature
-h <float> Height of the gaussian
-nt <integar> Number of iteration timesteps
The program will run with default input parameters, if no command line arguments are specified
padv
And, the command line
padv -x0 0.1 -y0 0.1 -nt 200 -vx 3 -vy 3
will initialize the mesh with a gaussian centered at [0.1,0.1] and will run the simulation for 200 iteration timesteps. The gaussian can be seen to move diagonally across the mesh in the direction of the vector joining [0,0] and [3,3].
NOTE: If a gnuplot window does not appear on your screen, then your SSH
display settings are not set correctly. If you are using a Linux based
machine and are connecting to valkyrie using SSH, your display should
directly work. If you are using a Windows based machine, and are using a
'secure shell client' or 'exceed' to log into valkyrie, you must ensure that
'X11 tunneling' is set. [If you have problems with this, send email to
, with cse160 in the subject line].
NOTE: This implementation of the advection solution is computationally simple, but is not always stable. Choosing input parameters very different from the default input values can result in an unstable simulation. Restrict -vx and -vy to be any value from 0.0 to 4.0, -x0 and -y0 to between -0.5 to 1.5.
Implementing Functional Parallelism
You are required to modify the given serial advection code to run as two MPI processes. One process (rank = 0) should handle the display (via gnuplot), and the other process (rank=1) should perform the computational updates. Data should be transferred between the processes via messages, and a gnuplot display mesh plot must appear for each iteration.
NOTE: If you have previously set up a ~/.ssh/config file, to ensure correct X11 forwarding (for the plots to appear on your terminal), gnuplot must be instantiated on the correct compute node. This can be done in two steps. First, make sure that the compute node listed as the first entry in the machine-file matches the compute node listed on the first line in the config file. This ensures that this compute node is the one which will be assigned rank=0. Second, in your code, let the process with rank = 0 be the one that runs gnuplot and does the plotting.
Document your work in a well-written report which discusses your findings carefully. Your report should present a clear evaluation of the design of your code, including bottlenecks of the implementation, and describe any special coding or tuned parameters. Provide code listings for files you wrote, or that you modified based on versions we gave to you (there is no need to provide listings of code we provided, that you did not modify).
Your report should cite any written works or software as appropriate in the text of the report. Citations should include any software you used that was written by someone else, or that was written by you for purposes other than this class.
Provide hard copy in class. Also transmit the report electronically along with your code. We will run the code on Valkyrie. Transmit a single filePlease tar your writeup, plots, and source code and email them to
(cs160x1(at)valkyrie) with cse160 in the subject line
The directory should contain two subdirectories (If you want to provide us additional information about the turnin, you may include a README file):
src: All source code including your makefile
report: Your report including any separate plot files or output
If you like, you may put an html file called index.html at the top level. From there you can then link to the README file to the src and report directories. .
As always, refer to the document titled Getting Started with Valkyrie for detailed instructions on how to set up your environment, and how to use MPI.
MPI documentation is found at at http://www-cse.ucsd.edu/users/baden/Doc/mpi.html.. You can obtain man pages for the MPI calls used in the example programs described here:
Copyright © 2004 Scott B. Baden. Last modified: 04/08/04 01:45 PM