KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > BarrierJacobi


1 // Barrier version of Jacobi iteration
2

3 import EDU.oswego.cs.dl.util.concurrent.*;
4
5 public class BarrierJacobi {
6
7   static final int DEFAULT_GRANULARITY = 128;
8
9   /**
10    * The maximum submatrix length (both row-wise and column-wise)
11    * for any Segment
12    **/

13
14   static int granularity = DEFAULT_GRANULARITY;
15
16   static final double EPSILON = 0.001; // convergence criterion
17

18
19   public static void main(String JavaDoc[] args) {
20     try {
21       int n;
22       int steps;
23       try {
24         n = Integer.parseInt(args[0]);
25         steps = Integer.parseInt(args[1]);
26         if (args.length > 2) granularity = Integer.parseInt(args[2]);
27       }
28
29       catch (Exception JavaDoc e) {
30         System.out.println("Usage: java BarrierJacobi <matrix size> <max steps> [<granularity>]");
31         return;
32       }
33
34       // allocate enough space for edges
35

36       double[][] a = new double[n+2][n+2];
37       double[][] b = new double[n+2][n+2];
38
39
40       // Simple initialization for demo. Fill all edges with 1's.
41
// (All interiors are already default-initialized to zero.)
42

43       for (int k = 0; k < n+2; ++k) {
44         a[k][0] = 1.0;
45         a[k][n+1] = 1.0;
46         a[0][k] = 1.0;
47         a[n+1][k] = 1.0;
48
49         b[k][0] = 1.0;
50         b[k][n+1] = 1.0;
51         b[0][k] = 1.0;
52         b[n+1][k] = 1.0;
53       }
54
55       long startTime = System.currentTimeMillis();
56
57       new Driver(a, b, 1, n, 1, n, steps).compute();
58
59       long time = System.currentTimeMillis() - startTime;
60       double secs = ((double)time) / 1000.0;
61
62       System.out.println("Compute Time: " + secs);
63
64     }
65     catch (InterruptedException JavaDoc ex) {}
66   }
67
68   static class Segment implements Runnable JavaDoc {
69
70     double[][] A; // matrix to get old values from
71
double[][] B; // matrix to put new values into
72

73     // indices of current submatrix
74
final int loRow;
75     final int hiRow;
76     final int loCol;
77     final int hiCol;
78     final int steps;
79     final CyclicBarrier barrier;
80
81     final Segment[] allSegments;
82
83     volatile double maxDiff; // maximum difference between old and new values
84
volatile boolean converged = false;
85
86     Segment(double[][] A, double[][] B,
87             int loRow, int hiRow,
88             int loCol, int hiCol,
89             int steps,
90             CyclicBarrier barrier,
91             Segment[] allSegments) {
92       this.A = A; this.B = B;
93       this.loRow = loRow; this.hiRow = hiRow;
94       this.loCol = loCol; this.hiCol = hiCol;
95       this.steps = steps;
96       this.barrier = barrier;
97       this.allSegments = allSegments;
98     }
99
100     void convergenceCheck(int step) {
101       for (int i = 0; i < allSegments.length; ++i)
102         if (allSegments[i].maxDiff > EPSILON) return;
103
104       System.out.println("Converged after " + step + " steps");
105
106       for (int i = 0; i < allSegments.length; ++i)
107         allSegments[i].converged = true;
108     }
109
110
111     public void run() {
112       try {
113         double[][] a = A;
114         double[][] b = B;
115         
116         for (int i = 1; i <= steps && !converged; ++i) {
117           maxDiff = update(a, b);
118
119           int index = barrier.barrier();
120           if (index == 0) convergenceCheck(i);
121           barrier.barrier();
122
123           double[][] tmp = a; a = b; b = tmp;
124         }
125       }
126       catch(Exception JavaDoc ex) {
127         return;
128       }
129     }
130
131     double update(double[][] a, double[][] b) {
132       double md = 0.0; // local for computing max diff
133

134       for (int i = loRow; i <= hiRow; ++i) {
135         for (int j = loCol; j <= hiCol; ++j) {
136           double v = 0.25 * (a[i-1][j] + a[i][j-1] +
137                              a[i+1][j] + a[i][j+1]);
138           b[i][j] = v;
139
140           double diff = v - a[i][j];
141           if (diff < 0) diff = -diff;
142           if (diff > md) md = diff;
143         }
144       }
145
146       return md;
147     }
148         
149   }
150         
151
152   static class Driver {
153     double[][] A; // matrix to get old values from
154
double[][] B; // matrix to put new values into
155

156     final int loRow; // indices of current submatrix
157
final int hiRow;
158     final int loCol;
159     final int hiCol;
160     final int steps;
161
162     Driver(double[][] mat1, double[][] mat2,
163            int firstRow, int lastRow,
164            int firstCol, int lastCol,
165            int steps) {
166       
167       this.A = mat1; this.B = mat2;
168       this.loRow = firstRow; this.hiRow = lastRow;
169       this.loCol = firstCol; this.hiCol = lastCol;
170       this.steps = steps;
171     }
172
173     public void compute() throws InterruptedException JavaDoc {
174
175       int rows = hiRow - loRow + 1;
176       int cols = hiCol - loCol + 1;
177       int rblocks = rows / granularity;
178       int cblocks = cols / granularity;
179
180       int n = rblocks * cblocks;
181
182       System.out.println("Using " + n + " segments (threads)");
183
184       Segment[] segs = new Segment[n];
185       Thread JavaDoc[] threads = new Thread JavaDoc[n];
186       CyclicBarrier barrier = new CyclicBarrier(n);
187
188       int k = 0;
189       for (int i = 0; i < rblocks; ++i) {
190         int lr = loRow + i * granularity;
191         int hr = lr + granularity;
192         if (i == rblocks-1) hr = hiRow;
193         
194         for (int j = 0; j < cblocks; ++j) {
195           int lc = loCol + j * granularity;
196           int hc = lc + granularity;
197           if (j == cblocks-1) hc = hiCol;
198
199           segs[k] = new Segment(A, B, lr, hr, lc, hc, steps, barrier, segs);
200           threads[k] = new Thread JavaDoc(segs[k]);
201           ++k;
202         }
203       }
204
205       for (k = 0; k < n; ++k) threads[k].start();
206
207       for (k = 0; k < n; ++k) threads[k].join();
208
209       double maxd = 0;
210       for (k = 0; k < n; ++k) {
211         double md = segs[k].maxDiff;
212         if (md > maxd) maxd = md;
213       }
214
215       System.out.println("Max diff after " + steps + " steps = " + maxd);
216
217
218     }
219   }
220
221
222 }
223
Popular Tags