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