ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/FJJacobi.java
Revision: 1.3
Committed: Mon Nov 2 23:42:46 2009 UTC (14 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.2: +3 -3 lines
Log Message:
whitespace

File Contents

# User Rev Content
1 dl 1.1 /*
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/licenses/publicdomain
5     */
6    
7     // Jacobi iteration on a mesh. Based loosely on a Filaments demo
8    
9     import java.util.concurrent.*;
10     //import jsr166y.*;
11    
12     public class FJJacobi {
13    
14     static final int DEFAULT_GRANULARITY = 4096; // 1024;
15    
16 jsr166 1.2 /**
17     * The maximum number of matrix cells
18 dl 1.1 * at which to stop recursing down and instead directly update.
19     **/
20    
21     static final double EPSILON = 0.0001; // convergence criterion
22    
23     public static void main(String[] args) throws Exception {
24     int n = 2048;
25     int steps = 1000;
26     int granularity = DEFAULT_GRANULARITY;
27 jsr166 1.2
28 dl 1.1 try {
29     if (args.length > 0)
30     n = Integer.parseInt(args[0]);
31     if (args.length > 1)
32     steps = Integer.parseInt(args[1]);
33 jsr166 1.2 if (args.length > 2)
34 dl 1.1 granularity = Integer.parseInt(args[2]);
35     }
36 jsr166 1.2
37 dl 1.1 catch (Exception e) {
38     System.out.println("Usage: java FJJacobi <matrix size> <max steps> [<leafcells>]");
39     return;
40     }
41    
42     ForkJoinPool fjp = new ForkJoinPool();
43    
44     // allocate enough space for edges
45     int dim = n+2;
46     int ncells = dim * dim;
47     double[][] a = new double[dim][dim];
48     double[][] b = new double[dim][dim];
49     // Initialize interiors to small value
50 jsr166 1.2 double smallVal = 1.0/dim;
51 dl 1.1 for (int i = 1; i < dim-1; ++i) {
52     for (int j = 1; j < dim-1; ++j)
53     a[i][j] = smallVal;
54     }
55 jsr166 1.2
56 dl 1.1 int nreps = 3;
57     for (int rep = 0; rep < nreps; ++rep) {
58     // Fill all edges with 1's.
59     for (int k = 0; k < dim; ++k) {
60     a[k][0] += 1.0;
61     a[k][n+1] += 1.0;
62     a[0][k] += 1.0;
63     a[n+1][k] += 1.0;
64     }
65     Driver driver = new Driver(a, b, 1, n, 1, n, steps, granularity);
66 jsr166 1.2
67 dl 1.1 long startTime = System.currentTimeMillis();
68     fjp.invoke(driver);
69 jsr166 1.2
70 dl 1.1 long time = System.currentTimeMillis() - startTime;
71     double secs = ((double)time) / 1000.0;
72 jsr166 1.2
73 dl 1.1 System.out.println("Compute Time: " + secs);
74     System.out.println("Workers: " + fjp.getPoolSize());
75     System.out.println(fjp);
76     }
77     }
78    
79    
80     abstract static class MatrixTree extends RecursiveAction {
81     // maximum difference between old and new values
82 jsr166 1.2 double maxDiff;
83     public final double directCompute() {
84     compute();
85 dl 1.1 return maxDiff;
86     }
87     public final double joinAndReinitialize(double md) {
88     if (tryUnfork())
89 jsr166 1.2 compute();
90 dl 1.1 else {
91     // quietlyJoin();
92     quietlyHelpJoin();
93     reinitialize();
94     }
95     double m = maxDiff;
96 jsr166 1.3 return (md > m) ? md : m;
97 dl 1.1 }
98    
99     }
100    
101    
102     static final class LeafNode extends MatrixTree {
103     final double[][] A; // matrix to get old values from
104     final double[][] B; // matrix to put new values into
105    
106     // indices of current submatrix
107     final int loRow; final int hiRow;
108     final int loCol; final int hiCol;
109    
110     int steps = 0; // track even/odd steps
111    
112 jsr166 1.2 LeafNode(double[][] A, double[][] B,
113 dl 1.1 int loRow, int hiRow,
114     int loCol, int hiCol) {
115     this.A = A; this.B = B;
116     this.loRow = loRow; this.hiRow = hiRow;
117     this.loCol = loCol; this.hiCol = hiCol;
118     }
119    
120 jsr166 1.2 public void compute() {
121 dl 1.1 boolean AtoB = (steps++ & 1) == 0;
122 jsr166 1.3 double[][] a = AtoB ? A : B;
123     double[][] b = AtoB ? B : A;
124 dl 1.1
125     double md = 0.0; // local for computing max diff
126    
127     for (int i = loRow; i <= hiRow; ++i) {
128     for (int j = loCol; j <= hiCol; ++j) {
129     double v = 0.25 * (a[i-1][j] + a[i][j-1] +
130     a[i+1][j] + a[i][j+1]);
131     b[i][j] = v;
132    
133     double diff = v - a[i][j];
134     if (diff < 0) diff = -diff;
135     if (diff > md) md = diff;
136     }
137     }
138    
139     maxDiff = md;
140     }
141     }
142    
143     static final class FourNode extends MatrixTree {
144     final MatrixTree q1;
145     final MatrixTree q2;
146     final MatrixTree q3;
147     final MatrixTree q4;
148 jsr166 1.2 FourNode(MatrixTree q1, MatrixTree q2,
149 dl 1.1 MatrixTree q3, MatrixTree q4) {
150     this.q1 = q1; this.q2 = q2; this.q3 = q3; this.q4 = q4;
151     }
152    
153 jsr166 1.2 public void compute() {
154 dl 1.1 q4.fork();
155     q3.fork();
156     q2.fork();
157     double md = q1.directCompute();
158     md = q2.joinAndReinitialize(md);
159     md = q3.joinAndReinitialize(md);
160     md = q4.joinAndReinitialize(md);
161     maxDiff = md;
162     }
163     }
164 jsr166 1.2
165 dl 1.1
166     static final class TwoNode extends MatrixTree {
167     final MatrixTree q1;
168     final MatrixTree q2;
169    
170     TwoNode(MatrixTree q1, MatrixTree q2) {
171     this.q1 = q1; this.q2 = q2;
172     }
173    
174 jsr166 1.2 public void compute() {
175 dl 1.1 q2.fork();
176     maxDiff = q2.joinAndReinitialize(q1.directCompute());
177     }
178 jsr166 1.2
179 dl 1.1 }
180 jsr166 1.2
181 dl 1.1
182     static final class Driver extends RecursiveAction {
183     MatrixTree mat;
184     double[][] A; double[][] B;
185     int firstRow; int lastRow;
186     int firstCol; int lastCol;
187     final int steps;
188     final int leafs;
189     int nleaf;
190    
191 jsr166 1.2 Driver(double[][] A, double[][] B,
192 dl 1.1 int firstRow, int lastRow,
193     int firstCol, int lastCol,
194     int steps, int leafs) {
195     this.A = A;
196     this.B = B;
197     this.firstRow = firstRow;
198     this.firstCol = firstCol;
199     this.lastRow = lastRow;
200     this.lastCol = lastCol;
201     this.steps = steps;
202     this.leafs = leafs;
203     mat = build(A, B, firstRow, lastRow, firstCol, lastCol, leafs);
204     System.out.println("Using " + nleaf + " segments");
205    
206     }
207    
208     MatrixTree build(double[][] a, double[][] b,
209     int lr, int hr, int lc, int hc, int leafs) {
210     int rows = (hr - lr + 1);
211     int cols = (hc - lc + 1);
212    
213     int mr = (lr + hr) >>> 1; // midpoints
214     int mc = (lc + hc) >>> 1;
215 jsr166 1.2
216 dl 1.1 int hrows = (mr - lr + 1);
217     int hcols = (mc - lc + 1);
218    
219     if (rows * cols <= leafs) {
220     ++nleaf;
221     return new LeafNode(a, b, lr, hr, lc, hc);
222     }
223     else if (hrows * hcols >= leafs) {
224     return new FourNode(build(a, b, lr, mr, lc, mc, leafs),
225     build(a, b, lr, mr, mc+1, hc, leafs),
226     build(a, b, mr+1, hr, lc, mc, leafs),
227     build(a, b, mr+1, hr, mc+1, hc, leafs));
228     }
229     else if (cols >= rows) {
230     return new TwoNode(build(a, b, lr, hr, lc, mc, leafs),
231     build(a, b, lr, hr, mc+1, hc, leafs));
232     }
233     else {
234     return new TwoNode(build(a, b, lr, mr, lc, hc, leafs),
235     build(a, b, mr+1, hr, lc, hc, leafs));
236 jsr166 1.2
237 dl 1.1 }
238     }
239    
240     static void doCompute(MatrixTree m, int s) {
241     for (int i = 0; i < s; ++i) {
242     m.invoke();
243     m.reinitialize();
244     }
245     }
246    
247     public void compute() {
248     doCompute(mat, steps);
249     double md = mat.maxDiff;
250     System.out.println("max diff after " + steps + " steps = " + md);
251     }
252     }
253    
254    
255     }