Scotch based LBs including ScotchRefine and ScotchTopo to work with the latest versio...
authorHarshitha Menon <gplkrsh2@illinois.edu>
Sat, 22 Oct 2011 19:43:51 +0000 (14:43 -0500)
committerHarshitha Menon <gplkrsh2@illinois.edu>
Sat, 22 Oct 2011 19:43:51 +0000 (14:43 -0500)
src/ck-ldb/ScotchLB.C
src/ck-ldb/ScotchRefineLB.C [new file with mode: 0644]
src/ck-ldb/ScotchRefineLB.ci [new file with mode: 0644]
src/ck-ldb/ScotchRefineLB.h [new file with mode: 0644]
src/ck-ldb/ScotchTopoLB.C [new file with mode: 0644]
src/ck-ldb/ScotchTopoLB.ci [new file with mode: 0644]
src/ck-ldb/ScotchTopoLB.h [new file with mode: 0644]

index f6f34fb09c1c7757d1a7d11962de25244f2545bd..0ba1d52a2bf4144b41dc82e00cc5101818028b40 100644 (file)
@@ -31,6 +31,7 @@ void ScotchLB::work(LDStats *stats) {
   /** ========================== INITIALIZATION ============================= */
   ProcArray *parr = new ProcArray(stats);
   ObjGraph *ogr = new ObjGraph(stats);
+  double start_time = CmiWallTimer();
 
   /** ============================= STRATEGY ================================ */
   // convert ObjGraph to the Scotch graph
@@ -39,28 +40,54 @@ void ScotchLB::work(LDStats *stats) {
   SCOTCH_Num edgenbr = 0;                      // number of edges
 
   double maxLoad = 0.0;
+  double minLoad = 0.0;
+  if (vertnbr > 0) {
+    minLoad = ogr->vertices[baseval].getVertexLoad();
+  }
+
+  long maxBytes = 1;
   int i, j, k, vert;
 
+
   /** remove duplicate edges from recvFrom */
   for(i = baseval; i < vertnbr; i++) {
     for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
       vert = ogr->vertices[i].sendToList[j].getNeighborId();
       for(k = 0; k < ogr->vertices[i].recvFromList.size(); k++) {
-       if(ogr->vertices[i].recvFromList[k].getNeighborId() == vert) {
-          ogr->vertices[i].sendToList[j].setNumBytes(ogr->vertices[i].sendToList[j].getNumBytes() + ogr->vertices[i].recvFromList[k].getNumBytes());
+        if(ogr->vertices[i].recvFromList[k].getNeighborId() == vert) {
+          ogr->vertices[i].sendToList[j].setNumBytes(
+              ogr->vertices[i].sendToList[j].getNumBytes() +
+              ogr->vertices[i].recvFromList[k].getNumBytes());
           ogr->vertices[i].recvFromList.erase(ogr->vertices[i].recvFromList.begin() + k);
         }
       }
     }
   }
-
   /** the object load is normalized to an integer between 0 and 256 */
   for(i = baseval; i < vertnbr; i++) {
     if(ogr->vertices[i].getVertexLoad() > maxLoad)
       maxLoad = ogr->vertices[i].getVertexLoad();
+
+    if (ogr->vertices[i].getVertexLoad() < minLoad) {
+      minLoad = ogr->vertices[i].getVertexLoad();
+    }
     edgenbr += ogr->vertices[i].sendToList.size() + ogr->vertices[i].recvFromList.size();
   }
 
+  for(i = baseval; i < vertnbr; i++) {
+    for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
+      if (ogr->vertices[i].sendToList[j].getNumBytes() > maxBytes) {
+        maxBytes = ogr->vertices[i].sendToList[j].getNumBytes();
+      }
+    }
+    for(j = 0; j < ogr->vertices[i].recvFromList.size(); j++) {
+      if (ogr->vertices[i].recvFromList[j].getNumBytes() > maxBytes) {
+        maxBytes = ogr->vertices[i].recvFromList[j].getNumBytes();
+      }
+    }
+  }
+
+
   /* adjacency list */
   SCOTCH_Num *verttab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * (vertnbr+1));
   /* loads of vertices */
