Skip to content

Commit

Permalink
New performance tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Kalashnikovni committed May 4, 2024
1 parent ed0e1ef commit bf4a3f0
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 56 deletions.
24 changes: 19 additions & 5 deletions sbg/sbg_algorithms.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -886,11 +886,11 @@ void SBGTopSort<Set>::updateStatus(Set dom, Exp exp, Set ingoing)

smap_ref().emplaceBack(SBGMap<Set>(ith_dom, exp));

Set ordv = smap().dom(), ith_dom_succs = smap().image(ith_dom);
if (ith_dom_succs.difference(ordv).isEmpty()) {
new_unord = new_unord.difference(ith_dom);
newE = newE.difference(mapD().preImage(ith_dom));
}
// Take out vertices whose succ now also has a succ
Set no_succ = unordered().difference(smap().dom());
Set whole_ord = smap().dom().difference(smap().preImage(no_succ));
new_unord = new_unord.difference(whole_ord);
newE = newE.difference(mapD().preImage(whole_ord));
}
else {
smap_ref().emplaceBack(SBGMap<Set>(dom, exp));
Expand Down Expand Up @@ -930,13 +930,20 @@ PWMap<Set> SBGTopSort<Set>::calculate()
if (debug())
Util::SBG_LOG << "Topological sort dsbg:\n" << dsbg() << "\n\n";

auto begin = std::chrono::high_resolution_clock::now();
Util::MD_NAT aux_curr = curr();
Set curr_set(curr());
Exp exp = calculateExp(curr(), curr());
updateStatus(curr_set, exp, mapD().preImage(curr_set));
set_curr(aux_curr);
while (!unordered().isEmpty())
topSortStep();
auto end = std::chrono::high_resolution_clock::now();

auto total = std::chrono::duration_cast<std::chrono::microseconds>(
end - begin
);
Util::SBG_LOG << "Total topological sort exec time: " << total.count() << " [μs]\n\n";

if (debug())
Util::SBG_LOG << "Topological sort result:\n" << smap().compact() << "\n\n";
Expand Down Expand Up @@ -978,6 +985,7 @@ template struct SBGTopSort<OrdSet>;
template<typename Set>
DSBGraph<Set> buildSCCFromMatching(const SBGMatching<Set> &match)
{
auto start = std::chrono::high_resolution_clock::now();
Set matched_edges = match.matched_E(), unmatched_edges = match.unmatched_E();

Set V = matched_edges;
Expand Down Expand Up @@ -1021,6 +1029,12 @@ DSBGraph<Set> buildSCCFromMatching(const SBGMatching<Set> &match)

DSBGraph<Set> res(V, Vmap, mapB, mapD, Emap);
res.set_subE_map(subE_map);
auto end = std::chrono::high_resolution_clock::now();
auto total = std::chrono::duration_cast<std::chrono::microseconds>(
end - start
);
Util::SBG_LOG << "SBG SCC builder: " << total.count() << " [μs]\n\n";

return res;
}

Expand Down
17 changes: 0 additions & 17 deletions sbg/sbg_algorithms.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,23 +209,6 @@ typedef SBGSCC<OrdSet> CanonSCC;

// Topological sort ------------------------------------------------------------

template<typename Set>
struct VertexOrder {
member_class(std::vector<Set>, container);

VertexOrder();

void emplaceBack(const Set &s);

bool operator==(const VertexOrder &other) const;
bool operator!=(const VertexOrder &other) const;
};
template<typename Set>
std::ostream &operator<<(std::ostream &out, const VertexOrder<Set> &vo);

typedef VertexOrder<UnordSet> BaseVO;
typedef VertexOrder<OrdSet> CanonVO;

template<typename Set>
struct SBGTopSort {
using PW = PWMap<Set>;
Expand Down
66 changes: 52 additions & 14 deletions test/performance/boost/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
@brief <b>Boost matching profiling</b>
This file is meant to test the three examples presented in the paper
"Efficient Matching of Large Systems ...". When executed it will ten times
the Boost Edmonds matching algorithm and report the average execution time
for each of them.
This file is meant to test the execution time of scalar algorithms for graphs
from the BGL library.
<hr>
Expand Down Expand Up @@ -34,6 +32,7 @@
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/max_cardinality_matching.hpp>
#include <boost/graph/strong_components.hpp>
#include <boost/graph/topological_sort.hpp>
#include <gtest/gtest.h>

#include <eval/visitors/program_visitor.hpp>
Expand Down Expand Up @@ -70,9 +69,23 @@ void computeSCC(OG::DGraph graph)
end - begin
);

SBG::Util::SBG_LOG << "Tarjan SCC time: "
SBG::Util::SBG_LOG << "Boost Tarjan SCC time: "
<< total.count() << " [μs]" << std::endl;
SBG::Util::SBG_LOG << "SCC sz: " << num << "\n";
}

