From 52d20f4c9fce1188696b9715acf0dfa276cf51de Mon Sep 17 00:00:00 2001 From: panhomyoung Date: Fri, 19 Jul 2024 16:29:09 +0800 Subject: [PATCH] update xag optimziation --- src/commands/balance.hpp | 19 +++++--- src/commands/lut_mapping.hpp | 4 +- src/commands/lutmap.hpp | 29 +++++++++++- src/commands/node_resynthesis.hpp | 3 +- src/commands/refactor.hpp | 34 ++++++++++---- src/commands/to_npz.hpp | 10 ++-- src/commands/window_rewriting.hpp | 78 ++++++++++++++++++++----------- src/core/tonpz.hpp | 72 ++++++++++++++++++---------- src/networks/stp/stp_npn.hpp | 2 +- src/phyLS.cpp | 2 +- 10 files changed, 174 insertions(+), 79 deletions(-) diff --git a/src/commands/balance.hpp b/src/commands/balance.hpp index 0413845..54dd868 100644 --- a/src/commands/balance.hpp +++ b/src/commands/balance.hpp @@ -34,6 +34,7 @@ class balance_command : public command { : command(env, "transforms the current network into a well-balanced AIG") { 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("--verbose, -v", "print the information"); } @@ -42,6 +43,8 @@ class balance_command : public command { void execute() { clock_t begin, end; double totalTime = 0.0; + begin = clock(); + if (is_set("xmg")) { xmg_network xmg = store().current(); xmg = balancing( @@ -53,31 +56,33 @@ class balance_command : public command { store().extend(); store().current() = xmg_copy; + } else if (is_set("xag")) { + xag_network xag = store().current(); + xag_network res = esop_balancing(xag); + phyLS::print_stats(res); + store().extend(); + store().current() = res; } else { if (store().size() == 0u) std::cerr << "Error: Empty AIG network\n"; else { auto aig = store().current(); if (is_set("strash")) { - begin = clock(); aig_balancing_params ps; ps.minimize_levels = false; aig_balance(aig, ps); - end = clock(); - totalTime = (double)(end - begin) / CLOCKS_PER_SEC; } else { - begin = clock(); aig_balance(aig); - end = clock(); - totalTime = (double)(end - begin) / CLOCKS_PER_SEC; } phyLS::print_stats(aig); - store().extend(); store().current() = aig; } } + end = clock(); + totalTime = (double)(end - begin) / CLOCKS_PER_SEC; + cout.setf(ios::fixed); cout << "[CPU time] " << setprecision(2) << totalTime << " s" << endl; } diff --git a/src/commands/lut_mapping.hpp b/src/commands/lut_mapping.hpp index 7e736e6..a033c2b 100644 --- a/src/commands/lut_mapping.hpp +++ b/src/commands/lut_mapping.hpp @@ -47,9 +47,7 @@ class lut_mapping_command : public command { clock_t begin, end; double totalTime; lut_mapping_params ps; - if (is_set("area")){ - ps.rounds_ela = 4u; - } + if (is_set("area")) ps.rounds = 0u; if (is_set("mig")) { /* derive some MIG */ diff --git a/src/commands/lutmap.hpp b/src/commands/lutmap.hpp index 1fa62d5..accc6a3 100644 --- a/src/commands/lutmap.hpp +++ b/src/commands/lutmap.hpp @@ -32,8 +32,9 @@ class lutmap_command : public command { add_flag("--mig, -m", "FPGA technology mapping for MIG"); add_flag("--xag, -g", "FPGA technology mapping for XAG"); 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, - "Maximum number of leaves for a cut [default = 4]"); + "Maximum number of leaves for a cut [default = 6]"); add_option( "--cut_limit, -l", cut_limit, "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]"); add_flag("--dominated_cuts, -d", "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"); } @@ -119,6 +121,24 @@ class lutmap_command : public command { phyLS::lut_map(mapped_xmg, ps); mapped_xmg.clear_mapping(); } + } else if (is_set("klut")) { + if (store().size() == 0u) + std::cerr << "Error: Empty k-LUT network\n"; + else { + auto klut = store().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 { if (store().size() == 0u) std::cerr << "Error: Empty AIG network\n"; @@ -139,7 +159,11 @@ class lutmap_command : public command { mapped_aig, ps); else 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_limit{8u}; uint32_t relax_required{0u}; + std::string filename = "lut.bench"; }; ALICE_ADD_COMMAND(lutmap, "Mapping") diff --git a/src/commands/node_resynthesis.hpp b/src/commands/node_resynthesis.hpp index b761e29..51686c2 100644 --- a/src/commands/node_resynthesis.hpp +++ b/src/commands/node_resynthesis.hpp @@ -31,6 +31,7 @@ #include #include "../core/misc.hpp" +#include "../networks/aoig/xag_lut_npn.hpp" using namespace std; using namespace mockturtle; @@ -75,7 +76,7 @@ class resyn_command : public command { totalTime = (double)(end - begin) / CLOCKS_PER_SEC; } else if (is_set("xag")) { begin = clock(); - xag_npn_resynthesis resyn; + xag_npn_lut_resynthesis resyn; const auto xag = node_resynthesis(klut, resyn); store().extend(); store().current() = cleanup_dangling(xag); diff --git a/src/commands/refactor.hpp b/src/commands/refactor.hpp index bdc851b..1be94ca 100644 --- a/src/commands/refactor.hpp +++ b/src/commands/refactor.hpp @@ -33,10 +33,13 @@ class refactor_command : public command { explicit refactor_command(const environment::ptr& env) : command(env, "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("--xag, -g", "refactoring for XAG"); add_flag("--xmg, -x", "refactoring for XMG"); 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"); } @@ -54,12 +57,12 @@ class refactor_command : public command { if (is_set("akers")) { akers_resynthesis resyn; refactoring_params ps; - ps.max_pis = 4u; + ps.max_pis = cut_size; refactoring(mig, resyn, ps); } else { mig_npn_resynthesis resyn; refactoring_params ps; - ps.max_pis = 4u; + ps.max_pis = cut_size; refactoring(mig, resyn, ps); } mig = cleanup_dangling(mig); @@ -77,7 +80,7 @@ class refactor_command : public command { begin = clock(); bidecomposition_resynthesis resyn; refactoring_params ps; - ps.max_pis = 4u; + ps.max_pis = cut_size; refactoring(xag, resyn, ps); xag = cleanup_dangling(xag); end = clock(); @@ -92,11 +95,23 @@ class refactor_command : public command { else { auto xmg = store().current(); begin = clock(); - xmg_npn_resynthesis resyn; - refactoring_params ps; - ps.max_pis = 4u; - refactoring(xmg, resyn, ps); - xmg = cleanup_dangling(xmg); + if (is_set("gain")) { + uint64_t size_current{}; + do { + size_current = xmg.num_gates(); + 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(); totalTime = (double)(end - begin) / CLOCKS_PER_SEC; phyLS::print_stats(xmg); @@ -111,7 +126,7 @@ class refactor_command : public command { begin = clock(); direct_resynthesis aig_resyn; refactoring_params ps; - ps.max_pis = 4u; + ps.max_pis = cut_size; refactoring(aig, aig_resyn, ps); aig = cleanup_dangling(aig); end = clock(); @@ -127,6 +142,7 @@ class refactor_command : public command { } private: + uint32_t cut_size = 4u; }; ALICE_ADD_COMMAND(refactor, "Synthesis") diff --git a/src/commands/to_npz.hpp b/src/commands/to_npz.hpp index 8e0de05..c55a553 100644 --- a/src/commands/to_npz.hpp +++ b/src/commands/to_npz.hpp @@ -34,8 +34,9 @@ class write_npz_command : public command { add_option("--csv, -c", filename_csv, "The path to store csv file, default: ./placement/test.csv"); add_option("--def, -d", filename_def, - "The path to store def file, default: " - "./placement/mfloorplan.def & ./placement/floorplan.def"); + "The path to store def file, default: ./placement/floorplan.def"); + add_option("--mdef, -f", filename_mdef, + "The path to store def file, default: ./placement/mfloorplan.def"); } protected: @@ -50,10 +51,9 @@ class write_npz_command : public command { aig_network aig = store().current(); if (is_set("csv")) { phyLS::write_npz(aig, filename_csv); - } else if (is_set("def")) { + } + if (is_set("def")) { phyLS::write_def(aig, filename_def, filename_mdef); - } else { - assert(false && "At least one filename should be specified. "); } } } diff --git a/src/commands/window_rewriting.hpp b/src/commands/window_rewriting.hpp index 5ab768d..3d20747 100644 --- a/src/commands/window_rewriting.hpp +++ b/src/commands/window_rewriting.hpp @@ -39,6 +39,7 @@ class wr_command : public command { "set the cut size from 2 to 6, default = 4"); add_option("num_levels, -l", num_levels, "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("--resub, -r", "window resub"); add_flag("--verbose, -v", "print the information"); @@ -48,44 +49,69 @@ class wr_command : public command { void execute() { clock_t begin, end; double totalTime; - begin = clock(); - auto aig = store().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("xag")) { + xag_network xag = store().current(); + window_rewriting_params ps; + ps.cut_size = cut_size; + ps.num_levels = num_levels; 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{}; do { - size_current = aig.num_gates(); + size_current = xag.num_gates(); window_rewriting_stats win_st; - window_rewriting(aig, ps, &win_st); + window_rewriting(xag, ps, &win_st); if (is_set("verbose")) win_st.report(); - aig = cleanup_dangling(aig); - } while (aig.num_gates() < size_current); + xag = cleanup_dangling(xag); + } while (xag.num_gates() < size_current); } else { window_rewriting_stats win_st; - window_rewriting(aig, ps, &win_st); - aig = cleanup_dangling(aig); + window_rewriting(xag, ps, &win_st); + xag = cleanup_dangling(xag); + } + phyLS::print_stats(xag); + store().extend(); + store().current() = xag; + } else { + if (store().size() == 0u) + std::cerr << "Error: Empty AIG network\n"; + else { + auto aig = store().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().extend(); + store().current() = aig; } } - phyLS::print_stats(aig); - store().extend(); - store().current() = aig; - end = clock(); totalTime = (double)(end - begin) / CLOCKS_PER_SEC; diff --git a/src/core/tonpz.hpp b/src/core/tonpz.hpp index 0f932dd..6c0a823 100644 --- a/src/core/tonpz.hpp +++ b/src/core/tonpz.hpp @@ -31,28 +31,38 @@ namespace phyLS { template void write_npz(Ntk const& ntk, std::ostream& os) { std::stringstream connect; - cout << "num_pis: " << ntk.num_pis() << endl; - cout << "num_pos: " << ntk.num_pos() << endl; - cout << "num_gates: " << ntk.num_gates() << endl; +// cout << "num_pis: " << ntk.num_pis() << endl; +// cout << "num_pos: " << ntk.num_pos() << endl; +// cout << "num_gates: " << ntk.num_gates() << endl; int num_pis = ntk.num_pis(), num_pos = ntk.num_pos(), num_gates = ntk.num_gates(); int size = num_pis + num_pos + num_gates; - vector> adj(size, vector(size, 0)); + cout << "size: " << size << endl; + vector value; + vector> coordinate(2); ntk.foreach_node([&](auto const& n) { if (ntk.is_constant(n) || ntk.is_ci(n)) return true; ntk.foreach_fanin(n, [&](auto const& f) { if (ntk.node_to_index(ntk.get_node(f)) <= num_pis) { - adj[ntk.node_to_index(n) - num_pis - 1] - [ntk.node_to_index(ntk.get_node(f)) + num_gates - 1] = 1; - adj[ntk.node_to_index(ntk.get_node(f)) + num_gates - 1] - [ntk.node_to_index(n) - num_pis - 1] = 1; + value.push_back(0.6); + coordinate[0].push_back(ntk.node_to_index(n) - num_pis - 1); + coordinate[1].push_back(ntk.node_to_index(ntk.get_node(f)) + num_gates - + 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 { - adj[ntk.node_to_index(n) - num_pis - 1] - [ntk.node_to_index(ntk.get_node(f)) - num_pis - 1] = 0.5; - adj[ntk.node_to_index(ntk.get_node(f)) - num_pis - 1] - [ntk.node_to_index(n) - num_pis - 1] = 0.5; + value.push_back(1); + coordinate[0].push_back(ntk.node_to_index(n) - num_pis - 1); + coordinate[1].push_back(ntk.node_to_index(ntk.get_node(f)) - num_pis - + 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; }); @@ -61,19 +71,33 @@ void write_npz(Ntk const& ntk, std::ostream& os) { ntk.foreach_po([&](auto const& f, auto i) { if (ntk.node_to_index(ntk.get_node(f)) <= num_pis) { - adj[i + num_pis + num_gates] - [ntk.node_to_index(ntk.get_node(f)) + num_gates - 1] = 1; - adj[ntk.node_to_index(ntk.get_node(f)) + num_gates - 1] - [i + num_pis + num_gates] = 1; + value.push_back(0.1); + coordinate[0].push_back(i + num_pis + num_gates); + coordinate[1].push_back(ntk.node_to_index(ntk.get_node(f)) + num_gates - + 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 { - adj[i + num_pis + num_gates] - [ntk.node_to_index(ntk.get_node(f)) - num_pis - 1] = 0.5; - adj[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(i + num_pis + num_gates); + coordinate[1].push_back(ntk.node_to_index(ntk.get_node(f)) - num_pis - 1); + 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++) { if (i == x.size() - 1) { connect << fmt::format("{}", x[i]); @@ -89,9 +113,9 @@ void write_npz(Ntk const& ntk, std::ostream& os) { template void write_def(Ntk const& ntk, std::ostream& os_def, std::ostream& os_mdef) { std::stringstream components, pins, pins_def; - cout << "num_pis: " << ntk.num_pis() << endl; - cout << "num_pos: " << ntk.num_pos() << endl; - cout << "num_gates: " << ntk.num_gates() << endl; +// cout << "num_pis: " << ntk.num_pis() << endl; +// cout << "num_pos: " << ntk.num_pos() << endl; +// cout << "num_gates: " << ntk.num_gates() << endl; int num_pis = ntk.num_pis(), num_pos = ntk.num_pos(), num_gates = ntk.num_gates(); int size = num_pis + num_pos + num_gates; diff --git a/src/networks/stp/stp_npn.hpp b/src/networks/stp/stp_npn.hpp index 4346d39..6fd0ea4 100644 --- a/src/networks/stp/stp_npn.hpp +++ b/src/networks/stp/stp_npn.hpp @@ -73,7 +73,7 @@ class stp_npn_resynthesis { std::unordered_map> opt_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) { std::cout << " Cannot open file " << std::endl; assert(false); diff --git a/src/phyLS.cpp b/src/phyLS.cpp index 68504ad..501ffc1 100644 --- a/src/phyLS.cpp +++ b/src/phyLS.cpp @@ -77,7 +77,7 @@ #include "commands/xmg/xmgrs.hpp" #include "commands/xmg/xmgrw.hpp" #include "commands/exact/exact_multi.hpp" +#include "commands/to_npz.hpp" // #include "commands/exact/exact_klut.hpp" // #include "commands/exact/exactlut.hpp" -// #include "commands/to_npz.hpp" ALICE_MAIN(phyLS) \ No newline at end of file