644a283dd7e33296fc3eb64f2f570ea39ea691e9
[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     }
121     Em3d.parseCmdLine(args, em);
122     
123     boolean printMsgs, printResult;
124     int numIter;
125     atomic {
126       printMsgs = em.printMsgs;
127       numIter = em.numIter;
128       printResult = em.printResult;
129     }
130     if (printMsgs) 
131       System.printString("Initializing em3d random graph...");
132     long start0 = System.currentTimeMillis();
133     int numThreads = 2;
134     System.printString("DEBUG -> numThreads = " + numThreads);
135     Barrier mybarr;
136     atomic {
137       mybarr = global new Barrier(numThreads);
138     }
139     BiGraph graph;
140     BiGraph graph1;
141     Random rand;
142     atomic {
143       rand = global new Random(783);
144     }
145     atomic {
146       graph1 = global new BiGraph();
147       graph = global new BiGraph();
148       graph =  graph1.create(em.numNodes, em.numDegree, em.printResult, rand);
149     }
150
151     long end0 = System.currentTimeMillis();
152
153     // compute a single iteration of electro-magnetic propagation
154     if (printMsgs) 
155       System.printString("Propagating field values for " + numIter + 
156           " iteration(s)...");
157     long start1 = System.currentTimeMillis();
158     Em3d[] em3d;
159     atomic {
160       em3d = global new Em3d[numThreads];
161     }
162
163     atomic {
164       em3d[0] = global new Em3d(graph, 1, em.numNodes/2, em.numIter, mybarr);
165       em3d[1] = global new Em3d(graph, (em.numNodes/2)+1, em.numNodes, em.numIter, mybarr);
166     }
167
168     int mid = (128<<24)|(195<<16)|(175<<8)|73;
169     Em3d tmp;
170     for(int i = 0; i<numThreads; i++) {
171       atomic {
172         tmp = em3d[i];
173       }
174       tmp.start(mid);
175     }
176
177     for(int i = 0; i<numThreads; i++) {
178       atomic { 
179         tmp = em3d[i];
180       }
181       tmp.join();
182     }
183     long end1 = System.currentTimeMillis();
184
185     // print current field values
186     if (printResult) {
187       //System.printString(graph);
188     }
189
190     if (printMsgs) {
191       System.printString("EM3D build time "+ (long)((end0 - start0)/1000.0));
192       System.printString("EM3D compute time " + (long)((end1 - start1)/1000.0));
193       System.printString("EM3D total time " + (long)((end1 - start0)/1000.0));
194     }
195     System.printString("Done!");
196   }
197
198
199   /**
200    * Parse the command line options.
201    * @param args the command line options.
202    **/
203
204   public static void parseCmdLine(String args[], Em3d em)
205   {
206     int i = 0;
207     String arg;
208
209     while (i < args.length && args[i].startsWith("-")) {
210       arg = args[i++];
211
212       // check for options that require arguments
213       if (arg.equals("-n")) {
214         if (i < args.length) {
215             atomic {
216                 em.numNodes = new Integer(args[i++]).intValue();
217             }
218         }
219       } else if (arg.equals("-d")) {
220         if (i < args.length) {
221             atomic {
222                 em.numDegree = new Integer(args[i++]).intValue();
223             }
224         }
225       } else if (arg.equals("-i")) {
226         if (i < args.length) {
227           atomic {
228             em.numIter = global new Integer(args[i++]).intValue();
229           }
230         }
231       } else if (arg.equals("-p")) {
232           atomic {
233               em.printResult = true;
234           }
235       } else if (arg.equals("-m")) {
236           atomic {
237               em.printMsgs = true;
238           }
239       } else if (arg.equals("-h")) {
240         //em.usage();
241       }
242     }
243
244     //if (em.numNodes == 0 || em.numDegree == 0) 
245       //em.usage();
246   }
247
248   /**
249    * The usage routine which describes the program options.
250    **/
251   public void usage()
252   {
253     System.printString("usage: java Em3d -n <nodes> -d <degree> [-p] [-m] [-h]");
254     System.printString("    -n the number of nodes");
255     System.printString("    -d the out-degree of each node");
256     System.printString("    -i the number of iterations");
257     System.printString("    -p (print detailed results)");
258     System.printString("    -m (print informative messages)");
259     System.printString("    -h (this message)");
260   }
261
262 }