diff --git a/include/mockturtle/io/aiger_reader.hpp b/include/mockturtle/io/aiger_reader.hpp index 50b513b38..cb770cc61 100644 --- a/include/mockturtle/io/aiger_reader.hpp +++ b/include/mockturtle/io/aiger_reader.hpp @@ -40,72 +40,6 @@ namespace mockturtle { -template, std::vector>, typename StorageContainerReverseMap = std::unordered_map>> -class NameMap -{ -public: - using signal = typename Ntk::signal; - -public: - NameMap() = default; - - void insert( signal const& s, std::string const& name ) - { - /* update direct map */ - auto const it = _names.find( s ); - if ( it == _names.end() ) - { - _names[s] = {name}; - } - else - { - it->second.push_back( name ); - } - - /* update reverse map */ - auto const rev_it = _rev_names.find( name ); - if ( rev_it != _rev_names.end() ) - { - std::cout << "[w] signal name `" << name << "` is used twice" << std::endl; - } - _rev_names.insert( std::make_pair( name, s ) ); - } - - std::vector operator[]( signal const& s ) - { - return _names[s]; - } - - std::vector operator[]( signal const& s ) const - { - return _names.at( s ); - } - - std::vector get_name( signal const& s ) const - { - return _names.at( s ); - } - - bool has_name( signal const& s, std::string const& name ) const - { - auto const it = _names.find( s ); - if ( it == _names.end() ) - { - return false; - } - return ( std::find( it->second.begin(), it->second.end(), name ) != it->second.end() ); - } - - StorageContainerReverseMap get_name_to_signal_mapping() const - { - return _rev_names; - } - -protected: - StorageContainerMap _names; - StorageContainerReverseMap _rev_names; -}; // NameMap - /*! \brief Lorina reader callback for Aiger files. * * **Required network functions:** @@ -136,7 +70,7 @@ template class aiger_reader : public lorina::aiger_reader { public: - explicit aiger_reader( Ntk& ntk, NameMap* names = nullptr ) : _ntk( ntk ), _names( names ) + explicit aiger_reader( Ntk& ntk ) : _ntk( ntk ) { static_assert( is_network_type_v, "Ntk is not a network type" ); static_assert( has_create_pi_v, "Ntk does not implement the create_pi function" ); @@ -148,6 +82,7 @@ class aiger_reader : public lorina::aiger_reader ~aiger_reader() { + uint32_t output_id{0}; for ( auto out : outputs ) { auto const lit = std::get<0>( out ); @@ -156,8 +91,10 @@ class aiger_reader : public lorina::aiger_reader { signal = _ntk.create_not( signal ); } - if ( _names ) - _names->insert( signal, std::get<1>( out ) ); + if constexpr ( has_set_output_name_v ) + { + _ntk.set_output_name( output_id++, std::get<1>( out ) ); + } _ntk.create_po( signal ); } @@ -174,8 +111,11 @@ class aiger_reader : public lorina::aiger_reader signal = _ntk.create_not( signal ); } - if ( _names ) - _names->insert( signal, std::get<2>( latch ) + "_next" ); + if constexpr ( has_set_name_v ) + { + _ntk.set_name( signal, std::get<2>( latch ) + "_next" ); + } + _ntk.create_ri( signal, reset ); } } @@ -212,9 +152,9 @@ class aiger_reader : public lorina::aiger_reader void on_input_name( unsigned index, const std::string& name ) const override { - if ( _names ) + if constexpr ( has_set_name_v ) { - _names->insert( signals[1 + index], name ); + _ntk.set_name( signals[1 + index], name ); } } @@ -227,9 +167,9 @@ class aiger_reader : public lorina::aiger_reader { if constexpr ( has_create_ri_v && has_create_ro_v ) { - if ( _names ) + if constexpr( has_set_name_v ) { - _names->insert( signals[1 + _num_inputs + index], name ); + _ntk.set_name( signals[1 + _num_inputs + index], name ); } std::get<2>( latches[index] ) = name; } @@ -275,11 +215,10 @@ class aiger_reader : public lorina::aiger_reader private: Ntk& _ntk; - mutable uint32_t _num_inputs = 0; + mutable uint32_t _num_inputs{0}; mutable std::vector> outputs; mutable std::vector signals; mutable std::vector> latches; - mutable NameMap* _names; }; -} /* namespace mockturtle */ \ No newline at end of file +} /* namespace mockturtle */ diff --git a/test/io/aiger_reader.cpp b/test/io/aiger_reader.cpp index 7d7cc87e0..b952e6376 100644 --- a/test/io/aiger_reader.cpp +++ b/test/io/aiger_reader.cpp @@ -1,18 +1,20 @@ #include -#include -#include - #include #include +#include #include +#include +#include + using namespace mockturtle; TEST_CASE( "read and write names", "[aiger_reader]" ) { aig_network aig; + names_view named_aig{aig}; std::string file{"aag 7 2 1 2 4\n" "2\n" @@ -31,28 +33,21 @@ TEST_CASE( "read and write names", "[aiger_reader]" ) "o1 y1\n"}; std::istringstream in( file ); - auto const result = lorina::read_ascii_aiger( in, aiger_reader( aig ) ); + auto const result = lorina::read_ascii_aiger( in, aiger_reader( named_aig ) ); CHECK( result == lorina::return_code::success ); - NameMap>> names; - names.insert( aig.make_signal( aig.pi_at( 0 ) ), "x0" ); - names.insert( aig.make_signal( aig.pi_at( 1 ) ), "x1" ); - names.insert( aig.make_signal( aig.ro_at( 0 ) ), "s0" ); - names.insert( aig.ri_at( 0 ), "s0_next" ); - names.insert( aig.po_at( 0 ), "y0" ); - names.insert( aig.po_at( 1 ), "y1" ); - - CHECK( names.has_name( aig.make_signal( aig.pi_at( 0 ) ), "x0" ) ); - CHECK( names.has_name( aig.make_signal( aig.pi_at( 1 ) ), "x1" ) ); - CHECK( names.has_name( aig.po_at( 0 ), "y0" ) ); - CHECK( names.has_name( aig.po_at( 1 ), "y1" ) ); - CHECK( names.has_name( aig.make_signal( aig.ro_at( 0 ) ), "s0" ) ); - CHECK( names.has_name( aig.ri_at( 0 ), "s0_next" ) ); + CHECK( named_aig.get_name( aig.make_signal( aig.pi_at( 0 ) ) ) == "x0" ); + CHECK( named_aig.get_name( aig.make_signal( aig.pi_at( 1 ) ) ) == "x1" ); + CHECK( named_aig.get_name( aig.make_signal( aig.ro_at( 0 ) ) ) == "s0" ); + CHECK( named_aig.get_name( aig.ri_at( 0 ) ) == "s0_next" ); + CHECK( named_aig.get_output_name( 0 ) == "y0" ); + CHECK( named_aig.get_output_name( 1 ) == "y1" ); } TEST_CASE( "read an ASCII Aiger file into an AIG network and store input-output names", "[aiger_reader]" ) { aig_network aig; + names_view named_aig{aig}; std::string file{"aag 6 2 0 1 4\n" "2\n" @@ -66,23 +61,23 @@ TEST_CASE( "read an ASCII Aiger file into an AIG network and store input-output "i1 bar\n" "o0 foobar\n"}; - NameMap names; std::istringstream in( file ); - auto const result = lorina::read_ascii_aiger( in, aiger_reader( aig, &names ) ); + auto const result = lorina::read_ascii_aiger( in, aiger_reader( named_aig ) ); CHECK( result == lorina::return_code::success ); - CHECK( aig.size() == 7 ); - CHECK( aig.num_pis() == 2 ); - CHECK( aig.num_pos() == 1 ); - CHECK( aig.num_gates() == 4 ); - - CHECK( names.has_name( aig.make_signal( aig.pi_at( 0 ) ), "foo" ) ); - CHECK( names.has_name( aig.make_signal( aig.pi_at( 1 ) ), "bar" ) ); - CHECK( names.has_name( aig.po_at( 0 ), "foobar" ) ); + CHECK( named_aig.size() == 7 ); + CHECK( named_aig.num_pis() == 2 ); + CHECK( named_aig.num_pos() == 1 ); + CHECK( named_aig.num_gates() == 4 ); + + CHECK( named_aig.get_name( aig.make_signal( aig.pi_at( 0 ) ) ) == "foo" ); + CHECK( named_aig.get_name( aig.make_signal( aig.pi_at( 1 ) ) ) == "bar" ); + CHECK( named_aig.get_output_name( 0 ) == "foobar" ); } TEST_CASE( "read a sequential ASCII Aiger file into an AIG network", "[aiger_reader]" ) { aig_network aig; + names_view named_aig{aig}; std::string file{"aag 7 2 1 2 4\n" "2\n" @@ -100,23 +95,22 @@ TEST_CASE( "read a sequential ASCII Aiger file into an AIG network", "[aiger_rea "o0 foobar\n" "o1 barbar\n"}; - NameMap names; lorina::diagnostic_engine diag; std::istringstream in( file ); - auto const result = lorina::read_ascii_aiger( in, aiger_reader( aig, &names ), &diag ); + auto const result = lorina::read_ascii_aiger( in, aiger_reader( named_aig ), &diag ); CHECK( result == lorina::return_code::success ); - CHECK( aig.size() == 8 ); - CHECK( aig.num_cis() == 3 ); - CHECK( aig.num_cos() == 3 ); - CHECK( aig.num_pis() == 2 ); - CHECK( aig.num_pos() == 2 ); - CHECK( aig.num_gates() == 4 ); - CHECK( aig.num_registers() == 1 ); - - CHECK( names.has_name( aig.make_signal( aig.pi_at( 0 ) ), "foo" ) ); - CHECK( names.has_name( aig.make_signal( aig.pi_at( 1 ) ), "bar" ) ); - CHECK( names.has_name( aig.make_signal( aig.ro_at( 0 ) ), "barfoo" ) ); - CHECK( names.has_name( aig.ri_at( 0 ), "barfoo_next" ) ); - CHECK( names.has_name( aig.po_at( 0 ), "foobar" ) ); - CHECK( names.has_name( aig.po_at( 1 ), "barbar" ) ); + CHECK( named_aig.size() == 8 ); + CHECK( named_aig.num_cis() == 3 ); + CHECK( named_aig.num_cos() == 3 ); + CHECK( named_aig.num_pis() == 2 ); + CHECK( named_aig.num_pos() == 2 ); + CHECK( named_aig.num_gates() == 4 ); + CHECK( named_aig.num_registers() == 1 ); + + CHECK( named_aig.get_name( aig.make_signal( aig.pi_at( 0 ) ) ) == "foo" ); + CHECK( named_aig.get_name( aig.make_signal( aig.pi_at( 1 ) ) ) == "bar" ); + CHECK( named_aig.get_name( aig.make_signal( aig.ro_at( 0 ) ) ) == "barfoo" ); + CHECK( named_aig.get_name( aig.ri_at( 0 ) ) == "barfoo_next" ); + CHECK( named_aig.get_output_name( 0 ) == "foobar" ); + CHECK( named_aig.get_output_name( 1 ) == "barbar" ); }