bug fix
[IRC.git] / Robust / src / Benchmarks / Prefetch / Em3d / dsm / Em3d2.java
1 /** 
2  *
3  *
4  * Java implementation of the <tt>em3d</tt> Olden benchmark.  This Olden
5  * benchmark models the propagation of electromagnetic waves through
6  * objects in 3 dimensions. It is a simple computation on an irregular
7  * bipartite graph containing nodes representing electric and magnetic
8  * field values.
9  *
10  * <p><cite>
11  * D. Culler, A. Dusseau, S. Goldstein, A. Krishnamurthy, S. Lumetta, T. von 
12  * Eicken and K. Yelick. "Parallel Programming in Split-C".  Supercomputing
13  * 1993, pages 262-273.
14  * </cite>
15  **/
16 public class Em3d extends Thread {
17
18   /**
19    * The number of nodes (E and H) 
20    **/
21   private int numNodes;
22   /**
23    * The out-degree of each node.
24    **/
25   private int numDegree;
26   /**
27    * The number of compute iterations 
28    **/
29   private int numIter;
30   /**
31    * Should we print the results and other runtime messages
32    **/
33   private boolean printResult;
34     /**
35      * Print information messages?
36      **/
37   private boolean printMsgs;
38
39     int threadindex;
40     int numThreads;
41
42   BiGraph bg;
43   int upperlimit;
44   int lowerlimit;
45   Barrier mybarr;
46     public Em3d() {
47     }
48
49     public Em3d(BiGraph bg, int lowerlimit, int upperlimit, int numIter, Barrier mybarr, int numDegree, int threadindex) {
50     this.bg = bg;
51     this.lowerlimit = lowerlimit;
52     this.upperlimit = upperlimit;
53     this.numIter = numIter;
54     this.mybarr = mybarr;
55     this.numDegree = numDegree;
56     this.threadindex=threadindex;
57   }
58
59   public void run() {
60     int iteration;
61     Barrier barr;
62     int degree;
63     Random random;
64
65     atomic {
66         iteration = numIter;
67         barr=mybarr;
68         degree = numDegree;
69         random = new Random(lowerlimit);
70     }
71
72     atomic {
73         //This is going to conflict badly...Minimize work here
74         bg.allocateNodes ( lowerlimit, upperlimit, threadindex);
75     }
76     Barrier.enterBarrier(barr);
77
78     atomic {
79         //initialize the eNodes
80         bg.initializeNodes(bg.eNodes, bg.hNodes, lowerlimit, upperlimit, degree, random, threadindex);
81     }
82     Barrier.enterBarrier(barr);
83
84     atomic {
85         //initialize the hNodes
86         bg.initializeNodes(bg.hNodes, bg.eNodes, lowerlimit, upperlimit, degree, random, threadindex);
87     }
88     Barrier.enterBarrier(barr);
89
90     atomic {
91         bg.makeFromNodes(bg.hNodes, lowerlimit, upperlimit, random);
92     }
93     Barrier.enterBarrier(barr);
94
95     atomic {
96         bg.makeFromNodes(bg.eNodes, lowerlimit, upperlimit, random);
97     }
98     Barrier.enterBarrier(barr);
99
100     //Do the computation
101     for (int i = 0; i < iteration; i++) {
102         /* for  eNodes */
103         atomic {
104             for(int j = lowerlimit; j<upperlimit; j++) {
105                 Node n = bg.eNodes[j];
106                 
107                 for (int k = 0; k < n.fromCount; k++) {
108                     n.value -= n.coeffs[k] * n.fromNodes[k].value;
109                 }
110             }
111         }
112         
113         Barrier.enterBarrier(barr);
114         
115         /* for  hNodes */
116         atomic {
117             for(int j = lowerlimit; j<upperlimit; j++) {
118                 Node n = bg.hNodes[j];
119                 for (int k = 0; k < n.fromCount; k++) {
120                     n.value -= n.coeffs[k] * n.fromNodes[k].value;
121                 }
122             }
123         }
124         Barrier.enterBarrier(barr);
125     }
126   }
127
128   /**
129    * The main roitine that creates the irregular, linked data structure
130    * that represents the electric and magnetic fields and propagates the
131    * waves through the graph.
132    * @param args the command line arguments
133    **/
134   public static void main(String args[]) {
135     Em3d em = new Em3d();
136     Em3d.parseCmdLine(args, em);
137     if (em.printMsgs) 
138       System.printString("Initializing em3d random graph...\n");
139     long start0 = System.currentTimeMillis();
140     int numThreads = em.numThreads;
141     int[] mid = new int[4];
142     mid[0] = (128<<24)|(195<<16)|(175<<8)|79;//dw-1
143     mid[1] = (128<<24)|(195<<16)|(175<<8)|80;//dw-2
144     mid[2] = (128<<24)|(195<<16)|(175<<8)|73;
145     mid[3] = (128<<24)|(195<<16)|(175<<8)|78;
146     System.printString("DEBUG -> numThreads = " + numThreads+"\n");
147     Barrier mybarr;
148     BiGraph graph;
149
150     
151     // initialization step 1: allocate BiGraph
152    // System.printString( "Allocating BiGraph.\n" );
153
154     atomic {
155       mybarr = global new Barrier(numThreads);
156       graph =  BiGraph.create(em.numNodes, em.numDegree, numThreads);
157     }
158
159     Em3dWrap[] em3d=new Em3dWrap[numThreads];    
160     int increment = em.numNodes/numThreads;
161
162
163     // initialization step 2: divide work of allocating nodes
164     // System.printString( "Launching distributed allocation of nodes.\n" );
165     
166     atomic {
167       int base=0;
168       for(int i=0;i<numThreads;i++) {
169           Em3d tmp;
170           if ((i+1)==numThreads)
171               tmp = global new Em3d(graph, base, em.numNodes, em.numIter, mybarr, em.numDegree, i);
172           else
173               tmp = global new Em3d(graph, base, base+increment, em.numIter, mybarr, em.numDegree, i);
174           em3d[i]=new Em3dWrap(tmp);
175           base+=increment;
176       }
177     }
178
179     for(int i = 0; i<numThreads; i++) {
180         em3d[i].em3d.start(mid[i]);
181     }
182
183     for(int i = 0; i<numThreads; i++) {
184         em3d[i].em3d.join();
185     }
186   }
187
188
189   /**
190    * Parse the command line options.
191    * @param args the command line options.
192    **/
193
194   public static void parseCmdLine(String args[], Em3d em)
195   {
196     int i = 0;
197     String arg;
198
199     while (i < args.length && args[i].startsWith("-")) {
200       arg = args[i++];
201
202       // check for options that require arguments
203       if (arg.equals("-N")) {
204         if (i < args.length) {
205                 em.numNodes = new Integer(args[i++]).intValue();
206         }
207       } else if (arg.equals("-T")) {
208         if (i < args.length) {
209                 em.numThreads = new Integer(args[i++]).intValue();
210         }
211       } else if (arg.equals("-d")) {
212         if (i < args.length) {
213                 em.numDegree = new Integer(args[i++]).intValue();
214         }
215       } else if (arg.equals("-i")) {
216         if (i < args.length) {
217             em.numIter = new Integer(args[i++]).intValue();
218         }
219       } else if (arg.equals("-p")) {
220               em.printResult = true;
221       } else if (arg.equals("-m")) {
222               em.printMsgs = true;
223       } else if (arg.equals("-h")) {
224         em.usage();
225       }
226     }
227
228     if (em.numNodes == 0 || em.numDegree == 0) 
229       em.usage();
230   }
231
232   /**
233    * The usage routine which describes the program options.
234    **/
235   public void usage()
236   {
237     System.printString("usage: java Em3d -T <threads> -N <nodes> -d <degree> [-p] [-m] [-h]\n");
238     System.printString("    -N the number of nodes\n");
239     System.printString("    -T the number of threads\n");
240     System.printString("    -d the out-degree of each node\n");
241     System.printString("    -i the number of iterations\n");
242     System.printString("    -p (print detailed results\n)");
243     System.printString("    -m (print informative messages)\n");
244     System.printString("    -h (this message)\n");
245   }
246
247 }