Skip to content

Commit

Permalink
LUT mapper (lsils#581)
Browse files Browse the repository at this point in the history
* New LUT mapper (to be cleaned and fixed)

* Updates to LUT mapper

* Adding space

* fix enum to enum class

* Add new experimental mapper with dominated cuts option

* Minor updates and clang formatting

* Adding tests, fixes

* Preparing the branch for merging

* Formatting

* Runtime optimization for truth table operations
  • Loading branch information
aletempiac authored Nov 28, 2022
1 parent 8b26b59 commit 0246326
Show file tree
Hide file tree
Showing 9 changed files with 2,583 additions and 11 deletions.
71 changes: 68 additions & 3 deletions docs/algorithms/lut_mapping.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,68 @@
LUT mapping
-----------
LUT mapping 1
-------------

Dynamic-programming based heuristic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

LUT mapping with cut size :math:`k` partitions a logic network into mapped
nodes and unmapped nodes, where a mapped node :math:`n` is assigned some cut
:math:`(n, L)` such that the following conditions hold: i) each node that
drives a primary output is mapped, and ii) each leaf in the cut of a mapped
node is either a primary input or also mapped. This ensures that the mapping
covers the whole logic network. LUT mapping aims to find a good mapping with
respect to a cost function, e.g., a short critical path in the mapping or a
small number of mapped nodes. The LUT mapping algorithm can assign a weight
to a cut for alternative cost functions.

This implementation offers delay- or area-oriented mapping. The mapper can be
configured using many options.

The following example shows how to perform a LUT mapping to an And-inverter
graph using the default settings:

.. code-block:: c++

aig_network aig = ...;
mapping_view mapped_aig{aig};
lut_map( mapped_aig );

Note that the AIG is wrapped into a `mapping_view` in order to equip the
network structure with the required mapping methods.

The next example is more complex. It uses an MIG as underlying network
structure, maps for area, changes the cut size :math:`k` to 8, and also
computes the functions for the cut of each mapped node:

.. code-block:: c++

mig_network mig = ...;
mapped_view<mig_network, true> mapped_mig{mig};

lut_map_params ps;
ps.area_oriented_mapping = true;
ps.edge_optimization = false;
ps.remove_dominated_cuts = false;
ps.recompute_cuts = false;
ps.cut_enumeration_ps.cut_size = 8;
lut_map<mapped_view<mig_network, true>, true>( mapped_mig, ps );

**Parameters and statistics**

.. doxygenstruct:: mockturtle::lut_map_params
:members:

.. doxygenstruct:: mockturtle::lut_map_stats
:members:

**Algorithm**

.. doxygenfunction:: mockturtle::lut_map


LUT mapping 2
-------------

Dynamic-programming based heuristic
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -16,6 +79,8 @@ respect to a cost function, e.g., a short critical path in the mapping or a
small number of mapped nodes. The LUT mapping algorithm can assign a weight
to a cut for alternative cost functions.

This implementation performs ony area-oriented mapping.

The following example shows how to perform a LUT mapping to an And-inverter
graph using the default settings:

Expand All @@ -39,7 +104,7 @@ for the cut of each mapped node:

lut_mapping_params ps;
ps.cut_enumeration_ps.cut_size = 8;
lut_mapping<mapped_view<mig_network, true>, true>( mapped_mig );
lut_mapping<mapped_view<mig_network, true>, true>( mapped_mig, ps );

**Parameters and statistics**

Expand Down
2 changes: 2 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ v0.4 (not yet released)
- Cost aware resynthesis solver (`cost_resyn`) `#554 <https://github.com/lsils/mockturtle/pull/554>`_
- Resynthesis based on SOP factoring (`sop_factoring`) `#579 <https://github.com/lsils/mockturtle/pull/579>`_
- XAG algebraic depth rewriting (`xag_algebraic_depth_rewriting`) `#580 <https://github.com/lsils/mockturtle/pull/580>`_
- Collapse mapped extended to compute mapping functions if the mapped network doesn't have them stored (`collapse_mapped`) `#581 <https://github.com/lsils/mockturtle/pull/581>`_
- Extended LUT mapping for delay and area (`lut_map`) `#581 <https://github.com/lsils/mockturtle/pull/581>`_
* Views:
- Add cost view to evaluate costs in the network and to maintain contexts (`cost_view`) `#554 <https://github.com/lsils/mockturtle/pull/554>`_
* Properties:
Expand Down
79 changes: 79 additions & 0 deletions experiments/lut_mapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/* mockturtle: C++ logic network library
* Copyright (C) 2018-2019 EPFL
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

#include <string>
#include <vector>

#include <fmt/format.h>
#include <lorina/aiger.hpp>
#include <mockturtle/algorithms/collapse_mapped.hpp>
#include <mockturtle/algorithms/lut_mapper.hpp>
#include <mockturtle/io/aiger_reader.hpp>
#include <mockturtle/networks/aig.hpp>
#include <mockturtle/networks/klut.hpp>
#include <mockturtle/views/depth_view.hpp>
#include <mockturtle/views/mapping_view.hpp>

#include <experiments.hpp>

int main()
{
using namespace experiments;
using namespace mockturtle;

experiment<std::string, uint32_t, uint32_t, uint32_t, double, bool> exp( "lut_mapper", "benchmark", "luts", "lut_depth", "edges", "runtime", "equivalent" );

for ( auto const& benchmark : epfl_benchmarks() )
{
fmt::print( "[i] processing {}\n", benchmark );
aig_network aig;
if ( lorina::read_aiger( benchmark_path( benchmark ), aiger_reader( aig ) ) != lorina::return_code::success )
{
continue;
}

lut_map_params ps;
ps.cut_enumeration_ps.cut_size = 6u;
ps.cut_enumeration_ps.cut_limit = 8u;
ps.recompute_cuts = true;
ps.area_oriented_mapping = false;
ps.cut_expansion = true;
lut_map_stats st;
mapping_view<aig_network, false> mapped_aig{ aig };
lut_map<decltype( mapped_aig ), false>( mapped_aig, ps, &st );
const auto klut = *collapse_mapped_network<klut_network>( mapped_aig );

depth_view<klut_network> klut_d{ klut };

auto const cec = benchmark == "hyp" ? true : abc_cec( klut, benchmark );

exp( benchmark, klut.num_gates(), klut_d.depth(), st.edges, to_seconds( st.time_total ), cec );
}

exp.save();
exp.table();

return 0;
}
52 changes: 46 additions & 6 deletions include/mockturtle/algorithms/collapse_mapped.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,28 @@
\file collapse_mapped.hpp
\brief Collapses mapped network into k-LUT network
\author Alessandro Tempia Calvino
\author Heinz Riener
\author Mathias Soeken
*/