void computeTS(OG::DGraph graph)
{
std::vector<int> order;
auto begin = std::chrono::high_resolution_clock::now();
topological_sort(graph, std::back_inserter(order));
auto end = std::chrono::high_resolution_clock::now();
auto total = std::chrono::duration_cast<std::chrono::microseconds>(
end - begin
);

SBG::Util::SBG_LOG << "Boost Topological Sort time: "
<< total.count() << " [μs]" << std::endl;
SBG::Util::SBG_LOG << "SCC sz: " << num << "\n";
}

auto graph_visitor_ = SBG::Util::Overload {
Expand All @@ -87,12 +100,21 @@ auto graph_visitor_ = SBG::Util::Overload {
}

SBG::LIB::BaseSCC scc(buildSCCFromMatching(match), false);
SBG::LIB::BasePWMap scc_res = scc.calculate();

if (a == 1) {
OG::OrdinaryDGraphBuilder ordinary_dgraph_builder(scc.dsbg());
OG::DGraph dgraph = ordinary_dgraph_builder.build();
computeSCC(dgraph);
}

SBG::LIB::BaseTopSort ts(buildSortFromSCC(scc, scc_res), false);

if (a == 2) {
OG::OrdinaryDGraphBuilder ordinary_dgraph_builder(ts.dsbg());
OG::DGraph dgraph = ordinary_dgraph_builder.build();
computeTS(dgraph);
}
},
[](int a, SBG::LIB::CanonSBG b) {
SBG::LIB::CanonMatch match(b, false);
Expand All @@ -105,12 +127,21 @@ auto graph_visitor_ = SBG::Util::Overload {
}

SBG::LIB::CanonSCC scc(buildSCCFromMatching(match), false);
SBG::LIB::CanonPWMap scc_res = scc.calculate();

if (a == 1) {
OG::OrdinaryDGraphBuilder ordinary_dgraph_builder(scc.dsbg());
OG::DGraph dgraph = ordinary_dgraph_builder.build();
computeSCC(dgraph);
}

SBG::LIB::CanonTopSort ts(buildSortFromSCC(scc, scc_res), false);

if (a == 2) {
OG::OrdinaryDGraphBuilder ordinary_dgraph_builder(ts.dsbg());
OG::DGraph dgraph = ordinary_dgraph_builder.build();
computeTS(dgraph);
}
},
[](auto a, auto b) {
SBG::Util::ERROR("Wrong arguments for algorithm");
Expand Down Expand Up @@ -166,15 +197,22 @@ void usage()
std::cout << "Usage parser [options] file" << std::endl;
std::cout << "Parses a SBG program." << std::endl;
std::cout << std::endl;
std::cout << "-a, --file Algorithm selection: [0] matching, [1] scc, [2] topological sort" << std::endl;
std::cout << "-f, --file SBG program file used as input " << std::endl;
std::cout << "-h, --help Display this information and exit" << std::endl;
std::cout << "-v, --version Display version information and exit"
<< std::endl;
std::cout << "-c, --copies Number of SBG copies" << std::endl;
std::cout << "-h, --help Display this information and exit." << std::endl;
std::cout << "-v, --version Display version information and exit."
<< std::endl;
std::cout << "-a, --algo Algorithm selection: [0] matching, [1] scc"
<< ", [2] topological sort." << std::endl;
std::cout << "-f, --file SBG program file used as input. It must be"
<< " an undirected SBG." << std::endl
<< " The program will causalize the system up to the"
<< " desired stage with\n"
<< " the SBG approach, scalarize it and execute"
<< " the selected\n"
<< " algorithm instead of the SBG one." << std::endl;
std::cout << "-c, --copies Number of SBG copies." << std::endl;
std::cout << std::endl;
std::cout << "SBG library home page: https://github.com/CIFASIS/sb-graph"
<< std::endl;
<< std::endl;
}

