These changes fix things that I have discovered about Grid load balancing.
authorGreg Koenig <koenig@uiuc.edu>
Sun, 22 Oct 2006 01:09:06 +0000 (01:09 +0000)
committerGreg Koenig <koenig@uiuc.edu>
Sun, 22 Oct 2006 01:09:06 +0000 (01:09 +0000)
First, criteria for balancing is on number of messages, not number of objects.
Second, secondary criteria for balancing (scaled CPU load) is done better.
Projections results show that what I was doing before wasn't exactly right.

src/ck-ldb/GridCommLB.C
src/ck-ldb/GridCommLB.h
src/ck-ldb/GridCommRefineLB.C
src/ck-ldb/GridCommRefineLB.h
src/ck-ldb/GridMetisLB.C
src/ck-ldb/GridMetisLB.h

index 55173bd67efd5e43b004527b0cece2cffb9aa5f0..3999e1001afd2198a5f43fddae7ce4211cae4d6a 100644 (file)
@@ -81,7 +81,7 @@ GridCommLB::GridCommLB (CkMigrateMessage *msg) : CentralLB (msg)
 */
 CmiBool GridCommLB::QueryBalanceNow (int step)
 {
-  if (_lb_args.debug() >= 1) {
+  if (_lb_args.debug() > 2) {
     CkPrintf ("[%d] GridCommLB is balancing on step %d.\n", CkMyPe(), step);
   }
 
@@ -112,6 +112,233 @@ int GridCommLB::Get_Cluster (int pe)
 
 
 
+/**************************************************************************
+** Instantiate and initialize the PE_Data[] data structure.
+**
+** While doing this...
+**    - ensure that there is at least one available PE
+**    - ensure that all PEs are mapped to a cluster
+**    - determine the maximum cluster number (gives the number of clusters)
+**    - determine the minimum speed PE (used to compute relative PE speeds)
+*/
+void GridCommLB::Initialize_PE_Data (CentralLB::LDStats *stats)
+{
+  int min_speed;
+  int i;
+
+
+  PE_Data = new PE_Data_T[Num_PEs];
+
+  min_speed = MAXINT;
+  for (i = 0; i < Num_PEs; i++) {
+    (&PE_Data[i])->available      = stats->procs[i].available;
+    (&PE_Data[i])->cluster        = Get_Cluster (i);
+    (&PE_Data[i])->num_objs       = 0;
+    (&PE_Data[i])->num_lan_objs   = 0;
+    (&PE_Data[i])->num_lan_msgs   = 0;
+    (&PE_Data[i])->num_wan_objs   = 0;
+    (&PE_Data[i])->num_wan_msgs   = 0;
+    (&PE_Data[i])->relative_speed = 0.0;
+    (&PE_Data[i])->scaled_load    = 0.0;
+
+    if (stats->procs[i].pe_speed < min_speed) {
+      min_speed = stats->procs[i].pe_speed;
+    }
+  }
+
+  // Compute the relative PE speeds.
+  // Also add background CPU time to each PE's scaled load.
+  for (i = 0; i < Num_PEs; i++) {
+    (&PE_Data[i])->relative_speed = (double) (stats->procs[i].pe_speed / min_speed);
+    (&PE_Data[i])->scaled_load += stats->procs[i].bg_cputime;
+  }
+}
+
+
+
+/**************************************************************************
+**
+*/
+int GridMetisLB::Available_PE_Count ()
+{
+  int available_pe_count;
+  int i;
+
+
+  available_pe_count = 0;
+  for (i = 0; i < Num_PEs; i++) {
+    if ((&PE_Data[i])->available) {
+      available_pe_count += 1;
+    }
+  }
+  return (available_pe_count);
+}
+
+
+
+/**************************************************************************
+**
+*/
+int GridMetisLB::Compute_Number_Of_Clusters ()
+{
+  int max_cluster;
+  int i;
+
+
+  max_cluster = 0;
+  for (i = 0; i < Num_PEs; i++) {
+    if ((&PE_Data[i])->cluster < 0) {
+      return (-1);
+    }
+
+    if ((&PE_Data[i])->cluster > max_cluster) {
+      max_cluster = (&PE_Data[i])->cluster;
+    }
+  }
+  return (max_cluster + 1);
+}
+
+
+
+/**************************************************************************
+**
+*/
+void GridCommLB::Initialize_Object_Data (CentralLB::LDStats *stats)
+{
+  int i;
+
+
+  Object_Data = new Object_Data_T[Num_Objects];
+
+  for (i = 0; i < Num_Objects; i++) {
+    (&Object_Data[i])->migratable   = (&stats->objData[i])->migratable;
+    (&Object_Data[i])->cluster      = Get_Cluster (stats->from_proc[i]);
+    (&Object_Data[i])->from_pe      = stats->from_proc[i];
+    (&Object_Data[i])->to_pe        = -1;
+    (&Object_Data[i])->num_lan_msgs = 0;
+    (&Object_Data[i])->num_wan_msgs = 0;
+    (&Object_Data[i])->load         = (&stats->objData[i])->wallTime;
+  }
+}
+
+
+
+/**************************************************************************
+**
+*/
+void GridCommLB::Examine_InterObject_Messages (CentralLB::LDStats *stats)
+{
+  int i;
+  LDCommData *com_data;
+  int send_object;
+  int send_pe;
+  int send_cluster;
+  int recv_object;
+  int recv_pe;
+  int recv_cluster;
+  LDObjKey *recv_objects;
+  int num_objects;
+
+
+  for (i = 0; i < stats->n_comm; i++) {
+    com_data = &(stats->commData[i]);
+    if ((!com_data->from_proc()) && (com_data->recv_type() == LD_OBJ_MSG)) {
+      send_object = stats->getHash (com_data->sender);
+      recv_object = stats->getHash (com_data->receiver.get_destObj());
+
+      if ((send_object < 0) || (send_object > Num_Objects) || (recv_object < 0) || (recv_object > Num_Objects)) {
+        continue;
+      }
+
+      send_pe = (&Object_Data[send_object])->from_pe;
+      recv_pe = (&Object_Data[recv_object])->from_pe;
+
+      send_cluster = Get_Cluster (send_pe);
+      recv_cluster = Get_Cluster (recv_pe);
+
+      if (send_cluster == recv_cluster) {
+       (&Object_Data[send_object])->num_lan_msgs += com_data->messages;
+      } else {
+       (&Object_Data[send_object])->num_wan_msgs += com_data->messages;
+      }
+    } else if (com_data->receiver.get_type() == LD_OBJLIST_MSG) {
+      send_object = stats->getHash (com_data->sender);
+
+      if ((send_object < 0) || (send_object > Num_Objects)) {
+        continue;
+      }
+
+      send_pe = (&Object_Data[send_object])->from_pe;
+      send_cluster = Get_Cluster (send_pe);
+
+      recv_objects = com_data->receiver.get_destObjs (num_objects);   // (num_objects is passed by reference)
+
+      for (j = 0; j < num_objects; j++) {
+       recv_object = stats->getHash (recv_objects[j]);
+
+        if ((recv_object < 0) || (recv_object > Num_Objects)) {
+          continue;
+        }
+
+       recv_pe = (&Object_Data[recv_object])->from_pe;
+       recv_cluster = Get_Cluster (recv_pe);
+
+       if (send_cluster == recv_cluster) {
+         (&Object_Data[send_object])->num_lan_msgs += com_data->messages;
+       } else {
+         (&Object_Data[send_object])->num_wan_msgs += com_data->messages;
+       }
+      }
+    }
+  }
+}
+
+
+
+/**************************************************************************
+**
+*/
+void GridCommLB::Map_NonMigratable_Objects_To_PEs ()
+{
+  int i;
+
+
+  for (i = 0; i < Num_Objects; i++) {
+    if (!((&Object_Data[i])->migratable)) {
+      if (_lb_args.debug() > 1) {
+       CkPrintf ("[%d] GridCommLB identifies object %d as non-migratable.\n", CkMyPe(), i);
+      }
+
+      Assign_Object_To_PE (i, (&Object_Data[i])->from_pe);
+    }
+  }
+}
+
+
+
+/**************************************************************************
+**
+*/
+void GridCommLB::Map_Migratable_Objects_To_PEs (int cluster)
+{
+  int target_object;
+  int target_pe;
+
+
+  while (1) {
+    target_object = Find_Maximum_WAN_Object (cluster);
+    target_pe = Find_Minimum_WAN_PE (cluster);
+
+    if ((target_object == -1) || (target_pe == -1)) {
+      break;
+    }
+
+    Assign_Object_To_PE (target_object, target_pe);
+  }
+}
+
+
+
 /**************************************************************************
 ** This method locates the maximum WAN object in terms of number of
 ** messages that traverse a wide-area connection.  The search is
@@ -162,13 +389,42 @@ int GridCommLB::Find_Maximum_WAN_Object (int cluster)
 */
 int GridCommLB::Find_Minimum_WAN_PE (int cluster)
 {
+  int i;
+  int min_index;
+  int min_wan_msgs;
+
+
+  min_index = -1;
+  min_wan_msgs = MAXINT;
+
+  for (i = 0; i < Num_PEs; i++) {
+    if (((&PE_Data[i])->available) && ((&PE_Data[i])->cluster == cluster)) {
+      if ((&PE_Data[i])->num_wan_msgs < min_wan_msgs) {
+       min_index = i;
+       min_wan_msgs = (&PE_Data[i])->num_wan_msgs;
+      } else if (((&PE_Data[i])->num_wan_msgs == min_wan_msgs) &&
+                ((&PE_Data[i])->scaled_load < (&PE_Data[min_index])->scaled_load)) {
+       min_index = i;
+       min_wan_msgs = (&PE_Data[i])->num_wan_msgs;
+      } else if (((&PE_Data[i])->num_wan_msgs == min_wan_msgs) &&
+                ((&PE_Data[i])->scaled_load == (&PE_Data[min_index])->scaled_load) &&
+                ((&PE_Data[i])->num_objs < (&PE_Data[min_index])->num_objs)) {
+       min_index = i;
+       min_wan_msgs = (&PE_Data[i])->num_wan_msgs;
+      }
+    }
+  }
+
+  return (min_index);
+
+/*
   int i;
   int min_index;
   int min_wan_objs;
 
 
   min_index = -1;
-  min_wan_objs = INT_MAX;
+  min_wan_objs = MAXINT;
 
   for (i = 0; i < Num_PEs; i++) {
     if (((&PE_Data[i])->available) && ((&PE_Data[i])->cluster == cluster)) {
@@ -189,6 +445,7 @@ int GridCommLB::Find_Minimum_WAN_PE (int cluster)
   }
 
   return (min_index);
+*/
 }
 
 
@@ -227,23 +484,23 @@ void GridCommLB::Assign_Object_To_PE (int target_object, int target_pe)
 void GridCommLB::work (CentralLB::LDStats *stats, int count)
 {
   int i;
-  CmiBool available;
-  CmiBool all_pes_mapped;
-  int max_cluster;
-  int min_speed;
-  int send_object;
-  int send_pe;
-  int send_cluster;
-  int recv_object;
-  int recv_pe;
-  int recv_cluster;
-  int target_object;
-  int target_pe;
-  LDCommData *com_data;
-
-
-  if (_lb_args.debug() >= 1) {
-    CkPrintf ("[%d] GridCommLB is working...\n", CkMyPe());
+  // CmiBool available;
+  // CmiBool all_pes_mapped;
+  // int max_cluster;
+  // int min_speed;
+  // int send_object;
+  // int send_pe;
+  // int send_cluster;
+  // int recv_object;
+  // int recv_pe;
+  // int recv_cluster;
+  // int target_object;
+  // int target_pe;
+  // LDCommData *com_data;
+
+
+  if (_lb_args.debug() > 0) {
+    CkPrintf ("[%d] GridCommLB is working.\n", CkMyPe());
   }
 
   // Since this load balancer looks at communications data, it must initialize the CommHash.
@@ -253,51 +510,16 @@ void GridCommLB::work (CentralLB::LDStats *stats, int count)
   Num_PEs = count;
   Num_Objects = stats->n_objs;
 
-  if (_lb_args.debug() >= 1) {
+  if (_lb_args.debug() > 0) {
     CkPrintf ("[%d] GridCommLB is examining %d PEs and %d objects.\n", CkMyPe(), Num_PEs, Num_Objects);
   }
 
-  // Instantiate and initialize the PE_Data[] data structure.
-  //
-  // While doing this...
-  //    - ensure that there is at least one available PE
-  //    - ensure that all PEs are mapped to a cluster
-  //    - determine the maximum cluster number (gives the number of clusters)
-  //    - determine the minimum speed PE (used to compute relative PE speeds)
-  PE_Data = new PE_Data_T[Num_PEs];
-
-  available = CmiFalse;
-  all_pes_mapped = CmiTrue;
-  max_cluster = -1;
-  min_speed = INT_MAX;
-
-  for (i = 0; i < Num_PEs; i++) {
-    (&PE_Data[i])->available      = stats->procs[i].available;
-    (&PE_Data[i])->cluster        = Get_Cluster (i);
-    (&PE_Data[i])->num_objs       = 0;
-    (&PE_Data[i])->num_lan_objs   = 0;
-    (&PE_Data[i])->num_lan_msgs   = 0;
-    (&PE_Data[i])->num_wan_objs   = 0;
-    (&PE_Data[i])->num_wan_msgs   = 0;
-    (&PE_Data[i])->relative_speed = 0.0;
-    (&PE_Data[i])->scaled_load    = 0.0;
-
-    available |= (&PE_Data[i])->available;
-
-    all_pes_mapped &= ((&PE_Data[i])->cluster >= 0);
-
-    if ((&PE_Data[i])->cluster > max_cluster) {
-      max_cluster = (&PE_Data[i])->cluster;
-    }
-
-    if (stats->procs[i].pe_speed < min_speed) {
-      min_speed = stats->procs[i].pe_speed;
-    }
-  }
+  // Initialize the PE_Data[] data structure.
+  Initialize_PE_Data (stats);
 
   // If at least one available PE does not exist, return from load balancing.
-  if (!available) {
-    if (_lb_args.debug() >= 1) {
+  if (Available_PE_Count() < 1) {
+    if (_lb_args.debug() > 0) {
       CkPrintf ("[%d] GridCommLB finds no available PEs -- no balancing done.\n", CkMyPe());
     }
 
@@ -306,9 +528,11 @@ void GridCommLB::work (CentralLB::LDStats *stats, int count)
     return;
   }
 
-  // If not all PEs are mapped to a cluster, return from load balancing.
-  if (!all_pes_mapped) {
-    if (_lb_args.debug() >= 1) {
+  // Determine the number of clusters.
+  // If any PE is not mapped to a cluster, return from load balancing.
+  Num_Clusters = Compute_Number_Of_Clusters ();
+  if (Num_Clusters < 1) {
+    if (_lb_args.debug() > 0) {
       CkPrintf ("[%d] GridCommLB finds incomplete PE cluster map -- no balancing done.\n", CkMyPe());
     }
 
@@ -317,87 +541,31 @@ void GridCommLB::work (CentralLB::LDStats *stats, int count)
     return;
   }
 
-  // The number of clusters is equal to the maximum cluster number plus one.
-  Num_Clusters = max_cluster + 1;
-
-  if (_lb_args.debug() >= 1) {
+  if (_lb_args.debug() > 0) {
     CkPrintf ("[%d] GridCommLB finds %d clusters.\n", CkMyPe(), Num_Clusters);
   }
 
-  // Compute the relative PE speeds.
-  // Also add background CPU time to each PE's scaled load.
-  for (i = 0; i < Num_PEs; i++) {
-    (&PE_Data[i])->relative_speed = (double) (stats->procs[i].pe_speed / min_speed);
-
-    (&PE_Data[i])->scaled_load += stats->procs[i].bg_cputime;
-  }
-
   // Initialize the Object_Data[] data structure.
-  Object_Data = new Object_Data_T[Num_Objects];
-
-  for (i = 0; i < Num_Objects; i++) {
-    (&Object_Data[i])->migratable   = (&stats->objData[i])->migratable;
-    (&Object_Data[i])->cluster      = Get_Cluster (stats->from_proc[i]);
-    (&Object_Data[i])->from_pe      = stats->from_proc[i];
-    (&Object_Data[i])->num_lan_msgs = 0;
-    (&Object_Data[i])->num_wan_msgs = 0;
-    (&Object_Data[i])->load         = (&stats->objData[i])->wallTime;
-
-    if ((&Object_Data[i])->migratable) {
-      (&Object_Data[i])->to_pe = -1;
-    } else {
-      (&Object_Data[i])->to_pe = (&Object_Data[i])->from_pe;
-
-      (&PE_Data[(&Object_Data[i])->to_pe])->scaled_load += (&Object_Data[i])->load;
-
-      if (_lb_args.debug() >= 2) {
-       CkPrintf ("[%d] GridCommLB identifies object %d as non-migratable.\n", CkMyPe(), i);
-      }
-    }
-  }
+  Initialize_Object_Data (stats);
 
   // Examine all object-to-object messages for intra-cluster and inter-cluster communications.
-  for (i = 0; i < stats->n_comm; i++) {
-    com_data = &(stats->commData[i]);
-    if ((!com_data->from_proc()) && (com_data->recv_type() == LD_OBJ_MSG)) {
-      send_object = stats->getHash (com_data->sender);
-      recv_object = stats->getHash (com_data->receiver.get_destObj());
+  Examine_InterObject_Messages (stats);
 
-      send_pe = (&Object_Data[send_object])->from_pe;
-      recv_pe = (&Object_Data[recv_object])->from_pe;
-
-      send_cluster = Get_Cluster (send_pe);
-      recv_cluster = Get_Cluster (recv_pe);
+  // Map non-migratable objects to PEs.
+  Map_NonMigratable_Objects_To_PEs ();
 
-      if (send_cluster == recv_cluster) {
-       (&Object_Data[send_object])->num_lan_msgs += com_data->messages;
-      } else {
-       (&Object_Data[send_object])->num_wan_msgs += com_data->messages;
-      }
-    }
-  }
-
-  // Map objects to PEs in each cluster.
+  // Map migratable objects to PEs in each cluster.
   for (i = 0; i < Num_Clusters; i++) {
-    while (1) {
-      target_object = Find_Maximum_WAN_Object (i);
-      target_pe = Find_Minimum_WAN_PE (i);
-
-      if ((target_object == -1) || (target_pe == -1)) {
-       break;
-      }
-
-      Assign_Object_To_PE (target_object, target_pe);
-    }
+    Map_Migratable_Objects_To_PEs (i);
   }
 
   // Make the assignment of objects to PEs in the load balancer framework.
   for (i = 0; i < Num_Objects; i++) {
     stats->to_proc[i] = (&Object_Data[i])->to_pe;
 
-    if (_lb_args.debug() >= 3) {
+    if (_lb_args.debug() > 2) {
       CkPrintf ("[%d] GridCommLB migrates object %d from PE %d to PE %d.\n", CkMyPe(), i, stats->from_proc[i], stats->to_proc[i]);
-    } else if (_lb_args.debug() >= 2) {
+    } else if (_lb_args.debug() > 1) {
       if (stats->to_proc[i] != stats->from_proc[i]) {
        CkPrintf ("[%d] GridCommLB migrates object %d from PE %d to PE %d.\n", CkMyPe(), i, stats->from_proc[i], stats->to_proc[i]);
       }
index 857315ad5ccc8474dd244c9dbf11acfa907b22d5..f6386eaf488c2f567d669e7561b97eb6227ca458 100644 (file)
@@ -9,6 +9,10 @@
 
 #include "CentralLB.h"
 
+#ifndef MAXINT
+#define MAXINT 2147483647
+#endif
+
 #if CONVERSE_VERSION_VMI
 extern "C" int CmiGetCluster (int process);
 #endif
@@ -47,16 +51,22 @@ class GridCommLB : public CentralLB
     GridCommLB (const CkLBOptions &);
     GridCommLB (CkMigrateMessage *msg);
 
+    CmiBool QueryBalanceNow (int step);
     void work (CentralLB::LDStats *stats, int count);
-
     void pup (PUP::er &p) { CentralLB::pup (p); }
 
   private:
     int Get_Cluster (int pe);
+    void Initialize_PE_Data (CentralLB::LDStats *stats);
+    int Available_PE_Count ();
+    int Compute_Number_Of_Clusters ();
+    void Initialize_Object_Data (CentralLB::LDStats *stats);
+    void Examine_InterObject_Messages (CentralLB::LDStats *stats);
+    void Map_NonMigratable_Objects_To_PEs ();
+    void Map_Migratable_Objects_To_PEs ();
     int Find_Maximum_WAN_Object (int cluster);
     int Find_Minimum_WAN_PE (int cluster);
     void Assign_Object_To_PE (int target_object, int target_pe);
-    CmiBool QueryBalanceNow (int step);
 
     int Num_PEs;
     int Num_Objects;
index c17230961a69b69578329b77e04f3da5b006c3c2..cd34c4d62cffbb3b432c47b65b9141e938fb00f5 100644 (file)
@@ -105,7 +105,7 @@ GridCommRefineLB::GridCommRefineLB (CkMigrateMessage *msg) : CentralLB (msg)
 */
 CmiBool GridCommRefineLB::QueryBalanceNow (int step)
 {
-  if (_lb_args.debug() >= 3) {
+  if (_lb_args.debug() > 2) {
     CkPrintf ("[%d] GridCommRefineLB is balancing on step %d.\n", CkMyPe(), step);
   }
 
@@ -136,6 +136,237 @@ int GridCommRefineLB::Get_Cluster (int pe)
 
 
 
+/**************************************************************************
+** Instantiate and initialize the PE_Data[] data structure.
+**
+** While doing this...
+**    - ensure that there is at least one available PE
+**    - ensure that all PEs are mapped to a cluster
+**    - determine the maximum cluster number (gives the number of clusters)
+**    - determine the minimum speed PE (used to compute relative PE speeds)
+*/
+void GridCommRefineLB::Initialize_PE_Data (CentralLB::LDStats *stats)
+{
+  int min_speed;
+  int i;
+
+
+  PE_Data = new PE_Data_T[Num_PEs];
+
+  min_speed = MAXINT;
+  for (i = 0; i < Num_PEs; i++) {
+    (&PE_Data[i])->available      = stats->procs[i].available;
+    (&PE_Data[i])->cluster        = Get_Cluster (i);
+    (&PE_Data[i])->num_objs       = 0;
+    (&PE_Data[i])->num_lan_objs   = 0;
+    (&PE_Data[i])->num_lan_msgs   = 0;
+    (&PE_Data[i])->num_wan_objs   = 0;
+    (&PE_Data[i])->num_wan_msgs   = 0;
+    (&PE_Data[i])->relative_speed = 0.0;
+    (&PE_Data[i])->scaled_load    = 0.0;
+
+    if (stats->procs[i].pe_speed < min_speed) {
+      min_speed = stats->procs[i].pe_speed;
+    }
+  }
+
+  // Compute the relative PE speeds.
+  // Also add background CPU time to each PE's scaled load.
+  for (i = 0; i < Num_PEs; i++) {
+    (&PE_Data[i])->relative_speed = (double) (stats->procs[i].pe_speed / min_speed);
+    (&PE_Data[i])->scaled_load += stats->procs[i].bg_cputime;
+  }
+}
+
+
+
+/**************************************************************************
+**
+*/
+void GridCommLB::Initialize_Object_Data (CentralLB::LDStats *stats)
+{
+  int i;
+
+
+  Object_Data = new Object_Data_T[Num_Objects];
+
+  for (i = 0; i < Num_Objects; i++) {
+    (&Object_Data[i])->migratable   = (&stats->objData[i])->migratable;
+    (&Object_Data[i])->cluster      = Get_Cluster (stats->from_proc[i]);
+    (&Object_Data[i])->from_pe      = stats->from_proc[i];
+    (&Object_Data[i])->to_pe        = stats->from_proc[i];
+    (&Object_Data[i])->num_lan_msgs = 0;
+    (&Object_Data[i])->num_wan_msgs = 0;
+    (&Object_Data[i])->load         = (&stats->objData[i])->wallTime;
+
+    //(&PE_Data[(&Object_Data[i])->from_pe])->num_objs += 1;
+    //(&PE_Data[(&Object_Data[i])->from_pe])->scaled_load += (&Object_Data[i])->load / (&PE_Data[(&Object_Data[i])->from_pe])->relative_speed;
+  }
+}
+
+
+
+/**************************************************************************
+**
+*/
+void GridCommLB::Examine_InterObject_Messages (CentralLB::LDStats *stats)
+{
+  int i;
+  LDCommData *com_data;
+  int send_object;
+  int send_pe;
+  int send_cluster;
+  int recv_object;
+  int recv_pe;
+  int recv_cluster;
+  LDObjKey *recv_objects;
+  int num_objects;
+
+
+  for (i = 0; i < stats->n_comm; i++) {
+    com_data = &(stats->commData[i]);
+    if ((!com_data->from_proc()) && (com_data->recv_type() == LD_OBJ_MSG)) {
+      send_object = stats->getHash (com_data->sender);
+      recv_object = stats->getHash (com_data->receiver.get_destObj());
+
+      if ((send_object < 0) || (send_object > Num_Objects) || (recv_object < 0) || (recv_object > Num_Objects)) {
+        continue;
+      }
+
+      send_pe = (&Object_Data[send_object])->from_pe;
+      recv_pe = (&Object_Data[recv_object])->from_pe;
+
+      send_cluster = Get_Cluster (send_pe);
+      recv_cluster = Get_Cluster (recv_pe);
+
+      if (send_cluster == recv_cluster) {
+        (&Object_Data[send_object])->num_lan_msgs += com_data->messages;
+      } else {
+        (&Object_Data[send_object])->num_wan_msgs += com_data->messages;
+      }
+    } else if (com_data->receiver.get_type() == LD_OBJLIST_MSG) {
+      send_object = stats->getHash (com_data->sender);
+
+      if ((send_object < 0) || (send_object > Num_Objects)) {
+        continue;
+      }
+
+      send_pe = (&Object_Data[send_object])->from_pe;
+      send_cluster = Get_Cluster (send_pe);
+
+      recv_objects = com_data->receiver.get_destObjs (num_objects);   // (num_objects is passed by reference)
+
+      for (j = 0; j < num_objects; j++) {
+        recv_object = stats->getHash (recv_objects[j]);
+
+        if ((recv_object < 0) || (recv_object > Num_Objects)) {
+          continue;
+        }
+
+        recv_pe = (&Object_Data[recv_object])->from_pe;
+        recv_cluster = Get_Cluster (recv_pe);
+
+        if (send_cluster == recv_cluster) {
+          (&Object_Data[send_object])->num_lan_msgs += com_data->messages;
+        } else {
+          (&Object_Data[send_object])->num_wan_msgs += com_data->messages;
+        }
+      }
+    }
+  }
+}
+
+
+
+/**************************************************************************
+**
+*/
+void GridCommRefineLB::Place_Objects_On_PEs ()
+{
+  int i;
+
+
+  for (i = 0; i < Num_Objects; i++) {
+    Assign_Object_To_PE (i, (&Object_Data[i])->from_pe);
+  }
+}
+
+
+
+/**************************************************************************
+**
+*/
+void GridCommRefineLB::Remap_Objects_To_PEs (int cluster)
+{
+  int num_cluster_pes;
+  int num_wan_msgs;
+  int avg_wan_msgs;
+  int target_object;
+  int target_pe;
+  int i;
+
+
+  // Compute average number of objects per PE for this cluster.
+  num_cluster_pes = 0;
+  num_wan_msgs = 0;
+  for (i = 0; i < Num_PEs; i++) {
+    if (cluster == (&PE_Data[i])->cluster) {
+      num_cluster_pes += 1;
+      num_wan_msgs += (&PE_Data[j])->num_wan_msgs;
+    }
+  }
+  avg_wan_msgs = num_wan_msgs / num_cluster_pes;
+
+  // Move objects away from PEs that exceed the average.
+  for (i = 0; i < Num_PEs; i++) {
+    if (cluster == (&PE_Data[i])->cluster) {
+      while ((&PE_Data[i])->num_wan_msgs > (avg_wan_msgs * CK_LDB_GridCommRefineLB_Tolerance)) {
+       target_object = Find_Maximum_WAN_Object (i);
+       target_pe = Find_Minimum_WAN_PE (cluster);
+
+       if ((target_object == -1) || (target_pe == -1)) {
+         break;
+       }
+
+       Remove_Object_From_PE (target_object, i);
+       Assign_Object_To_PE (target_object, target_pe);
+      }
+    }
+  }
+
+/*
+  // Compute average number of objects per PE for this cluster.
+  num_cluster_pes = 0;
+  num_wan_objs = 0;
+  for (j = 0; j < Num_PEs; j++) {
+    if (cluster == (&PE_Data[j])->cluster) {
+      num_cluster_pes += 1;
+      num_wan_objs += (&PE_Data[j])->num_wan_objs;
+    }
+  }
+  avg_wan_objs = num_wan_objs / num_cluster_pes;
+
+  // Move objects away from PEs that exceed the average.
+  for (j = 0; j < Num_PEs; j++) {
+    if (cluster == (&PE_Data[j])->cluster) {
+      while ((&PE_Data[j])->num_wan_objs > (avg_wan_objs * CK_LDB_GridCommRefineLB_Tolerance)) {
+       target_object = Find_Maximum_WAN_Object (j);
+       target_pe = Find_Minimum_WAN_PE (i);
+
+       if ((target_object == -1) || (target_pe == -1)) {
+         break;
+       }
+
+       Remove_Object_From_PE (target_object, j);
+       Assign_Object_To_PE (target_object, target_pe);
+      }
+    }
+  }
+*/
+}
+
+
+
 /**************************************************************************
 ** This method locates the maximum WAN object in terms of number of
 ** messages that traverse a wide-area connection.  The search is
@@ -185,13 +416,42 @@ int GridCommRefineLB::Find_Maximum_WAN_Object (int pe)
 */
 int GridCommRefineLB::Find_Minimum_WAN_PE (int cluster)
 {
+  int i;
+  int min_index;
+  int min_wan_msgs;
+
+
+  min_index = -1;
+  min_wan_msgs = MAXINT;
+
+  for (i = 0; i < Num_PEs; i++) {
+    if (((&PE_Data[i])->available) && ((&PE_Data[i])->cluster == cluster)) {
+      if ((&PE_Data[i])->num_wan_msgs < min_wan_msgs) {
+        min_index = i;
+        min_wan_msgs = (&PE_Data[i])->num_wan_msgs;
+      } else if (((&PE_Data[i])->num_wan_msgs == min_wan_msgs) &&
+                 ((&PE_Data[i])->scaled_load < (&PE_Data[min_index])->scaled_load)) {
+        min_index = i;
+        min_wan_msgs = (&PE_Data[i])->num_wan_msgs;
+      } else if (((&PE_Data[i])->num_wan_msgs == min_wan_msgs) &&
+                 ((&PE_Data[i])->scaled_load == (&PE_Data[min_index])->scaled_load) &&
+                 ((&PE_Data[i])->num_objs < (&PE_Data[min_index])->num_objs)) {
+        min_index = i;
+        min_wan_msgs = (&PE_Data[i])->num_wan_msgs;
+      }
+    }
+  }
+
+  return (min_index);
+
+/*
   int i;
   int min_index;
   int min_wan_objs;
 
 
   min_index = -1;
-  min_wan_objs = INT_MAX;
+  min_wan_objs = MAXINT;
 
   for (i = 0; i < Num_PEs; i++) {
     if (((&PE_Data[i])->available) && ((&PE_Data[i])->cluster == cluster)) {
@@ -212,6 +472,7 @@ int GridCommRefineLB::Find_Minimum_WAN_PE (int cluster)
   }
 
   return (min_index);
+*/
 }
 
 
@@ -275,26 +536,21 @@ void GridCommRefineLB::Assign_Object_To_PE (int target_object, int target_pe)
 void GridCommRefineLB::work (CentralLB::LDStats *stats, int count)
 {
   int i;
-  int j;
-  CmiBool available;
-  CmiBool all_pes_mapped;
-  int max_cluster;
-  int min_speed;
-  int send_object;
-  int send_pe;
-  int send_cluster;
-  int recv_object;
-  int recv_pe;
-  int recv_cluster;
-  int num_cluster_pes;
-  int num_wan_objs;
-  int avg_wan_objs;
-  int target_object;
-  int target_pe;
-  LDCommData *com_data;
-
-
-  if (_lb_args.debug() >= 1) {
+  // int j;
+  // CmiBool available;
+  // CmiBool all_pes_mapped;
+  // int max_cluster;
+  // int min_speed;
+  // int send_object;
+  // int send_pe;
+  // int send_cluster;
+  // int recv_object;
+  // int recv_pe;
+  // int recv_cluster;
+  // LDCommData *com_data;
+
+
+  if (_lb_args.debug() > 0) {
     CkPrintf ("[%d] GridCommRefineLB is working.\n", CkMyPe());
   }
 
@@ -305,52 +561,17 @@ void GridCommRefineLB::work (CentralLB::LDStats *stats, int count)
   Num_PEs = count;
   Num_Objects = stats->n_objs;
 
-  if (_lb_args.debug() >= 1) {
+  if (_lb_args.debug() > 0) {
     CkPrintf ("[%d] GridCommRefineLB is examining %d PEs and %d objects.\n", CkMyPe(), Num_PEs, Num_Objects);
   }
 
-  // Instantiate and initialize the PE_Data[] data structure.
-  //
-  // While doing this...
-  //    - ensure that there is at least one available PE
-  //    - ensure that all PEs are mapped to a cluster
-  //    - determine the maximum cluster number (gives the number of clusters)
-  //    - determine the minimum speed PE (used to compute relative PE speeds)
-  PE_Data = new PE_Data_T[Num_PEs];
-
-  available = CmiFalse;
-  all_pes_mapped = CmiTrue;
-  max_cluster = -1;
-  min_speed = INT_MAX;
-
-  for (i = 0; i < Num_PEs; i++) {
-    (&PE_Data[i])->available      = stats->procs[i].available;
-    (&PE_Data[i])->cluster        = Get_Cluster (i);
-    (&PE_Data[i])->num_objs       = 0;
-    (&PE_Data[i])->num_lan_objs   = 0;
-    (&PE_Data[i])->num_lan_msgs   = 0;
-    (&PE_Data[i])->num_wan_objs   = 0;
-    (&PE_Data[i])->num_wan_msgs   = 0;
-    (&PE_Data[i])->relative_speed = 0.0;
-    (&PE_Data[i])->scaled_load    = 0.0;
-
-    available |= (&PE_Data[i])->available;
-
-    all_pes_mapped &= ((&PE_Data[i])->cluster >= 0);
-
-    if ((&PE_Data[i])->cluster > max_cluster) {
-      max_cluster = (&PE_Data[i])->cluster;
-    }
-
-    if (stats->procs[i].pe_speed < min_speed) {
-      min_speed = stats->procs[i].pe_speed;
-    }
-  }
+  // Initialize the PE_Data[] data structure.
+  Initialize_PE_Data (stats);
 
   // If at least one available PE does not exist, return from load balancing.
-  if (!available) {
-    if (_lb_args.debug() >= 1) {
-      CkPrintf ("[%d] GridCommRefineLB finds no available PEs -- no balancing done.\n", CkMyPe());
+  if (Available_PE_Count() < 1) {
+    if (_lb_args.debug() > 0) {
+      CkPrintf ("[%d] GridCommLB finds no available PEs -- no balancing done.\n", CkMyPe());
     }
 
     delete [] PE_Data;
@@ -358,10 +579,12 @@ void GridCommRefineLB::work (CentralLB::LDStats *stats, int count)
     return;
   }
 
-  // If not all PEs are mapped to a cluster, return from load balancing.
-  if (!all_pes_mapped) {
-    if (_lb_args.debug() >= 1) {
-      CkPrintf ("[%d] GridCommRefineLB finds incomplete PE cluster map -- no balancing done.\n", CkMyPe());
+  // Determine the number of clusters.
+  // If any PE is not mapped to a cluster, return from load balancing.
+  Num_Clusters = Compute_Number_Of_Clusters ();
+  if (Num_Clusters < 1) {
+    if (_lb_args.debug() > 0) {
+      CkPrintf ("[%d] GridCommLB finds incomplete PE cluster map -- no balancing done.\n", CkMyPe());
     }
 
     delete [] PE_Data;
@@ -369,109 +592,31 @@ void GridCommRefineLB::work (CentralLB::LDStats *stats, int count)
     return;
   }
 
-  // The number of clusters is equal to the maximum cluster number plus one.
-  Num_Clusters = max_cluster + 1;
-
-  if (_lb_args.debug() >= 1) {
-    CkPrintf ("[%d] GridCommRefineLB finds %d clusters.\n", CkMyPe(), Num_Clusters);
-  }
-
-  // Compute the relative PE speeds.
-  // Also add background CPU time to each PE's scaled load.
-  for (i = 0; i < Num_PEs; i++) {
-    (&PE_Data[i])->relative_speed = (double) (stats->procs[i].pe_speed / min_speed);
-
-    (&PE_Data[i])->scaled_load += stats->procs[i].bg_cputime;
+  if (_lb_args.debug() > 0) {
+    CkPrintf ("[%d] GridCommLB finds %d clusters.\n", CkMyPe(), Num_Clusters);
   }
 
   // Initialize the Object_Data[] data structure.
-  Object_Data = new Object_Data_T[Num_Objects];
-
-  for (i = 0; i < Num_Objects; i++) {
-    (&Object_Data[i])->migratable   = (&stats->objData[i])->migratable;
-    (&Object_Data[i])->cluster      = Get_Cluster (stats->from_proc[i]);
-    (&Object_Data[i])->from_pe      = stats->from_proc[i];
-    (&Object_Data[i])->to_pe        = stats->from_proc[i];
-    (&Object_Data[i])->num_lan_msgs = 0;
-    (&Object_Data[i])->num_wan_msgs = 0;
-    (&Object_Data[i])->load         = (&stats->objData[i])->wallTime;
-
-    (&PE_Data[(&Object_Data[i])->from_pe])->num_objs += 1;
-    (&PE_Data[(&Object_Data[i])->from_pe])->scaled_load += (&Object_Data[i])->load;
-  }
+  Initialize_Object_Data (stats);
 
   // Examine all object-to-object messages for intra-cluster and inter-cluster communications.
-  for (i = 0; i < stats->n_comm; i++) {
-    com_data = &(stats->commData[i]);
-    if ((!com_data->from_proc()) && (com_data->recv_type() == LD_OBJ_MSG)) {
-      send_object = stats->getHash (com_data->sender);
-      recv_object = stats->getHash (com_data->receiver.get_destObj());
-
-      send_pe = (&Object_Data[send_object])->from_pe;
-      recv_pe = (&Object_Data[recv_object])->from_pe;
-
-      send_cluster = Get_Cluster (send_pe);
-      recv_cluster = Get_Cluster (recv_pe);
-
-      if (send_cluster == recv_cluster) {
-       (&Object_Data[send_object])->num_lan_msgs += com_data->messages;
-      } else {
-       (&Object_Data[send_object])->num_wan_msgs += com_data->messages;
-      }
-    }
-  }
-
-  // Increment the number of LAN and WAN objects and messages for each PE.
-  for (i = 0; i < Num_Objects; i++) {
-    if ((&Object_Data[i])->num_lan_msgs > 0) {
-      (&PE_Data[(&Object_Data[i])->from_pe])->num_lan_objs += 1;
-      (&PE_Data[(&Object_Data[i])->from_pe])->num_lan_msgs += (&Object_Data[i])->num_lan_msgs;
-    }
+  Examine_InterObject_Messages (stats);
 
-    if ((&Object_Data[i])->num_wan_msgs > 0) {
-      (&PE_Data[(&Object_Data[i])->from_pe])->num_wan_objs += 1;
-      (&PE_Data[(&Object_Data[i])->from_pe])->num_wan_msgs += (&Object_Data[i])->num_wan_msgs;
-    }
-  }
+  // Place objects on the PE they are currently assigned to.
+  Place_Objects_On_PEs ();
 
-  // Map objects to PEs in each cluster.
+  // Remap objects to PEs in each cluster.
   for (i = 0; i < Num_Clusters; i++) {
-    // Compute average number of objects per PE for this cluster.
-    num_cluster_pes = 0;
-    num_wan_objs = 0;
-    for (j = 0; j < Num_PEs; j++) {
-      if (i == (&PE_Data[j])->cluster) {
-       num_cluster_pes += 1;
-       num_wan_objs += (&PE_Data[j])->num_wan_objs;
-      }
-    }
-    avg_wan_objs = num_wan_objs / num_cluster_pes;
-
-    // Move objects away from PEs that exceed the average.
-    for (j = 0; j < Num_PEs; j++) {
-      if (i == (&PE_Data[j])->cluster) {
-       while ((&PE_Data[j])->num_wan_objs > (avg_wan_objs * CK_LDB_GridCommRefineLB_Tolerance)) {
-         target_object = Find_Maximum_WAN_Object (j);
-         target_pe = Find_Minimum_WAN_PE (i);
-
-         if ((target_object == -1) || (target_pe == -1)) {
-           break;
-         }
-
-         Remove_Object_From_PE (target_object, j);
-         Assign_Object_To_PE (target_object, target_pe);
-       }
-      }
-    }
+    Remap_Objects_To_PEs (i);
   }
 
   // Make the assignment of objects to PEs in the load balancer framework.
   for (i = 0; i < Num_Objects; i++) {
     stats->to_proc[i] = (&Object_Data[i])->to_pe;
 
-    if (_lb_args.debug() >= 3) {
+    if (_lb_args.debug() > 2) {
       CkPrintf ("[%d] GridCommRefineLB migrates object %d from PE %d to PE %d.\n", CkMyPe(), i, stats->from_proc[i], stats->to_proc[i]);
-    } else if (_lb_args.debug() >= 2) {
+    } else if (_lb_args.debug() > 1) {
       if (stats->to_proc[i] != stats->from_proc[i]) {
        CkPrintf ("[%d] GridCommRefineLB migrates object %d from PE %d to PE %d.\n", CkMyPe(), i, stats->from_proc[i], stats->to_proc[i]);
       }
index f0e1dba5177d207d52e30d3191175ff5386a2629..dbcc2870c88f5b4621e0fec422704232bd6936ca 100644 (file)
 
 #define CK_LDB_GRIDCOMMREFINELB_TOLERANCE 1.10
 
+#ifndef MAXINT
+#define MAXINT 2147483647
+#endif
+
 #if CONVERSE_VERSION_VMI
 extern "C" int CmiGetCluster (int process);
 #endif
@@ -49,17 +53,21 @@ class GridCommRefineLB : public CentralLB
     GridCommRefineLB (const CkLBOptions &);
     GridCommRefineLB (CkMigrateMessage *msg);
 
+    CmiBool QueryBalanceNow (int step);
     void work (CentralLB::LDStats *stats, int count);
-
     void pup (PUP::er &p) { CentralLB::pup (p); }
 
   private:
     int Get_Cluster (int pe);
+    void Initialize_PE_Data (CentralLB::LDStats *stats);
+    void Initialize_Object_Data (CentralLB::LDStats *stats);
+    void Examine_InterObject_Messages (CentralLB::LDStats *stats);
+    void Place_Objects_On_PEs ();
+    void Remap_Objects_To_PEs (int cluster);
     int Find_Maximum_WAN_Object (int pe);
     int Find_Minimum_WAN_PE (int cluster);
-    void Assign_Object_To_PE (int target_object, int target_pe);
     void Remove_Object_From_PE (int target_object, int target_pe);
-    CmiBool QueryBalanceNow (int step);
+    void Assign_Object_To_PE (int target_object, int target_pe);
 
     int Num_PEs;
     int Num_Objects;
index d3197837cecac1e7d48df3fe67af7b2c72babb74..bb260a554b9f6fabe7542c1164fa6812a2ce36dc 100644 (file)
@@ -169,16 +169,17 @@ void GridMetisLB::Initialize_Object_Data (CentralLB::LDStats *stats)
   Object_Data = new Object_Data_T[Num_Objects];
 
   for (i = 0; i < Num_Objects; i++) {
-    (&Object_Data[i])->migratable   = (&stats->objData[i])->migratable;
-    (&Object_Data[i])->cluster      = Get_Cluster (stats->from_proc[i]);
-    (&Object_Data[i])->from_pe      = stats->from_proc[i];
-    (&Object_Data[i])->load         = (&stats->objData[i])->wallTime;
+    (&Object_Data[i])->migratable = (&stats->objData[i])->migratable;
+    (&Object_Data[i])->cluster    = Get_Cluster (stats->from_proc[i]);
+    (&Object_Data[i])->from_pe    = stats->from_proc[i];
+    (&Object_Data[i])->load       = (&stats->objData[i])->wallTime;
 
     if ((&Object_Data[i])->migratable) {
       (&Object_Data[i])->to_pe = -1;
     } else {
       (&Object_Data[i])->to_pe = (&Object_Data[i])->from_pe;
-      (&PE_Data[(&Object_Data[i])->to_pe])->scaled_load += (&Object_Data[i])->load;
+      //(&PE_Data[(&Object_Data[i])->to_pe])->scaled_load += (&Object_Data[i])->load;
+      (&PE_Data[(&Object_Data[i])->to_pe])->scaled_load += (&Object_Data[i])->load / (&PE_Data[(&Object_Data[i])->to_pe])->relative_speed;
       if (_lb_args.debug() > 1) {
        CkPrintf ("[%d] GridMetisLB identifies object %d as non-migratable.\n", CkMyPe(), i);
       }
@@ -329,7 +330,8 @@ void GridMetisLB::Partition_Objects_Into_Clusters (CentralLB::LDStats *stats)
       send_object = stats->getHash (com_data->sender);
       recv_object = stats->getHash (com_data->receiver.get_destObj());
 
-      if ((recv_object == -1) && (stats->complete_flag == 0)) {
+      //if ((recv_object == -1) && (stats->complete_flag == 0)) {
+      if ((send_object < 0) || (send_object > Num_Objects) || (recv_object < 0) || (recv_object > Num_Objects)) {
        continue;
       }
 
@@ -345,6 +347,10 @@ void GridMetisLB::Partition_Objects_Into_Clusters (CentralLB::LDStats *stats)
     } else if (com_data->receiver.get_type() == LD_OBJLIST_MSG) {
       send_object = stats->getHash (com_data->sender);
 
+      if ((send_object < 0) || (send_object > Num_Objects)) {
+       continue;
+      }
+
       if (!(&Object_Data[send_object])->migratable) {
        continue;
       }
@@ -354,7 +360,8 @@ void GridMetisLB::Partition_Objects_Into_Clusters (CentralLB::LDStats *stats)
       for (j = 0; j < num_objects; j++) {
        recv_object = stats->getHash (recv_objects[j]);
 
-       if (recv_object == -1) {
+       //if (recv_object == -1) {
+       if ((recv_object < 0) || (recv_object > Num_Objects)) {
          continue;
        }
 
@@ -380,7 +387,7 @@ void GridMetisLB::Partition_Objects_Into_Clusters (CentralLB::LDStats *stats)
   num_edges = 0;
   for (i = 0; i < num_migratable_objects; i++) {
     for (j = 0; j < num_migratable_objects; j++) {
-      if (communication_matrix[i][j] != 0) {
+      if (communication_matrix[i][j] > 0) {
        num_edges += 1;
       }
     }
@@ -391,7 +398,7 @@ void GridMetisLB::Partition_Objects_Into_Clusters (CentralLB::LDStats *stats)
   xadj[0] = 0;
   for (i = 0; i < num_migratable_objects; i++) {
     for (j = 0; j < num_migratable_objects; j++) {
-      if (communication_matrix[i][j] != 0) {
+      if (communication_matrix[i][j] > 0) {
        adjncy[count] = j;
        edge_weights[count] = communication_matrix[i][j];
        count += 1;
@@ -406,8 +413,7 @@ void GridMetisLB::Partition_Objects_Into_Clusters (CentralLB::LDStats *stats)
   options[0] = 0;
   newmap = new int[num_migratable_objects];
 
-  METIS_PartGraphRecursive (&num_migratable_objects, xadj, adjncy, NULL, edge_weights, &weight_flag, &numbering_flag, &num_partitions, options,
-                           &edgecut, newmap);
+  METIS_PartGraphRecursive (&num_migratable_objects, xadj, adjncy, NULL, edge_weights, &weight_flag, &numbering_flag, &num_partitions, options, &edgecut, newmap);
 
   // Place the partitioned objects into their correct clusters.
   for (i = 0; i < num_migratable_objects; i++) {
@@ -517,7 +523,7 @@ void GridMetisLB::Partition_ClusterObjects_Into_PEs (CentralLB::LDStats *stats,
     pe += 1;
   }
   if (pe >= Num_PEs) {
-    CmiAbort ("GridMetisLB: Error 1!\n");
+    CmiAbort ("GridMetisLB: Error computing partition to PE map!\n");
   }
   partition = 0;
   while (partition < num_partitions) {
@@ -533,8 +539,8 @@ void GridMetisLB::Partition_ClusterObjects_Into_PEs (CentralLB::LDStats *stats,
     while (((!(&PE_Data[pe])->available) || ((&PE_Data[pe])->cluster != cluster)) && (pe < Num_PEs)) {
       pe += 1;
     }
-    if (pe > Num_PEs) {
-      CmiPrintf ("[%d] GridMetisLB: PE=%d, Num_PEs=%d\n", CmiMyPe(), pe, Num_PEs);
+    if (pe >= Num_PEs) {
+      CmiAbort ("GridMetisLB: Error computing partition to PE map!\n");
     }
   }
 
@@ -563,7 +569,8 @@ void GridMetisLB::Partition_ClusterObjects_Into_PEs (CentralLB::LDStats *stats,
       send_object = stats->getHash (com_data->sender);
       recv_object = stats->getHash (com_data->receiver.get_destObj());
 
-      if (recv_object == -1 && stats->complete_flag == 0) {
+      //if ((recv_object == -1) && (stats->complete_flag == 0)) {
+      if ((send_object < 0) || (send_object > Num_Objects) || (recv_object < 0) || (recv_object > Num_Objects)) {
        continue;
       }
 
@@ -583,6 +590,10 @@ void GridMetisLB::Partition_ClusterObjects_Into_PEs (CentralLB::LDStats *stats,
     } else if (com_data->receiver.get_type() == LD_OBJLIST_MSG) {
       send_object = stats->getHash (com_data->sender);
 
+      if ((send_object < 0) || (send_object > Num_Objects)) {
+       continue;
+      }
+
       if (!(&Object_Data[send_object])->migratable) {
        continue;
       }
@@ -596,7 +607,8 @@ void GridMetisLB::Partition_ClusterObjects_Into_PEs (CentralLB::LDStats *stats,
       for (j = 0; j < num_objects; j++) {
        recv_object = stats->getHash (recv_objects[j]);
 
-       if (recv_object == -1) {
+       //if (recv_object == -1) {
+       if ((recv_object < 0) || (recv_object > Num_Objects)) {
          continue;
        }
 
@@ -626,7 +638,7 @@ void GridMetisLB::Partition_ClusterObjects_Into_PEs (CentralLB::LDStats *stats,
   num_edges = 0;
   for (i = 0; i < num_migratable_cluster_objects; i++) {
     for (j = 0; j < num_migratable_cluster_objects; j++) {
-      if (communication_matrix[i][j] != 0) {
+      if (communication_matrix[i][j] > 0) {
        num_edges += 1;
       }
     }
@@ -637,7 +649,7 @@ void GridMetisLB::Partition_ClusterObjects_Into_PEs (CentralLB::LDStats *stats,
   xadj[0] = 0;
   for (i = 0; i < num_migratable_cluster_objects; i++) {
     for (j = 0; j < num_migratable_cluster_objects; j++) {
-      if (communication_matrix[i][j] != 0) {
+      if (communication_matrix[i][j] > 0) {
        adjncy[count] = j;
        edge_weights[count] = communication_matrix[i][j];
        count += 1;
@@ -654,8 +666,7 @@ void GridMetisLB::Partition_ClusterObjects_Into_PEs (CentralLB::LDStats *stats,
 
   CmiPrintf ("[%d] GridMetisLB partitioning %d objects in cluster %d into %d partitions\n", CmiMyPe(), num_migratable_cluster_objects, cluster, num_partitions);
 
-  METIS_PartGraphRecursive (&num_migratable_cluster_objects, xadj, adjncy, vertex_weights, edge_weights, &weight_flag, &numbering_flag, &num_partitions, options,
-                           &edgecut, newmap);
+  METIS_PartGraphRecursive (&num_migratable_cluster_objects, xadj, adjncy, vertex_weights, edge_weights, &weight_flag, &numbering_flag, &num_partitions, options, &edgecut, newmap);
 
   // Place the partitioned objects onto their correct PEs.
   for (i = 0; i < num_migratable_cluster_objects; i++) {
index 4989bdd4ef9b2d90d13eeeacbe623cb55d1e2ad6..e62779aeaf7cd2d7f576a80694127c716ebe66e1 100644 (file)
@@ -82,13 +82,12 @@ class GridMetisLB : public CentralLB
     GridMetisLB (const CkLBOptions &);
     GridMetisLB (CkMigrateMessage *msg);
 
+    CmiBool QueryBalanceNow (int step);
     void work (CentralLB::LDStats *stats, int count);
-
     void pup (PUP::er &p) { CentralLB::pup (p); }
 
   private:
     int Get_Cluster (int pe);
-    CmiBool QueryBalanceNow (int step);
     void Initialize_PE_Data (CentralLB::LDStats *stats);
     int Available_PE_Count ();
     int Compute_Number_Of_Clusters ();