update xag optimziation

master
panhomyoung 2024-07-19 16:29:09 +08:00
parent 33e191e2d5
commit 52d20f4c9f
10 changed files with 174 additions and 79 deletions

View File

@ -34,6 +34,7 @@ class balance_command : public command {
: command(env, : command(env,
"transforms the current network into a well-balanced AIG") { "transforms the current network into a well-balanced AIG") {
add_flag("--xmg, -x", "Balance for XMG"); add_flag("--xmg, -x", "Balance for XMG");
add_flag("--xag, -g", "ESOP balance for XAG");
add_flag("--strash, -s", "Balance AND finding structural hashing"); add_flag("--strash, -s", "Balance AND finding structural hashing");
add_flag("--verbose, -v", "print the information"); add_flag("--verbose, -v", "print the information");
} }
@ -42,6 +43,8 @@ class balance_command : public command {
void execute() { void execute() {
clock_t begin, end; clock_t begin, end;
double totalTime = 0.0; double totalTime = 0.0;
begin = clock();
if (is_set("xmg")) { if (is_set("xmg")) {
xmg_network xmg = store<xmg_network>().current(); xmg_network xmg = store<xmg_network>().current();
xmg = balancing( xmg = balancing(
@ -53,31 +56,33 @@ class balance_command : public command {
store<xmg_network>().extend(); store<xmg_network>().extend();
store<xmg_network>().current() = xmg_copy; store<xmg_network>().current() = xmg_copy;
} else if (is_set("xag")) {
xag_network xag = store<xag_network>().current();
xag_network res = esop_balancing(xag);
phyLS::print_stats(res);
store<xag_network>().extend();
store<xag_network>().current() = res;
} else { } else {
if (store<aig_network>().size() == 0u) if (store<aig_network>().size() == 0u)
std::cerr << "Error: Empty AIG network\n"; std::cerr << "Error: Empty AIG network\n";
else { else {
auto aig = store<aig_network>().current(); auto aig = store<aig_network>().current();
if (is_set("strash")) { if (is_set("strash")) {
begin = clock();
aig_balancing_params ps; aig_balancing_params ps;
ps.minimize_levels = false; ps.minimize_levels = false;
aig_balance(aig, ps); aig_balance(aig, ps);
end = clock();
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
} else { } else {
begin = clock();
aig_balance(aig); aig_balance(aig);
end = clock();
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
} }
phyLS::print_stats(aig); phyLS::print_stats(aig);
store<aig_network>().extend(); store<aig_network>().extend();
store<aig_network>().current() = aig; store<aig_network>().current() = aig;
} }
} }
end = clock();
totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
cout.setf(ios::fixed); cout.setf(ios::fixed);
cout << "[CPU time] " << setprecision(2) << totalTime << " s" << endl; cout << "[CPU time] " << setprecision(2) << totalTime << " s" << endl;
} }

View File

@ -47,9 +47,7 @@ class lut_mapping_command : public command {
clock_t begin, end; clock_t begin, end;
double totalTime; double totalTime;
lut_mapping_params ps; lut_mapping_params ps;
if (is_set("area")){ if (is_set("area")) ps.rounds = 0u;
ps.rounds_ela = 4u;
}
if (is_set("mig")) { if (is_set("mig")) {
/* derive some MIG */ /* derive some MIG */

View File

@ -32,8 +32,9 @@ class lutmap_command : public command {
add_flag("--mig, -m", "FPGA technology mapping for MIG"); add_flag("--mig, -m", "FPGA technology mapping for MIG");
add_flag("--xag, -g", "FPGA technology mapping for XAG"); add_flag("--xag, -g", "FPGA technology mapping for XAG");
add_flag("--xmg, -x", "FPGA technology mapping for XMG"); add_flag("--xmg, -x", "FPGA technology mapping for XMG");
add_flag("--klut, -k", "FPGA technology mapping for k-LUT");
add_option("--cut_size, -s", cut_size, add_option("--cut_size, -s", cut_size,
"Maximum number of leaves for a cut [default = 4]"); "Maximum number of leaves for a cut [default = 6]");
add_option( add_option(
"--cut_limit, -l", cut_limit, "--cut_limit, -l", cut_limit,
"the input Maximum number of cuts for a node name [default = 25]"); "the input Maximum number of cuts for a node name [default = 25]");
@ -47,6 +48,7 @@ class lutmap_command : public command {
"LUT map with cost function [default = false]"); "LUT map with cost function [default = false]");
add_flag("--dominated_cuts, -d", add_flag("--dominated_cuts, -d",
"Remove the cuts that are contained in others [default = true]"); "Remove the cuts that are contained in others [default = true]");
add_option("--output, -o", filename, "the bench filename");
add_flag("--verbose, -v", "print the information"); add_flag("--verbose, -v", "print the information");
} }
@ -119,6 +121,24 @@ class lutmap_command : public command {
phyLS::lut_map(mapped_xmg, ps); phyLS::lut_map(mapped_xmg, ps);
mapped_xmg.clear_mapping(); mapped_xmg.clear_mapping();
} }
} else if (is_set("klut")) {
if (store<klut_network>().size() == 0u)
std::cerr << "Error: Empty k-LUT network\n";
else {
auto klut = store<klut_network>().current();
mapping_view mapped_klut{klut};
phyLS::lut_map_params ps;
if (is_set("area")) ps.area_oriented_mapping = true;
if (is_set("relax_required")) ps.relax_required = relax_required;
if (is_set("cut_size")) ps.cut_enumeration_ps.cut_size = cut_size;
if (is_set("cut_limit")) ps.cut_enumeration_ps.cut_limit = cut_limit;
if (is_set("recompute_cuts")) ps.recompute_cuts = false;
if (is_set("edge")) ps.edge_optimization = false;
if (is_set("dominated_cuts")) ps.remove_dominated_cuts = false;
cout << "Mapped kLUT into " << cut_size << "-LUT : ";
phyLS::lut_map(mapped_klut, ps);
mapped_klut.clear_mapping();
}
} else { } else {
if (store<aig_network>().size() == 0u) if (store<aig_network>().size() == 0u)
std::cerr << "Error: Empty AIG network\n"; std::cerr << "Error: Empty AIG network\n";
@ -139,7 +159,11 @@ class lutmap_command : public command {
mapped_aig, ps); mapped_aig, ps);
else else
phyLS::lut_map(mapped_aig, ps); phyLS::lut_map(mapped_aig, ps);
mapped_aig.clear_mapping(); if (is_set("output")) {
write_bench(mapped_aig, filename);
} else {
mapped_aig.clear_mapping();
}
} }
} }
} }
@ -148,6 +172,7 @@ class lutmap_command : public command {
uint32_t cut_size{6u}; uint32_t cut_size{6u};
uint32_t cut_limit{8u}; uint32_t cut_limit{8u};
uint32_t relax_required{0u}; uint32_t relax_required{0u};
std::string filename = "lut.bench";
}; };
ALICE_ADD_COMMAND(lutmap, "Mapping") ALICE_ADD_COMMAND(lutmap, "Mapping")

