Skip to content

Commit

Permalink
Updates to mapping (#627)
Browse files Browse the repository at this point in the history
  • Loading branch information
aletempiac authored Dec 28, 2023
1 parent d0fddde commit d0f4ed2
Show file tree
Hide file tree
Showing 19 changed files with 1,249 additions and 125 deletions.
1 change: 1 addition & 0 deletions docs/algorithms/index_restructuring.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ Logic restructuring and optimization
functional_reduction
refactoring
aig_balancing
xag_balancing
balancing
cost_generic_resub
6 changes: 3 additions & 3 deletions docs/algorithms/mapper.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ using a NPN resynthesis database of structures:

/* load the npn database in the library */
mig_npn_resynthesis resyn{ true };
exact_library<mig_network, mig_npn_resynthesis> exact_lib( resyn );
exact_library<mig_network> exact_lib( resyn );
/* perform graph mapping */
map_params ps;
Expand Down Expand Up @@ -90,7 +90,7 @@ database of structures:

/* load the npn database in the library */
mig_npn_resynthesis resyn{ true };
exact_library<sequential<mig_network>, mig_npn_resynthesis> exact_lib( resyn );
exact_library<sequential<mig_network>> exact_lib( resyn );
/* perform graph mapping */
map_params ps;
Expand All @@ -109,7 +109,7 @@ leverage satisfiability don't cares:
mig_npn_resynthesis resyn{ true };
exact_library_params lps;
lps.compute_dc_classes = true;
exact_library<mig_network, mig_npn_resynthesis> exact_lib( resyn, lps );
exact_library<mig_network> exact_lib( resyn, lps );
/* perform area-oriented rewriting */
map_params ps;
Expand Down
6 changes: 3 additions & 3 deletions docs/algorithms/rewrite.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ networks. In this case the maximum number of variables for a node function is
mig_npn_resynthesis resyn{ true };
exact_library_params eps;
eps.np_classification = false;
exact_library<mig_network, decltype( resyn )> exact_lib( resyn, eps );
exact_library<mig_network> exact_lib( resyn, eps );
It is possible to change the cost function of nodes in rewrite. Here is
an example, in which the cost function only accounts for AND gates in a network,
Expand All @@ -36,7 +36,7 @@ which corresponds to the multiplicative complexity of a function.
SomeResynthesisClass resyn;
exact_library_params eps;
eps.np_classification = false;
exact_library<xag_network, decltype( resyn )> exact_lib( resyn, eps );
exact_library<xag_network> exact_lib( resyn, eps );
rewrite<decltype( Ntk ), decltype( exact_lib ), mc_cost>( ntk, exact_lib );

Rewrite supports also satisfiability don't cares:
Expand All @@ -51,7 +51,7 @@ Rewrite supports also satisfiability don't cares:
exact_library_params eps;
eps.np_classification = false;
eps.compute_dc_classes = true;
exact_library<mig_network, decltype( resyn )> exact_lib( resyn, eps );
exact_library<mig_network> exact_lib( resyn, eps );
/* rewrite */
rewrite_params ps;
Expand Down
15 changes: 15 additions & 0 deletions docs/algorithms/xag_balancing.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
XAG balancing
-------------

**Header:** ``mockturtle/algorithms/xag_balancing.hpp``

Parameters
~~~~~~~~~~

.. doxygenstruct:: mockturtle::xag_balancing_params
:members:

Algorithm
~~~~~~~~~

.. doxygenfunction:: mockturtle::xag_balance
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ v0.4 (not yet released)
- Adding a new technology mapper supporting multi-output cells (`emap`) `#623 <https://github.com/lsils/mockturtle/pull/623>`_
- Adding circuit extraction of half and full adders (`extract_adders`) `#623 <https://github.com/lsils/mockturtle/pull/623>`_
- Adding don't care support in rewriting (`map`, `rewrite`) `#623 <https://github.com/lsils/mockturtle/pull/623>`_
- XAG balancing (`xag_balance`) `#627 <https://github.com/lsils/mockturtle/pull/627>`_
* I/O:
- Write gates to GENLIB file (`write_genlib`) `#606 <https://github.com/lsils/mockturtle/pull/606>`_
* Views:
Expand Down
3 changes: 2 additions & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
sphinx==5.1.1
breathe==4.34.0
breathe==4.34.0
sphinx-rtd-theme==1.2.2
5 changes: 3 additions & 2 deletions experiments/aqfp_flow_date.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ struct opt_stats_t
uint32_t jj_level_after_exact;
};

