Adding anew load imbalanced benchmark
[charm.git] / examples / charm++ / imbalanced / LB_Bench.C
1 #include "LB_Bench.decl.h"
2 #include "charm++.h"
3
4 // See README for documentation
5
6 /*readonly*/ CProxy_Main mainProxy;
7 /*readonly*/ int num_chare_rows;
8 /*readonly*/ int num_chare_cols;
9
10 // We want to wrap entries around, and because mod operator % sometimes misbehaves on negative values, 
11 // I just wrote these simple wrappers that will make the mod work as expected. -1 maps to the highest value.
12 #define wrap_x(a)  (((a)+num_chare_cols)%num_chare_cols)
13 #define wrap_y(a)  (((a)+num_chare_rows)%num_chare_rows)
14
15 CkArrayID a;
16
17 #define total_iterations 200
18
19 class Main : public CBase_Main
20 {
21 public:
22   int done_count;
23   CProxy_LB_Bench array;
24   int num_chares;
25
26   Main(CkArgMsg* m) {
27         if (m->argc < 2) {
28           CkPrintf("%s [number chares per dimension]\n", m->argv[0]);
29           CkAbort("Abort");
30         }
31
32         // store the main proxy
33         mainProxy = thisProxy;
34
35         num_chare_rows = atoi(m->argv[1]);
36         num_chare_cols = atoi(m->argv[1]);
37
38         // print info
39         CkPrintf("Running on %d processors with a %d x %d chare array\n", CkNumPes(), num_chare_rows, num_chare_cols);
40
41         // Create new array of worker chares
42         array = CProxy_LB_Bench::ckNew(num_chare_cols, num_chare_rows);
43
44         // save the total number of worker chares we have in this simulation
45         num_chares = num_chare_rows*num_chare_cols;
46
47         //Start the computation
48         done_count = 0;
49         array.startup();
50   }
51
52   // Each worker reports back to here when it completes an iteration
53   void report_done() {
54         done_count++;
55         if (num_chares == done_count) {
56           CkPrintf("Done\n");
57           CkExit();
58         }
59   }
60
61 };
62
63 class LB_Bench: public CBase_LB_Bench {
64 public:
65   int iterations;
66   int received_right, received_left, received_up, received_down;
67
68   // Constructor
69   LB_Bench() : iterations(0), received_right(0), received_down(0), received_up(0), received_left(0) {
70         /*      iterations=0;
71           received_right=0;
72           received_left=0;
73           received_up=0;
74           received_down=0;
75         */
76   }
77
78   // For migration
79   LB_Bench(CkMigrateMessage* m) {}
80
81   // Destructor
82   ~LB_Bench() { }
83
84   // Perform one iteration of work
85   // The first step is to send the local state to the neighbors
86   void startup(void) {
87         next_iter();
88   }
89
90   void next_iter(){
91         thisProxy(wrap_x(thisIndex.x-1), thisIndex.y).fromRight();
92         thisProxy(wrap_x(thisIndex.x+1), thisIndex.y).fromLeft();
93         thisProxy(thisIndex.x, wrap_y(thisIndex.y-1)).fromDown();
94         thisProxy(thisIndex.x, wrap_y(thisIndex.y+1)).fromUp();
95
96         if(iterations % 10 ==5 &&  usesAtSync==CmiTrue )
97           AtSync();
98
99
100   }
101
102   void fromRight() {
103         received_right ++;
104         //      CkPrintf("%d,%d R=%d L=%d D=%d U=%d\n", thisIndex.x, thisIndex.y, received_right, received_left, received_down, received_up);
105         //      CkAssert(received_right <= 2);
106         check_and_compute();
107   }
108
109   void fromLeft() {
110         received_left ++;
111         //      CkPrintf("%d,%d R=%d L=%d D=%d U=%d\n", thisIndex.x, thisIndex.y, received_right, received_left, received_down, received_up);
112         //      CkAssert(received_left <= 2);
113         check_and_compute();
114   }
115
116   void fromDown() {
117         received_down ++;
118         //      CkPrintf("%d,%d R=%d L=%d D=%d U=%d\n", thisIndex.x, thisIndex.y, received_right, received_left, received_down, received_up);
119         //CkAssert(received_down <= 2);
120         check_and_compute();
121   }
122
123   void fromUp() {
124         received_up ++;
125         //      CkPrintf("%d,%d R=%d L=%d D=%d U=%d\n", thisIndex.x, thisIndex.y, received_right, received_left, received_down, received_up);
126         //      CkAssert(received_up <= 2);
127         check_and_compute();
128   }
129
130   void check_and_compute() {
131         if(received_right>0 && received_left>0 && received_up>0 && received_down>0) {
132           //CkPrintf("%d,%d ====================== \n", thisIndex.x, thisIndex.y);
133
134           received_right --;
135           received_left --;
136           received_down --;
137           received_up --;
138           
139           //      CkPrintf("%d,%d R=%d L=%d D=%d U=%d\n", thisIndex.x, thisIndex.y, received_right, received_left, received_down, received_up);
140
141           if(iterations < total_iterations){
142                 iterations++;
143                 thisProxy(thisIndex.x,thisIndex.y).compute();
144           } else {
145                 mainProxy.report_done();
146           }
147
148         }
149   }
150
151
152   void compute() {
153         double work_factor = 1.0;
154
155         //      CkPrintf("my x index is %d of %d, iteration=%d\n", thisIndex.x, num_chare_cols, iterations);
156         if(thisIndex.x >= num_chare_cols*0.40 && thisIndex.x <= num_chare_cols*0.60){
157           const double start_activate=0.4*(double)total_iterations;
158           const double end_activate=0.7*(double)total_iterations;
159           double fraction_activated;
160
161           if(iterations < start_activate)
162                 fraction_activated = 0.0;
163           else if(iterations > end_activate)
164                 fraction_activated = 1.0;
165           else
166                 fraction_activated = ((double)iterations-start_activate) / (end_activate-start_activate); 
167
168           if( ((double)thisIndex.y / ((double)num_chare_rows-1.0)) <= fraction_activated)
169                 work_factor += num_chare_rows*2.0;
170           //      CkPrintf("x index %d has work_factor %f at iteration %d\n", thisIndex.x, work_factor, iterations);
171         }
172
173         double a[2000], b[2000], c[2000];
174         for(int j=0;j<100*work_factor;j++){
175           for(int i=0;i<2000;i++){
176                 a[i] = 7.0;
177                 b[i] = 5.0;
178           }
179           for(int i=0;i<2000/2;i++){
180                 c[i] = a[2*i]*b[2*i+1]*a[i];
181                 c[2*i] = a[2*i];
182           }
183         }
184
185         next_iter();
186   }
187  
188
189
190   void ResumeFromSync(void) { //Called by Load-balancing framework
191         // CkPrintf("Element %d,%d resumeFromSync on PE %d\n",thisIndex.x, thisIndex.y, CkMyPe());
192   }
193
194
195   virtual void pup(PUP::er &p)
196   {
197         p | iterations;
198     p | received_right;
199         p | received_left;
200         p | received_up;
201         p | received_down;
202   }
203
204
205
206
207 };
208
209 #include "LB_Bench.def.h"