diff --git a/src/odb/include/odb/dbStream.h b/src/odb/include/odb/dbStream.h index 6506d066c7c..39406d88c71 100644 --- a/src/odb/include/odb/dbStream.h +++ b/src/odb/include/odb/dbStream.h @@ -55,10 +55,18 @@ inline constexpr size_t kTemplateRecursionLimit = 16; class dbOStream { + using Position = std::ostream::pos_type; + struct Scope + { + std::string name; + Position start_pos; + }; + _dbDatabase* _db; std::ostream& _f; double _lef_area_factor; double _lef_dist_factor; + std::vector _scopes; // By default values are written as their string ("255" vs 0xFF) // representations when using the << stream method. In dbOstream we are @@ -248,6 +256,26 @@ class dbOStream double lefarea(int value) { return ((double) value * _lef_area_factor); } double lefdist(int value) { return ((double) value * _lef_dist_factor); } + + Position pos() const { return _f.tellp(); } + + void pushScope(const std::string& name); + void popScope(); +}; + +// RAII class for scoping ostream operations +class dbOStreamScope +{ + public: + dbOStreamScope(dbOStream& ostream, const std::string& name) + : ostream_(ostream) + { + ostream_.pushScope(name); + } + + ~dbOStreamScope() { ostream_.popScope(); } + + dbOStream& ostream_; }; class dbIStream diff --git a/src/odb/src/db/dbBlock.cpp b/src/odb/src/db/dbBlock.cpp index b8ded36fbd4..e2b40c22e82 100644 --- a/src/odb/src/db/dbBlock.cpp +++ b/src/odb/src/db/dbBlock.cpp @@ -874,6 +874,7 @@ dbOStream& operator<<(dbOStream& stream, const _dbBlock& block) (**cbitr)().inDbBlockStreamOutBefore( (dbBlock*) &block); // client ECO initialization - payam + dbOStreamScope scope(stream, "dbBlock"); stream << block._def_units; stream << block._dbu_per_micron; stream << block._hier_delimeter; @@ -911,47 +912,47 @@ dbOStream& operator<<(dbOStream& stream, const _dbBlock& block) stream << block._children; stream << block._component_mask_shift; stream << block._currentCcAdjOrder; - stream << *block._bterm_tbl; - stream << *block._iterm_tbl; - stream << *block._net_tbl; - stream << *block._inst_hdr_tbl; - stream << *block._inst_tbl; - stream << *block._module_tbl; - stream << *block._modinst_tbl; - stream << *block._powerdomain_tbl; - stream << *block._logicport_tbl; - stream << *block._powerswitch_tbl; - stream << *block._isolation_tbl; - stream << *block._levelshifter_tbl; - stream << *block._group_tbl; - stream << *block.ap_tbl_; - stream << *block.global_connect_tbl_; - stream << *block._guide_tbl; - stream << *block._net_tracks_tbl; - stream << *block._box_tbl; - stream << *block._via_tbl; - stream << *block._gcell_grid_tbl; - stream << *block._track_grid_tbl; - stream << *block._obstruction_tbl; - stream << *block._blockage_tbl; - stream << *block._wire_tbl; - stream << *block._swire_tbl; - stream << *block._sbox_tbl; - stream << *block._row_tbl; - stream << *block._fill_tbl; - stream << *block._region_tbl; - stream << *block._hier_tbl; - stream << *block._bpin_tbl; - stream << *block._non_default_rule_tbl; - stream << *block._layer_rule_tbl; - stream << *block._prop_tbl; + stream << NamedTable("bterm_tbl", block._bterm_tbl); + stream << NamedTable("iterm_tbl", block._iterm_tbl); + stream << NamedTable("net_tbl", block._net_tbl); + stream << NamedTable("inst_hdr_tbl", block._inst_hdr_tbl); + stream << NamedTable("inst_tbl", block._inst_tbl); + stream << NamedTable("module_tbl", block._module_tbl); + stream << NamedTable("modinst_tbl", block._modinst_tbl); + stream << NamedTable("powerdomain_tbl", block._powerdomain_tbl); + stream << NamedTable("logicport_tbl", block._logicport_tbl); + stream << NamedTable("powerswitch_tbl", block._powerswitch_tbl); + stream << NamedTable("isolation_tbl", block._isolation_tbl); + stream << NamedTable("levelshifter_tbl", block._levelshifter_tbl); + stream << NamedTable("group_tbl", block._group_tbl); + stream << NamedTable("ap_tbl", block.ap_tbl_); + stream << NamedTable("global_connect_tbl", block.global_connect_tbl_); + stream << NamedTable("guide_tbl", block._guide_tbl); + stream << NamedTable("net_tracks_tbl", block._net_tracks_tbl); + stream << NamedTable("box_tbl", block._box_tbl); + stream << NamedTable("via_tbl", block._via_tbl); + stream << NamedTable("gcell_grid_tbl", block._gcell_grid_tbl); + stream << NamedTable("track_grid_tbl", block._track_grid_tbl); + stream << NamedTable("obstruction_tbl", block._obstruction_tbl); + stream << NamedTable("blockage_tbl", block._blockage_tbl); + stream << NamedTable("wire_tbl", block._wire_tbl); + stream << NamedTable("swire_tbl", block._swire_tbl); + stream << NamedTable("sbox_tbl", block._sbox_tbl); + stream << NamedTable("row_tbl", block._row_tbl); + stream << NamedTable("fill_tbl", block._fill_tbl); + stream << NamedTable("region_tbl", block._region_tbl); + stream << NamedTable("hier_tbl", block._hier_tbl); + stream << NamedTable("bpin_tbl", block._bpin_tbl); + stream << NamedTable("non_default_rule_tbl", block._non_default_rule_tbl); + stream << NamedTable("layer_rule_tbl", block._layer_rule_tbl); + stream << NamedTable("prop_tbl", block._prop_tbl); stream << *block._name_cache; stream << *block._r_val_tbl; stream << *block._c_val_tbl; stream << *block._cc_val_tbl; - stream << *block._cap_node_tbl; // DKF - 2/21/05 - stream << *block._r_seg_tbl; // DKF - 2/21/05 - stream << *block._cc_seg_tbl; + stream << NamedTable("cap_node_tbl", block._cap_node_tbl); + stream << NamedTable("r_seg_tbl", block._r_seg_tbl); + stream << NamedTable("cc_seg_tbl", block._cc_seg_tbl); stream << *block._extControl; //---------------------------------------------------------- stream out diff --git a/src/odb/src/db/dbChip.cpp b/src/odb/src/db/dbChip.cpp index 486e4f773e2..05d8ead84e4 100644 --- a/src/odb/src/db/dbChip.cpp +++ b/src/odb/src/db/dbChip.cpp @@ -132,9 +132,10 @@ _dbChip::~_dbChip() dbOStream& operator<<(dbOStream& stream, const _dbChip& chip) { + dbOStreamScope scope(stream, "dbChip"); stream << chip._top; stream << *chip._block_tbl; - stream << *chip._prop_tbl; + stream << NamedTable("prop_tbl", chip._prop_tbl); stream << *chip._name_cache; return stream; } diff --git a/src/odb/src/db/dbDatabase.cpp b/src/odb/src/db/dbDatabase.cpp index 761f428ddde..befbd8e1d71 100644 --- a/src/odb/src/db/dbDatabase.cpp +++ b/src/odb/src/db/dbDatabase.cpp @@ -265,6 +265,7 @@ _dbDatabase::~_dbDatabase() dbOStream& operator<<(dbOStream& stream, const _dbDatabase& db) { + dbOStreamScope scope(stream, "dbDatabase"); stream << db._magic1; stream << db._magic2; stream << db._schema_major; @@ -274,7 +275,7 @@ dbOStream& operator<<(dbOStream& stream, const _dbDatabase& db) stream << *db._tech_tbl; stream << *db._lib_tbl; stream << *db._chip_tbl; - stream << *db._prop_tbl; + stream << NamedTable("prop_tbl", db._prop_tbl); stream << *db._name_cache; return stream; } diff --git a/src/odb/src/db/dbLib.cpp b/src/odb/src/db/dbLib.cpp index 71d758de2a7..fef80acd038 100644 --- a/src/odb/src/db/dbLib.cpp +++ b/src/odb/src/db/dbLib.cpp @@ -220,6 +220,7 @@ _dbLib::~_dbLib() dbOStream& operator<<(dbOStream& stream, const _dbLib& lib) { + dbOStreamScope scope(stream, fmt::format("dbLib({})", lib._name)); stream << lib._lef_units; stream << lib._dbu_per_micron; stream << lib._hier_delimeter; @@ -230,9 +231,9 @@ dbOStream& operator<<(dbOStream& stream, const _dbLib& lib) stream << lib._master_hash; stream << lib._site_hash; stream << lib._tech; - stream << *lib._master_tbl; - stream << *lib._site_tbl; - stream << *lib._prop_tbl; + stream << NamedTable("master_tbl", lib._master_tbl); + stream << NamedTable("site_tbl", lib._site_tbl); + stream << NamedTable("prop_tbl", lib._prop_tbl); stream << *lib._name_cache; return stream; } diff --git a/src/odb/src/db/dbStream.cpp b/src/odb/src/db/dbStream.cpp index c6ea201f346..630fc2f70b4 100644 --- a/src/odb/src/db/dbStream.cpp +++ b/src/odb/src/db/dbStream.cpp @@ -33,11 +33,38 @@ #include "dbStream.h" #include +#include #include "db.h" +#include "dbDatabase.h" namespace odb { +void dbOStream::pushScope(const std::string& name) +{ + _scopes.push_back({name, pos()}); +} + +void dbOStream::popScope() +{ + auto logger = _db->getLogger(); + if (logger->debugCheck(utl::ODB, "io_size", 1)) { + auto size = pos() - _scopes.back().start_pos; + if (size >= 1024) { // hide tiny contributors + std::ostringstream scope_name; + + std::transform(_scopes.begin(), + _scopes.end(), + std::ostream_iterator(scope_name, "/"), + [](const Scope& scope) { return scope.name; }); + + logger->report("{:8.1f} MB in {}", size / 1048576.0, scope_name.str()); + } + } + + _scopes.pop_back(); +} + dbOStream& operator<<(dbOStream& stream, const Rect& r) { stream << r.xlo_; diff --git a/src/odb/src/db/dbTable.h b/src/odb/src/db/dbTable.h index 65722568374..eebb861000a 100644 --- a/src/odb/src/db/dbTable.h +++ b/src/odb/src/db/dbTable.h @@ -182,4 +182,19 @@ dbOStream& operator<<(dbOStream& stream, const dbTable& table); template dbIStream& operator>>(dbIStream& stream, dbTable& table); +// Useful if you want to write the table in a named scope +template +struct NamedTable +{ + NamedTable(const char* name, const dbTable* table) + : name(name), table(table) + { + } + const char* name; + const dbTable* table; +}; + +template +dbOStream& operator<<(dbOStream& stream, const NamedTable& named_table); + } // namespace odb diff --git a/src/odb/src/db/dbTable.hpp b/src/odb/src/db/dbTable.hpp index 1b68f33fe02..3710585d0dc 100644 --- a/src/odb/src/db/dbTable.hpp +++ b/src/odb/src/db/dbTable.hpp @@ -621,6 +621,16 @@ void dbTable::copy_page(uint page_id, dbTablePage* page) } } +template +dbOStream& operator<<(dbOStream& stream, const NamedTable& named_table) +{ + dbOStreamScope scope( + stream, + fmt::format("{}({})", named_table.name, named_table.table->size())); + stream << *named_table.table; + return stream; +} + template dbOStream& operator<<(dbOStream& stream, const dbTable& table) { diff --git a/src/odb/src/db/dbTech.cpp b/src/odb/src/db/dbTech.cpp index a2e956e8ab8..3cc5821204f 100644 --- a/src/odb/src/db/dbTech.cpp +++ b/src/odb/src/db/dbTech.cpp @@ -450,6 +450,7 @@ _dbTech::~_dbTech() dbOStream& operator<<(dbOStream& stream, const _dbTech& tech) { + dbOStreamScope scope(stream, "dbTech"); stream << tech._name; stream << tech._via_cnt; stream << tech._layer_cnt; @@ -467,18 +468,19 @@ dbOStream& operator<<(dbOStream& stream, const _dbTech& tech) stream << tech._non_default_rules; stream << tech._samenet_rules; stream << tech._samenet_matrix; - stream << *tech._layer_tbl; - stream << *tech._via_tbl; - stream << *tech._non_default_rule_tbl; - stream << *tech._layer_rule_tbl; - stream << *tech._box_tbl; - stream << *tech._samenet_rule_tbl; - stream << *tech._antenna_rule_tbl; - stream << *tech._via_rule_tbl; - stream << *tech._via_layer_rule_tbl; - stream << *tech._via_generate_rule_tbl; - stream << *tech._prop_tbl; - stream << *tech._metal_width_via_map_tbl; + stream << NamedTable("layer_tbl", tech._layer_tbl); + stream << NamedTable("via_tbl", tech._via_tbl); + stream << NamedTable("non_default_rule_tbl", tech._non_default_rule_tbl); + stream << NamedTable("layer_rule_tbl", tech._layer_rule_tbl); + stream << NamedTable("box_tbl", tech._box_tbl); + stream << NamedTable("samenet_rule_tbl", tech._samenet_rule_tbl); + stream << NamedTable("antenna_rule_tbl", tech._antenna_rule_tbl); + stream << NamedTable("via_rule_tbl", tech._via_rule_tbl); + stream << NamedTable("via_layer_rule_tbl", tech._via_layer_rule_tbl); + stream << NamedTable("via_generate_rule_tbl", tech._via_generate_rule_tbl); + stream << NamedTable("prop_tbl", tech._prop_tbl); + stream << NamedTable("metal_width_via_map_tbl", + tech._metal_width_via_map_tbl); stream << *tech._name_cache; stream << tech._via_hash; return stream;