void version()
Expand All @@ -195,7 +233,7 @@ int main(int argc, char**argv)

while (true) {
static struct option long_options[] = {
{"algorithm", required_argument, 0, 'a'}
{"algo", required_argument, 0, 'a'}
, {"file", required_argument, 0, 'f'}
, {"help", no_argument, 0, 'h'}
, {"version", no_argument, 0, 'v'}
Expand Down
39 changes: 28 additions & 11 deletions test/performance/boost/ordinary_graph_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ OG::Graph OrdinaryGraphBuilder<Set>::build()
for (const SBG::LIB::SetPiece &v : _sb_graph.V()) {
assert(!v.isEmpty());
SBG::Util::MD_NAT beg = v.minElem(), end = v.maxElem();
for (auto it = beg; it != end; it = nextElem(it, v))
for (auto it = beg; it != end; it = nextElem(it, v))
addVertex(it, graph);
addVertex(end, graph);
}
Expand Down Expand Up @@ -117,21 +117,43 @@ OG::DGraph OrdinaryDGraphBuilder<Set>::build()
{
OG::DGraph graph;

std::chrono::microseconds total(0);
for (const SBG::LIB::SetPiece &v : _sb_graph.V()) {
assert(!v.isEmpty());
SBG::Util::MD_NAT beg = v.minElem(), end = v.maxElem();
for (auto it = beg; it != end; it = nextElem(it, v))
for (auto it = beg; it != end; it = nextElem(it, v)) {
auto tbegin = std::chrono::high_resolution_clock::now();
addVertex(it, graph);
auto tend = std::chrono::high_resolution_clock::now();
total += std::chrono::duration_cast<std::chrono::microseconds>(
tend - tbegin
);
}
addVertex(end, graph);
}

PW mapb = _sb_graph.mapB(), mapd = _sb_graph.mapD();
for (const SBG::LIB::SetPiece &e : _sb_graph.E()) {
assert(!e.isEmpty());
SBG::Util::MD_NAT beg = e.minElem(), end = e.maxElem();
for (auto it = beg; it != end; it = nextElem(it, e))
addEdge(it, graph);
addEdge(end, graph);
for (auto it = beg; it != end; it = nextElem(it, e)) {
SBG::LIB::SetPiece mdi(it);
SBG::Util::MD_NAT v1 = mapb.image(Set(mdi)).minElem();
SBG::Util::MD_NAT v2 = mapd.image(Set(mdi)).minElem();
auto tbegin = std::chrono::high_resolution_clock::now();
addEdge(it, v1, v2, graph);
auto tend = std::chrono::high_resolution_clock::now();
total += std::chrono::duration_cast<std::chrono::microseconds>(
tend - tbegin
);
}
SBG::LIB::SetPiece mdi(end);
SBG::Util::MD_NAT v1 = mapb.image(Set(mdi)).minElem();
SBG::Util::MD_NAT v2 = mapd.image(Set(mdi)).minElem();
addEdge(end, v1, v2, graph);
}
SBG::Util::SBG_LOG << "Scalar directed graph builder time: "
<< total.count() << " [μs]\n";

return graph;
}
Expand All @@ -150,14 +172,9 @@ OG::DVertexDesc OrdinaryDGraphBuilder<Set>::addVertex(

template<typename Set>
OG::DEdgeDesc OrdinaryDGraphBuilder<Set>::addEdge(
SBG::Util::MD_NAT id, OG::DGraph &g
SBG::Util::MD_NAT id, SBG::Util::MD_NAT v1, SBG::Util::MD_NAT v2, OG::DGraph &g
)
{
SBG::LIB::SetPiece mdi(id);
PW mapb = _sb_graph.mapB(), mapd = _sb_graph.mapD();
SBG::Util::MD_NAT v1 = mapb.image(Set(mdi)).minElem();
SBG::Util::MD_NAT v2 = mapd.image(Set(mdi)).minElem();

Edge E(id);
OG::DEdgeDesc e;
bool b;
Expand Down
5 changes: 4 additions & 1 deletion test/performance/boost/ordinary_graph_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
#define PERF_ORD_BUILDER_HPP

#include <cassert>
#include <chrono>
#include <map>

#include <test/performance/boost/ordinary_graph.hpp>
#include <sbg/sbg.hpp>
#include <util/logger.hpp>

namespace OG {

Expand Down Expand Up @@ -63,7 +65,8 @@ class OrdinaryDGraphBuilder {

protected:
OG::DVertexDesc addVertex(SBG::Util::MD_NAT id, OG::DGraph &g);
OG::DEdgeDesc addEdge(SBG::Util::MD_NAT id, OG::DGraph &g);
OG::DEdgeDesc addEdge(SBG::Util::MD_NAT id, SBG::Util::MD_NAT v1
, SBG::Util::MD_NAT v2, OG::DGraph &g);

DSBGraph _sb_graph;
std::map<SBG::Util::MD_NAT, OG::DVertexDesc> _vertex_map;
Expand Down
79 changes: 79 additions & 0 deletions test/performance/boost/perf_boost.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/bin/bash

file=$1
algo=$2
iterations=$3
size=$4

# Ignore multi-line comments
echo > aux_file
sed -r ':a;$!{N;ba};s|/\*[^*]*\*+([^/*][^*]*\*+)*/\n||' $file > aux_file

echo > test_file
echo > test_values
echo > builder_values

while read line; do
if echo "$line" | grep -q "N = "; then
echo $line > eval; awk -v s=$size '{print "N = " s}' eval >> test_file; start=true;
else
echo $line >> test_file
fi
done < aux_file


for i in $(seq "$iterations"); do
echo $i
./bin/boost-performance -a $algo -f test_file
mv SBG.log SBG_${i}.log
echo
if [[ $algo==0 ]]; then
while read line; do
if echo "$line" | grep -q "Boost Edmonds"; then echo $line > eval; awk '{print $7}' eval >> test_values; fi
done < "SBG_${i}.log"
fi;

if [[ $algo==1 ]]; then
while read line; do
if echo "$line" | grep -q "Boost Tarjan"; then echo $line > eval; awk '{print $5}' eval >> test_values; fi
if echo "$line" | grep -q "Scalar"; then echo $line > eval; awk '{print $6}' eval >> builder_values; fi
done < "SBG_${i}.log"
fi;

if [[ $algo==2 ]]; then
while read line; do
if echo "$line" | grep -q "Boost Topological"; then echo $line > eval; awk '{print $5}' eval >> test_values; fi
done < "SBG_${i}.log"
fi;
done

echo "Results:"

cat test_values

count=0;
total=0;

for i in $( awk '{ print $1; }' test_values )
do
total=$(echo $total+$i | bc )
((count++))
done

echo
echo "Average:"
echo "scale=2; $total / $count" | bc


count=0;
total=0;

for i in $( awk '{ print $1; }' builder_values )
do
total=$(echo $total+$i | bc )
((count++))
done

echo
echo "Average:"
echo "scale=2; $total / $count" | bc
Loading

0 comments on commit bf4a3f0

Please sign in to comment.