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