mig_network remapping_round( mig_network const& ntk, exact_library<mig_network, mig_npn_resynthesis> const& exact_lib, opt_params_t const& opt_params, opt_stats_t& stats )
mig_network remapping_round( mig_network const& ntk, exact_library<mig_network> const& exact_lib, opt_params_t const& opt_params, opt_stats_t& stats )
{
map_params psm;
psm.skip_delay_round = false;
Expand Down Expand Up @@ -354,7 +354,8 @@ int main( int argc, char** argv )
/* library to map to MIGs */
mig_npn_resynthesis resyn{ true };
exact_library_params eps;
exact_library<mig_network, mig_npn_resynthesis> exact_lib( resyn, eps );
eps.np_classification = true;
exact_library<mig_network> exact_lib( resyn, eps );

/* database loading for aqfp resynthesis*/
auto db3_str = get_database( "db3" );
Expand Down
3 changes: 2 additions & 1 deletion experiments/mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ int main()
/* library to map to MIGs */
mig_npn_resynthesis resyn{ true };
exact_library_params eps;
exact_library<mig_network, mig_npn_resynthesis> exact_lib( resyn, eps );
eps.np_classification = true;
exact_library<mig_network> exact_lib( resyn, eps );

/* library to map to technology */
std::vector<gate> gates;
Expand Down
9 changes: 5 additions & 4 deletions experiments/rewrite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <mockturtle/algorithms/cleanup.hpp>
#include <mockturtle/algorithms/node_resynthesis/xag_npn.hpp>
#include <mockturtle/algorithms/rewrite.hpp>
#include <mockturtle/algorithms/xag_balancing.hpp>
#include <mockturtle/io/aiger_reader.hpp>
#include <mockturtle/networks/xag.hpp>
#include <mockturtle/utils/tech_library.hpp>
Expand All @@ -44,10 +45,8 @@ int main()
experiment<std::string, uint32_t, uint32_t, uint32_t, uint32_t, float, bool>
exp( "rewrite", "benchmark", "size_before", "size_after", "depth_before", "depth_after", "runtime", "equivalent" );

xag_npn_resynthesis<xag_network, xag_network, xag_npn_db_kind::xag_incomplete> resyn;
exact_library_params eps;
eps.np_classification = false;
exact_library<xag_network, decltype( resyn )> exact_lib( resyn, eps );
xag_npn_resynthesis<xag_network, xag_network, xag_npn_db_kind::xag_complete> resyn;
exact_library<xag_network> exact_lib( resyn );

for ( auto const& benchmark : epfl_benchmarks() )
{
Expand All @@ -62,6 +61,8 @@ int main()
rewrite_params ps;
rewrite_stats st;

xag_balance( xag );

uint32_t const size_before = xag.num_gates();
uint32_t const depth_before = depth_view( xag ).depth();

Expand Down
155 changes: 120 additions & 35 deletions include/mockturtle/algorithms/lut_mapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#include "../views/mffc_view.hpp"
#include "../views/topo_view.hpp"
#include "cleanup.hpp"
#include "collapse_mapped.hpp"
#include "cut_enumeration.hpp"
#include "exorcism.hpp"
#include "simulation.hpp"
Expand Down Expand Up @@ -2248,6 +2249,12 @@ class lut_map_impl
#pragma region Dump network
klut_network create_lut_network()
{
/* specialized method: does not support buffer/inverter sweeping */
if ( StoreFunction && ps.cut_enumeration_ps.minimize_truth_table )
{
return create_lut_network_mapped();
}

klut_network res;
node_map<signal<klut_network>, Ntk> node_to_signal( ntk );

Expand Down Expand Up @@ -2330,6 +2337,7 @@ class lut_map_impl
} );

/* TODO: add sequential compatibility */
edges = 0;
for ( auto const& n : topo_order )
{
if ( ntk.is_ci( n ) || ntk.is_constant( n ) )
Expand All @@ -2344,6 +2352,7 @@ class lut_map_impl
kitty::dynamic_truth_table tt;
std::vector<signal<klut_network>> children;
std::tie( tt, children ) = create_lut( n, node_to_signal, node_driver_type );
edges += children.size();

switch ( node_driver_type[n] )
{
Expand All @@ -2360,6 +2369,7 @@ class lut_map_impl
case driver_type::mixed:
node_to_signal[n] = res.create_node( children, tt );
opposites[n] = res.create_node( children, ~tt );
edges += children.size();
break;
}
}
Expand All @@ -2379,6 +2389,46 @@ class lut_map_impl
return res;
}

klut_network create_lut_network_mapped()
{
klut_network res;
mapping_view<Ntk, true> mapping_ntk{ ntk };

/* load mapping info */
for ( auto const& n : topo_order )
{
if ( ntk.is_ci( n ) || ntk.is_constant( n ) )
continue;

const auto index = ntk.node_to_index( n );
if ( node_match[index].map_refs == 0 )
continue;

std::vector<node> nodes;
auto const& best_cut = cuts[index][0];

for ( auto const& l : best_cut )
{
nodes.push_back( ntk.index_to_node( l ) );
}
mapping_ntk.add_to_mapping( n, nodes.begin(), nodes.end() );

if constexpr ( StoreFunction )
{
mapping_ntk.set_cell_function( n, truth_tables[best_cut->func_id] );
}
}

/* generate mapped network */
collapse_mapped_network( res, mapping_ntk );

st.area = area;
st.delay = delay;
st.edges = edges;

return res;
}

inline lut_info create_lut( node const& n, node_map<signal<klut_network>, Ntk>& node_to_signal, node_map<driver_type, Ntk> const& node_driver_type )
{
auto const& best_cut = cuts[ntk.node_to_index( n )][0];
Expand All @@ -2389,48 +2439,41 @@ class lut_map_impl
children.push_back( node_to_signal[ntk.index_to_node( l )] );
}

