A new imbalanced benchmark program that mimics Fractography3d.
[charm.git] / examples / charm++ / imbalanced / LB_Bench.C
1 #include "LB_Bench.decl.h"
2
3 // See README for documentation
4
5 /*readonly*/ CProxy_Main mainProxy;
6 /*readonly*/ int num_chare_rows;
7 /*readonly*/ int num_chare_cols;
8
9 // We want to wrap entries around, and because mod operator % sometimes misbehaves on negative values, 
10 // I just wrote these simple wrappers that will make the mod work as expected. -1 maps to the highest value.
11 #define wrap_x(a)  (((a)+num_chare_cols)%num_chare_cols)
12 #define wrap_y(a)  (((a)+num_chare_rows)%num_chare_rows)
13
14 CkArrayID a;
15
16 #define total_iterations 100
17
18 class Main : public CBase_Main
19 {
20 public:
21   int done_count;
22   CProxy_LB_Bench array;
23   int num_chares;
24
25   Main(CkArgMsg* m) {
26         if (m->argc < 2) {
27           CkPrintf("%s [number chares per dimension]\n", m->argv[0]);
28           CkAbort("Abort");
29         }
30
31         // store the main proxy
32         mainProxy = thisProxy;
33
34         num_chare_rows = atoi(m->argv[1]);
35         num_chare_cols = atoi(m->argv[1]);
36
37         // print info
38         CkPrintf("Running on %d processors with a %d x %d chare array\n", CkNumPes(), num_chare_rows, num_chare_cols);
39
40         // Create new array of worker chares
41         array = CProxy_LB_Bench::ckNew(num_chare_cols, num_chare_rows);
42
43         // save the total number of worker chares we have in this simulation
44         num_chares = num_chare_rows*num_chare_cols;
45
46         //Start the computation
47         done_count = 0;
48         array.do_iteration();
49   }
50
51   // Each worker reports back to here when it completes an iteration
52   void report_done() {
53         done_count++;
54         if (num_chares == done_count) {
55           CkPrintf("Done\n");
56           CkExit();
57         }
58   }
59
60 };
61
62 class LB_Bench: public CBase_LB_Bench {
63 public:
64   int messages_due;
65   double **temperature;
66   int iterations;
67   int received_right, received_left, received_up, received_down;
68
69   // Constructor
70   LB_Bench() {
71         iterations=0;
72         received_right=0;
73         received_left=0;
74         received_up=0;
75         received_down=0;
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 do_iteration(void) {
87           
88         thisProxy(wrap_x(thisIndex.x-1), thisIndex.y).fromRight();
89         thisProxy(wrap_x(thisIndex.x+1), thisIndex.y).fromLeft();
90         thisProxy(thisIndex.x, wrap_y(thisIndex.y-1)).fromDown();
91         thisProxy(thisIndex.x, wrap_y(thisIndex.y+1)).fromUp();
92
93   }
94
95   void fromRight() {
96         received_right ++;
97         check_and_compute();
98   }
99
100   void fromLeft() {
101         received_left ++;
102         check_and_compute();
103   }
104
105   void fromDown() {
106         received_down ++;
107         check_and_compute();
108   }
109
110   void fromUp() {
111         received_up ++;
112         check_and_compute();
113   }
114
115   void check_and_compute() {
116         if(received_right>0 && received_left>0 && received_up>0 && received_down>0) {
117
118           received_right --;
119           received_left --;
120           received_down --;
121           received_up --;
122
123           if(iterations < total_iterations){
124                 iterations++;
125                 compute();
126                 do_iteration();
127           } else {
128                 mainProxy.report_done();
129           }
130
131         }
132   }
133
134
135   void compute() {
136         double work_factor = 0.3;
137
138         //      CkPrintf("my x index is %d of %d, iteration=%d\n", thisIndex.x, num_chare_cols, iterations);
139         if(thisIndex.y == num_chare_cols / 2){
140           const double start_activate=0.1*(double)total_iterations;
141           const double end_activate=0.7*(double)total_iterations;
142           double fraction_activated;
143
144           if(iterations < start_activate)
145                 fraction_activated = 0.0;
146           else if(iterations > end_activate)
147                 fraction_activated = 1.0;
148           else
149                 fraction_activated = ((double)iterations-start_activate) / (end_activate-start_activate); 
150
151           if( ((double)thisIndex.x / ((double)num_chare_cols-1.0)) <= fraction_activated)
152                 work_factor += 0.7;
153
154           //      CkPrintf("x index %d has work_factor %f at iteration %d\n", thisIndex.x, work_factor, iterations);
155         }
156
157         double a[2000], b[2000], c[2000];
158         for(int j=0;j<100*work_factor;j++){
159           for(int i=0;i<2000;i++){
160                 a[i] = 7.0;
161                 b[i] = 5.0;
162           }
163           for(int i=0;i<2000/2;i++){
164                 c[i] = a[2*i]*b[2*i+1]*a[i];
165                 c[2*i] = a[2*i];
166           }
167         }
168   }
169  
170
171 };
172
173 #include "LB_Bench.def.h"