220 likes | 297 Views
Computer Science 320. Barrier Actions. 1-D Continuous Cellular Automata. 1-D array of cells, each having a value between 0.0 and 1.0 Each cell has a neighborhood consisting of itself and the cells to its left and right The array wraps arround to accommodate neighbors of first and last cells.
E N D
Computer Science 320 Barrier Actions
1-D Continuous Cellular Automata • 1-D array of cells, each having a value between 0.0 and 1.0 • Each cell has a neighborhood consisting of itself and the cells to its left and right • The array wraps arround to accommodate neighbors of first and last cells
Processing a 1-D CCA Initially, all cells are 0, except for XC/2 = 1 For each cell, calculate a new value by multiplying the average of the neighbors by a constant A, adding another constant B, and keeping the fractional part
Processing a 1-D CCA s X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 0 0 0 0 0 0 1 0 0 0 0 1 11/12 11/12 11/12 11/12 1/4 1/4 1/4 11/12 11/12 11/12 2 5/6 5/6 5/6 11/18 7/18 1/6 7/18 11/18 5/6 5/6 3 3/4 3/4 73/108 19/36 11/36 25/108 11/36 19/36 73/108 3/4 4 2/3 52/81 46/81 34/81 22/81 16/81 22/81 34/81 46/81 52/81 5 551/972 527/972 149/324 109/324 23/108 53/324 23/108 109/324 149/324 After 5 iterations on10 cells, with A = 1 and B = 11/12 Note the rational number results
Imaging the 1-D CCA After 5 iterations on10 cells, with A = 1 and B = 11/12
Imaging the 1-D CCA After 200 iterations on 400 cells, with A = 1 and B = 11/12
Resources for Rational Arithmetic • edu.rit.smp.ca.BigRational • assign • add • mul • fracPart • normalize • floatValue
Program Design: Data • Could use a byte matrix for the pixel data and a BigRational matrix for the cells • But O(SC) complexity: limits both the number of cells and the number of steps when scaling up
Program Design: Data • Represent just the current row and the previous row (2 arrays of C cells) • Swap the array references after each step to avoid copying cells • Also need just the row of current pixel values, not the whole matrix
CCASeq import edu.rit.image.GrayImageRow; import edu.rit.image.PJGGrayImage; import edu.rit.image.PJGImage; import edu.rit.util.Range; // Constants. staticfinal BigRational ZERO = new BigRational ("0"); staticfinal BigRational ONE = new BigRational ("1"); staticfinal BigRational ONE_THIRD = new BigRational ("1/3"); // Command line arguments. staticint C; staticint S; staticBigRational A; staticBigRational B; staticFile imagefile;
CCASeq // Old and new cell arrays. static BigRational[] currentCell; static BigRational[] nextCell; // Grayscale image matrix. static byte[][] pixelmatrix; static PJGGrayImage image; static PJGImage.Writer writer; // One row of the grayscale image matrix. static byte[] pixelrow; static GrayImageRowimagerow;
CCASeq // Parse command line arguments. if (args.length != 5) usage(); C = Integer.parseInt (args[0]); S = Integer.parseInt (args[1]); A = new BigRational (args[2]).mul(ONE_THIRD); B = new BigRational (args[3]); imagefile= new File (args[4]); // Allocate storage for old and new cell arrays. Initialize all cells to // 0, except center cell to 1. currentCell= new BigRational[C]; nextCell= new BigRational[C]; for (int i = 0; i < C; ++ i){ currentCell[i] = new BigRational(); nextCell[i] = new BigRational(); } currentCell[C/2].assign(ONE);
CCASeq // Set up pixel matrix, image, and image writer. pixelmatrix= new byte [S+1] []; image = new PJGGrayImage (S+1, C, pixelmatrix); writer = image.prepareToWrite(new BufferedOutputStream (new FileOutputStream(imagefile))); // Allocate storage for one pixel matrix row. pixelrow= new byte[C]; imagerow= new GrayImageRow(pixelrow); imagerow.setInterpretation(PJGGrayImage.ZERO_IS_WHITE);
CCASeq // Do S time steps. for (int s = 0; s < S; ++ s){ // Calculatenextstate of eachcell. for (int i = 0; i < C; ++ i){ nextCell[i] .assign (currentCell[i]) .add (currentCell[(i-1+C)%C]) .add (currentCell[(i+1)%C]) .mul (A) .add (B) .normalize() .fracPart(); } // Writecurrent CA stateto image file. writeCurrentCell(s); // Advance one time step -- swap old and new cell arrays. BigRational[] tmp = currentCell; currentCell= nextCell; nextCell= tmp; }
CCASeq private static void writeCurrentCell(int r) throws IOException{ // Set image row's gray values based on current cell states. for (int i = 0; i < C; ++ i) imagerow.setPixel(i, currentCell[i].floatValue()); // Set row r of the pixel matrix. pixelmatrix[r] = pixelrow; // Write row-r slice of the image to the image file. writer.writeRowSlice(new Range(r, r)); }
Parallelize! • Calculation of each row depends on previous row, so can’t have a parallel outer loop • But calcs within a row are independent, so can have a parallel inner loop • But must synchronize array reference swaps and writing pixel data to file
Barrier Action • All threads in a parallel for loop wait at a barrier until all are finished • A barrier action allows one thread to do some cleanup while the others continue to wait at the barrier
Barrier Action new ParallelTeam().execute(new ParallelRegion(){ . . . execute(0, 99, new IntegerForLoop(){ public void run(){ for (in I = first; I <= last; ++i) // Loop body } }, new BarrierAction(){ public void run(){ // Code to execute in a single thread } }); . . . ));
CCASmp // Do S time steps. Sequential outer loop. for (int s = 0; s < S; ++ s){ final int step = s; // Calculatenextstate of eachcell. Parallel inner loop. execute (0, C-1, new IntegerForLoop(){ public IntegerSchedule schedule(){ return IntegerSchedule.guided(); } public void run (int first, int last){ for (inti = first; i <= last; ++ i){ nextCell[i] .assign (currentCell[i]) .add (currentCell[(i-1+C)%C]) .add (currentCell[(i+1)%C]) .mul (A) .add (B) .normalize() .fracPart(); } } },
CCASmp // Synchronize threads before next outer loop iteration. new BarrierAction(){ public void run() throws Exception{ // Write current CA state to image file. writeCurrentCell(step); // Advance one time step -- swap old and new cell // arrays. BigRational[] tmp = currentCell; currentCell= nextCell; nextCell= tmp; } });