kitty::dynamic_truth_table tt;
/* recursively compute the function for each choice until success */
ntk.incr_trav_id();
unordered_node_map<kitty::dynamic_truth_table, Ntk> node_to_value( ntk );

if constexpr ( StoreFunction )
/* add constants */
node_to_value[ntk.get_node( ntk.get_constant( false ) )] = kitty::dynamic_truth_table( best_cut.size() );
ntk.set_visited( ntk.get_node( ntk.get_constant( false ) ), ntk.trav_id() );
if ( ntk.get_node( ntk.get_constant( false ) ) != ntk.get_node( ntk.get_constant( true ) ) )
{
tt = truth_tables[best_cut->func_id];
node_to_value[ntk.get_node( ntk.get_constant( true ) )] = ~kitty::dynamic_truth_table( best_cut.size() );
ntk.set_visited( ntk.get_node( ntk.get_constant( true ) ), ntk.trav_id() );
}
else
{
/* recursively compute the function for each choice until success */
ntk.incr_trav_id();
unordered_node_map<kitty::dynamic_truth_table, Ntk> node_to_value( ntk );

/* add constants */
node_to_value[ntk.get_node( ntk.get_constant( false ) )] = kitty::dynamic_truth_table( best_cut.size() );
ntk.set_visited( ntk.get_node( ntk.get_constant( false ) ), ntk.trav_id() );
if ( ntk.get_node( ntk.get_constant( false ) ) != ntk.get_node( ntk.get_constant( true ) ) )
{
node_to_value[ntk.get_node( ntk.get_constant( true ) )] = ~kitty::dynamic_truth_table( best_cut.size() );
ntk.set_visited( ntk.get_node( ntk.get_constant( true ) ), ntk.trav_id() );
}
/* add leaves */
uint32_t ctr = 0;
for ( uint32_t leaf : best_cut )
{
kitty::dynamic_truth_table tt_leaf( best_cut.size() );
kitty::create_nth_var( tt_leaf, ctr++, node_driver_type[ntk.index_to_node( leaf )] == driver_type::neg );
node_to_value[ntk.index_to_node( leaf )] = tt_leaf;
ntk.set_visited( ntk.index_to_node( leaf ), ntk.trav_id() );
}

/* add leaves */
uint32_t ctr = 0;
for ( uint32_t leaf : best_cut )
{
kitty::dynamic_truth_table tt_leaf( best_cut.size() );
kitty::create_nth_var( tt_leaf, ctr++, node_driver_type[ntk.index_to_node( leaf )] == driver_type::neg );
node_to_value[ntk.index_to_node( leaf )] = tt_leaf;
ntk.set_visited( ntk.index_to_node( leaf ), ntk.trav_id() );
}
/* recursively compute the function */
ntk.foreach_fanin( n, [&]( auto const& f ) {
compute_function_rec( ntk.get_node( f ), node_to_value );
} );

/* recursively compute the function */
ntk.foreach_fanin( n, [&]( auto const& f ) {
compute_function_rec( ntk.get_node( f ), node_to_value );
} );
std::vector<kitty::dynamic_truth_table> tts;
ntk.foreach_fanin( n, [&]( auto const& f ) {
tts.push_back( node_to_value[ntk.get_node( f )] );
} );
TT tt = ntk.compute( n, tts.begin(), tts.end() );

std::vector<kitty::dynamic_truth_table> tts;
ntk.foreach_fanin( n, [&]( auto const& f ) {
tts.push_back( node_to_value[ntk.get_node( f )] );
} );
tt = ntk.compute( n, tts.begin(), tts.end() );
}
minimize_support( tt, children );

return { tt, children };
}
Expand Down Expand Up @@ -2491,6 +2534,48 @@ class lut_map_impl
st.delay = delay;
st.edges = edges;
}

void minimize_support( TT& tt, std::vector<signal<klut_network>>& children )
{
uint32_t support = 0u;
uint32_t support_size = 0u;
for ( uint32_t i = 0u; i < tt.num_vars(); ++i )
{
if ( kitty::has_var( tt, i ) )
{
support |= 1u << i;
++support_size;
}
}

/* variables not in the support are the most significative */
if ( ( support & ( support + 1u ) ) == 0u )
{
if ( support_size != children.size() )
{
children.erase( children.begin() + support_size, children.end() );
tt = kitty::shrink_to( tt, support_size );
}

return;
}

/* vacuous variables */
const auto support_vector = kitty::min_base_inplace( tt );
assert( support_vector.size() != children.size() );

auto tt_shrink = shrink_to( tt, support_size );
std::vector<signal<klut_network>> children_support( support_size );

auto it_support = support_vector.begin();
auto it_children = children_support.begin();
while ( it_support != support_vector.end() )
{
*it_children++ = children[*it_support++];
}

children = std::move( children_support );
}
#pragma endregion

#pragma region balancing
Expand Down
Loading

0 comments on commit d0f4ed2

Please sign in to comment.