ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/CCJacobi.java
Revision: 1.3
Committed: Thu Aug 16 12:26:27 2012 UTC (11 years, 8 months ago) by dl
Branch: MAIN
Changes since 1.2: +7 -7 lines
Log Message:
Parameterize CountedCompleters

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/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 CCJacobi {
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();
42    
43     // allocate enough space for edges
44     int dim = n+2;
45     int ncells = dim * dim;
46     double[][] a = new double[dim][dim];
47     double[][] b = new double[dim][dim];
48     // Initialize interiors to small value
49     double smallVal = EPSILON; // 1.0/dim;
50     for (int i = 1; i < dim-1; ++i) {
51     for (int j = 1; j < dim-1; ++j)
52     a[i][j] = smallVal;
53     }
54     // Fill all edges with 1's.
55     for (int k = 0; k < dim; ++k) {
56     a[k][0] = 1.0;
57     a[k][n+1] = 1.0;
58     a[0][k] = 1.0;
59     a[n+1][k] = 1.0;
60     b[k][0] = 1.0;
61     b[k][n+1] = 1.0;
62     b[0][k] = 1.0;
63     b[n+1][k] = 1.0;
64     }
65     int nreps = 10;
66     for (int rep = 0; rep < nreps; ++rep) {
67     Driver driver = new Driver(a, b, 1, n, 1, n, steps, granularity);
68    
69     long startTime = System.currentTimeMillis();
70     fjp.invoke(driver);
71    
72     long time = System.currentTimeMillis() - startTime;
73     double secs = ((double)time) / 1000.0;
74    
75     System.out.println("Compute Time: " + secs);
76     System.out.println(fjp);
77     }
78     }
79    
80    
81 dl 1.3 abstract static class MatrixTree extends CountedCompleter<Void> {
82 dl 1.1 // maximum difference between old and new values
83     double maxDiff;
84 dl 1.3 MatrixTree(CountedCompleter<?> p, int c) { super(p, c); }
85 dl 1.1 }
86    
87    
88     static final class LeafNode extends MatrixTree {
89     final double[][] A; // matrix to get old values from
90     final double[][] B; // matrix to put new values into
91    
92     // indices of current submatrix
93     final int loRow; final int hiRow;
94     final int loCol; final int hiCol;
95    
96     int steps = 0; // track even/odd steps
97    
98 dl 1.3 LeafNode(CountedCompleter<?> p,
99 dl 1.1 double[][] A, double[][] B,
100     int loRow, int hiRow,
101     int loCol, int hiCol) {
102     super(p, 0);
103     this.A = A; this.B = B;
104     this.loRow = loRow; this.hiRow = hiRow;
105     this.loCol = loCol; this.hiCol = hiCol;
106     }
107    
108     public final void compute() {
109     boolean AtoB = (steps++ & 1) == 0;
110     double[][] a = AtoB ? A : B;
111     double[][] b = AtoB ? B : A;
112    
113     double md = 0.0; // local for computing max diff
114    
115     for (int i = loRow; i <= hiRow; ++i) {
116     for (int j = loCol; j <= hiCol; ++j) {
117     double v = 0.25 * (a[i-1][j] + a[i][j-1] +
118     a[i+1][j] + a[i][j+1]);
119     b[i][j] = v;
120    
121     double diff = v - a[i][j];
122     if (diff < 0) diff = -diff;
123     if (diff > md) md = diff;
124     }
125     }
126    
127     maxDiff = md;
128 jsr166 1.2 tryComplete();
129 dl 1.1 }
130     }
131    
132     static final class FourNode extends MatrixTree {
133     MatrixTree q1;
134     MatrixTree q2;
135     MatrixTree q3;
136     MatrixTree q4;
137 dl 1.3 FourNode(CountedCompleter<?> p) {
138 dl 1.1 super(p, 3);
139     }
140    
141 dl 1.3 public void onCompletion(CountedCompleter<?> caller) {
142 dl 1.1 double md = q1.maxDiff, m;
143     if ((m = q2.maxDiff) > md)
144     md = m;
145     if ((m = q3.maxDiff) > md)
146     md = m;
147     if ((m = q4.maxDiff) > md)
148     md = m;
149     maxDiff = md;
150     setPendingCount(3);
151     }
152    
153     public final void compute() {
154     q4.fork();
155     q3.fork();
156     q2.fork();
157     q1.compute();
158     }
159     }
160    
161    
162     static final class TwoNode extends MatrixTree {
163     MatrixTree q1;
164     MatrixTree q2;
165    
166 dl 1.3 TwoNode(CountedCompleter<?> p) {
167 dl 1.1 super(p, 1);
168     }
169    
170 dl 1.3 public void onCompletion(CountedCompleter<?> caller) {
171 dl 1.1 double md = q1.maxDiff, m;
172     if ((m = q2.maxDiff) > md)
173     md = m;
174     maxDiff = md;
175     setPendingCount(1);
176     }
177    
178     public final void compute() {
179     q2.fork();
180     q1.compute();
181     }
182    
183     }
184    
185     static final class Driver extends RecursiveAction {
186     MatrixTree mat;
187     double[][] A; double[][] B;
188     int firstRow; int lastRow;
189     int firstCol; int lastCol;
190     final int steps;
191     final int leafs;
192     int nleaf;
193    
194     Driver(double[][] A, double[][] B,
195     int firstRow, int lastRow,
196     int firstCol, int lastCol,
197     int steps, int leafs) {
198     this.A = A;
199     this.B = B;
200     this.firstRow = firstRow;
201     this.firstCol = firstCol;
202     this.lastRow = lastRow;
203     this.lastCol = lastCol;
204     this.steps = steps;
205     this.leafs = leafs;
206     mat = build(null, A, B, firstRow, lastRow, firstCol, lastCol, leafs);
207     System.out.println("Using " + nleaf + " segments");
208    
209     }
210    
211     MatrixTree build(MatrixTree p,
212     double[][] a, double[][] b,
213     int lr, int hr, int lc, int hc, int leafs) {
214     int rows = (hr - lr + 1);
215     int cols = (hc - lc + 1);
216    
217     int mr = (lr + hr) >>> 1; // midpoints
218     int mc = (lc + hc) >>> 1;
219    
220     int hrows = (mr - lr + 1);
221     int hcols = (mc - lc + 1);
222    
223     if (rows * cols <= leafs) {
224     ++nleaf;
225     return new LeafNode(p, a, b, lr, hr, lc, hc);
226     }
227     else if (hrows * hcols >= leafs) {
228     FourNode q = new FourNode(p);
229     q.q1 = build(q, a, b, lr, mr, lc, mc, leafs);
230     q.q2 = build(q, a, b, lr, mr, mc+1, hc, leafs);
231     q.q3 = build(q, a, b, mr+1, hr, lc, mc, leafs);
232     q.q4 = build(q, a, b, mr+1, hr, mc+1, hc, leafs);
233     return q;
234     }
235     else if (cols >= rows) {
236     TwoNode q = new TwoNode(p);
237     q.q1 = build(q, a, b, lr, hr, lc, mc, leafs);
238     q.q2 = build(q, a, b, lr, hr, mc+1, hc, leafs);
239     return q;
240     }
241     else {
242     TwoNode q = new TwoNode(p);
243     q.q1 = build(q, a, b, lr, mr, lc, hc, leafs);
244     q.q2 = build(q, a, b, mr+1, hr, lc, hc, leafs);
245     return q;
246     }
247     }
248    
249     static void doCompute(MatrixTree m, int s) {
250     for (int i = 0; i < s; ++i) {
251     m.setPendingCount(3);
252     m.invoke();
253     m.reinitialize();
254     }
255     }
256    
257     public void compute() {
258     doCompute(mat, steps);
259     double md = mat.maxDiff;
260     System.out.println("max diff after " + steps + " steps = " + md);
261     }
262     }
263    
264    
265     }