#pragma once

#include <algorithm>
#include <iterator>
#include <optional>
#include <unordered_map>

#include "../traits.hpp"
#include "../utils/node_map.hpp"
#include "../utils/window_utils.hpp"
#include "../views/color_view.hpp"
#include "../views/fanout_view.hpp"
#include "../views/topo_view.hpp"
#include "../views/window_view.hpp"
#include "simulation.hpp"

#include <kitty/dynamic_truth_table.hpp>

namespace mockturtle
{
Expand Down Expand Up @@ -164,6 +174,10 @@ class collapse_mapped_network_impl
}
} );

fanout_view<NtkSource> fanout_ntk{ ntk };
fanout_ntk.clear_visited();
color_view<fanout_view<NtkSource>> color_ntk{ fanout_ntk };

/* nodes */
topo_view topo{ ntk };
topo.foreach_node( [&]( auto n ) {
Expand All @@ -175,21 +189,49 @@ class collapse_mapped_network_impl
children.push_back( node_to_signal[fanin] );
} );

kitty::dynamic_truth_table tt;

if constexpr ( has_cell_function_v<NtkSource> )
{
tt = ntk.cell_function( n );
}
else
{
/* compute function constructing a window */
std::vector<node<NtkSource>> roots{ n };
std::vector<node<NtkSource>> leaves;

ntk.foreach_cell_fanin( n, [&]( auto fanin ) {
leaves.push_back( fanin );
} );

std::vector<node<NtkSource>> gates{ collect_nodes( color_ntk, leaves, roots ) };
window_view window_ntk{ color_ntk, leaves, roots, gates };

using Ntk = mockturtle::window_view<mockturtle::color_view<mockturtle::fanout_view<NtkSource>>>;
default_simulator<kitty::dynamic_truth_table> sim( window_ntk.num_pis() );
unordered_node_map<kitty::dynamic_truth_table, Ntk> node_to_value( window_ntk );

simulate_nodes( window_ntk, node_to_value, sim );

tt = node_to_value[n];
}

switch ( node_driver_type[n] )
{
default:
case driver_type::none:
case driver_type::pos:
node_to_signal[n] = dest.create_node( children, ntk.cell_function( n ) );
node_to_signal[n] = dest.create_node( children, tt );
break;

case driver_type::neg:
node_to_signal[n] = dest.create_node( children, ~ntk.cell_function( n ) );
node_to_signal[n] = dest.create_node( children, ~tt );
break;

case driver_type::mixed:
node_to_signal[n] = dest.create_node( children, ntk.cell_function( n ) );
opposites[n] = dest.create_node( children, ~ntk.cell_function( n ) );
node_to_signal[n] = dest.create_node( children, tt );
opposites[n] = dest.create_node( children, ~tt );
break;
}
} );
Expand Down Expand Up @@ -276,7 +318,6 @@ std::optional<NtkDest> collapse_mapped_network( NtkSource const& ntk )
static_assert( has_is_constant_v<NtkSource>, "NtkSource does not implement the is_constant method" );
static_assert( has_is_pi_v<NtkSource>, "NtkSource does not implement the is_pi method" );
static_assert( has_is_cell_root_v<NtkSource>, "NtkSource does not implement the is_cell_root method" );
static_assert( has_cell_function_v<NtkSource>, "NtkSource does not implement the cell_function method" );
static_assert( has_is_complemented_v<NtkSource>, "NtkSource does not implement the is_complemented method" );

static_assert( has_get_constant_v<NtkDest>, "NtkDest does not implement the get_constant method" );
Expand Down Expand Up @@ -350,7 +391,6 @@ bool collapse_mapped_network( NtkDest& dest, NtkSource const& ntk )
static_assert( has_is_constant_v<NtkSource>, "NtkSource does not implement the is_constant method" );
static_assert( has_is_pi_v<NtkSource>, "NtkSource does not implement the is_pi method" );
static_assert( has_is_cell_root_v<NtkSource>, "NtkSource does not implement the is_cell_root method" );
static_assert( has_cell_function_v<NtkSource>, "NtkSource does not implement the cell_function method" );
static_assert( has_is_complemented_v<NtkSource>, "NtkSource does not implement the is_complemented method" );

static_assert( has_get_constant_v<NtkDest>, "NtkDest does not implement the get_constant method" );
Expand Down
Loading

0 comments on commit 0246326

Please sign in to comment.