Solaris compilers did not know about INT_MAX, so I simply replaced using
[charm.git] / src / ck-ldb / GridCommLB.C
1 /**************************************************************************
2 ** Greg Koenig (koenig@uiuc.edu)
3 ** November 4, 2004
4 */
5 #include <stdio.h>
6
7 #include "charm++.h"
8 #include "cklists.h"
9
10 #include "GridCommLB.decl.h"
11
12 #include "GridCommLB.h"
13 #include "manager.h"
14
15
16 CreateLBFunc_Def (GridCommLB, "Load balancer for Grid computing environments");
17
18
19 /**************************************************************************
20 **
21 */
22 GridCommLB::GridCommLB (const CkLBOptions &opt) : CentralLB (opt)
23 {
24     lbname = (char *) "GridCommLB";
25
26     if (CkMyPe () == 0) {
27       CkPrintf ("[%d] GridCommLB created\n", CkMyPe ());
28     }
29
30     manager_init ();
31 }
32
33
34 /**************************************************************************
35 **
36 */
37 GridCommLB::GridCommLB (CkMigrateMessage *m) : CentralLB (m)
38 {
39   lbname = (char *) "GridCommLB";
40
41   manager_init ();
42 }
43
44
45 /**************************************************************************
46 **
47 */
48 CmiBool GridCommLB::QueryBalanceNow (int step)
49 {
50   // CkPrintf ("[%d] Balancing on step %d\n", CkMyPe (), step);
51   return (CmiTrue);
52 }
53
54
55 /**************************************************************************
56 **
57 */
58 int GridCommLB::Get_Cluster (int pe)
59 {
60   if (pe < (Num_PEs / 2)) {
61     return (0);
62   } else {
63     return (1);
64   }
65 }
66
67
68 /**************************************************************************
69 **
70 */
71 int GridCommLB::Find_Maximum_WAN_Object (int cluster)
72 {
73   int i;
74   int max_index;
75   int max_wan_msgs;
76
77
78   max_index    = -1;
79   max_wan_msgs = -1;
80
81   for (i = 0; i < Num_Objects; i++) {
82     if ((&Object_Data[i])->cluster == cluster) {
83       if ((&Object_Data[i])->to_pe == -1) {
84         if ((&Object_Data[i])->num_wan_msgs > max_wan_msgs) {
85           max_index = i;
86           max_wan_msgs = (&Object_Data[i])->num_wan_msgs;
87         }
88       }
89     }
90   }
91
92   return (max_index);
93 }
94
95
96 /**************************************************************************
97 **
98 */
99 int GridCommLB::Find_Minimum_WAN_PE (int cluster)
100 {
101   int i;
102   int min_index;
103   int min_wan_objs;
104   int min_lan_objs;
105
106
107   min_index = -1;
108   min_wan_objs = 999999999;
109   min_lan_objs = 999999999;
110
111   for (i = 0; i < Num_PEs; i++) {
112     if (((&PE_Data[i])->available) && ((&PE_Data[i])->cluster == cluster)) {
113       if ((&PE_Data[i])->num_wan_objs < min_wan_objs) {
114         min_index = i;
115         min_wan_objs = (&PE_Data[i])->num_wan_objs;
116         min_lan_objs = (&PE_Data[i])->num_lan_objs;
117       } else if ((&PE_Data[i])->num_wan_objs == min_wan_objs) {
118         if ((&PE_Data[i])->num_lan_objs < min_lan_objs) {
119           min_index = i;
120           min_lan_objs = (&PE_Data[i])->num_lan_objs;
121         }
122       }
123     }
124   }
125
126   return (min_index);
127 }
128
129
130 /**************************************************************************
131 **
132 */
133 void GridCommLB::Assign_Object_To_PE (int target_object, int target_pe)
134 {
135   (&Object_Data[target_object])->to_pe = target_pe;
136
137   (&PE_Data[target_pe])->num_objs++;
138
139   if ((&Object_Data[target_object])->num_lan_msgs > 0) {
140     (&PE_Data[target_pe])->num_lan_objs++;
141     (&PE_Data[target_pe])->num_lan_msgs +=
142         (&Object_Data[target_object])->num_lan_msgs;
143   }
144
145   if ((&Object_Data[target_object])->num_wan_msgs > 0) {
146     (&PE_Data[target_pe])->num_wan_objs++;
147     (&PE_Data[target_pe])->num_wan_msgs +=
148         (&Object_Data[target_object])->num_wan_msgs;
149   }
150 }
151
152
153 /**************************************************************************
154 **
155 */
156 void GridCommLB::work (CentralLB::LDStats *stats, int count)
157 {
158   int i;
159   int send_object;
160   int send_pe;
161   int send_cluster;
162   int recv_object;
163   int recv_pe;
164   int recv_cluster;
165   int target_object;
166   int target_pe;
167   LDCommData *com_data;
168
169
170   stats->makeCommHash ();
171
172   Num_PEs = count;
173   Num_Objects = stats->n_objs;
174
175   PE_Data = new PE_Data_T[Num_PEs];
176   Object_Data = new Object_Data_T[Num_Objects];
177
178   for (i = 0; i < Num_PEs; i++) {
179     (&PE_Data[i])->available    = stats->procs[i].available;
180     (&PE_Data[i])->cluster      = Get_Cluster (i);
181     (&PE_Data[i])->num_objs     = 0;
182     (&PE_Data[i])->num_lan_objs = 0;
183     (&PE_Data[i])->num_lan_msgs = 0;
184     (&PE_Data[i])->num_wan_objs = 0;
185     (&PE_Data[i])->num_wan_msgs = 0;
186   }
187
188   for (i = 0; i < Num_Objects; i++) {
189     (&Object_Data[i])->migratable   = (&stats->objData[i])->migratable;
190     (&Object_Data[i])->cluster      = Get_Cluster (stats->from_proc[i]);
191     (&Object_Data[i])->from_pe      = stats->from_proc[i];
192     (&Object_Data[i])->num_lan_msgs = 0;
193     (&Object_Data[i])->num_wan_msgs = 0;
194
195     if ((&Object_Data[i])->migratable) {
196       (&Object_Data[i])->to_pe = -1;
197     } else {
198       (&Object_Data[i])->to_pe = (&Object_Data[i])->from_pe;
199     }
200   }
201
202   for (i = 0; i < stats->n_comm; i++) {
203     com_data = &(stats->commData[i]);
204     if ((!com_data->from_proc()) && (com_data->recv_type() == LD_OBJ_MSG)) {
205       send_object = stats->getHash (com_data->sender);
206       recv_object = stats->getHash (com_data->receiver.get_destObj());
207
208       send_pe = (&Object_Data[send_object])->from_pe;
209       recv_pe = (&Object_Data[recv_object])->from_pe;
210
211       send_cluster = Get_Cluster (send_pe);
212       recv_cluster = Get_Cluster (recv_pe);
213
214       if (send_cluster == recv_cluster) {
215         (&Object_Data[send_object])->num_lan_msgs += com_data->messages;
216       } else {
217         (&Object_Data[send_object])->num_wan_msgs += com_data->messages;
218       }
219     }
220   }
221
222   // Map objects to PEs in cluster 0.
223   while (1) {
224     target_object = Find_Maximum_WAN_Object (0);
225     target_pe     = Find_Minimum_WAN_PE (0);
226
227     if ((target_object == -1) || (target_pe == -1)) {
228       break;
229     }
230
231     Assign_Object_To_PE (target_object, target_pe);
232   }
233
234   // Map objects to PEs in cluster 1.
235   while (1) {
236     target_object = Find_Maximum_WAN_Object (1);
237     target_pe     = Find_Minimum_WAN_PE (1);
238
239     if ((target_object == -1) || (target_pe == -1)) {
240       break;
241     }
242
243     Assign_Object_To_PE (target_object, target_pe);
244   }
245
246   // Make the assignment of objects to PEs in the load balancer framework.
247   for (i = 0; i < Num_Objects; i++) {
248     stats->to_proc[i] = (&Object_Data[i])->to_pe;
249   }
250 }
251
252
253 #include "GridCommLB.def.h"