Skip to content

Instantly share code, notes, and snippets.

@iondune
Last active August 29, 2015 14:02
Show Gist options
  • Select an option

  • Save iondune/28bbd1a9c942a06dd50c to your computer and use it in GitHub Desktop.

Select an option

Save iondune/28bbd1a9c942a06dd50c to your computer and use it in GitHub Desktop.
LinearSim spec

LinearSim Multiprocessing Project

Overview

In this project, you'll do a modest simulation in one dimension that mimics what is normally done in 2 or 3 dimensions in computational fluid dynamics (CFD). And, you'll distribute the work across multiple processes, which will communicate their state to one another via pipes.

A Bit on CFD

CFD programs include such things as weather simulation, heat flow analysis, and aerodynamic simulations. They divide a planar region or a 3-D space into square or cubic "cells", each of which carries some property such as temperature or air pressure. The simulation starts with the cells in some initial state, and then simulates a physical process like heat flow or weather by repeatedly updating each cell's state based on the state of its neighboring cells. If, for instance, a cell's neighbors have higher temperature than it, then this implies some heat flow into the cell from its neighbors, and the update would increase the cell's temperature accordingly.

Such simulations are very time consumptive, since they must perform an update computation for every cell on every time step. If multiple CPUs can cooperate in doing the simulation, dividing the cells between them, then a modern multicore processor can do CFD simulations much more quickly.

Our "CFD" Problem

We'll solve a very simple CFD-type problem, so that we can concentrate on the process configuration, not on the math. Our problem will have a line of cells (no grid or 3-D arrangement). At each end of the line will be a cell with a fixed value - call it a temperature if you'd like a physical analogy. All the interior cells (those not on the ends of the line) will start with a temperature of 0. We'll then loop through some number of time iterations, and on each iteration each interior cell will take the temperature from its two neighboring cells for time n, and average it to produce a new cell temperature for time n+1.

Here's an example sequence with 5 cells:

10 0 0 0 20 time 0
10 5 0 10 20 time 1
10 5 7.5 10 20 time 2
10 8.75 7.5 13.75 20 time 3

The catch is, we'll use a different process for each cell. A main process will set up all the cells, with pipes as needed between pairs of cells. The configuration just shown, for instance, will need 6 pipes between cells. (Each interior cell pair needs two pipes between them, going in each direction; end cells need only one pipe leading from them to their adjacent cell - they don't need data from the adjacent cell.) In addition, one more pipe (with 5 separate writers) will lead back to the parent process, reporting each cell's value at each time interval, and the parent process will print these values out, as the main output of the program.

Cell Program

The first step in the project is to write the program that will process one cell. Call it "Cell.c". This program takes commandline arguments of the following forms, with representing a nonnegative integer and representing a double.

S<N> Simulate from time 0 to time N, inclusive

O<N> Transmit your state to another program, via a pipe on file descriptor N

I<N> Accept state from a neighboring program, via a pipe on file descriptor N

V<X> Assume a fixed value of X; do not average neighboring values.

D<N> Use N as your unique ID number when reporting state on pipes

Don't bother error-checking the arguments; just ignore any that do not fit the formats above. If a cell has multiple inputs or outputs, the I and O arguments will appear multiple times. The arguments may appear in any order. Here is one possible Cell command for the leftmost interior cell, for instance, on the assumption that out pipes to the next cell and to the parent are on fds 3 and 4, and in pipes are on fds 5 and 6 (your fds may vary):

Cell S5 O3 O4 I5 I6 D1

The state reporting, in any direction, on any pipe, is a Report struct, as defined here and in the provided include file Report.h, written and read in binary form on the pipe, in whatever endianness is correct for the architecture (no need to enforce big-endian order).

typedef struct {
   int id; // ID of the Cell reporting
   int step; // Time for which report is being made
   double value; // Value of the cell at time "step"
} Report;

Be sure to close all pipes in the Cell before exiting, and return a status code of 0 if the Cell is one of the middle ones in the sequence (has two input pipes) or of 42 is if the Cell is on the ends.

Reject any commandline argument giving a file descriptor greater than 12. There's no need to use such high-valued descriptors if you're closing files correctly in the driver.

Driver Program

The second major part of the project is the driver program, call it "LinearSim.c". This program accepts a single line of input, without prompt, having two doubles followed by two ints, e.g.

42.0 24.0 10 5

The doubles give the fixed values for the left and right ends of the line of Cells. The first int gives the final time step to simulate (simulate from 0 to that time, inclusive). The second int tells how many Cells to set up.

The driver program forks itself once for each Cell, setting up the needed pipes as it does so, and the exec-ing the child copy to become a Cell, with the right commandline arguments and with all needed pipes opened and ready upon execution of Cell.

The driver also sets up a single pipe, with each Cell writing to it, and the driver as the only reader. After starting all Cells, the driver reads reports from this pipe, and prints them in this format:

Result from <id>, step <timestep>: <value, to 3 decimal places>

The order of reports from Cells may vary on different runs, depending on which Cell gets processor time. You'll be required to match the model outputs after your output has been sorted. You don't have to do the sorting; Bender will do this as part of his testing, and you should do it to verify your code's correctness, by piping the driver's output through the Unix sort utility.

Once all reports have arrived, which you must determine by testing for EOF on the reporting pipe, not just counting reports, the driver waits for each child process, and reports each one's exit status. It reports children by their id's from the commandline arguments, not their their process numbers, since the latter will be unpredictable per-run.

Special Rules and Hints

No forking around

The live fork Unix system call is quite dangerous. In extreme cases of uncontrolled fork-loops, a system restart may be needed to fix the problem. For this reason:

YOU MAY NOT EXECUTE YOUR LINEARSIM EXCEPT UNDER SafeRun CONTROL!

Never execute your LinearSim directly; doing so might bring down an entire Unix system, and remember, your login is on the processes that did it. If you have a commandline anywhere that begins with your LinearSim executable (or even mine!) that's a grave error. All lines should start with "SafeRun".

The -p parameter for SafeRun must be set carefully. To get the right figure, do the following:

1. Run ps -u to determine all processes running under your name on the current machine. On dept Unix machines, this should be just 3 or 4. On a local machine running X windows, it may amount to several dozen. Piping the output of the ps command through "wc" (look it up) may make it easier to count them.

2. If any of these processes are Cell or LinearSim, kill them. Do the signals lecture if you don't know how to do this.

Do _not _proceed until you've killed all lingering Cell or LinearSim processes. Half the reason for SafeRun is to prevent you from clogging the systems with zombies. This will bring down the system for ALL students in the dept. And, of course, if you have lingering zombies they're due to a bug in your code you need to fix anyway.

3. With zombies cleared, add the number of processes you have now, plus 5 for SafeRun overhead and the one LinearSim you'll run, plus the number of Cell processes. This number is the -p argument for SafeRun.

Interoperate with my executables

The kit for this project includes Unix executables for my LinearSim and Cell. Your LinearSim and Cell must work properly with these. (Running my LinearSim, with your Cell executable, must work, and running your LinearSim with my Cell executable must work.)

Watch out for SIGPIPE

Look up SIGPIPE, and be aware of this issue wrt writing to a closed pipe.

Kit and Turnin

The directory ~grade_cstaley/357/LinearSim has the "kit" for the project, including the sample executables. This is also where you submit your project. Submit these files to ~grade_cstaley/357/LinearSim/turnin:

  • Cell.c
  • LinearSim.c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment