Add multiple thread version
[IRC.git] / Robust / src / Benchmarks / Prefetch / Em3d / dsm / Em3dN.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     int numThreads;
41
42   BiGraph bg;
43   int upperlimit;
44   int lowerlimit;
45   Barrier mybarr;
46
47   public Em3d() {
48     numNodes = 0;
49     numDegree = 0;
50     numIter = 1;
51     printResult = false;
52     printMsgs = false;
53   }
54
55   public Em3d(BiGraph bg, int lowerlimit, int upperlimit, int numIter, Barrier mybarr) {
56     this.bg = bg;
57     this.lowerlimit = lowerlimit;
58     this.upperlimit = upperlimit;
59     this.numIter = numIter;
60     this.mybarr = mybarr;
61   }
62
63   public void run() {
64     int iteration;
65     Barrier barr;
66
67     atomic {
68       iteration = numIter;
69       barr=mybarr;
70     }
71
72     for (int i = 0; i < iteration; i++) {
73         /* for  eNodes */
74         atomic {
75             for(int j = lowerlimit; j<upperlimit; j++) {
76                 Node n = bg.eNodes[j];
77                 
78                 for (int k = 0; k < n.fromCount; k++) {
79                     n.value -= n.coeffs[k] * n.fromNodes[k].value;
80                 }
81             }
82         }
83         
84         Barrier.enterBarrier(barr);
85         System.clearPrefetchCache();
86
87         /* for  hNodes */
88         atomic {
89             for(int j = lowerlimit; j<upperlimit; j++) {
90                 Node n = bg.hNodes[j];
91                 for (int k = 0; k < n.fromCount; k++) {
92                     n.value -= n.coeffs[k] * n.fromNodes[k].value;
93                 }
94             }
95         }
96         Barrier.enterBarrier(barr);
97         System.clearPrefetchCache();
98     }
99   }
100
101   /**
102    * The main roitine that creates the irregular, linked data structure
103    * that represents the electric and magnetic fields and propagates the
104    * waves through the graph.
105    * @param args the command line arguments
106    **/
107   public static void main(String args[]) {
108     Em3d em = new Em3d();
109     Em3d.parseCmdLine(args, em);
110     if (em.printMsgs) 
111       System.printString("Initializing em3d random graph...\n");
112     long start0 = System.currentTimeMillis();
113     int numThreads = em.numThreads;
114     int[] mid = new int[4];
115     mid[0] = (128<<24)|(195<<16)|(175<<8)|80;
116     mid[1] = (128<<24)|(195<<16)|(175<<8)|78;
117     mid[2] = (128<<24)|(195<<16)|(175<<8)|73;
118     mid[3] = (128<<24)|(195<<16)|(175<<8)|79;
119     System.printString("DEBUG -> numThreads = " + numThreads+"\n");
120     Barrier mybarr;
121     BiGraph graph;
122     Random rand = new Random(783);
123
124     atomic {
125       mybarr = global new Barrier(numThreads);
126       graph =  BiGraph.create(em.numNodes, em.numDegree, em.printResult, rand);
127     }
128
129     long end0 = System.currentTimeMillis();
130
131     // compute a single iteration of electro-magnetic propagation
132     if (em.printMsgs) 
133       System.printString("Propagating field values for " + em.numIter + 
134           " iteration(s)...\n");
135     long start1 = System.currentTimeMillis();
136     Em3d[] em3d;
137
138     atomic {
139       em3d = global new Em3d[numThreads];
140       int increment=em.numNodes/numThreads;
141       int base=0;
142       for(int i=0;i<numThreads;i++) {
143           if ((i+1)==numThreads)
144               em3d[i] = global new Em3d(graph, base, em.numNodes, em.numIter, mybarr);
145           else
146               em3d[i] = global new Em3d(graph, base, base+increment, em.numIter, mybarr);
147           base+=increment;
148       }
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[0].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("-T")) {
205         if (i < args.length) {
206                 em.numThreads = 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 -T <threads> -N <nodes> -d <degree> [-p] [-m] [-h]\n");
235     System.printString("    -N the number of nodes\n");
236     System.printString("    -T the number of threads\n");
237     System.printString("    -d the out-degree of each node\n");
238     System.printString("    -i the number of iterations\n");
239     System.printString("    -p (print detailed results\n)");
240     System.printString("    -m (print informative messages)\n");
241     System.printString("    -h (this message)\n");
242   }
243
244 }