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