ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/FJPhaserJacobi.java
Revision: 1.10
Committed: Sat Feb 16 21:37:44 2013 UTC (11 years, 2 months ago) by jsr166
Branch: MAIN
Changes since 1.9: +6 -1 lines
Log Message:
add missing public domain notices

File Contents

# User Rev Content
1 jsr166 1.10 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4     * http://creativecommons.org/publicdomain/zero/1.0/
5     */
6 dl 1.1
7     import java.util.concurrent.*;
8    
9 jsr166 1.10 /** Barrier version of Jacobi iteration */
10 dl 1.1 public class FJPhaserJacobi {
11    
12     static int dimGran;
13    
14     static final double EPSILON = 0.0001; // convergence criterion
15    
16     public static void main(String[] args) {
17     int n = 2048;
18     int steps = 1000;
19     try {
20     if (args.length > 0)
21     n = Integer.parseInt(args[0]);
22     if (args.length > 1)
23     steps = Integer.parseInt(args[1]);
24     }
25 jsr166 1.8
26 dl 1.1 catch (Exception e) {
27 dl 1.7 System.out.println("Usage: java ThreadPhaserJacobi <matrix size> <max steps>");
28 dl 1.1 return;
29     }
30 jsr166 1.8
31 dl 1.1 ForkJoinPool fjp = new ForkJoinPool();
32 dl 1.7 // int granularity = (n * n / fjp.getParallelism()) / 2;
33 dl 1.1 int granularity = n * n / fjp.getParallelism();
34 dl 1.7 dimGran = (int)(Math.sqrt(granularity));
35 jsr166 1.8
36 dl 1.1 // allocate enough space for edges
37     int dim = n+2;
38     int ncells = dim * dim;
39     double[][] a = new double[dim][dim];
40     double[][] b = new double[dim][dim];
41     // Initialize interiors to small value
42 jsr166 1.8 double smallVal = 1.0/dim;
43 dl 1.1 for (int i = 1; i < dim-1; ++i) {
44     for (int j = 1; j < dim-1; ++j)
45     a[i][j] = smallVal;
46     }
47     int nreps = 3;
48     for (int rep = 0; rep < nreps; ++rep) {
49     // Fill all edges with 1's.
50     for (int k = 0; k < dim; ++k) {
51     a[k][0] += 1.0;
52     a[k][n+1] += 1.0;
53     a[0][k] += 1.0;
54     a[n+1][k] += 1.0;
55     }
56     Driver driver = new Driver(a, b, 1, n, 1, n, steps);
57     long startTime = System.currentTimeMillis();
58     fjp.invoke(driver);
59 jsr166 1.8
60 dl 1.1 long time = System.currentTimeMillis() - startTime;
61 dl 1.7 double secs = ((double)time) / 1000.0;
62 jsr166 1.8
63 dl 1.1 System.out.println("Compute Time: " + secs);
64     System.out.println(fjp);
65    
66     }
67 jsr166 1.8
68 dl 1.1 }
69    
70     static class Segment extends CyclicAction {
71     double[][] A; // matrix to get old values from
72     double[][] B; // matrix to put new values into
73     // indices of current submatrix
74 jsr166 1.8 final int loRow;
75 dl 1.1 final int hiRow;
76     final int loCol;
77     final int hiCol;
78     volatile double maxDiff; // maximum difference between old and new values
79    
80 jsr166 1.8 Segment(double[][] A, double[][] B,
81 dl 1.1 int loRow, int hiRow,
82 jsr166 1.8 int loCol, int hiCol,
83 dl 1.1 Phaser br) {
84     super(br);
85     this.A = A; this.B = B;
86     this.loRow = loRow; this.hiRow = hiRow;
87     this.loCol = loCol; this.hiCol = hiCol;
88     }
89    
90     public void step() {
91     maxDiff = update(A, B);
92     double[][] tmp = A; A = B; B = tmp;
93     }
94    
95     double update(double[][] a, double[][] b) {
96     double md = 0.0; // local for computing max diff
97    
98     for (int i = loRow; i <= hiRow; ++i) {
99     for (int j = loCol; j <= hiCol; ++j) {
100     double v = 0.25 * (a[i-1][j] + a[i][j-1] +
101     a[i+1][j] + a[i][j+1]);
102     b[i][j] = v;
103    
104     double diff = v - a[i][j];
105     if (diff < 0) diff = -diff;
106     if (diff > md) md = diff;
107     }
108     }
109    
110     return md;
111     }
112 jsr166 1.8
113 dl 1.1 }
114    
115     static class MyPhaser extends Phaser {
116     final int max;
117     MyPhaser(int steps) { this.max = steps - 1; }
118     public boolean onAdvance(int phase, int registeredParties) {
119     return phase >= max || registeredParties <= 0;
120     }
121     }
122    
123 jsr166 1.8 static class Driver extends RecursiveAction {
124 dl 1.1 double[][] A; // matrix to get old values from
125     double[][] B; // matrix to put new values into
126     final int loRow; // indices of current submatrix
127     final int hiRow;
128     final int loCol;
129     final int hiCol;
130     final int steps;
131 jsr166 1.8 Driver(double[][] mat1, double[][] mat2,
132 dl 1.1 int firstRow, int lastRow,
133     int firstCol, int lastCol,
134     int steps) {
135 jsr166 1.8
136 dl 1.1 this.A = mat1; this.B = mat2;
137     this.loRow = firstRow; this.hiRow = lastRow;
138     this.loCol = firstCol; this.hiCol = lastCol;
139     this.steps = steps;
140     }
141    
142     public void compute() {
143     int rows = hiRow - loRow + 1;
144     int cols = hiCol - loCol + 1;
145 dl 1.7 int rblocks = (int)(Math.round((float)rows / dimGran));
146     int cblocks = (int)(Math.round((float)cols / dimGran));
147 jsr166 1.8
148 dl 1.1 int n = rblocks * cblocks;
149 jsr166 1.8
150 dl 1.1 System.out.println("Using " + n + " segments");
151 jsr166 1.8
152 dl 1.1 Segment[] segs = new Segment[n];
153     Phaser barrier = new MyPhaser(steps);
154     int k = 0;
155     for (int i = 0; i < rblocks; ++i) {
156     int lr = loRow + i * dimGran;
157     int hr = lr + dimGran;
158     if (i == rblocks-1) hr = hiRow;
159 jsr166 1.8
160 dl 1.1 for (int j = 0; j < cblocks; ++j) {
161     int lc = loCol + j * dimGran;
162     int hc = lc + dimGran;
163     if (j == cblocks-1) hc = hiCol;
164 jsr166 1.8
165 dl 1.1 segs[k] = new Segment(A, B, lr, hr, lc, hc, barrier);
166     ++k;
167     }
168     }
169     invokeAll(segs);
170     double maxd = 0;
171     for (k = 0; k < n; ++k) {
172     double md = segs[k].maxDiff;
173     if (md > maxd) maxd = md;
174     }
175     System.out.println("Max diff after " + steps + " steps = " + maxd);
176     }
177     }
178     }