View File

@ -31,6 +31,7 @@
#include <mockturtle/networks/xmg.hpp> #include <mockturtle/networks/xmg.hpp>
#include "../core/misc.hpp" #include "../core/misc.hpp"
#include "../networks/aoig/xag_lut_npn.hpp"
using namespace std; using namespace std;
using namespace mockturtle; using namespace mockturtle;
@ -75,7 +76,7 @@ class resyn_command : public command {
totalTime = (double)(end - begin) / CLOCKS_PER_SEC; totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
} else if (is_set("xag")) { } else if (is_set("xag")) {
begin = clock(); begin = clock();
xag_npn_resynthesis<xag_network> resyn; xag_npn_lut_resynthesis resyn;
const auto xag = node_resynthesis<xag_network>(klut, resyn); const auto xag = node_resynthesis<xag_network>(klut, resyn);
store<xag_network>().extend(); store<xag_network>().extend();
store<xag_network>().current() = cleanup_dangling(xag); store<xag_network>().current() = cleanup_dangling(xag);

View File

@ -33,10 +33,13 @@ class refactor_command : public command {
explicit refactor_command(const environment::ptr& env) explicit refactor_command(const environment::ptr& env)
: command(env, : command(env,
"performs technology-independent refactoring [default = AIG]") { "performs technology-independent refactoring [default = AIG]") {
add_option("--cut_size, -k", cut_size,
"Maximum number of PIs of the MFFC or window");
add_flag("--mig, -m", "refactoring for MIG"); add_flag("--mig, -m", "refactoring for MIG");
add_flag("--xag, -g", "refactoring for XAG"); add_flag("--xag, -g", "refactoring for XAG");
add_flag("--xmg, -x", "refactoring for XMG"); add_flag("--xmg, -x", "refactoring for XMG");
add_flag("--akers, -a", "Refactoring with Akers synthesis for MIG"); add_flag("--akers, -a", "Refactoring with Akers synthesis for MIG");
add_flag("--gain, -n", "optimize until there is no gain");
add_flag("--verbose, -v", "print the information"); add_flag("--verbose, -v", "print the information");
} }
@ -54,12 +57,12 @@ class refactor_command : public command {
if (is_set("akers")) { if (is_set("akers")) {
akers_resynthesis<mig_network> resyn; akers_resynthesis<mig_network> resyn;
refactoring_params ps; refactoring_params ps;
ps.max_pis = 4u; ps.max_pis = cut_size;
refactoring(mig, resyn, ps); refactoring(mig, resyn, ps);
} else { } else {
mig_npn_resynthesis resyn; mig_npn_resynthesis resyn;
refactoring_params ps; refactoring_params ps;
ps.max_pis = 4u; ps.max_pis = cut_size;
refactoring(mig, resyn, ps); refactoring(mig, resyn, ps);
} }
mig = cleanup_dangling(mig); mig = cleanup_dangling(mig);
@ -77,7 +80,7 @@ class refactor_command : public command {
begin = clock(); begin = clock();
bidecomposition_resynthesis<xag_network> resyn; bidecomposition_resynthesis<xag_network> resyn;
refactoring_params ps; refactoring_params ps;
ps.max_pis = 4u; ps.max_pis = cut_size;
refactoring(xag, resyn, ps); refactoring(xag, resyn, ps);
xag = cleanup_dangling(xag); xag = cleanup_dangling(xag);
end = clock(); end = clock();
@ -92,11 +95,23 @@ class refactor_command : public command {
else { else {
auto xmg = store<xmg_network>().current(); auto xmg = store<xmg_network>().current();
begin = clock(); begin = clock();
xmg_npn_resynthesis resyn; if (is_set("gain")) {
refactoring_params ps; uint64_t size_current{};
ps.max_pis = 4u; do {
refactoring(xmg, resyn, ps); size_current = xmg.num_gates();
xmg = cleanup_dangling(xmg); xmg_npn_resynthesis resyn;
refactoring_params ps;
ps.max_pis = cut_size;
refactoring(xmg, resyn, ps);
xmg = cleanup_dangling(xmg);
} while (xmg.num_gates() < size_current);
} else {
xmg_npn_resynthesis resyn;
refactoring_params ps;
ps.max_pis = cut_size;
refactoring(xmg, resyn, ps);
xmg = cleanup_dangling(xmg);
}
end = clock(); end = clock();
totalTime = (double)(end - begin) / CLOCKS_PER_SEC; totalTime = (double)(end - begin) / CLOCKS_PER_SEC;
phyLS::print_stats(xmg); phyLS::print_stats(xmg);
@ -111,7 +126,7 @@ class refactor_command : public command {
begin = clock(); begin = clock();
direct_resynthesis<aig_network> aig_resyn; direct_resynthesis<aig_network> aig_resyn;
refactoring_params ps; refactoring_params ps;
ps.max_pis = 4u; ps.max_pis = cut_size;
refactoring(aig, aig_resyn, ps); refactoring(aig, aig_resyn, ps);
aig = cleanup_dangling(aig); aig = cleanup_dangling(aig);
end = clock(); end = clock();
@ -127,6 +142,7 @@ class refactor_command : public command {
} }
private: private:
uint32_t cut_size = 4u;
}; };
ALICE_ADD_COMMAND(refactor, "Synthesis") ALICE_ADD_COMMAND(refactor, "Synthesis")

View File

@ -34,8 +34,9 @@ class write_npz_command : public command {
add_option("--csv, -c", filename_csv, add_option("--csv, -c", filename_csv,
"The path to store csv file, default: ./placement/test.csv"); "The path to store csv file, default: ./placement/test.csv");
add_option("--def, -d", filename_def, add_option("--def, -d", filename_def,
"The path to store def file, default: " "The path to store def file, default: ./placement/floorplan.def");
"./placement/mfloorplan.def & ./placement/floorplan.def"); add_option("--mdef, -f", filename_mdef,
"The path to store def file, default: ./placement/mfloorplan.def");
} }
protected: protected:
@ -50,10 +51,9 @@ class write_npz_command : public command {
aig_network aig = store<aig_network>().current(); aig_network aig = store<aig_network>().current();
if (is_set("csv")) { if (is_set("csv")) {
phyLS::write_npz(aig, filename_csv); phyLS::write_npz(aig, filename_csv);
} else if (is_set("def")) { }
if (is_set("def")) {
phyLS::write_def(aig, filename_def, filename_mdef); phyLS::write_def(aig, filename_def, filename_mdef);
} else {
assert(false && "At least one filename should be specified. ");
} }
} }
} }

View File

@ -39,6 +39,7 @@ class wr_command : public command {
"set the cut size from 2 to 6, default = 4"); "set the cut size from 2 to 6, default = 4");
add_option("num_levels, -l", num_levels, add_option("num_levels, -l", num_levels,
"set the window level, default = 5"); "set the window level, default = 5");
add_flag("--xag, -a", "indow rewriting for XAG");
add_flag("--gain, -g", "optimize until there is no gain"); add_flag("--gain, -g", "optimize until there is no gain");
add_flag("--resub, -r", "window resub"); add_flag("--resub, -r", "window resub");
add_flag("--verbose, -v", "print the information"); add_flag("--verbose, -v", "print the information");
@ -48,44 +49,69 @@ class wr_command : public command {
void execute() { void execute() {
clock_t begin, end; clock_t begin, end;
double totalTime; double totalTime;
begin = clock(); begin = clock();
auto aig = store<aig_network>().current();
window_rewriting_params ps; if (is_set("xag")) {
ps.cut_size = cut_size; xag_network xag = store<xag_network>().current();
ps.num_levels = num_levels; window_rewriting_params ps;
ps.cut_size = cut_size;
if (is_set("resub")) { ps.num_levels = num_levels;
window_resub_params ps_r;
if (is_set("gain")) { if (is_set("gain")) {
window_aig_enumerative_resub(aig, ps_r);
} else {
window_aig_heuristic_resub(aig, ps_r);
}
aig = cleanup_dangling(aig);
} else {
if (is_set("gain")) {
uint64_t const size_before{aig.num_gates()};
uint64_t size_current{}; uint64_t size_current{};
do { do {
size_current = aig.num_gates(); size_current = xag.num_gates();
window_rewriting_stats win_st; window_rewriting_stats win_st;
window_rewriting(aig, ps, &win_st); window_rewriting(xag, ps, &win_st);
if (is_set("verbose")) win_st.report(); if (is_set("verbose")) win_st.report();
aig = cleanup_dangling(aig); xag = cleanup_dangling(xag);
} while (aig.num_gates() < size_current); } while (xag.num_gates() < size_current);
} else { } else {
window_rewriting_stats win_st; window_rewriting_stats win_st;
window_rewriting(aig, ps, &win_st); window_rewriting(xag, ps, &win_st);
aig = cleanup_dangling(aig); xag = cleanup_dangling(xag);
}
phyLS::print_stats(xag);
store<xag_network>().extend();
store<xag_network>().current() = xag;
} else {
if (store<aig_network>().size() == 0u)
std::cerr << "Error: Empty AIG network\n";
else {
auto aig = store<aig_network>().current();
window_rewriting_params ps;
ps.cut_size = cut_size;
ps.num_levels = num_levels;
if (is_set("resub")) {
window_resub_params ps_r;
if (is_set("gain")) {
window_aig_enumerative_resub(aig, ps_r);
} else {
window_aig_heuristic_resub(aig, ps_r);
}
aig = cleanup_dangling(aig);
} else {
if (is_set("gain")) {
uint64_t size_current{};
do {
size_current = aig.num_gates();
window_rewriting_stats win_st;
window_rewriting(aig, ps, &win_st);
if (is_set("verbose")) win_st.report();
aig = cleanup_dangling(aig);
} while (aig.num_gates() < size_current);
} else {
window_rewriting_stats win_st;
window_rewriting(aig, ps, &win_st);
aig = cleanup_dangling(aig);
}
}
phyLS::print_stats(aig);
store<aig_network>().extend();
store<aig_network>().current() = aig;
} }
} }
phyLS::print_stats(aig);
store<aig_network>().extend();
store<aig_network>().current() = aig;
end = clock(); end = clock();
totalTime = (double)(end - begin) / CLOCKS_PER_SEC; totalTime = (double)(end - begin) / CLOCKS_PER_SEC;

View File

@ -31,28 +31,38 @@ namespace phyLS {
template <class Ntk> template <class Ntk>
void write_npz(Ntk const& ntk, std::ostream& os) { void write_npz(Ntk const& ntk, std::ostream& os) {
std::stringstream connect; std::stringstream connect;
cout << "num_pis: " << ntk.num_pis() << endl; // cout << "num_pis: " << ntk.num_pis() << endl;
cout << "num_pos: " << ntk.num_pos() << endl; // cout << "num_pos: " << ntk.num_pos() << endl;
cout << "num_gates: " << ntk.num_gates() << endl; // cout << "num_gates: " << ntk.num_gates() << endl;
int num_pis = ntk.num_pis(), num_pos = ntk.num_pos(), int num_pis = ntk.num_pis(), num_pos = ntk.num_pos(),
num_gates = ntk.num_gates(); num_gates = ntk.num_gates();
int size = num_pis + num_pos + num_gates; int size = num_pis + num_pos + num_gates;
vector<vector<double>> adj(size, vector<double>(size, 0)); cout << "size: " << size << endl;
vector<double> value;
vector<vector<int>> coordinate(2);
ntk.foreach_node([&](auto const& n) { ntk.foreach_node([&](auto const& n) {
if (ntk.is_constant(n) || ntk.is_ci(n)) return true; if (ntk.is_constant(n) || ntk.is_ci(n)) return true;
ntk.foreach_fanin(n, [&](auto const& f) { ntk.foreach_fanin(n, [&](auto const& f) {
if (ntk.node_to_index(ntk.get_node(f)) <= num_pis) { if (ntk.node_to_index(ntk.get_node(f)) <= num_pis) {
adj[ntk.node_to_index(n) - num_pis - 1] value.push_back(0.6);
[ntk.node_to_index(ntk.get_node(f)) + num_gates - 1] = 1; coordinate[0].push_back(ntk.node_to_index(n) - num_pis - 1);
adj[ntk.node_to_index(ntk.get_node(f)) + num_gates - 1] coordinate[1].push_back(ntk.node_to_index(ntk.get_node(f)) + num_gates -
[ntk.node_to_index(n) - num_pis - 1] = 1; 1);
value.push_back(0.6);
coordinate[0].push_back(ntk.node_to_index(ntk.get_node(f)) + num_gates -
1);
coordinate[1].push_back(ntk.node_to_index(n) - num_pis - 1);
} else { } else {
adj[ntk.node_to_index(n) - num_pis - 1] value.push_back(1);
[ntk.node_to_index(ntk.get_node(f)) - num_pis - 1] = 0.5; coordinate[0].push_back(ntk.node_to_index(n) - num_pis - 1);
adj[ntk.node_to_index(ntk.get_node(f)) - num_pis - 1] coordinate[1].push_back(ntk.node_to_index(ntk.get_node(f)) - num_pis -
[ntk.node_to_index(n) - num_pis - 1] = 0.5; 1);
value.push_back(1);
coordinate[0].push_back(ntk.node_to_index(ntk.get_node(f)) - num_pis -
1);
coordinate[1].push_back(ntk.node_to_index(n) - num_pis - 1);
} }
return true; return true;
}); });
@ -61,19 +71,33 @@ void write_npz(Ntk const& ntk, std::ostream& os) {
ntk.foreach_po([&](auto const& f, auto i) { ntk.foreach_po([&](auto const& f, auto i) {
if (ntk.node_to_index(ntk.get_node(f)) <= num_pis) { if (ntk.node_to_index(ntk.get_node(f)) <= num_pis) {
adj[i + num_pis + num_gates] value.push_back(0.1);
[ntk.node_to_index(ntk.get_node(f)) + num_gates - 1] = 1; coordinate[0].push_back(i + num_pis + num_gates);
adj[ntk.node_to_index(ntk.get_node(f)) + num_gates - 1] coordinate[1].push_back(ntk.node_to_index(ntk.get_node(f)) + num_gates -
[i + num_pis + num_gates] = 1; 1);
value.push_back(0.1);
coordinate[0].push_back(ntk.node_to_index(ntk.get_node(f)) + num_gates -
1);
coordinate[1].push_back(i + num_pis + num_gates);
} else { } else {
adj[i + num_pis + num_gates] value.push_back(0.6);
[ntk.node_to_index(ntk.get_node(f)) - num_pis - 1] = 0.5; coordinate[0].push_back(i + num_pis + num_gates);
adj[ntk.node_to_index(ntk.get_node(f)) - num_pis - 1] coordinate[1].push_back(ntk.node_to_index(ntk.get_node(f)) - num_pis - 1);
[i + num_pis + num_gates] = 0.5; value.push_back(0.6);
coordinate[0].push_back(ntk.node_to_index(ntk.get_node(f)) - num_pis - 1);
coordinate[1].push_back(i + num_pis + num_gates);
} }
}); });
for (auto x : adj) { for (int i = 0; i < value.size(); i++) {
if (i == value.size() - 1) {
connect << fmt::format("{}", value[i]);
} else {
connect << fmt::format("{}", value[i]) << ",";
}
}
connect << "\n";
for (auto x : coordinate) {
for (int i = 0; i < x.size(); i++) { for (int i = 0; i < x.size(); i++) {
if (i == x.size() - 1) { if (i == x.size() - 1) {
connect << fmt::format("{}", x[i]); connect << fmt::format("{}", x[i]);
@ -89,9 +113,9 @@ void write_npz(Ntk const& ntk, std::ostream& os) {
template <class Ntk> template <class Ntk>
void write_def(Ntk const& ntk, std::ostream& os_def, std::ostream& os_mdef) { void write_def(Ntk const& ntk, std::ostream& os_def, std::ostream& os_mdef) {
std::stringstream components, pins, pins_def; std::stringstream components, pins, pins_def;
cout << "num_pis: " << ntk.num_pis() << endl; // cout << "num_pis: " << ntk.num_pis() << endl;
cout << "num_pos: " << ntk.num_pos() << endl; // cout << "num_pos: " << ntk.num_pos() << endl;
cout << "num_gates: " << ntk.num_gates() << endl; // cout << "num_gates: " << ntk.num_gates() << endl;
int num_pis = ntk.num_pis(), num_pos = ntk.num_pos(), int num_pis = ntk.num_pis(), num_pos = ntk.num_pos(),
num_gates = ntk.num_gates(); num_gates = ntk.num_gates();
int size = num_pis + num_pos + num_gates; int size = num_pis + num_pos + num_gates;

View File

@ -73,7 +73,7 @@ class stp_npn_resynthesis {
std::unordered_map<std::string, std::vector<std::string>> opt_klut; std::unordered_map<std::string, std::vector<std::string>> opt_klut;
void load_optimal_klut() { void load_optimal_klut() {
std::ifstream infile("../src/networks/stp/opt_map.txt"); std::ifstream infile("../src/networks/stp/opt_stp.txt");
if (!infile) { if (!infile) {
std::cout << " Cannot open file " << std::endl; std::cout << " Cannot open file " << std::endl;
assert(false); assert(false);

View File

@ -77,7 +77,7 @@
#include "commands/xmg/xmgrs.hpp" #include "commands/xmg/xmgrs.hpp"
#include "commands/xmg/xmgrw.hpp" #include "commands/xmg/xmgrw.hpp"
#include "commands/exact/exact_multi.hpp" #include "commands/exact/exact_multi.hpp"
#include "commands/to_npz.hpp"
// #include "commands/exact/exact_klut.hpp" // #include "commands/exact/exact_klut.hpp"
// #include "commands/exact/exactlut.hpp" // #include "commands/exact/exactlut.hpp"
// #include "commands/to_npz.hpp"
ALICE_MAIN(phyLS) ALICE_MAIN(phyLS)