@@ -72,18 +99,19 @@ void ScotchLB::work(LDStats *stats) {
 
   int edgeNum = 0;
   double ratio = 256.0/maxLoad;
+  double byteRatio = 1024.0/maxBytes;
 
   for(i = baseval; i < vertnbr; i++) {
     verttab[i] = edgeNum;
-    velotab[i] = (int)ceil(ogr->vertices[i].getVertexLoad() * ratio);
+    velotab[i] = (SCOTCH_Num) ceil(ogr->vertices[i].getVertexLoad() * ratio);
     for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
       edgetab[edgeNum] = ogr->vertices[i].sendToList[j].getNeighborId();
-      edlotab[edgeNum] = ogr->vertices[i].sendToList[j].getNumBytes();
+      edlotab[edgeNum] = (int) ceil(ogr->vertices[i].sendToList[j].getNumBytes() * byteRatio);
       edgeNum++;
     }
     for(j = 0; j < ogr->vertices[i].recvFromList.size(); j++) {
       edgetab[edgeNum] = ogr->vertices[i].recvFromList[j].getNeighborId();
-      edlotab[edgeNum] = ogr->vertices[i].recvFromList[j].getNumBytes();
+      edlotab[edgeNum] = (int) ceil(ogr->vertices[i].recvFromList[j].getNumBytes() * byteRatio);
       edgeNum++;
     }
   }
