ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/FJPhaserJacobi.java
Revision: 1.4
Committed: Fri Oct 30 14:15:04 2009 UTC (14 years, 6 months ago) by dl
Branch: MAIN
Changes since 1.3: +6 -0 lines
Log Message:
Missing file headers

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