28ffe641750bfb5e8db2dde1ed832815244cf1f7
[IRC.git] / Robust / src / Benchmarks / Prefetch / Em3d / dsm / Em3d.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   /**
20    * The number of nodes (E and H) 
21    **/
22   private int numNodes;
23   /**
24    * The out-degree of each node.
25    **/
26   private int numDegree;
27   /**
28    * The number of compute iterations 
29    **/
30   private int numIter;
31   /**
32    * Should we print the results and other runtime messages
33    **/
34   private boolean printResult;
35   /**
36    * Print information messages?
37    **/
38   private boolean printMsgs;
39
40   BiGraph bg;
41   int upperlimit;
42   int lowerlimit;
43   //Random rand;
44   Barrier mybarr;
45
46   public Em3d() {
47     numNodes = 0;
48     numDegree = 0;
49     numIter = 1;
50     printResult = false;
51     printMsgs = false;
52   }
53
54   public Em3d(BiGraph bg, int lowerlimit, int upperlimit, int numIter, Barrier mybarr) {
55     this.bg = bg;
56     this.lowerlimit = lowerlimit;
57     this.upperlimit = upperlimit;
58     this.numIter = numIter;
59     this.mybarr = mybarr;
60   }
61
62   public void run() {
63     int iteration;
64     atomic {
65       iteration = numIter;
66     }
67
68     for (int i = 0; i < iteration; i++) {
69       Barrier runBarrier = new Barrier();
70       /* for  eNodes */
71       Node prev, curr;
72       atomic {
73         prev = bg.eNodes;
74         curr = null;
75         for(int j = 0; j<lowerlimit; j++){
76           curr = prev;
77           prev = prev.next;
78         }
79         for(int j = lowerlimit; j<=upperlimit; j++) {
80           Node n = curr;
81           for (int k = 0; k < n.fromCount; k++) {
82             n.value -= n.coeffs[k] * n.fromNodes[k].value;
83           }
84           curr = curr.next;
85         }
86         runBarrier.enterBarrier(mybarr);
87         //mybarr.reset();
88       }
89
90       /* for  hNodes */
91       atomic {
92         prev = bg.hNodes;
93         curr = null;
94         for(int j = 0; j<lowerlimit; j++){
95           curr = prev;
96           prev = prev.next;
97         }
98         for(int j = lowerlimit; j<=upperlimit; j++) {
99           Node n = curr;
100           for (int k = 0; k < n.fromCount; k++) {
101             n.value -= n.coeffs[k] * n.fromNodes[k].value;
102           }
103           curr = curr.next;
104         }
105         runBarrier.enterBarrier(mybarr);
106         //mybarr.reset();
107       }
108     }
109   }
110
111   /**
112    * The main roitine that creates the irregular, linked data structure
113    * that represents the electric and magnetic fields and propagates the
114    * waves through the graph.
115    * @param args the command line arguments
116    **/
117   public static void main(String args[])
118   {
119     Random rand = new Random(783);
120     Em3d em;
121     atomic {
122       em = global new Em3d();
123       em.parseCmdLine(args, em);
124     }
125     boolean printMsgs, printResult;
126     int numIter;
127     atomic {
128       printMsgs = em.printMsgs;
129       numIter = em.numIter;
130       printResult = em.printResult;
131     }
132     if (printMsgs) 
133       System.printString("Initializing em3d random graph...");
134     long start0 = System.currentTimeMillis();
135     int numThreads = 2;
136     System.printString("DEBUG -> numThreads = " + numThreads);
137     Barrier mybarr;
138     atomic {
139       mybarr = global new Barrier(numThreads);
140     }
141     BiGraph graph;
142     BiGraph graph1;
143     atomic {
144       graph1 = global new BiGraph();
145       graph = global new BiGraph();
146       graph =  graph1.create(em.numNodes, em.numDegree, em.printResult, rand);
147     }
148
149     long end0 = System.currentTimeMillis();
150
151     // compute a single iteration of electro-magnetic propagation
152     if (printMsgs) 
153       System.printString("Propagating field values for " + numIter + 
154           " iteration(s)...");
155     long start1 = System.currentTimeMillis();
156     Em3d[] em3d;
157     atomic {
158       em3d = global new Em3d[numThreads];
159     }
160
161     atomic {
162       em3d[0] = global new Em3d(graph, 1, em.numNodes/2, em.numIter, mybarr);
163       em3d[1] = global new Em3d(graph, (em.numNodes/2)+1, em.numNodes, em.numIter, mybarr);
164     }
165
166     int mid = (128<<24)|(195<<16)|(175<<8)|73;
167     Em3d tmp;
168     for(int i = 0; i<numThreads; i++) {
169       atomic {
170         tmp = em3d[i];
171       }
172       tmp.start(mid);
173     }
174
175     for(int i = 0; i<numThreads; i++) {
176       atomic { 
177         tmp = em3d[i];
178       }
179       tmp.join();
180     }
181     long end1 = System.currentTimeMillis();
182
183     // print current field values
184     if (printResult) {
185       //System.printString(graph);
186     }
187
188     if (printMsgs) {
189       System.printString("EM3D build time "+ (long)((end0 - start0)/1000.0));
190       System.printString("EM3D compute time " + (long)((end1 - start1)/1000.0));
191       System.printString("EM3D total time " + (long)((end1 - start0)/1000.0));
192     }
193     System.printString("Done!");
194   }
195
196
197   /**
198    * Parse the command line options.
199    * @param args the command line options.
200    **/
201
202   public void parseCmdLine(String args[], Em3d em)
203   {
204     int i = 0;
205     String arg;
206
207     while (i < args.length && args[i].startsWith("-")) {
208       arg = args[i++];
209
210       // check for options that require arguments
211       if (arg.equals("-n")) {
212         if (i < args.length) {
213           em.numNodes = new Integer(args[i++]).intValue();
214         }
215       } else if (arg.equals("-d")) {
216         if (i < args.length) {
217           em.numDegree = new Integer(args[i++]).intValue();
218         }
219       } else if (arg.equals("-i")) {
220         if (i < args.length) {
221           atomic {
222             em.numIter = global new Integer(args[i++]).intValue();
223           }
224         }
225       } else if (arg.equals("-p")) {
226         em.printResult = true;
227       } else if (arg.equals("-m")) {
228         em.printMsgs = true;
229       } else if (arg.equals("-h")) {
230         //em.usage();
231       }
232     }
233
234     //if (em.numNodes == 0 || em.numDegree == 0) 
235       //em.usage();
236   }
237
238   /**
239    * The usage routine which describes the program options.
240    **/
241   public void usage()
242   {
243     System.printString("usage: java Em3d -n <nodes> -d <degree> [-p] [-m] [-h]");
244     System.printString("    -n the number of nodes");
245     System.printString("    -d the out-degree of each node");
246     System.printString("    -i the number of iterations");
247     System.printString("    -p (print detailed results)");
248     System.printString("    -m (print informative messages)");
249     System.printString("    -h (this message)");
250   }
251
252 }