Removing memory leak in kNeighbor benchmark
[charm.git] / examples / charm++ / Maj_Min / jacobi2d.C
1 #include <controlPoints.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "TempCore.h"
5 #include "jacobi2d.decl.h"
6
7 #define PRIOR
8
9 int minElements;
10 int majElements;
11 int MAJLOOP = 8000000;
12 FILE *f;
13 int ldbTime = 5;
14 CkEntryOptions *opts, *opts1;
15 // See README for documentation
16
17 /*readonly*/ CProxy_Main mainProxy;
18 CProxy_Minor minorProxy;
19 CProxy_ProcFreq freqProxy;
20 // specify the number of worker chares in each dimension
21
22 // We want to wrap entries around, and because mod operator % sometimes misbehaves on negative values, 
23 // I just wrote these simple wrappers that will make the mod work as expected. -1 maps to the highest value.
24
25 double start;
26 //#define total_iterations 200
27
28 class Main:public CBase_Main
29 {
30 public:
31   int recieve_count;
32   CProxy_Jacobi array;
33   CProxy_Minor arrayMin;
34   int num_chares;
35   int iterations;
36   int total_iterations;
37   double startTime;
38
39     Main (CkArgMsg * m)
40   {
41     if (m->argc < 3)
42       {
43         CkPrintf ("%s [array_size] [block_size]\n", m->argv[0]);
44         CkAbort ("Abort");
45       }
46     f = fopen ("temp.out", "w");
47     // set iteration counter to zero
48     iterations = 0;
49
50     // store the main proxy
51     mainProxy = thisProxy;
52     freqProxy = CProxy_ProcFreq::ckNew ();
53     majElements = minElements = 8;
54     majElements = atoi (m->argv[1]);
55     minElements = atoi (m->argv[2]);
56
57     // print info
58
59     total_iterations = 200;
60     if (m->argc > 3)
61       {
62         total_iterations = atoi (m->argv[3]);
63       }
64
65     // Create new array of worker chares
66
67     array = CProxy_Jacobi::ckNew (majElements, majElements);
68     arrayMin = CProxy_Minor::ckNew (minElements, minElements);
69     minorProxy = arrayMin;
70     CkPrintf
71       ("************** majorElements=%d minorElements=%d iterations=%d ********************\n",
72        majElements, minElements, total_iterations);
73     // save the total number of worker chares we have in this simulation
74     num_chares = majElements + minElements;
75
76     //Start the computation
77     startTime = CmiWallTimer ();
78     start = startTime;
79     recieve_count = 0;
80 #ifdef PRIOR
81     opts = new CkEntryOptions ();
82     opts1 = new CkEntryOptions ();
83     opts->setPriority (-100);
84     opts1->setPriority (100);
85
86     array[0].begin_iteration (1, opts);
87       for(int i=0;i<7;i++)
88               arrayMin[i].begin_iteration(1,opts1);
89 //      arrayMin.begin_iteration(1,opts1);
90 #else
91     array[0].begin_iteration (1);
92     for (int i = 0; i < 7; i++)
93       arrayMin[i].begin_iteration (1);
94 #endif
95 //      arrayMin.begin_iteration(1,opts1);
96   }
97
98   void exiting()
99   {
100         CkExit();
101   }
102
103   // Each worker reports back to here when it completes an iteration
104   void report (CkReductionMsg *msg)
105   {
106     recieve_count++;
107     double totaltime = CmiWallTimer () - startTime;
108 //    printf("coming in report--------------------------------------------- rec=%d\n",recieve_count);
109     if (2 == recieve_count)
110 //      if(minElements+1 == recieve_count)
111       {
112         if (iterations == total_iterations)
113           {
114             CkPrintf
115               ("Completed %d iterations; last iteration time: %.6lf total time=%f\n",
116                iterations, totaltime, CmiWallTimer () - start);
117 //          CkExit ();
118                 mainProxy.exiting();
119           }
120         else
121           {
122 if(iterations==1) useThisCriticalPathForPriorities();
123             if (iterations % 1 == 0)
124               {
125                 char tempArr[50];
126                 for (int x = 0; x < 50; x++)
127                   tempArr[x] = 0;
128                 float avg = 0;
129                 for (int pe = 0; pe < CkNumPes (); pe++)
130                   {
131                     sprintf (tempArr + strlen (tempArr), "%d ",
132                              (int) getTemp (pe));
133                     avg += getTemp (pe);
134                     //if(gmaxTemp<stats->procs[pe].pe_temp) gmaxTemp=stats->procs[pe].pe_temp;
135                   }
136                 avg /= CkNumPes ();
137                 CkPrintf
138                   ("starting new iteration; iteration %d time: %.6lf AVG=%.6lf\n",
139                    iterations, totaltime, avg);
140                 //printf("********* iteration=%d AVG temp=%f **********\n",iterations,avg);
141 //                      sprintf(tempArr,"%d %f",iterations,avg);
142                 // printf("temps=%s\n",tempArr);
143                 writeTemps (f, tempArr);
144 //              if (CkMyPe () == 0)
145                   freqProxy.measureFreq (iterations, total_iterations);
146               }
147
148 //                CkPrintf("starting new iteration; iteration %d time: %.6lf\n", iterations, totaltime);
149             recieve_count = 0;
150             iterations++;
151             // Call begin_iteration on all worker chares in array
152             startTime = CmiWallTimer ();
153 #ifdef PRIOR
154             opts = new CkEntryOptions ();
155             opts1 = new CkEntryOptions ();
156             opts->setPriority (-100);
157             opts1->setPriority (100);
158
159             array[0].begin_iteration (1, opts);
160                 for(int i=0;i<7;i++)
161                         arrayMin[i].begin_iteration(1,opts1);
162 //              arrayMin.begin_iteration(1,opts1);              
163 #else
164             array[0].begin_iteration (1);
165             for (int i = 0; i < 7; i++)
166               arrayMin[i].begin_iteration (1);
167 #endif
168
169           }
170       }
171   }
172 };
173
174 class ProcFreq:public CBase_ProcFreq
175 {
176 public:
177   int lowFreq;
178   int highFreq;
179     ProcFreq ()
180   {
181     lowFreq = highFreq = 0;
182   }
183   void measureFreq (int it, int total_itr)
184   {
185     if (cpufreq_sysfs_read (CkMyPe ()) == 1596000)
186       lowFreq += 1;
187     else
188       highFreq += 1;
189     if (it == total_itr - 1 && CkMyPe () % 4 == 0)
190       printf
191         ("PROC#%d ddddddddddddddddddddddddddddddddddddddddddddddddddd h=%d l=%d\n",
192          CkMyPe (), highFreq, lowFreq);
193
194
195   }
196
197
198 };
199
200
201 class Jacobi:public CBase_Jacobi
202 {
203 public:
204 //    int messages_due;
205   int iterations;
206   float *arr;
207   int useLB;
208   // Constructor, initialize values
209     Jacobi (int x)
210   {
211     int i, j;
212       majElements = x;
213       useLB = 1;
214       arr = new float[1000];
215     for (int i = 0; i < 1000; i++)
216         arr[i] = rand ();
217       usesAtSync = CmiTrue;
218       iterations = 0;
219     // allocate two dimensional array
220   }
221
222   void pup (PUP::er & p)
223   {
224     CBase_Jacobi::pup (p);
225 //        p|messages_due;
226     p | iterations;
227     p | useLB;
228     if (p.isUnpacking ())
229       arr = new float[1000];
230     for (int i = 0; i < 1000; i++)
231       p | arr[i];
232 /* There may be some more variables used in doWork */
233   }
234
235
236   // a necessary function which we ignore now
237   // if we were to use load balancing and migration
238   // this function might become useful
239   Jacobi (CkMigrateMessage * m)
240   {
241   }
242
243   ~Jacobi ()
244   {
245     delete[]arr;
246   }
247
248   // Perform one iteration of work
249   // The first step is to send the local state to the neighbors
250   void begin_iteration (int i)
251   {
252 //printf("PROC#%d coming for Jacobi[%d] iteration=%d majElements=%d\n",CkMyPe(),thisIndex,iterations,majElements);
253 /*
254 if ( iterations %10 ==0 && useLB) {
255 printf("calling sync\n");
256         useLB = 0;
257         AtSync();
258 }
259 else
260 */
261     {
262 //printf("PROC#%din elsssssssssssssssssssssss\n",CkMyPe());
263       useLB = 1;
264       iterations++;
265
266
267       check_and_compute ();
268     }
269   }
270
271   void check_and_compute ()
272   {
273 //       if (--messages_due == 0) 
274 //          messages_due = 4;
275       compute ();
276 //          mainProxy.report();
277       if (thisIndex < majElements - 1)
278         {
279 //                      printf("DONE WITH index=%d and calling for ind=%d\n",thisIndex,thisIndex+1);
280 #ifdef PRIOR
281           opts = new CkEntryOptions ();
282           opts1 = new CkEntryOptions ();
283           opts->setPriority (-100);
284           opts1->setPriority (100);
285
286 //printf("-------- Jacobi[%d] sending message to next one at time=%f\n",thisIndex,CmiWallTimer());
287           thisProxy[thisIndex + 1].begin_iteration (1, opts);
288         for(int i=(thisIndex+1)*7;i<(thisIndex+1)*7+7;i++)
289                 minorProxy[i].begin_iteration(1,opts1);
290 #else
291           thisProxy[thisIndex + 1].begin_iteration (1);
292           for (int i = (thisIndex + 1) * 7; i < (thisIndex + 1) * 7 + 7; i++)
293             minorProxy[i].begin_iteration (1);
294 #endif
295         }
296       else
297         {
298 //                      printf("CAlling report Jacobi[%d] time=%f!!!!!!!!!!1\n",thisIndex,CmiWallTimer());
299
300 //        else
301 //          mainProxy.report ();
302         }
303         if (iterations % ldbTime == 4) AtSync();
304         else contribute(CkCallback(CkIndex_Main::report(NULL),mainProxy));
305   }
306
307   // Check to see if we have received all neighbor values yet
308   // If all neighbor values have been received, we update our values and proceed
309   void compute ()
310   {
311     // We must create a new array for these values because we don't want to update any of the
312     // the values in temperature[][] array until using them first. Other schemes could be used
313     // to accomplish this same problem. We just put the new values in a temporary array
314     // and write them to temperature[][] after all of the new values are computed.
315
316     for (int i = 1; i < MAJLOOP; ++i)
317       {
318         // update my value based on the surrounding values
319         int ind = i % 1000;
320         float x =
321           arr[ind] + arr[ind] + arr[ind + 1] + arr[ind + 2] + arr[ind + 3];
322       }
323
324     // Enforce the boundary conditions again
325
326   }
327
328
329
330   void ResumeFromSync ()
331   {
332 //      printf("Jacobi[%d] calling resumeSync\n",thisIndex);
333 //    if (thisIndex == 0)
334 //      mainProxy.report ();
335 //CkPrintf("Coming in MAJ MAJ MAJ RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR ++++++++\n");
336         contribute(CkCallback(CkIndex_Main::report(NULL),mainProxy));
337   }
338 };
339
340 class Minor:public CBase_Minor
341 {
342 public:
343 //    int messages_due;
344   int iterations;
345   float *arr;
346   int useLB;
347   // Constructor, initialize values
348     Minor (int x)
349   {
350     int i, j;
351       useLB = 1;
352       minElements = x;
353       arr = new float[1000];
354     for (int i = 0; i < 1000; i++)
355         arr[i] = rand ();
356       usesAtSync = CmiTrue;
357       iterations = 0;
358     // allocate two dimensional array
359   }
360
361   void pup (PUP::er & p)
362   {
363     CBase_Minor::pup (p);
364 //        p|messages_due;
365     p | iterations;
366     p | useLB;
367     if (p.isUnpacking ())
368       arr = new float[1000];
369     for (int i = 0; i < 1000; i++)
370       p | arr[i];
371 /* There may be some more variables used in doWork */
372   }
373
374
375   // a necessary function which we ignore now
376   // if we were to use load balancing and migration
377   // this function might become useful
378   Minor (CkMigrateMessage * m)
379   {
380   }
381
382   ~Minor ()
383   {
384     delete[]arr;
385   }
386
387   // Perform one iteration of work
388   // The first step is to send the local state to the neighbors
389   void begin_iteration (int i)
390   {
391 //printf("XXXXXXXXX Minor[%d] coming in begin_itertaion at time=%f\n",thisIndex,CmiWallTimer());
392     useLB = 1;
393     iterations++;
394
395
396     check_and_compute ();
397   }
398
399   void check_and_compute ()
400   {
401 //       if (--messages_due == 0) 
402
403 //          messages_due = 4;
404     compute ();
405     if (iterations % ldbTime == 4/* || iterations == 100*/)
406       {
407 //                        printf("MINOR[%d] itr=%d ----------------------------- ssssssssssssss\n",thisIndex,iterations);
408         AtSync ();
409       }
410
411     else
412 //      mainProxy.report ();
413         contribute(CkCallback(CkIndex_Main::report(NULL),mainProxy));
414
415
416   }
417
418   // Check to see if we have received all neighbor values yet
419   // If all neighbor values have been received, we update our values and proceed
420   void compute ()
421   {
422     // We must create a new array for these values because we don't want to update any of the
423     // the values in temperature[][] array until using them first. Other schemes could be used
424     // to accomplish this same problem. We just put the new values in a temporary array
425     // and write them to temperature[][] after all of the new values are computed.
426
427     for (int i = 1; i < MAJLOOP * .6; ++i)
428       {
429         // update my value based on the surrounding values
430         int ind = i % 1000;
431         float x =
432           arr[ind] + arr[ind] + arr[ind + 1] + arr[ind + 2] + arr[ind + 3];
433       }
434
435     // Enforce the boundary conditions again
436
437   }
438
439
440   void ResumeFromSync ()
441   {
442 //    mainProxy.report ();;
443 //      CkPrintf("Coming in MIN MIN MIN RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR \n");
444         contribute(CkCallback(CkIndex_Main::report(NULL),mainProxy));
445   }
446 };
447
448 #include "jacobi2d.def.h"