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

# User Rev Content
1 dl 1.4 /*
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 dl 1.1 // 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 jsr166 1.2
28 dl 1.1 catch (Exception e) {
29 jsr166 1.3 System.out.println("Usage: java FJPhaserJacobi <matrix size> <max steps>");
30 dl 1.1 return;
31     }
32 jsr166 1.2
33 dl 1.1 ForkJoinPool fjp = new ForkJoinPool();
34     int granularity = n * n / fjp.getParallelism();
35     dimGran = (int)(Math.sqrt(granularity));
36 jsr166 1.2
37 dl 1.1 // 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 jsr166 1.2 double smallVal = 1.0/dim;
44 dl 1.1 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 jsr166 1.2
61 dl 1.1 long time = System.currentTimeMillis() - startTime;
62     double secs = ((double)time) / 1000.0;
63 jsr166 1.2
64 dl 1.1 System.out.println("Compute Time: " + secs);
65     System.out.println(fjp);
66    
67     }
68 jsr166 1.2
69 dl 1.1 }
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 jsr166 1.2 final int loRow;
76 dl 1.1 final int hiRow;
77     final int loCol;
78     final int hiCol;
79     volatile double maxDiff; // maximum difference between old and new values
80    
81 jsr166 1.2 Segment(double[][] A, double[][] B,
82 dl 1.1 int loRow, int hiRow,
83 jsr166 1.2 int loCol, int hiCol,
84 dl 1.1 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 jsr166 1.2
114 dl 1.1 }
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 jsr166 1.2 static class Driver extends RecursiveAction {
125 dl 1.1 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 jsr166 1.2 Driver(double[][] mat1, double[][] mat2,
133 dl 1.1 int firstRow, int lastRow,
134     int firstCol, int lastCol,
135     int steps) {
136 jsr166 1.2
137 dl 1.1 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 jsr166 1.2
149 dl 1.1 int n = rblocks * cblocks;
150 jsr166 1.2
151 dl 1.1 System.out.println("Using " + n + " segments");
152 jsr166 1.2
153 dl 1.1 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 jsr166 1.2
161 dl 1.1 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 jsr166 1.2
166 dl 1.1 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     }