ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/FJPhaserJacobi.java
Revision: 1.10
Committed: Sat Feb 16 21:37:44 2013 UTC (11 years, 2 months ago) by jsr166
Branch: MAIN
Changes since 1.9: +6 -1 lines
Log Message:
add missing public domain notices

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