Stencil Pattern A stencil describes a 2- or 3- dimensional layout of processes, with each process able to communicate with its neighbors. Appears in simulating many real-life situations where data at one point affects data neighboring points, often with changing or converging data requiring a synchronized computation loop. ITCS 4/5145 Parallel computing, UNC-Charlotte, B. Wilkinson, Sept 27, 2012 slides6b.ppt 6b.1
Examples Solving partial differential equations using discretized methods, which may be for: Modeling engineering structures Weather forecasting, see intro to course slides1a-1 Particle dynamics simulations Modeling chemical and biological structures 6b.2
Stencil pattern Synchronous computation - Performs a number of iterations to converge on solution On each iteration, each node communicates with neighbors to get stored computed values Two-way connection Compute node Source/sink 6b.3
Locally Synchronous Computation Heat Distribution Problem (Static Heat Equation) Objective is to find the static distribution of heat in a space, here a 2-dimensional space but could be 3-dimensional. An area has known temperatures along each of its borders. Find the temperature distribution within. 6b.4
Divide area into fine mesh of points, hi,j. Temperature at an inside point taken to be average of temperatures of four neighboring points. Convenient to describe edges by points. Temperature of each point by iterating the equation: (0 < i < n, 0 < j < n) for a fixed number of iterations or until the difference between iterations less than some very small amount. 6b.5
Heat Distribution Problem For convenience, edges also represented by points, but having fixed values, and used by computing internal values. 6b.6
Natural ordering 6.7
Natural Ordering: Each point will then use equation: which leads to a linear equation containing unknowns xi-m, xi-1, xi+1, and xi+m: Note: solving a (sparse) system Also solving Laplace’s equation, see later. 6b.8
Sequential Code Using a fixed number of iterations for (iteration = 0; iteration < limit; iteration++) { for (i = 1; i < n; i++) for (j = 1; j < n; j++) g[i][j] = 0.25*(h[i-1][j]+h[i+1][j]+h[i][j-1]+h[i][j+1]); for (i = 1; i < n; i++) /* update points */ h[i][j] = g[i][j]; } using original numbering system (n x n array). 6b.9
Partitioning Normally allocate more than one point to each processor, because many more points than processors. Points could be partitioned into square blocks or strips: Communication on 4 edges Communication on 2 edges In general, strip partition best for large communication startup time, and block partition best for small startup time – see textbook for analysis 6b.10
Ghost Points Additional row of points at each edge that hold values from adjacent edge. Each array of points increased to accommodate ghost rows. 6b.11
Application Example A room has four walls and a fireplace. Temperature of wall is 20°C, and temperature of fireplace is 100°C. Write a parallel program using Jacobi iteration to compute the temperature inside the room and plot (preferably in color) temperature contours at 10°C intervals. 6b.12
Sample student output 6b.13
Other class of synchronous problems suitable for the Stencil pattern: Cellular Automata The problem space is divided into cells. Each cell can be in one of a finite number of states. Cells affected by their neighbors according to certain rules, and all cells are affected simultaneously in a “generation.” Rules re-applied in subsequent generations so that cells evolve, or change state, from generation to generation. Most famous cellular automata is the “Game of Life” devised by John Horton Conway, a Cambridge mathematician. 6b.14
The Game of Life Board game - theoretically infinite two-dimensional array of cells. Each cell can hold one “organism” and has eight neighboring cells, including those diagonally adjacent. Initially, some cells occupied. The following rules apply: 1. Every organism with two or three neighboring organisms survives for the next generation. 2. Every organism with four or more neighbors dies from overpopulation. 3. Every organism with one neighbor or none dies from isolation. 4. Each empty cell adjacent to exactly three occupied neighbors will give birth to an organism. These rules were derived by Conway “after a long period of experimentation.” 6b.15
Simple Fun Examples of Cellular Automata “Sharks and Fishes” An ocean could be modeled as a three-dimensional array of cells. Each cell can hold one fish or one shark (but not both). Fish and sharks follow “rules.” 6b.16
Fish Might move around according to these rules: If there is one empty adjacent cell, the fish moves to this cell. 2. If there is more than one empty adjacent cell, the fish moves to one cell chosen at random. 3. If there are no empty adjacent cells, the fish stays where it is. 4. If the fish moves and has reached its breeding age, it gives birth to a baby fish, which is left in the vacating cell. 5. Fish die after x generations. 6b.17
Sharks Might be governed by the following rules: 1. If one adjacent cell is occupied by a fish, the shark moves to this cell and eats the fish. 2. If more than one adjacent cell is occupied by a fish, the shark chooses one fish at random, moves to the cell occupied by the fish, and eats the fish. 3. If no fish are in adjacent cells, the shark chooses an unoccupied adjacent cell to move to in a similar manner as fish move. 4. If the shark moves and has reached its breeding age, it gives birth to a baby shark, which is left in the vacating cell. 5. If a shark has not eaten for y generations, it dies. 6b.18
Sample Student Output 6b.19 6.68
Similar examples: “foxes and rabbits” - Behavior of rabbits to move around happily whereas behavior of foxes is to eat any rabbits they come across. 6b.20
Serious Applications for Cellular Automata Examples • fluid/gas dynamics • the movement of fluids and gases around objects • diffusion of gases • biological growth • airflow across an airplane wing • erosion/movement of sand at a beach or riverbank. 6b.21
Partially Synchronous Computations -- Computations in which individual processes operate without needing to synchronize with other processes on every iteration. Important idea because synchronizing processes very significantly slows the computation and a major cause for reduced performance of parallel programs. 6b.22
Heat Distribution Problem Re-visited Making Partially Synchronous Uses previous iteration results h[][] for next iteration, g[][] forall (i = 1; i < n; i++) forall (j = 1; j < n; j++) { g[i][j]=0.25*(h[i-1][j]+h[i+1][j]+h[i][j-1]+h[i][j+1]); } Synchronization point at end of each iteration The waiting can be reduced by not forcing synchronization at each iteration by allowing processes to move to next iteration before all data points computed – then uses data from not only last iteration but possibly from earlier iterations. Method then becomes an “asynchronous iterative method.” 6b.23
Asynchronous Iterative Method Convergence Conditions Mathematical conditions for convergence may be more strict. Each process may not be allowed to use any previous iteration values if the method is to converge. Chaotic Relaxation A form of asynchronous iterative method introduced by Chazan and Miranker (1969) in which conditions stated as: “there must be a fixed positive integer s such that, in carrying out the evaluation of the ith iterate, a process cannot make use of any value of the components of the jth iterate if j < i - s” (Baudet, 1978). 6b.24
The following is derived from: Seeds Stencil Pattern The following is derived from: “Seeds Framework Stencil Template Tutorial” Jeremy Villalobos http://coit-grid01.uncc.edu/seeds/tutorials.php Interface: public abstract class Stencil extends BasicLayerInterface{ public abstract boolean OneIterationCompute( StencilData data); public abstract StencilData DiffuseData(int segment); public abstract void GatherData(int segment, StencilData dat); public abstract int getCellCount(); } 6b.25
package edu.uncc.grid.seeds.example.stencil; import edu.uncc.grid.pgaf.datamodules.StencilData; import edu.uncc.grid.pgaf.interfaces.basic.Stencil; public class HeatDistribution extends Stencil { private static final long serialVersionUID = 1L; double[][] MainMatrix; int loop; public HeatDistribution(){ loop = 0; } public void loadMatrix(){ MainMatrix = MatrixReader.getMainMatrix(); 6b.26
DiffuseData() method @Override public StencilData DiffuseData(int segment) { double[][]m=MatrixReader.getSubMatrix(MainMatrix,segment, this.getCellCount()); HeatDistributionData heat = new HeatDistributionData(m); return heat; } 6b.27
GatherData() method @Override public void GatherData(int segment, StencilData dat) { HeatDistributionData heat = (HeatDistributionData) dat; MatrixReader.setSubMatrix(this.MainMatrix, heat.matrix, segment, this.getCellCount()); } 6b.28
OneIterationCompute() method @Override public boolean OneIterationCompute(StencilData data) { HeatDistributionData heat = (HeatDistributionData) data; double[][] m = new double[heat.Width][heat.Height]; for( int r = 1; r < heat.Height -1;r++){ // except sides, top and bottom for( int c = 1; c < heat.Width -1;c++){ m[c][r] = 0.25 * (heat.matrix[c+1][r]+heat.matrix[c-1][r]+heat.matrix[c][r+1]+heat.matrix[c][r-1]); } … // code to sides, top and bottom, see tutorial heat.matrix = m; ++loop; return loop >= 10000; 6b.29
getCellCount() method @Override public int getCellCount() { return HeatDistributionData.CellCount; } public void initializeModule(String[] args) {} 6b.30
Bootstrap class package edu.uncc.grid.seeds.example.stencil; import java.io.IOException; import net.jxta.pipe.PipeID; import edu.uncc.grid.pgaf.Anchor; import edu.uncc.grid.pgaf.Operand; import edu.uncc.grid.pgaf.Seeds; import edu.uncc.grid.pgaf.p2p.Types.DataFlowRoll; public class RunHeatDistribution { public static void main(String[] args) { try { Seeds.start("/path/to/seed/folder", false); HeatDistribution hd = new HeatDistribution(); hd.loadMatrix(); Operand f = new Operand((String) null,new Anchor("Kronos", DataFlowRoll.SINK_SOURCE), hd ); PipeID p_id = Seeds.startPattern( f ); Seeds.waitOnPattern(p_id); hd.saveImage(); Seeds.stop(); } catch (SecurityException e) { e.printStackTrace(); } catch (IOException e) { } catch (Exception e) { } Bootstrap class 6b.31
package edu.uncc.grid.seeds.example.stencil; import java.io.Serializable; import edu.uncc.grid.pgaf.datamodules.StencilData; public class HeatDistributionData implements StencilData { private static final long serialVersionUID = 1L; public double [][] matrix; public int Width; public int Height; double[][] Sides; public static final int CellCount = 4; public HeatDistributionData(double [][]m){ Width = m.length; Height = m[0].length; matrix = m; Sides = new double[4][]; } @Override public Serializable getBottom() { return SyncData.getBorder(matrix, Width, Height, SyncData.BOTTOM); public Serializable getLeft() { return SyncData.getBorder( matrix, Width, Height, SyncData.LEFT); public Serializable getRight() { return SyncData.getBorder(matrix, Width, Height, SyncData.RIGHT); Data interface For the Stencil pattern, StencilData must be implemented into the Data object: 6b.32
Data interface continued @Override public Serializable getTop() { return SyncData.getBorder(matrix, Width, Height, SyncData.TOP); } public void setBottom(Serializable data) { this.Sides[SyncData.BOTTOM] = (double[]) data; public void setLeft(Serializable data) { this.Sides[SyncData.LEFT] = (double[])data; public void setRight(Serializable data) { this.Sides[SyncData.RIGHT] = (double[])data; public void setTop(Serializable data) { this.Sides[SyncData.TOP] = (double[])data; Data interface continued 6b.33
Questions 6b.34