From ae571265e499c1e4969fc36b008c450f91697bfc Mon Sep 17 00:00:00 2001 From: Heinz Riener Date: Sat, 10 Apr 2021 23:08:57 +0200 Subject: [PATCH] refactor xmgcost. --- include/mockturtle/mockturtle.hpp | 3 +- include/mockturtle/properties/migcost.hpp | 2 +- include/mockturtle/properties/xmgcost.hpp | 151 +++++++--------------- test/properties/xmgcost.cpp | 30 +++++ 4 files changed, 79 insertions(+), 107 deletions(-) create mode 100644 test/properties/xmgcost.cpp diff --git a/include/mockturtle/mockturtle.hpp b/include/mockturtle/mockturtle.hpp index b2fb33876..83e7a6070 100644 --- a/include/mockturtle/mockturtle.hpp +++ b/include/mockturtle/mockturtle.hpp @@ -115,6 +115,7 @@ #include "mockturtle/networks/mig.hpp" #include "mockturtle/properties/migcost.hpp" #include "mockturtle/properties/mccost.hpp" +#include "mockturtle/properties/xmgcost.hpp" #include "mockturtle/mockturtle.hpp" #include "mockturtle/generators/sorting.hpp" #include "mockturtle/generators/arithmetic.hpp" @@ -132,4 +133,4 @@ #include "mockturtle/views/fanout_view.hpp" #include "mockturtle/views/cut_view.hpp" #include "mockturtle/views/depth_view.hpp" -#include "mockturtle/views/aqfp_view.hpp" \ No newline at end of file +#include "mockturtle/views/aqfp_view.hpp" diff --git a/include/mockturtle/properties/migcost.hpp b/include/mockturtle/properties/migcost.hpp index c756b884f..b44aa40e6 100644 --- a/include/mockturtle/properties/migcost.hpp +++ b/include/mockturtle/properties/migcost.hpp @@ -114,4 +114,4 @@ uint32_t num_dangling_inputs( Ntk const& ntk ) return costs; } -} // namespace mockturtle \ No newline at end of file +} // namespace mockturtle diff --git a/include/mockturtle/properties/xmgcost.hpp b/include/mockturtle/properties/xmgcost.hpp index f05a0ea40..382809556 100644 --- a/include/mockturtle/properties/xmgcost.hpp +++ b/include/mockturtle/properties/xmgcost.hpp @@ -33,156 +33,97 @@ #pragma once -#include -#include - #include "../traits.hpp" +#include + namespace mockturtle { -/*! \brief Counts number of inverters. - * - * This number counts all nodes that need to be inverted. Multiple signals - * with complements to the same node are counted once. - * - * \param ntk Network - */ - -struct xmg_cost_params +struct xmg_gate_stats { - /*! \brief Total number of XOR3 . */ + /*! \brief Total number of XOR3 gates (structurally). */ uint32_t total_xor3{0}; - /*! \brief Actual number of XOR3 with three number of inputs. */ - uint32_t actual_xor3{0}; + /*! \brief Number of XOR3 (functionally). */ + uint32_t xor3{0}; - /*! \brief Actual number of XOR2. */ - uint32_t actual_xor2{0}; + /*! \brief Number of XOR2 (functionally). */ + uint32_t xor2{0}; - /*! \brief Total number of Majority. */ + /*! \brief Total number of MAJ gates (structurally). */ uint32_t total_maj{0}; - /*! \brief Actual number of Majority with three inputs. */ - uint32_t actual_maj{0}; + /*! \brief Number of MAJ gates. */ + uint32_t maj{0}; - /*! \brief Remaining number of Maj where one of the inputs is a constant. */ - uint32_t remaining_maj{0}; + /*! \brief Number of AND/OR gates. */ + uint32_t and_or{0}; void report() const { - fmt::print( "#total_xor3 = {} / #total_maj = {} / #xor2 = {} / #xor3 = {} / #actual_maj = {} / #remaining_maj = {} \n", total_xor3, total_maj, actual_xor2, actual_xor3, actual_maj, remaining_maj ); + fmt::print( "XOR3: {} = {} XOR3 + {} XOR2 / MAJ: {} = {} MAJ3 + {} AND/OR\n", + total_xor3, xor2, xor3, total_maj, maj, and_or ); } }; -template -uint32_t num_inverters( Ntk const& ntk ) -{ - static_assert( is_network_type_v, "Ntk is not a network type" ); - static_assert( has_foreach_gate_v, "Ntk does not implement the foreach_gate method" ); - static_assert( has_foreach_fanin_v, "Ntk does not implement the foreach_fanin method" ); - static_assert( has_foreach_po_v, "Ntk does not implement the foreach_po method" ); - static_assert( has_is_complemented_v, "Ntk does not implement the is_complemented method" ); - static_assert( has_get_node_v, "Ntk does not implement the get_node method" ); - - std::unordered_set> inverted_nodes; - - ntk.foreach_gate( [&]( auto const& n ) { - ntk.foreach_fanin( n, [&]( auto const& f ) { - if ( ntk.is_complemented( f ) ) - { - inverted_nodes.insert( ntk.get_node( f ) ); - } - } ); - } ); - - ntk.foreach_po( [&]( auto const& f ) { - if ( ntk.is_complemented( f ) ) - { - inverted_nodes.insert( ntk.get_node( f ) ); - } - } ); - - return inverted_nodes.size(); -} - -/*! \brief Counts fanins which are primary inputs. +/*! \brief Profile gates + * + * Counts the numbers of MAJ and XOR nodes in an XMG. * * \param ntk Network + * \param stats Statistics */ - -template -uint32_t num_dangling_inputs( Ntk const& ntk ) -{ - static_assert( is_network_type_v, "Ntk is not a network type" ); - static_assert( has_foreach_gate_v, "Ntk does not implement the foreach_gate method" ); - static_assert( has_foreach_fanin_v, "Ntk does not implement the foreach_fanin method" ); - static_assert( has_foreach_po_v, "Ntk does not implement the foreach_po method" ); - static_assert( has_is_pi_v, "Ntk does not implement the is_pi method" ); - static_assert( has_get_node_v, "Ntk does not implement the get_node method" ); - - uint32_t costs{0u}; - - ntk.foreach_gate( [&]( auto const& n ) { - ntk.foreach_fanin( n, [&]( auto const& f ) { - if ( ntk.is_pi( ntk.get_node( f ) ) ) - { - costs++; - } - } ); - } ); - - ntk.foreach_po( [&]( auto const& f ) { - if ( ntk.is_pi( ntk.get_node( f ) ) ) - { - costs++; - } - } ); - - return costs; -} - template -void num_gate_profile( Ntk const& ntk, xmg_cost_params& xmg_ps ) +void xmg_profile_gates( Ntk const& ntk, xmg_gate_stats& stats ) { static_assert( is_network_type_v, "Ntk is not a network type" ); static_assert( has_foreach_gate_v, "Ntk does not implement the foreach_gate method" ); static_assert( has_foreach_fanin_v, "Ntk does not implement the foreach_fanin method" ); - static_assert( has_foreach_po_v, "Ntk does not implement the foreach_po method" ); - static_assert( has_is_pi_v, "Ntk does not implement the is_pi method" ); static_assert( has_get_node_v, "Ntk does not implement the get_node method" ); + static_assert( has_is_constant_v, "Ntk does not implement the is_constant method" ); + static_assert( has_is_maj_v, "Ntk does not implement the is_maj method" ); + static_assert( has_is_xor3_v, "Ntk does not implement the is_xor3 method" ); ntk.foreach_gate( [&]( auto const& node ) { - bool has_const = false; + bool has_const_fanin = false; + + /* Check if all of the fanin nodes are not constant */ ntk.foreach_fanin( node, [&]( auto const& f ) { - // Check whether all of the fanin node are not constant if ( ntk.is_constant( ntk.get_node( f ) ) ) { - has_const = true; + has_const_fanin = true; return false; } - else - return true; - } ); // Foreach_fanin + return true; + } ); if ( ntk.is_maj( node ) ) { - if ( has_const ) - ++xmg_ps.remaining_maj; + if ( has_const_fanin ) + { + ++stats.and_or; + } else - ++xmg_ps.actual_maj; + { + ++stats.maj; + } } else if ( ntk.is_xor3( node ) ) { - if ( has_const ) - ++xmg_ps.actual_xor2; + if ( has_const_fanin ) + { + ++stats.xor2; + } else - ++xmg_ps.actual_xor3; + { + ++stats.xor3; + } } } ); - xmg_ps.total_xor3 = xmg_ps.actual_xor2 + xmg_ps.actual_xor3; - xmg_ps.total_maj = xmg_ps.remaining_maj + xmg_ps.actual_maj; + stats.total_xor3 = stats.xor2 + stats.xor3; + stats.total_maj = stats.and_or + stats.maj; } -} // namespace mockturtle \ No newline at end of file +} // namespace mockturtle diff --git a/test/properties/xmgcost.cpp b/test/properties/xmgcost.cpp new file mode 100644 index 000000000..e7e2b46a0 --- /dev/null +++ b/test/properties/xmgcost.cpp @@ -0,0 +1,30 @@ +#include + +#include +#include + +using namespace mockturtle; + +TEST_CASE( "profile gates in XMG", "[xmgcost]" ) +{ + xmg_network xmg; + const auto a = xmg.create_pi(); + const auto b = xmg.create_pi(); + const auto c = xmg.create_pi(); + const auto f1 = xmg.create_xor3( a, b, c ); + const auto f2 = xmg.create_xor3( a, b, xmg.get_constant( 0 ) ); + const auto f3 = xmg.create_and( a, b ); + const auto f4 = xmg.create_maj( f1, f2, f3 ); + xmg.create_po( f4 ); + + xmg_gate_stats stats; + xmg_profile_gates( xmg, stats ); + CHECK( stats.total_xor3 == 2u ); + CHECK( stats.xor3 == 1u ); + CHECK( stats.xor2 == 1u ); + + CHECK( stats.total_maj == 2u ); + CHECK( stats.maj == 1u ); + CHECK( stats.and_or == 1u ); +} +