Skip to content

Commit

Permalink
kway fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
Sepideh Maleki committed Nov 23, 2020
1 parent c6ab08b commit fe7ddd2
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 107 deletions.
276 changes: 173 additions & 103 deletions lonestar/analytics/cpu/bipart/bipart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ static cll::opt<bool>
static cll::opt<bool>
output("output", cll::desc("Specify if partitions need to be written"),
cll::init(false));

double Ctime = 0.0f;
double Ptime = 0.0f;
double Rtime = 0.0f;
/**
* Partitioning
*/
Expand All @@ -119,9 +121,12 @@ void Partition(MetisGraph* metisGraph, unsigned coarsenTo, unsigned K) {
T3.start();
refine(mcg, K);
T3.stop();
std::cout << "coarsen:," << T.get() << "\n";
std::cout << "clustering:," << T2.get() << '\n';
std::cout << "Refinement:," << T3.get() << "\n";
Ctime += (T.get()/1000.0f);
Ptime += (T2.get()/1000.0f);
Rtime += (T3.get()/1000.0f);
//std::cout << "coarsen:," << T.get() << "\n";
//std::cout << "clustering:," << T2.get() << '\n';
//std::cout << "Refinement:," << T3.get() << "\n";

execTime.stop();
}
Expand Down Expand Up @@ -198,6 +203,7 @@ int hash(unsigned val) {

int main(int argc, char** argv) {
galois::SharedMemSys G;

LonestarStart(argc, argv, name, desc, url, &inputFile);

galois::StatTimer totalTime("TimerTotal");
Expand All @@ -209,25 +215,23 @@ int main(int argc, char** argv) {
" to indicate the input is a hMetisGraph graph.");
}

// srand(-1);
MetisGraph metisGraph;
GGraph& graph = *metisGraph.getGraph();
std::ifstream f(inputFile.c_str());
// GGraph graph;// = *metisGraph.getGraph();
std::string line;
std::getline(f, line);
std::stringstream ss(line);
uint32_t i1;
uint64_t i2;
ss >> i1 >> i2;
const uint32_t hedges = i1;
const uint64_t nodes = i2;
uint32_t hedges = i1;
uint64_t nodes = i2;
std::cout << "hedges: " << hedges << "\n";
std::cout << "nodes: " << nodes << "\n\n";

galois::StatTimer T("buildingG");
T.start();
// read rest of input and initialize hedges (build hgraph)

galois::gstl::Vector<galois::PODResizeableArray<uint32_t>> edges_id(hedges +
nodes);
std::vector<std::vector<EdgeTy>> edges_data(hedges + nodes);
Expand Down Expand Up @@ -255,33 +259,35 @@ int main(int argc, char** argv) {
f.close();
graph.hedges = hedges;
graph.hnodes = nodes;
std::cout << "number of edges " << edges << "\n";
std::cout << "number of hedges " << hedges << "\n";
uint32_t sizes = hedges + nodes;

galois::do_all(galois::iterate(uint32_t{0}, sizes),
[&](uint32_t c) { prefix_edges[c] = edges_id[c].size(); });

for (uint64_t c = 1; c < nodes + hedges; ++c) {
prefix_edges[c] += prefix_edges[c - 1];
}
// edges = #edges, hedgecount = how many edges each node has, edges_id: for
// each node, which ndoes it is connected to edges_data: data for each edge =
// 1

graph.constructFrom(nodes + hedges, edges, prefix_edges, edges_id,
edges_data);
galois::do_all(galois::iterate(graph), [&](GNode n) {
if (n < hedges)
graph.getData(n).netnum = n + 1;
else
graph.getData(n).netnum = INT_MAX;
graph.getData(n).netrand = INT_MAX;
graph.getData(n).netval = INT_MAX;
graph.getData(n).nodeid = n + 1;
});
galois::do_all(
galois::iterate(graph),
[&](GNode n) {
if (n < hedges)
graph.getData(n).netnum = n + 1;
else
graph.getData(n).netnum = INT_MAX;
graph.getData(n).netrand = INT_MAX;
graph.getData(n).netval = INT_MAX;
graph.getData(n).nodeid = n + 1;
},
galois::steal(), galois::loopname("build initial graph"));
T.stop();
std::cout << "time to build a graph " << T.get() << "\n";
graphStat(graph);
std::cout << "\n";
galois::preAlloc(galois::runtime::numPagePoolAllocTotal() * 5);
galois::preAlloc(galois::runtime::numPagePoolAllocTotal() * 10);
galois::reportPageAlloc("MeminfoPre");
galois::do_all(
galois::iterate(graph.hedges, graph.size()),
Expand All @@ -291,105 +297,161 @@ int main(int argc, char** argv) {
.initRefine(0, true);
graph.getData(item, galois::MethodFlag::UNPROTECTED).initPartition();
},
galois::loopname("initPart"));
galois::steal(), galois::loopname("initPart"));

Partition(&metisGraph, csize, numPartitions);

const int k = numPartitions;
// calculating number of iterations/levels required
int num = log2(k) + 1;
int num = log2(k);

int kValue[k];
for (int i = 0; i < k; i++)
kValue[i] = 0;

kValue[0] = k;
kValue[0] = (k + 1) / 2;
kValue[(k + 1) / 2] = k / 2;

galois::do_all(
galois::iterate((uint64_t)graph.hedges, graph.size()),
[&](GNode n) {
unsigned pp = graph.getData(n).getPart();
if (pp == 1) {
graph.getData(n).setPart((k + 1) / 2);
}
},
galois::steal(), galois::loopname("set part (original graph)"));

// running it level by level

// toProcess contains nodes to be executed in a given level
std::set<int> toProcess;
std::set<int> toProcessNew;
toProcess.insert(0);
for (int level = 0; level < num; level++) {
// calling Partition for each partition number
for (auto i : toProcess) {
if (kValue[i] > 1) {
MetisGraph metisG;
GGraph& gr = *metisG.getGraph();
std::vector<GNode> nodesvec;
std::vector<GNode> hedgevec;
for (GNode n = graph.hedges; n < graph.size(); n++) {
int pp = graph.getData(n).getPart();
if (kValue[pp] > 1 && pp == i) {
nodesvec.push_back(n);
}
}
// unsigned nodesize = nodesvec.size();
std::map<GNode, unsigned> nodemap;
std::map<GNode, unsigned> edgemap;
unsigned ed = 0;
for (GNode h = 0; h < graph.hedges; h++) {
bool flag = true;
auto c = graph.edges(h).begin();
GNode dst = graph.getEdgeDst(*c);
unsigned nPart = graph.getData(dst).getPart();
unsigned ii = i;
if (nPart != ii)
continue;
toProcess.insert((k + 1) / 2);

std::vector<std::vector<GNode>> nodesvec(k);
// std::array<std::vector<GNode>, 100> hedgesvec;

for (int level = 1; level < num; level++) {

for (int i = 0; i < k; i++)
nodesvec[i].clear();

// distributing nodes in relevant vectors according to their current
// partition assignment
for (GNode n = graph.hedges; n < graph.size(); n++) {
unsigned pp = graph.getData(n).getPart();
nodesvec[pp].push_back(n);
}

std::vector<std::vector<GNode>> hedgevec(k);

// distribute hyperedges according to their current partition
galois::do_all(
galois::iterate((uint64_t)0, graph.hedges),
[&](GNode h) {
auto edge = *(graph.edges(h).begin());
auto dst = graph.getEdgeDst(edge);
auto ii = graph.getData(dst).getPart();

bool flag = true;

for (auto n : graph.edges(h)) {
if (graph.getData(graph.getEdgeDst(n)).getPart() != nPart) {
auto part = graph.getData(graph.getEdgeDst(n)).getPart();

if (part != ii) {
flag = false;
break;
}
}

if (flag && kValue[nPart] > 1) {
hedgevec.push_back(h);
edgemap[h] = ed++;
}
}
unsigned id = hedgevec.size();
for (auto n : nodesvec) {
nodemap[n] = id++;
if (flag)
graph.getData(h).setPart(ii);
else
graph.getData(h).setPart(100000);
},
galois::steal(), galois::loopname("distribute hedges"));

for (GNode h = 0; h < graph.hedges; h++) {
unsigned part = graph.getData(h).getPart();
if (part != 100000)
hedgevec[part].push_back(h);
}

// calling Partition for each partition number
for (unsigned i : toProcess) {
if (kValue[i] > 1) {
MetisGraph metisG;
GGraph& gr = *metisG.getGraph();

unsigned ed = 0;

for (auto h : hedgevec[i])
graph.getData(h).index = ed++;

unsigned id = ed;
for (auto n : nodesvec[i]) {
graph.getData(n).index = id++;
}
unsigned totalnodes = hedgevec.size() + nodesvec.size();

unsigned totalnodes = id;
galois::gstl::Vector<galois::PODResizeableArray<uint32_t>> edges_ids(
totalnodes);
std::vector<std::vector<EdgeTy>> edge_data(totalnodes);
std::vector<uint64_t> pre_edges(totalnodes);
unsigned edges = 0;
for (auto h : hedgevec) {
for (auto v : graph.edges(h)) {
auto vv = graph.getEdgeDst(v);
uint32_t newid = edgemap[h];
unsigned nm = nodemap[vv];
edges_ids[newid].push_back(nm);
}
}
galois::GAccumulator<uint64_t> num_edges_acc;

galois::do_all(
galois::iterate(uint32_t{0}, totalnodes),
[&](uint32_t c) {
galois::iterate(hedgevec[i]),
[&](GNode h) {
for (auto v : graph.edges(h)) {
auto vv = graph.getEdgeDst(v);

uint32_t newid = graph.getData(h).index;
unsigned nm = graph.getData(vv).index;
edges_ids[newid].push_back(nm);
}
},
galois::steal(), galois::loopname("populate edge ids"));

uint64_t num_edges_acc = 0;
//galois::do_all(
// galois::iterate(uint32_t{0}, totalnodes),
for(uint32_t c = 0;c<totalnodes;c++) {
pre_edges[c] = edges_ids[c].size();
num_edges_acc += pre_edges[c];
},
galois::steal());
edges = num_edges_acc.reduce();
}
//galois::steal(), galois::loopname("set pre edges"));

edges = num_edges_acc;

for (uint64_t c = 1; c < totalnodes; ++c) {
pre_edges[c] += pre_edges[c - 1];
}
gr.constructFrom(totalnodes, edges, pre_edges, edges_ids, edge_data);
gr.hedges = hedgevec.size();
gr.hnodes = nodesvec.size();
galois::do_all(galois::iterate(gr), [&](GNode n) {
if (n < gr.hedges)
gr.getData(n).netnum = n + 1;
else
gr.getData(n).netnum = INT_MAX;
gr.getData(n).netrand = INT_MAX;
gr.getData(n).netval = INT_MAX;
gr.getData(n).nodeid = n + 1;
});

gr.hedges = ed;
gr.hnodes = id - ed;

galois::do_all(
galois::iterate(gr),
[&](GNode n) {
if (n < gr.hedges)
gr.getData(n).netnum = n + 1;
else
gr.getData(n).netnum = INT_MAX;
gr.getData(n).netrand = INT_MAX;
gr.getData(n).netval = INT_MAX;
gr.getData(n).nodeid = n + 1;
},
galois::steal(), galois::loopname("build graph: recursion level"));

Partition(&metisG, csize, kValue[i]);

MetisGraph* mcg = &metisG;

// now free up the memory by deleting all coarsened graphs
while (mcg->getCoarserGraph() != NULL) {
mcg = mcg->getCoarserGraph();
}
Expand All @@ -405,34 +467,42 @@ int main(int argc, char** argv) {
kValue[i + (tmp + 1) / 2] = (tmp) / 2;
toProcessNew.insert(i);
toProcessNew.insert(i + (tmp + 1) / 2);
for (GNode v : nodesvec) {
GNode n = nodemap[v];
unsigned pp = gr.getData(n).getPart();
if (pp == 0) {
graph.getData(v).setPart(i);
} else if (pp == 1) {
graph.getData(v).setPart(i + (tmp + 1) / 2);
}
}

galois::do_all(
galois::iterate(nodesvec[i]),
[&](GNode v) {
GNode n = graph.getData(v).index;
unsigned pp = gr.getData(n).getPart();
if (pp == 0) {
graph.getData(v).setPart(i);
} else if (pp == 1) {
graph.getData(v).setPart(i + (tmp + 1) / 2);
}
},
galois::steal(),
galois::loopname("set part: inside recursive call"));

delete mcg;
}
}
} // end if
} // end for

toProcess = toProcessNew;
toProcessNew.clear();
}
// std::cout<<"Total Edge Cut: "<<computingCut(graph)<<"\n";
} // end while
std::cout<<"Coarsening time(s): "<<Ctime<<"\n";
std::cout<<"Partitiong time(s): "<<Ptime<<"\n";
std::cout<<"Refinement time(s): "<<Rtime<<"\n";
std::cout<<"\n";
std::cout<<"Edge Cut "<<computingCut(graph)<<"\n\n";

galois::runtime::reportStat_Single("BiPart", "Edge Cut", computingCut(graph));
galois::runtime::reportStat_Single("BiPart", "zero-one",
computingBalance(graph));
// galois::reportPageAlloc("MeminfoPost");

totalTime.stop();

if (output) {

std::cout << "hedgs: " << graph.hedges << "\n";
std::cout << "size: " << graph.size() << "\n";
std::vector<uint32_t> parts(graph.size() - graph.hedges);
std::vector<uint64_t> IDs(graph.size() - graph.hedges);

Expand Down
Loading

0 comments on commit fe7ddd2

Please sign in to comment.