00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "GridMetisLB.decl.h"
00010
00011 #include "GridMetisLB.h"
00012 #include "manager.h"
00013
00014 extern int quietModeRequested;
00015
00016 CreateLBFunc_Def (GridMetisLB, "Grid load balancer that uses Metis to optimize communication graph")
00017
00018
00019
00020
00021
00022
00023 GridMetisLB::GridMetisLB (const CkLBOptions &opt) : CBase_GridMetisLB (opt)
00024 {
00025 char *value;
00026
00027
00028 lbname = (char *) "GridMetisLB";
00029
00030 if (CkMyPe() == 0 && !quietModeRequested) {
00031 CkPrintf ("CharmLB> GridMetisLB created.\n");
00032 }
00033
00034 if ((value = getenv ("CK_LDB_GRIDMETISLB_MODE"))) {
00035 CK_LDB_GridMetisLB_Mode = atoi (value);
00036 } else {
00037 CK_LDB_GridMetisLB_Mode = CK_LDB_GRIDMETISLB_MODE;
00038 }
00039
00040 if ((value = getenv ("CK_LDB_GRIDMETISLB_BACKGROUND_LOAD"))) {
00041 CK_LDB_GridMetisLB_Background_Load = atoi (value);
00042 } else {
00043 CK_LDB_GridMetisLB_Background_Load = CK_LDB_GRIDMETISLB_BACKGROUND_LOAD;
00044 }
00045
00046 manager_init ();
00047 }
00048
00049
00050
00051
00052
00053
00054 GridMetisLB::GridMetisLB (CkMigrateMessage *msg) : CBase_GridMetisLB (msg)
00055 {
00056 char *value;
00057
00058
00059 lbname = (char *) "GridMetisLB";
00060
00061 if ((value = getenv ("CK_LDB_GRIDMETISLB_MODE"))) {
00062 CK_LDB_GridMetisLB_Mode = atoi (value);
00063 } else {
00064 CK_LDB_GridMetisLB_Mode = CK_LDB_GRIDMETISLB_MODE;
00065 }
00066
00067 if ((value = getenv ("CK_LDB_GRIDMETISLB_BACKGROUND_LOAD"))) {
00068 CK_LDB_GridMetisLB_Background_Load = atoi (value);
00069 } else {
00070 CK_LDB_GridMetisLB_Background_Load = CK_LDB_GRIDMETISLB_BACKGROUND_LOAD;
00071 }
00072
00073 manager_init ();
00074 }
00075
00076
00077
00078
00079
00080
00081
00082 bool GridMetisLB::QueryBalanceNow (int step)
00083 {
00084 if (_lb_args.debug() > 2) {
00085 CkPrintf ("[%d] GridMetisLB is balancing on step %d.\n", CkMyPe(), step);
00086 }
00087
00088 return (true);
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 int GridMetisLB::Get_Cluster (int pe)
00105 {
00106 return (0);
00107 }
00108
00109
00110
00111
00112
00113
00114 void GridMetisLB::Initialize_PE_Data (CentralLB::LDStats *stats)
00115 {
00116 int min_speed;
00117 int i;
00118
00119
00120 PE_Data = new PE_Data_T[Num_PEs];
00121
00122 min_speed = MAXINT;
00123 for (i = 0; i < Num_PEs; i++) {
00124 (&PE_Data[i])->available = stats->procs[i].available;
00125 (&PE_Data[i])->cluster = Get_Cluster (i);
00126 (&PE_Data[i])->num_objs = 0;
00127 (&PE_Data[i])->relative_speed = 0.0;
00128 (&PE_Data[i])->scaled_load = 0.0;
00129
00130 if (stats->procs[i].pe_speed < min_speed) {
00131 min_speed = stats->procs[i].pe_speed;
00132 }
00133 }
00134
00135
00136
00137 for (i = 0; i < Num_PEs; i++) {
00138 (&PE_Data[i])->relative_speed = (double) (stats->procs[i].pe_speed / min_speed);
00139 if (CK_LDB_GridMetisLB_Background_Load) {
00140 (&PE_Data[i])->scaled_load += stats->procs[i].bg_walltime;
00141 }
00142 }
00143 }
00144
00145
00146
00147
00148
00149
00150 int GridMetisLB::Available_PE_Count ()
00151 {
00152 int available_pe_count;
00153 int i;
00154
00155
00156 available_pe_count = 0;
00157 for (i = 0; i < Num_PEs; i++) {
00158 if ((&PE_Data[i])->available) {
00159 available_pe_count += 1;
00160 }
00161 }
00162 return (available_pe_count);
00163 }
00164
00165
00166
00167
00168
00169
00170 int GridMetisLB::Compute_Number_Of_Clusters ()
00171 {
00172 int max_cluster;
00173 int i;
00174
00175
00176 max_cluster = 0;
00177 for (i = 0; i < Num_PEs; i++) {
00178 if ((&PE_Data[i])->cluster < 0) {
00179 return (-1);
00180 }
00181
00182 if ((&PE_Data[i])->cluster > max_cluster) {
00183 max_cluster = (&PE_Data[i])->cluster;
00184 }
00185 }
00186 return (max_cluster + 1);
00187 }
00188
00189
00190
00191
00192
00193
00194 void GridMetisLB::Initialize_Object_Data (CentralLB::LDStats *stats)
00195 {
00196 int i;
00197
00198
00199 Object_Data = new Object_Data_T[Num_Objects];
00200
00201 for (i = 0; i < Num_Objects; i++) {
00202 (&Object_Data[i])->migratable = (&stats->objData[i])->migratable;
00203
00204 (&Object_Data[i])->cluster = -1;
00205 (&Object_Data[i])->from_pe = stats->from_proc[i];
00206 (&Object_Data[i])->load = (&stats->objData[i])->wallTime;
00207
00208 if ((&Object_Data[i])->migratable) {
00209 (&Object_Data[i])->to_pe = -1;
00210 } else {
00211 (&Object_Data[i])->to_pe = (&Object_Data[i])->from_pe;
00212
00213 (&PE_Data[(&Object_Data[i])->to_pe])->scaled_load += (&Object_Data[i])->load / (&PE_Data[(&Object_Data[i])->to_pe])->relative_speed;
00214 if (_lb_args.debug() > 1) {
00215 CkPrintf ("[%d] GridMetisLB identifies object %d as non-migratable.\n", CkMyPe(), i);
00216 }
00217 }
00218 }
00219 }
00220
00221
00222
00223
00224
00225
00226 void GridMetisLB::Initialize_Cluster_Data ()
00227 {
00228 int cluster;
00229 double min_total_cpu_power;
00230 int i;
00231
00232
00233 Cluster_Data = new Cluster_Data_T[Num_Clusters];
00234
00235 for (i = 0; i < Num_Clusters; i++) {
00236 (&Cluster_Data[i])->num_pes = 0;
00237 (&Cluster_Data[i])->total_cpu_power = 0.0;
00238 (&Cluster_Data[i])->scaled_cpu_power = 0.0;
00239 }
00240
00241
00242 for (i = 0; i < Num_PEs; i++) {
00243 cluster = (&PE_Data[i])->cluster;
00244
00245 (&Cluster_Data[cluster])->num_pes += 1;
00246 (&Cluster_Data[cluster])->total_cpu_power += (&PE_Data[i])->relative_speed;
00247 }
00248
00249 min_total_cpu_power = MAXDOUBLE;
00250 for (i = 0; i < Num_Clusters; i++) {
00251 if ((&Cluster_Data[i])->total_cpu_power < min_total_cpu_power) {
00252 min_total_cpu_power = (&Cluster_Data[i])->total_cpu_power;
00253 }
00254 }
00255
00256 for (i = 0; i < Num_Clusters; i++) {
00257 (&Cluster_Data[i])->scaled_cpu_power = (double) ((&Cluster_Data[i])->total_cpu_power / min_total_cpu_power);
00258 }
00259 }
00260
00261
00262
00263
00264
00265
00266 void GridMetisLB::Partition_Objects_Into_Clusters (CentralLB::LDStats *stats)
00267 {
00268 int num_migratable_objects;
00269 int *migratable_objects;
00270 int index;
00271 int num_partitions;
00272 int *partition_to_cluster_map;
00273 int cluster;
00274 int partition;
00275 int partition_count;
00276 int *vertex_weights;
00277 int vertex;
00278 int **communication_matrix;
00279 LDCommData *com_data;
00280 int send_object;
00281 int recv_object;
00282 int send_index;
00283 int recv_index;
00284 const LDObjKey *recv_objects;
00285 int num_objects;
00286 int *xadj;
00287 int num_edges;
00288 int *adjncy;
00289 int *edge_weights;
00290 int count;
00291 int weight_flag;
00292 int numbering_flag;
00293 int options[5];
00294 int edgecut;
00295 int *newmap;
00296 int i;
00297 int j;
00298
00299
00300 if (Num_Clusters == 1) {
00301 for (i = 0; i < Num_Objects; i++) {
00302 (&Object_Data[i])->cluster = 0;
00303 }
00304
00305 return;
00306 }
00307
00308 for (i = 0; i < Num_Objects; i++) {
00309 (&Object_Data[i])->secondary_index = -1;
00310 }
00311
00312
00313
00314
00315 num_migratable_objects = 0;
00316 for (i = 0; i < Num_Objects; i++) {
00317 if ((&Object_Data[i])->migratable) {
00318 num_migratable_objects += 1;
00319 }
00320 }
00321
00322 migratable_objects = new int[num_migratable_objects];
00323
00324 index = 0;
00325 for (i = 0; i < Num_Objects; i++) {
00326 if ((&Object_Data[i])->migratable) {
00327 (&Object_Data[i])->secondary_index = index;
00328 migratable_objects[index] = i;
00329 index += 1;
00330 }
00331 }
00332
00333
00334
00335 num_partitions = 0;
00336 for (i = 0; i < Num_Clusters; i++) {
00337 num_partitions += (int) ceil ((&Cluster_Data[i])->scaled_cpu_power);
00338 }
00339
00340 partition_to_cluster_map = new int[num_partitions];
00341
00342 cluster = 0;
00343 partition = 0;
00344 while (partition < num_partitions) {
00345 partition_count = (int) ceil ((&Cluster_Data[cluster])->scaled_cpu_power);
00346
00347 for (i = partition; i < (partition + partition_count); i++) {
00348 partition_to_cluster_map[i] = cluster;
00349 }
00350
00351 partition += partition_count;
00352 cluster += 1;
00353 }
00354
00355 if (CK_LDB_GridMetisLB_Mode == 1) {
00356 vertex_weights = new int[num_migratable_objects];
00357 vertex = 0;
00358 for (i = 0; i < Num_Objects; i++) {
00359 if ((&Object_Data[i])->migratable) {
00360 vertex_weights[vertex] = (int) ceil ((&Object_Data[i])->load * 10000);
00361 vertex += 1;
00362 }
00363 }
00364 }
00365
00366
00367 communication_matrix = new int *[num_migratable_objects];
00368 for (i = 0; i < num_migratable_objects; i++) {
00369 communication_matrix[i] = new int[num_migratable_objects];
00370 for (j = 0; j < num_migratable_objects; j++) {
00371 communication_matrix[i][j] = 0;
00372 }
00373 }
00374
00375 for (i = 0; i < stats->n_comm; i++) {
00376 com_data = &(stats->commData[i]);
00377 if ((!com_data->from_proc()) && (com_data->recv_type() == LD_OBJ_MSG)) {
00378 send_object = stats->getHash (com_data->sender);
00379 recv_object = stats->getHash (com_data->receiver.get_destObj());
00380
00381
00382 if ((send_object < 0) || (send_object > Num_Objects) || (recv_object < 0) || (recv_object > Num_Objects)) {
00383 continue;
00384 }
00385
00386 if ((!(&Object_Data[send_object])->migratable) || (!(&Object_Data[recv_object])->migratable)) {
00387 continue;
00388 }
00389
00390 send_index = (&Object_Data[send_object])->secondary_index;
00391 recv_index = (&Object_Data[recv_object])->secondary_index;
00392
00393 communication_matrix[send_index][recv_index] += com_data->messages;
00394 communication_matrix[recv_index][send_index] += com_data->messages;
00395 } else if (com_data->receiver.get_type() == LD_OBJLIST_MSG) {
00396 send_object = stats->getHash (com_data->sender);
00397
00398 if ((send_object < 0) || (send_object > Num_Objects)) {
00399 continue;
00400 }
00401
00402 if (!(&Object_Data[send_object])->migratable) {
00403 continue;
00404 }
00405
00406 recv_objects = com_data->receiver.get_destObjs (num_objects);
00407
00408 for (j = 0; j < num_objects; j++) {
00409 recv_object = stats->getHash (recv_objects[j]);
00410
00411
00412 if ((recv_object < 0) || (recv_object > Num_Objects)) {
00413 continue;
00414 }
00415
00416 if (!(&Object_Data[recv_object])->migratable) {
00417 continue;
00418 }
00419
00420 send_index = (&Object_Data[send_object])->secondary_index;
00421 recv_index = (&Object_Data[recv_object])->secondary_index;
00422
00423 communication_matrix[send_index][recv_index] += com_data->messages;
00424 communication_matrix[recv_index][send_index] += com_data->messages;
00425 }
00426 }
00427 }
00428
00429 for (i = 0; i < num_migratable_objects; i++) {
00430 communication_matrix[i][i] = 0;
00431 }
00432
00433
00434 xadj = new int[num_migratable_objects + 1];
00435 num_edges = 0;
00436 for (i = 0; i < num_migratable_objects; i++) {
00437 for (j = 0; j < num_migratable_objects; j++) {
00438 if (communication_matrix[i][j] > 0) {
00439 num_edges += 1;
00440 }
00441 }
00442 }
00443 adjncy = new int[num_edges];
00444 edge_weights = new int[num_edges];
00445 count = 0;
00446 xadj[0] = 0;
00447 for (i = 0; i < num_migratable_objects; i++) {
00448 for (j = 0; j < num_migratable_objects; j++) {
00449 if (communication_matrix[i][j] > 0) {
00450 adjncy[count] = j;
00451 edge_weights[count] = communication_matrix[i][j];
00452 count += 1;
00453 }
00454 }
00455 xadj[i+1] = count;
00456 }
00457
00458 if (CK_LDB_GridMetisLB_Mode == 0) {
00459
00460 weight_flag = 1;
00461 numbering_flag = 0;
00462 options[0] = 0;
00463 newmap = new int[num_migratable_objects];
00464
00465 METIS_PartGraphRecursive (&num_migratable_objects, xadj, adjncy, NULL, edge_weights, &weight_flag, &numbering_flag, &num_partitions, options, &edgecut, newmap);
00466 } else if (CK_LDB_GridMetisLB_Mode == 1) {
00467
00468 weight_flag = 3;
00469 numbering_flag = 0;
00470 options[0] = 0;
00471 newmap = new int[num_migratable_objects];
00472
00473 METIS_PartGraphRecursive (&num_migratable_objects, xadj, adjncy, vertex_weights, edge_weights, &weight_flag, &numbering_flag, &num_partitions, options, &edgecut, newmap);
00474 } else {
00475 if (_lb_args.debug() > 0) {
00476 CkPrintf ("[%d] GridMetisLB was told to use bad mode (%d).\n", CkMyPe(), CK_LDB_GridMetisLB_Mode);
00477 }
00478 }
00479
00480
00481 for (i = 0; i < num_migratable_objects; i++) {
00482 partition = newmap[i];
00483 cluster = partition_to_cluster_map[partition];
00484
00485 index = migratable_objects[i];
00486
00487 (&Object_Data[index])->cluster = cluster;
00488 }
00489
00490
00491 delete [] newmap;
00492 delete [] edge_weights;
00493 delete [] adjncy;
00494 delete [] xadj;
00495 for (i = 0; i < num_migratable_objects; i++) {
00496 delete [] communication_matrix[i];
00497 }
00498 delete [] communication_matrix;
00499 if (CK_LDB_GridMetisLB_Mode == 1) {
00500 delete [] vertex_weights;
00501 }
00502 delete [] partition_to_cluster_map;
00503 delete [] migratable_objects;
00504 }
00505
00506
00507
00508
00509
00510
00511 void GridMetisLB::Partition_ClusterObjects_Into_PEs (CentralLB::LDStats *stats, int cluster)
00512 {
00513 int num_migratable_cluster_objects;
00514 int *migratable_cluster_objects;
00515 int index;
00516 int num_available_cluster_pes;
00517 int num_partitions;
00518 int *partition_to_pe_map;
00519 int pe;
00520 int partition;
00521 int partition_count;
00522 int *vertex_weights;
00523 int vertex;
00524 int **communication_matrix;
00525 LDCommData *com_data;
00526 int send_object;
00527 int recv_object;
00528 int send_index;
00529 int recv_index;
00530 const LDObjKey *recv_objects;
00531 int num_objects;
00532 int *xadj;
00533 int num_edges;
00534 int *adjncy;
00535 int *edge_weights;
00536 int count;
00537 int weight_flag;
00538 int numbering_flag;
00539 int options[5];
00540 int edgecut;
00541 int *newmap;
00542 int i;
00543 int j;
00544
00545
00546 for (i = 0; i < Num_Objects; i++) {
00547 (&Object_Data[i])->secondary_index = -1;
00548 }
00549
00550
00551
00552
00553 num_migratable_cluster_objects = 0;
00554 for (i = 0; i < Num_Objects; i++) {
00555 if (((&Object_Data[i])->migratable) && ((&Object_Data[i])->cluster == cluster)) {
00556 num_migratable_cluster_objects += 1;
00557 }
00558 }
00559
00560 migratable_cluster_objects = new int[num_migratable_cluster_objects];
00561
00562 index = 0;
00563 for (i = 0; i < Num_Objects; i++) {
00564 if (((&Object_Data[i])->migratable) && ((&Object_Data[i])->cluster == cluster)) {
00565 (&Object_Data[i])->secondary_index = index;
00566 migratable_cluster_objects[index] = i;
00567 index += 1;
00568 }
00569 }
00570
00571
00572 num_available_cluster_pes = 0;
00573 for (i = 0; i < Num_PEs; i++) {
00574 if (((&PE_Data[i])->available) && ((&PE_Data[i])->cluster == cluster)) {
00575 num_available_cluster_pes += 1;
00576 }
00577 }
00578
00579
00580
00581 num_partitions = 0;
00582 for (i = 0; i < Num_PEs; i++) {
00583 if (((&PE_Data[i])->available) && ((&PE_Data[i])->cluster == cluster)) {
00584 num_partitions += (int) ceil ((&PE_Data[i])->relative_speed);
00585 }
00586 }
00587
00588 partition_to_pe_map = new int[num_partitions];
00589
00590 pe = 0;
00591 while (((!(&PE_Data[pe])->available) || ((&PE_Data[pe])->cluster != cluster)) && (pe < Num_PEs)) {
00592 pe += 1;
00593 }
00594 if (pe >= Num_PEs) {
00595 CmiAbort ("GridMetisLB: Error computing partition to PE map!\n");
00596 }
00597 partition = 0;
00598 while (partition < num_partitions) {
00599 partition_count = (int) ceil ((&PE_Data[pe])->relative_speed);
00600
00601 for (i = partition; i < (partition + partition_count); i++) {
00602 partition_to_pe_map[i] = pe;
00603 }
00604
00605 partition += partition_count;
00606
00607 pe += 1;
00608 while (((!(&PE_Data[pe])->available) || ((&PE_Data[pe])->cluster != cluster)) && (pe < Num_PEs)) {
00609 pe += 1;
00610 }
00611 if (pe > Num_PEs) {
00612 CmiAbort ("GridMetisLB: Error computing partition to PE map!\n");
00613 }
00614 }
00615
00616
00617 vertex_weights = new int[num_migratable_cluster_objects];
00618 vertex = 0;
00619 for (i = 0; i < Num_Objects; i++) {
00620 if ((&Object_Data[i])->migratable && ((&Object_Data[i])->cluster == cluster)) {
00621 vertex_weights[vertex] = (int) ceil ((&Object_Data[i])->load * 10000);
00622 vertex += 1;
00623 }
00624 }
00625
00626
00627 communication_matrix = new int *[num_migratable_cluster_objects];
00628 for (i = 0; i < num_migratable_cluster_objects; i++) {
00629 communication_matrix[i] = new int[num_migratable_cluster_objects];
00630 for (j = 0; j < num_migratable_cluster_objects; j++) {
00631 communication_matrix[i][j] = 0;
00632 }
00633 }
00634
00635 for (i = 0; i < stats->n_comm; i++) {
00636 com_data = &(stats->commData[i]);
00637 if ((!com_data->from_proc()) && (com_data->recv_type() == LD_OBJ_MSG)) {
00638 send_object = stats->getHash (com_data->sender);
00639 recv_object = stats->getHash (com_data->receiver.get_destObj());
00640
00641
00642 if ((send_object < 0) || (send_object > Num_Objects) || (recv_object < 0) || (recv_object > Num_Objects)) {
00643 continue;
00644 }
00645
00646 if ((!(&Object_Data[send_object])->migratable) || (!(&Object_Data[recv_object])->migratable)) {
00647 continue;
00648 }
00649
00650 if (((&Object_Data[send_object])->cluster != cluster) || ((&Object_Data[recv_object])->cluster != cluster)) {
00651 continue;
00652 }
00653
00654 send_index = (&Object_Data[send_object])->secondary_index;
00655 recv_index = (&Object_Data[recv_object])->secondary_index;
00656
00657 communication_matrix[send_index][recv_index] += com_data->messages;
00658 communication_matrix[recv_index][send_index] += com_data->messages;
00659 } else if (com_data->receiver.get_type() == LD_OBJLIST_MSG) {
00660 send_object = stats->getHash (com_data->sender);
00661
00662 if ((send_object < 0) || (send_object > Num_Objects)) {
00663 continue;
00664 }
00665
00666 if (!(&Object_Data[send_object])->migratable) {
00667 continue;
00668 }
00669
00670 if ((&Object_Data[send_object])->cluster != cluster) {
00671 continue;
00672 }
00673
00674 recv_objects = com_data->receiver.get_destObjs (num_objects);
00675
00676 for (j = 0; j < num_objects; j++) {
00677 recv_object = stats->getHash (recv_objects[j]);
00678
00679
00680 if ((recv_object < 0) || (recv_object > Num_Objects)) {
00681 continue;
00682 }
00683
00684 if (!(&Object_Data[recv_object])->migratable) {
00685 continue;
00686 }
00687
00688 if ((&Object_Data[recv_object])->cluster != cluster) {
00689 continue;
00690 }
00691
00692 send_index = (&Object_Data[send_object])->secondary_index;
00693 recv_index = (&Object_Data[recv_object])->secondary_index;
00694
00695 communication_matrix[send_index][recv_index] += com_data->messages;
00696 communication_matrix[recv_index][send_index] += com_data->messages;
00697 }
00698 }
00699 }
00700
00701 for (i = 0; i < num_migratable_cluster_objects; i++) {
00702 communication_matrix[i][i] = 0;
00703 }
00704
00705
00706 xadj = new int[num_migratable_cluster_objects + 1];
00707 num_edges = 0;
00708 for (i = 0; i < num_migratable_cluster_objects; i++) {
00709 for (j = 0; j < num_migratable_cluster_objects; j++) {
00710 if (communication_matrix[i][j] > 0) {
00711 num_edges += 1;
00712 }
00713 }
00714 }
00715 adjncy = new int[num_edges];
00716 edge_weights = new int[num_edges];
00717 count = 0;
00718 xadj[0] = 0;
00719 for (i = 0; i < num_migratable_cluster_objects; i++) {
00720 for (j = 0; j < num_migratable_cluster_objects; j++) {
00721 if (communication_matrix[i][j] > 0) {
00722 adjncy[count] = j;
00723 edge_weights[count] = communication_matrix[i][j];
00724 count += 1;
00725 }
00726 }
00727 xadj[i+1] = count;
00728 }
00729
00730
00731 weight_flag = 3;
00732 numbering_flag = 0;
00733 options[0] = 0;
00734 newmap = new int[num_migratable_cluster_objects];
00735
00736 CmiPrintf ("[%d] GridMetisLB is partitioning %d objects in cluster %d into %d partitions.\n", CmiMyPe(), num_migratable_cluster_objects, cluster, num_partitions);
00737
00738 METIS_PartGraphRecursive (&num_migratable_cluster_objects, xadj, adjncy, vertex_weights, edge_weights, &weight_flag, &numbering_flag, &num_partitions, options, &edgecut, newmap);
00739
00740
00741 for (i = 0; i < num_migratable_cluster_objects; i++) {
00742 partition = newmap[i];
00743 pe = partition_to_pe_map[partition];
00744
00745 index = migratable_cluster_objects[i];
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 (&Object_Data[index])->to_pe = pe;
00757 }
00758
00759
00760 delete [] newmap;
00761 delete [] edge_weights;
00762 delete [] adjncy;
00763 delete [] xadj;
00764 for (i = 0; i < num_migratable_cluster_objects; i++) {
00765 delete [] communication_matrix[i];
00766 }
00767 delete [] communication_matrix;
00768 delete [] vertex_weights;
00769 delete [] partition_to_pe_map;
00770 delete [] migratable_cluster_objects;
00771 }
00772
00773
00774
00775
00776
00777
00778
00779 void GridMetisLB::work (LDStats *stats)
00780 {
00781 int i;
00782
00783
00784 if (_lb_args.debug() > 0) {
00785 CkPrintf ("[%d] GridMetisLB is working (mode=%d, background load=%d).\n", CkMyPe(), CK_LDB_GridMetisLB_Mode, CK_LDB_GridMetisLB_Background_Load);
00786 }
00787
00788
00789 stats->makeCommHash ();
00790
00791
00792 Num_PEs = stats->nprocs();
00793 Num_Objects = stats->n_objs;
00794
00795 if (_lb_args.debug() > 0) {
00796 CkPrintf ("[%d] GridMetisLB is examining %d PEs and %d objects.\n", CkMyPe(), Num_PEs, Num_Objects);
00797 }
00798
00799
00800 Initialize_PE_Data (stats);
00801
00802
00803 if (Available_PE_Count() < 1) {
00804 if (_lb_args.debug() > 0) {
00805 CkPrintf ("[%d] GridMetisLB finds no available PEs -- no balancing done.\n", CkMyPe());
00806 }
00807
00808 delete [] PE_Data;
00809
00810 return;
00811 }
00812
00813
00814
00815 Num_Clusters = Compute_Number_Of_Clusters ();
00816 if (Num_Clusters < 1) {
00817 if (_lb_args.debug() > 0) {
00818 CkPrintf ("[%d] GridMetisLB finds incomplete PE cluster map -- no balancing done.\n", CkMyPe());
00819 }
00820
00821 delete [] PE_Data;
00822
00823 return;
00824 }
00825
00826 if (_lb_args.debug() > 0) {
00827 CkPrintf ("[%d] GridMetisLB finds %d clusters.\n", CkMyPe(), Num_Clusters);
00828 }
00829
00830
00831 Initialize_Object_Data (stats);
00832
00833
00834 Initialize_Cluster_Data ();
00835
00836 Partition_Objects_Into_Clusters (stats);
00837 for (i = 0; i < Num_Clusters; i++) {
00838 Partition_ClusterObjects_Into_PEs (stats, i);
00839 }
00840
00841
00842 for (i = 0; i < Num_Objects; i++) {
00843 stats->to_proc[i] = (&Object_Data[i])->to_pe;
00844
00845 if (_lb_args.debug() > 2) {
00846 CkPrintf ("[%d] GridMetisLB migrates object %d from PE %d to PE %d.\n", CkMyPe(), i, stats->from_proc[i], stats->to_proc[i]);
00847 } else if (_lb_args.debug() > 1) {
00848 if (stats->to_proc[i] != stats->from_proc[i]) {
00849 CkPrintf ("[%d] GridMetisLB migrates object %d from PE %d to PE %d.\n", CkMyPe(), i, stats->from_proc[i], stats->to_proc[i]);
00850 }
00851 }
00852 }
00853
00854
00855 delete [] Cluster_Data;
00856 delete [] Object_Data;
00857 delete [] PE_Data;
00858 }
00859
00860 #include "GridMetisLB.def.h"