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