@@ -91,6 +119,7 @@ void ScotchLB::work(LDStats *stats) {
   CkAssert(edgeNum == edgenbr);
 
   SCOTCH_Graph graph;          // Graph to partition
+  SCOTCH_Arch  arch;            // Target architecture
   SCOTCH_Strat strat;          // Strategy to achieve partitioning
 
   /* Initialize data structures */
@@ -100,25 +129,24 @@ void ScotchLB::work(LDStats *stats) {
   SCOTCH_graphBuild (&graph, baseval, vertnbr, verttab, NULL, velotab, NULL, edgenbr, edgetab, edlotab); 
   SCOTCH_graphCheck (&graph);
 
-  // SCOTCH_stratGraphMap (&strat, "m{type=h,vert=80,low=r{job=t,map=t,poli=S,sep=h{pass=10}},asc=b{bnd=d{dif=1,rem=1,pass=40},org=}f{bal=0.01,move=80}}");
-
-  SCOTCH_stratGraphMap (&strat, "r{job=t,map=t,poli=S,sep=(m{type=h,vert=80,low=h{pass=10}f{bal=0.001,move=80},asc=b{bnd=f{bal=0.001,move=80},org=f{bal=0.001,move=80}}}|m{type=h,vert=80,low=h{pass=10}f{bal=0.001,move=80},asc=b{bnd=f{bal=0.001,move=80},org=f{bal=0.001,move=80}}})}");
-
+  SCOTCH_stratGraphMapBuild (&strat, SCOTCH_STRATBALANCE, parr->procs.size (), 0.01);
   SCOTCH_Num *pemap = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * vertnbr);
 
   SCOTCH_graphPart(&graph, parr->procs.size(), &strat, pemap);
 
+
   SCOTCH_graphExit (&graph);
+  SCOTCH_archExit  (&arch);
   SCOTCH_stratExit (&strat);
+
   free(verttab);
   free(velotab);
   free(edgetab);
   free(edlotab);
-
   for(i = baseval; i < vertnbr; i++) {
-    if(pemap[i] != ogr->vertices[i].getCurrentPe())
+    if(pemap[i] != ogr->vertices[i].getCurrentPe()) {
       ogr->vertices[i].setNewPe(pemap[i]);
+    }
   }
 
   free(pemap);
diff --git a/src/ck-ldb/ScotchRefineLB.C b/src/ck-ldb/ScotchRefineLB.C
new file mode 100644 (file)
index 0000000..1ff4394
--- /dev/null
@@ -0,0 +1,176 @@
+/** \file ScotchRefineLB.C
+ *
+ */
+
+/**
+ *  \addtogroup CkLdb
+ */
+
+/*@{*/
+
+#include "ScotchRefineLB.h"
+#include "ckgraph.h"
+#include "scotch.h"
+
+CreateLBFunc_Def(ScotchRefineLB, "Load balancing using the Scotch graph partitioning library")
+
+ScotchRefineLB::ScotchRefineLB(const CkLBOptions &opt) : CentralLB(opt) {
+  lbname = "ScotchRefineLB";
+  if(CkMyPe() == 0)
+    CkPrintf("ScotchRefineLB created\n");
+}
+
+CmiBool ScotchRefineLB::QueryBalanceNow(int _step) {
+  return CmiTrue;
+}
+
+void ScotchRefineLB::work(LDStats *stats) {
+  /** ========================== INITIALIZATION ============================= */
+  ProcArray *parr = new ProcArray(stats);
+  ObjGraph *ogr = new ObjGraph(stats);
+  int cost_array[10] = {64, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536};
+
+  /** ============================= STRATEGY ================================ */
+  // convert ObjGraph to the Scotch graph
+  SCOTCH_Num baseval = 0;                      // starting index of vertices
+  SCOTCH_Num vertnbr = ogr->vertices.size();   // number of vertices
+  SCOTCH_Num edgenbr = 0;                      // number of edges
+
+  SCOTCH_Num *oldpemap = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * vertnbr);
+
+  double maxLoad = 0.0;
+  double minLoad = 0.0;
+  if (vertnbr > 0) {
+    minLoad = ogr->vertices[baseval].getVertexLoad();
+  }
+
+  long maxBytes = 1;
+  int i, j, k, vert;
+  
+
+  /** remove duplicate edges from recvFrom */
+  for(i = baseval; i < vertnbr; i++) {
+    for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
+      vert = ogr->vertices[i].sendToList[j].getNeighborId();
+      for(k = 0; k < ogr->vertices[i].recvFromList.size(); k++) {
+        if(ogr->vertices[i].recvFromList[k].getNeighborId() == vert) {
+          ogr->vertices[i].sendToList[j].setNumBytes(ogr->vertices[i].sendToList[j].getNumBytes() + ogr->vertices[i].recvFromList[k].getNumBytes());
+          ogr->vertices[i].recvFromList.erase(ogr->vertices[i].recvFromList.begin() + k);
+        }
+      }
+    }
+  }
+
+  /** the object load is normalized to an integer between 0 and 256 */
+  for(i = baseval; i < vertnbr; i++) {
+    if(ogr->vertices[i].getVertexLoad() > maxLoad)
+      maxLoad = ogr->vertices[i].getVertexLoad();
+
+    if (ogr->vertices[i].getVertexLoad() < minLoad) {
+      minLoad = ogr->vertices[i].getVertexLoad();
+    }
+    edgenbr += ogr->vertices[i].sendToList.size() + ogr->vertices[i].recvFromList.size();
+    oldpemap[i] = ogr->vertices[i].getCurrentPe();
+  }
+
+  for(i = baseval; i < vertnbr; i++) {
+    for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
+      if (ogr->vertices[i].sendToList[j].getNumBytes() > maxBytes) {
+        maxBytes = ogr->vertices[i].sendToList[j].getNumBytes();
+      }
+    }
+    for(j = 0; j < ogr->vertices[i].recvFromList.size(); j++) {
+      if (ogr->vertices[i].recvFromList[j].getNumBytes() > maxBytes) {
+        maxBytes = ogr->vertices[i].recvFromList[j].getNumBytes();
+      }
+    }
+  }
+
+  /* adjacency list */
+  SCOTCH_Num *verttab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * (vertnbr+1));
+  /* loads of vertices */
+  SCOTCH_Num *velotab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * vertnbr);
+  /* id of the neighbors */
+  SCOTCH_Num *edgetab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * edgenbr);
+  /* number of bytes exchanged */
+  SCOTCH_Num *edlotab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * edgenbr);
+
+  int edgeNum = 0;
+  double ratio = 256.0/maxLoad;
+  double byteRatio = 1024.0/maxBytes;
+  
+  for(i = baseval; i < vertnbr; i++) {
+    verttab[i] = edgeNum;
+    velotab[i] = (int)ceil(ogr->vertices[i].getVertexLoad() * ratio);
+    for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
+      edgetab[edgeNum] = ogr->vertices[i].sendToList[j].getNeighborId();
+      edlotab[edgeNum] = (int) ceil(ogr->vertices[i].sendToList[j].getNumBytes()
+          * byteRatio);
+      edgeNum++;
+    }
+    for(j = 0; j < ogr->vertices[i].recvFromList.size(); j++) {
+      edgetab[edgeNum] = ogr->vertices[i].recvFromList[j].getNeighborId();
+      edlotab[edgeNum] = (int)
+          ceil(ogr->vertices[i].recvFromList[j].getNumBytes() * byteRatio);
+      edgeNum++;
+    }
+  }
+  verttab[i] = edgeNum;
+  CkAssert(edgeNum == edgenbr);
+
+  SCOTCH_Graph graph;          // Graph to partition
+  SCOTCH_Arch  arch;            // Target architecture
+  SCOTCH_Strat strat;          // Strategy to achieve partitioning
+
+  /* Initialize data structures */
+  SCOTCH_graphInit (&graph);
+  SCOTCH_stratInit (&strat);
+
+  SCOTCH_graphBuild (&graph, baseval, vertnbr, verttab, NULL, velotab, NULL, edgenbr, edgetab, edlotab); 
+  SCOTCH_graphCheck (&graph);
+
+  double migration_cost = 1024.0;
+
+    if (step() == 0) {
+      SCOTCH_stratGraphMapBuild (&strat, SCOTCH_STRATBALANCE, parr->procs.size (), 0.01);
+    } else {
+      SCOTCH_stratGraphMapBuild (&strat, SCOTCH_STRATBALANCE | SCOTCH_STRATREMAP, parr->procs.size (), 0.01);
+    }
+
+  SCOTCH_archInit (&arch);
+  SCOTCH_archCmplt (&arch, parr->procs.size ());
+
+  SCOTCH_Num *pemap = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * vertnbr);
+
+  // Takes as input the graph, arch graph, strategy, migration cost in
+  // double, old mapping and new mapping
+
+  if (step() == 0) {
+    SCOTCH_graphPart(&graph, parr->procs.size(), &strat, pemap);
+  } else {
+    SCOTCH_graphRepart(&graph, parr->procs.size(), oldpemap, migration_cost, NULL, &strat, pemap);
+  }
+  
+  SCOTCH_graphExit (&graph);
+  SCOTCH_archExit  (&arch);
+  SCOTCH_stratExit (&strat);
+
+  free(verttab);
+  free(velotab);
+  free(edgetab);
+  free(edlotab);
+
+  for(i = baseval; i < vertnbr; i++) {
+    if(pemap[i] != ogr->vertices[i].getCurrentPe())
+      ogr->vertices[i].setNewPe(pemap[i]);
+  }
+
+  free(pemap);
+  free(oldpemap);
+  /** ============================== CLEANUP ================================ */
+  ogr->convertDecisions(stats);
+}
+
+#include "ScotchRefineLB.def.h"
+
+/*@}*/
diff --git a/src/ck-ldb/ScotchRefineLB.ci b/src/ck-ldb/ScotchRefineLB.ci
new file mode 100644 (file)
index 0000000..cbbc813
--- /dev/null
@@ -0,0 +1,8 @@
+module ScotchRefineLB {
+  extern module CentralLB;
+  initnode void lbinit (void);
+
+  group [migratable] ScotchRefineLB : CentralLB {
+    entry void ScotchRefineLB(const CkLBOptions &);
+  };
+};
diff --git a/src/ck-ldb/ScotchRefineLB.h b/src/ck-ldb/ScotchRefineLB.h
new file mode 100644 (file)
index 0000000..dc1de60
--- /dev/null
@@ -0,0 +1,34 @@
+/** \file ScotchRefineLB.h
+ *  Date Created: November 25th, 2010
+ *
+ */
+
+/**
+ *  \addtogroup CkLdb
+ */
+
+/*@{*/
+
+#ifndef _SCOTCHREFINELB_H_
+#define _SCOTCHREFINELB_H_
+
+#include "CentralLB.h"
+#include "ScotchRefineLB.decl.h"
+
+void CreateScotchRefineLB();
+
+class ScotchRefineLB : public CentralLB {
+  public:
+    ScotchRefineLB(const CkLBOptions &opt);
+    ScotchRefineLB(CkMigrateMessage *m) : CentralLB (m) { };
+
+    void work(LDStats *stats);
+    void pup(PUP::er &p) { CentralLB::pup(p); }
+
+  private:
+    CmiBool QueryBalanceNow(int _step);
+};
+
+#endif /* _SCOTCHREFINELB_H_ */
+
+/*@}*/
diff --git a/src/ck-ldb/ScotchTopoLB.C b/src/ck-ldb/ScotchTopoLB.C
new file mode 100644 (file)
index 0000000..ff76e85
--- /dev/null
@@ -0,0 +1,162 @@
+/** \file ScotchTopoLB.C
+ *  Authors: Abhinav S Bhatele (bhatele@illinois.edu)
+ *           Sebastien Fourestier (fouresti@labri.fr)
+ *  Date Created: November 25th, 2010
+ *
+ */
+
+/**
+ *  \addtogroup CkLdb
+ */
+
+/*@{*/
+
+#include "ScotchTopoLB.h"
+#include "TopoManager.h"
+#include "ckgraph.h"
+#include "scotch.h"
+
+CreateLBFunc_Def(ScotchTopoLB, "Load balancing using the Scotch graph partitioning library")
+
+ScotchTopoLB::ScotchTopoLB(const CkLBOptions &opt) : CentralLB(opt) {
+  lbname = "ScotchTopoLB";
+  if(CkMyPe() == 0)
+    CkPrintf("ScotchTopoLB created\n");
+}
+
+CmiBool ScotchTopoLB::QueryBalanceNow(int _step) {
+  return CmiTrue;
+}
+
+void ScotchTopoLB::work(LDStats *stats) {
+  /** ========================== INITIALIZATION ============================= */
+  ProcArray *parr = new ProcArray(stats);
+  ObjGraph *ogr = new ObjGraph(stats);
+  TopoManager tmgr;
+  double start_time = CmiWallTimer();
+
+  /** ============================= STRATEGY ================================ */
+  // convert ObjGraph to the Scotch graph
+  SCOTCH_Num baseval = 0;                      // starting index of vertices
+  SCOTCH_Num vertnbr = ogr->vertices.size();   // number of vertices
+  SCOTCH_Num edgenbr = 0;                      // number of edges
+
+  double maxLoad = 0.0;
+  double minLoad = 0.0;
+  if (vertnbr > 0) {
+    minLoad = ogr->vertices[baseval].getVertexLoad();
+  }
+
+  long maxBytes = 1;
+  int i, j, k, vert;
+
+
+  /** remove duplicate edges from recvFrom */
+  for(i = baseval; i < vertnbr; i++) {
+    for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
+      vert = ogr->vertices[i].sendToList[j].getNeighborId();
+      for(k = 0; k < ogr->vertices[i].recvFromList.size(); k++) {
+        if(ogr->vertices[i].recvFromList[k].getNeighborId() == vert) {
+          ogr->vertices[i].sendToList[j].setNumBytes(ogr->vertices[i].sendToList[j].getNumBytes() + ogr->vertices[i].recvFromList[k].getNumBytes());
+          ogr->vertices[i].recvFromList.erase(ogr->vertices[i].recvFromList.begin() + k);
+        }
+      }
+    }
+  }
+  /** the object load is normalized to an integer between 0 and 256 */
+  for(i = baseval; i < vertnbr; i++) {
+    if(ogr->vertices[i].getVertexLoad() > maxLoad)
+      maxLoad = ogr->vertices[i].getVertexLoad();
+
+    if (ogr->vertices[i].getVertexLoad() < minLoad) {
+      minLoad = ogr->vertices[i].getVertexLoad();
+    }
+    edgenbr += ogr->vertices[i].sendToList.size() + ogr->vertices[i].recvFromList.size();
+  }
+
+  for(i = baseval; i < vertnbr; i++) {
+    for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
+      if (ogr->vertices[i].sendToList[j].getNumBytes() > maxBytes) {
+        maxBytes = ogr->vertices[i].sendToList[j].getNumBytes();
+      }
+    }
+    for(j = 0; j < ogr->vertices[i].recvFromList.size(); j++) {
+      if (ogr->vertices[i].recvFromList[j].getNumBytes() > maxBytes) {
+        maxBytes = ogr->vertices[i].recvFromList[j].getNumBytes();
+      }
+    }
+  }
+
+
+  /* adjacency list */
+  SCOTCH_Num *verttab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * (vertnbr+1));
+  /* loads of vertices */
+  SCOTCH_Num *velotab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * vertnbr);
+  /* id of the neighbors */
+  SCOTCH_Num *edgetab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * edgenbr);
+  /* number of bytes exchanged */
+  SCOTCH_Num *edlotab = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * edgenbr);
+
+  int edgeNum = 0;
+  double ratio = 256.0/maxLoad;
+  double byteRatio = 1024.0/maxBytes;
+
+  for(i = baseval; i < vertnbr; i++) {
+    verttab[i] = edgeNum;
+    velotab[i] = (SCOTCH_Num) ceil(ogr->vertices[i].getVertexLoad() * ratio);
+    for(j = 0; j < ogr->vertices[i].sendToList.size(); j++) {
+      edgetab[edgeNum] = ogr->vertices[i].sendToList[j].getNeighborId();
+      edlotab[edgeNum] = (int) ceil(ogr->vertices[i].sendToList[j].getNumBytes() * byteRatio);
+      edgeNum++;
+    }
+    for(j = 0; j < ogr->vertices[i].recvFromList.size(); j++) {
+      edgetab[edgeNum] = ogr->vertices[i].recvFromList[j].getNeighborId();
+      edlotab[edgeNum] = (int) ceil(ogr->vertices[i].recvFromList[j].getNumBytes() * byteRatio);
+      edgeNum++;
+    }
+  }
+  verttab[i] = edgeNum;
+  CkAssert(edgeNum == edgenbr);
+
+  SCOTCH_Graph graph;          // Graph to partition
+  SCOTCH_Arch  arch;            // Target architecture
+  SCOTCH_Strat strat;          // Strategy to achieve partitioning
+
+  /* Initialize data structures */
+  SCOTCH_graphInit (&graph);
+  SCOTCH_stratInit (&strat);
+
+  SCOTCH_graphBuild (&graph, baseval, vertnbr, verttab, NULL, velotab, NULL, edgenbr, edgetab, edlotab); 
+  SCOTCH_graphCheck (&graph);
+
+
+  SCOTCH_stratGraphMapBuild (&strat, SCOTCH_STRATBALANCE, parr->procs.size (), 0.01);
+
+  SCOTCH_Num *pemap = (SCOTCH_Num *)malloc(sizeof(SCOTCH_Num) * vertnbr);
+  SCOTCH_archInit (&arch);
+  SCOTCH_archTorus3 (&arch, tmgr.getDimNX(), tmgr.getDimNY(), tmgr.getDimNZ());
+
+  SCOTCH_graphMap (&graph, &arch, &strat, pemap);
+
+  SCOTCH_graphExit (&graph);
+  SCOTCH_archExit  (&arch);
+  SCOTCH_stratExit (&strat);
+
+  free(verttab);
+  free(velotab);
+  free(edgetab);
+  free(edlotab);
+  for(i = baseval; i < vertnbr; i++) {
+    if(pemap[i] != ogr->vertices[i].getCurrentPe()) {
+      ogr->vertices[i].setNewPe(pemap[i]);
+    }
+  }
+
+  free(pemap);
+  /** ============================== CLEANUP ================================ */
+  ogr->convertDecisions(stats);
+}
+
+#include "ScotchTopoLB.def.h"
+
+/*@}*/
diff --git a/src/ck-ldb/ScotchTopoLB.ci b/src/ck-ldb/ScotchTopoLB.ci
new file mode 100644 (file)
index 0000000..c753d35
--- /dev/null
@@ -0,0 +1,8 @@
+module ScotchTopoLB {
+  extern module CentralLB;
+  initnode void lbinit (void);
+
+  group [migratable] ScotchTopoLB : CentralLB {
+    entry void ScotchTopoLB(const CkLBOptions &);
+  };
+};
diff --git a/src/ck-ldb/ScotchTopoLB.h b/src/ck-ldb/ScotchTopoLB.h
new file mode 100644 (file)
index 0000000..25c822a
--- /dev/null
@@ -0,0 +1,36 @@
+/** \file ScotchTopoLB.h
+ *  Authors: Abhinav S Bhatele (bhatele@illinois.edu)
+ *           Sebastien Fourestier (fouresti@labri.fr)
+ *  Date Created: November 25th, 2010
+ *
+ */
+
+/**
+ *  \addtogroup CkLdb
+ */
+
+/*@{*/
+
+#ifndef _SCOTCHLB_H_
+#define _SCOTCHLB_H_
+
+#include "CentralLB.h"
+#include "ScotchTopoLB.decl.h"
+
+void CreateScotchTopoLB();
+
+class ScotchTopoLB : public CentralLB {
+  public:
+    ScotchTopoLB(const CkLBOptions &opt);
+    ScotchTopoLB(CkMigrateMessage *m) : CentralLB (m) { };
+
+    void work(LDStats *stats);
+    void pup(PUP::er &p) { CentralLB::pup(p); }
+
+  private:
+    CmiBool QueryBalanceNow(int _step);
+};
+
+#endif /* _GRAPHPARTLB_H_ */
+
+/*@}*/