ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/ThreadPhaserJacobi.java
Revision: 1.2
Committed: Thu Oct 29 23:09:08 2009 UTC (14 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.1: +19 -19 lines
Log Message:
whitespace

File Contents

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