ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/FJJacobi.java
Revision: 1.10
Committed: Tue Mar 15 19:47:05 2011 UTC (13 years, 2 months ago) by jsr166
Branch: MAIN
CVS Tags: release-1_7_0
Changes since 1.9: +1 -1 lines
Log Message:
Update Creative Commons license URL in legal notices

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