Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion include/mockturtle/algorithms/lut_mapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ class lut_cut_set
{
*pit++ = &c;
}
/* best() exposes the first cut even when the set is empty. */
_cuts[0].set_leaves( _cuts[0].begin(), _cuts[0].begin() );
_cuts[0].data() = {};
}

/*! \brief Adds a cut to the end of the set.
Expand Down Expand Up @@ -3012,4 +3015,4 @@ void lut_map_inplace( Ntk& ntk, lut_map_params const& ps = {}, lut_map_stats* ps
}
}

} /* namespace mockturtle */
} /* namespace mockturtle */
3 changes: 3 additions & 0 deletions include/mockturtle/utils/cuts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,9 @@ void cut_set<CutType, MaxCuts>::clear()
{
*pit++ = &c;
}
/* best() exposes the first cut even when the set is empty. */
_cuts[0].set_leaves( _cuts[0].begin(), _cuts[0].begin() );
_cuts[0].data() = {};
}

template<typename CutType, int MaxCuts>
Expand Down
63 changes: 63 additions & 0 deletions test/algorithms/lut_mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,3 +334,66 @@ TEST_CASE( "LUT map remapping LUT network", "[lut_mapper]" )
CHECK( mapped_ntk.num_cells() == 1 );
CHECK( *equivalence_checking( miter_ntk ) == true );
}

TEST_CASE( "LUT map of an AIG with nodes unreachable from the outputs", "[lut_mapper]" )
{
/* `compute_share_mapping_init` calls `best()` on every node index, including
nodes the cut enumerator never visited because no output depends on them.
Their cut set is empty, so `clear()` must initialize the first cut
exposed by `best()`. */
aig_network aig;

auto const a = aig.create_pi();
auto const b = aig.create_pi();
auto const c = aig.create_pi();

auto const f1 = aig.create_and( a, b );
auto const f2 = aig.create_and( f1, c );
aig.create_po( f2 );

/* dangling: driven by primary inputs, driving no output */
auto const d1 = aig.create_and( a, !b );
auto const d2 = aig.create_and( d1, !c );
auto const d3 = aig.create_and( d2, a );
aig.create_and( d3, !b );

CHECK( aig.num_gates() == 6 );

lut_map_params ps;
ps.cut_enumeration_ps.cut_size = 4;
ps.area_oriented_mapping = true;

const klut_network klut = lut_map<aig_network, true>( aig, ps );

CHECK( klut.num_gates() == 1 );
}

TEST_CASE( "empty LUT cut set has an initialized best cut", "[lut_mapper]" )
{
using cut_type = cut<16, cut_data<true, detail::cut_enumeration_lut_cut>>;
detail::lut_cut_set<cut_type, 32> set;

SECTION( "newly constructed" )
{
}

SECTION( "after clearing populated and reordered storage" )
{
std::vector<uint32_t> leaves{ 1, 2, 3 };
auto& first = set.add_cut( leaves.begin(), leaves.end() );
first->func_id = 42;
first->data.lut_area = 23;
set.add_cut( leaves.begin(), leaves.begin() + 1 );
set.update_best( 1 );
set.clear();
}

CHECK( set.size() == 0 );
CHECK( set.best().size() == 0 );
CHECK( set.best().signature() == 0 );
CHECK( set.best().begin() == set.best().end() );
auto const& best = set.best();
CHECK( best.begin() == best.end() );
CHECK( best->func_id == 0 );
CHECK( best->data.lut_area == 0 );
}
25 changes: 25 additions & 0 deletions test/utils/cuts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,28 @@ TEST_CASE( "merge three cuts", "[cuts]" )
ct.merge( c3, cr, 10 );
CHECK( std::vector<uint32_t>( cr.begin(), cr.end() ) == std::vector{ 1u, 2u, 3u, 4u, 5u, 6u, 7u, 9u } );
}

TEST_CASE( "empty cut set has an initialized best cut", "[cuts]" )
{
cut_set<cut<10, uint32_t>, 25> set;

SECTION( "newly constructed" )
{
}

SECTION( "after clearing populated and reordered storage" )
{
std::vector<uint32_t> leaves{ 1, 2, 3 };
set.add_cut( leaves.begin(), leaves.end() ).data() = 42;
set.add_cut( leaves.begin(), leaves.begin() + 1 ).data() = 23;
set.update_best( 1 );
set.clear();
}

CHECK( set.size() == 0 );
CHECK( set.best().size() == 0 );
CHECK( set.best().signature() == 0 );
CHECK( set.best().begin() == set.best().end() );
CHECK( ( *set.begin() )->begin() == ( *set.begin() )->end() );
CHECK( set.best().data() == 0 );
}
Loading