ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/FJJacobi.java
Revision: 1.14
Committed: Sat Sep 12 18:34:50 2015 UTC (8 years, 7 months ago) by dl
Branch: MAIN
CVS Tags: HEAD
Changes since 1.13: +3 -1 lines
Log Message:
Use commonPool

File Contents

# Content
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/publicdomain/zero/1.0/
5 */
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;
14 static final int DEFAULT_GRANULARITY = 256;
15
16 /**
17 * The maximum number of matrix cells
18 * at which to stop recursing down and instead directly update.
19 */
20 static final double EPSILON = 0.0001; // convergence criterion
21
22 public static void main(String[] args) throws Exception {
23 int n = 2048;
24 int steps = 1000;
25 int granularity = DEFAULT_GRANULARITY;
26
27 try {
28 if (args.length > 0)
29 n = Integer.parseInt(args[0]);
30 if (args.length > 1)
31 steps = Integer.parseInt(args[1]);
32 if (args.length > 2)
33 granularity = Integer.parseInt(args[2]);
34 }
35
36 catch (Exception e) {
37 System.out.println("Usage: java FJJacobi <matrix size> <max steps> [<leafcells>]");
38 return;
39 }
40
41 // ForkJoinPool fjp = new ForkJoinPool(1);
42 ForkJoinPool fjp = ForkJoinPool.commonPool();
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 double smallVal = EPSILON; // 1.0/dim;
51 for (int i = 1; i < dim-1; ++i) {
52 for (int j = 1; j < dim-1; ++j)
53 a[i][j] = smallVal;
54 }
55 // Fill all edges with 1's.
56 for (int k = 0; k < dim; ++k) {
57 a[k][0] = 1.0;
58 a[k][n+1] = 1.0;
59 a[0][k] = 1.0;
60 a[n+1][k] = 1.0;
61 b[k][0] = 1.0;
62 b[k][n+1] = 1.0;
63 b[0][k] = 1.0;
64 b[n+1][k] = 1.0;
65 }
66 int nreps = 10;
67 for (int rep = 0; rep < nreps; ++rep) {
68 Driver driver = new Driver(a, b, 1, n, 1, n, steps, granularity);
69
70 long startTime = System.currentTimeMillis();
71 fjp.invoke(driver);
72
73 long time = System.currentTimeMillis() - startTime;
74 double secs = ((double)time) / 1000.0;
75
76 System.out.println("Compute Time: " + secs);
77 System.out.println(fjp);
78 Thread.sleep(1000);
79 }
80 }
81
82 abstract static class MatrixTree extends RecursiveAction {
83 // maximum difference between old and new values
84 double maxDiff;
85 public final double directCompute() {
86 compute();
87 return maxDiff;
88 }
89 public final double joinAndReinitialize(double md) {
90 if (tryUnfork())
91 compute();
92 else {
93 quietlyJoin();
94 reinitialize();
95 }
96 double m = maxDiff;
97 return (md > m) ? md : m;
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 LeafNode(double[][] A, double[][] B,
112 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 public void compute() {
120 boolean AtoB = (steps++ & 1) == 0;
121 double[][] a = AtoB ? A : B;
122 double[][] b = AtoB ? B : A;
123
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
132 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 FourNode(MatrixTree q1, MatrixTree q2,
148 MatrixTree q3, MatrixTree q4) {
149 this.q1 = q1; this.q2 = q2; this.q3 = q3; this.q4 = q4;
150 }
151
152 public void compute() {
153 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
164 static final class TwoNode extends MatrixTree {
165 final MatrixTree q1;
166 final MatrixTree q2;
167
168 TwoNode(MatrixTree q1, MatrixTree q2) {
169 this.q1 = q1; this.q2 = q2;
170 }
171
172 public void compute() {
173 q2.fork();
174 maxDiff = q2.joinAndReinitialize(q1.directCompute());
175 }
176
177 }
178
179 static final class Driver extends RecursiveAction {
180 MatrixTree mat;
181 double[][] A; double[][] B;
182 int firstRow; int lastRow;
183 int firstCol; int lastCol;
184 final int steps;
185 final int leafs;
186 int nleaf;
187
188 Driver(double[][] A, double[][] B,
189 int firstRow, int lastRow,
190 int firstCol, int lastCol,
191 int steps, int leafs) {
192 this.A = A;
193 this.B = B;
194 this.firstRow = firstRow;
195 this.firstCol = firstCol;
196 this.lastRow = lastRow;
197 this.lastCol = lastCol;
198 this.steps = steps;
199 this.leafs = leafs;
200 mat = build(A, B, firstRow, lastRow, firstCol, lastCol, leafs);
201 System.out.println("Using " + nleaf + " segments");
202
203 }
204
205 MatrixTree build(double[][] a, double[][] b,
206 int lr, int hr, int lc, int hc, int leafs) {
207 int rows = (hr - lr + 1);
208 int cols = (hc - lc + 1);
209
210 int mr = (lr + hr) >>> 1; // midpoints
211 int mc = (lc + hc) >>> 1;
212
213 int hrows = (mr - lr + 1);
214 int hcols = (mc - lc + 1);
215
216 if (rows * cols <= leafs) {
217 ++nleaf;
218 return new LeafNode(a, b, lr, hr, lc, hc);
219 }
220 else if (hrows * hcols >= leafs) {
221 return new FourNode(build(a, b, lr, mr, lc, mc, leafs),
222 build(a, b, lr, mr, mc+1, hc, leafs),
223 build(a, b, mr+1, hr, lc, mc, leafs),
224 build(a, b, mr+1, hr, mc+1, hc, leafs));
225 }
226 else if (cols >= rows) {
227 return new TwoNode(build(a, b, lr, hr, lc, mc, leafs),
228 build(a, b, lr, hr, mc+1, hc, leafs));
229 }
230 else {
231 return new TwoNode(build(a, b, lr, mr, lc, hc, leafs),
232 build(a, b, mr+1, hr, lc, hc, leafs));
233
234 }
235 }
236
237 static void doCompute(MatrixTree m, int s) {
238 for (int i = 0; i < s; ++i) {
239 m.invoke();
240 m.reinitialize();
241 }
242 }
243
244 public void compute() {
245 doCompute(mat, steps);
246 double md = mat.maxDiff;
247 System.out.println("max diff after " + steps + " steps = " + md);
248 }
249 }
250 }