From f023652ac47ce61f2847ec396435222282155297 Mon Sep 17 00:00:00 2001 From: tangxifan Date: Tue, 30 Jun 2020 14:18:05 -0600 Subject: [PATCH] keep optimizing memory footprint of module manager by using net terminal storage --- openfpga/src/fabric/module_manager.cpp | 112 +++++++++++++++++-------- openfpga/src/fabric/module_manager.h | 12 ++- 2 files changed, 86 insertions(+), 38 deletions(-) diff --git a/openfpga/src/fabric/module_manager.cpp b/openfpga/src/fabric/module_manager.cpp index b1d503211..371c07608 100644 --- a/openfpga/src/fabric/module_manager.cpp +++ b/openfpga/src/fabric/module_manager.cpp @@ -303,7 +303,13 @@ vtr::vector ModuleManager::net_source_modules(const Mo /* Validate module net */ VTR_ASSERT(valid_module_net_id(module, net)); - return net_src_module_ids_[module][net]; + vtr::vector src_modules; + src_modules.reserve(net_src_terminal_ids_[module][net].size()); + for (const size_t& id : net_src_terminal_ids_[module][net]) { + src_modules.push_back(net_terminal_storage_[id].first); + } + + return src_modules; } /* Find the ids of source instances of a net */ @@ -319,7 +325,13 @@ vtr::vector ModuleManager::net_source_ports(const /* Validate module net */ VTR_ASSERT(valid_module_net_id(module, net)); - return net_src_port_ids_[module][net]; + vtr::vector src_ports; + src_ports.reserve(net_src_terminal_ids_[module][net].size()); + for (const size_t& id : net_src_terminal_ids_[module][net]) { + src_ports.push_back(net_terminal_storage_[id].second); + } + + return src_ports; } /* Find the source pin indices of a net */ @@ -342,9 +354,9 @@ bool ModuleManager::net_source_exist(const ModuleId& module, const ModuleNetId& * we can say that the source has already been added to this net! */ for (const ModuleNetSrcId& net_src : module_net_sources(module, net)) { - if ( (src_module == net_source_modules(module, net)[net_src]) + if ( (src_module == net_terminal_storage_[net_src_terminal_ids_[module][net][net_src]].first) && (instance_id == net_source_instances(module, net)[net_src]) - && (src_port == net_source_ports(module, net)[net_src]) + && (src_port == net_terminal_storage_[net_src_terminal_ids_[module][net][net_src]].second) && (src_pin == net_source_pins(module, net)[net_src]) ) { return true; } @@ -359,7 +371,13 @@ vtr::vector ModuleManager::net_sink_modules(const Mod /* Validate module net */ VTR_ASSERT(valid_module_net_id(module, net)); - return net_sink_module_ids_[module][net]; + vtr::vector sink_modules; + sink_modules.reserve(net_sink_terminal_ids_[module][net].size()); + for (const size_t& id : net_sink_terminal_ids_[module][net]) { + sink_modules.push_back(net_terminal_storage_[id].first); + } + + return sink_modules; } /* Find the ids of sink instances of a net */ @@ -375,7 +393,13 @@ vtr::vector ModuleManager::net_sink_ports(const M /* Validate module net */ VTR_ASSERT(valid_module_net_id(module, net)); - return net_sink_port_ids_[module][net]; + vtr::vector sink_ports; + sink_ports.reserve(net_sink_terminal_ids_[module][net].size()); + for (const size_t& id : net_sink_terminal_ids_[module][net]) { + sink_ports.push_back(net_terminal_storage_[id].second); + } + + return sink_ports; } /* Find the sink pin indices of a net */ @@ -398,9 +422,9 @@ bool ModuleManager::net_sink_exist(const ModuleId& module, const ModuleNetId& ne * we can say that the sink has already been added to this net! */ for (const ModuleNetSinkId& net_sink : module_net_sinks(module, net)) { - if ( (sink_module == net_sink_modules(module, net)[net_sink]) + if ( (sink_module == net_terminal_storage_[net_sink_terminal_ids_[module][net][net_sink]].first) && (instance_id == net_sink_instances(module, net)[net_sink]) - && (sink_port == net_sink_ports(module, net)[net_sink]) + && (sink_port == net_terminal_storage_[net_sink_terminal_ids_[module][net][net_sink]].second) && (sink_pin == net_sink_pins(module, net)[net_sink]) ) { return true; } @@ -463,15 +487,13 @@ ModuleId ModuleManager::add_module(const std::string& name) { invalid_net_ids_.emplace_back(); net_names_.emplace_back(); net_src_ids_.emplace_back(); - net_src_module_ids_.emplace_back(); + net_src_terminal_ids_.emplace_back(); net_src_instance_ids_.emplace_back(); - net_src_port_ids_.emplace_back(); net_src_pin_ids_.emplace_back(); net_sink_ids_.emplace_back(); - net_sink_module_ids_.emplace_back(); + net_sink_terminal_ids_.emplace_back(); net_sink_instance_ids_.emplace_back(); - net_sink_port_ids_.emplace_back(); net_sink_pin_ids_.emplace_back(); /* Register in the name-to-id map */ @@ -647,15 +669,13 @@ void ModuleManager::reserve_module_nets(const ModuleId& module, net_names_[module].reserve(num_nets); net_src_ids_[module].reserve(num_nets); - net_src_module_ids_[module].reserve(num_nets); + net_src_terminal_ids_[module].reserve(num_nets); net_src_instance_ids_[module].reserve(num_nets); - net_src_port_ids_[module].reserve(num_nets); net_src_pin_ids_[module].reserve(num_nets); net_sink_ids_[module].reserve(num_nets); - net_sink_module_ids_[module].reserve(num_nets); + net_sink_terminal_ids_[module].reserve(num_nets); net_sink_instance_ids_[module].reserve(num_nets); - net_sink_port_ids_[module].reserve(num_nets); net_sink_pin_ids_[module].reserve(num_nets); } @@ -671,18 +691,16 @@ ModuleNetId ModuleManager::create_module_net(const ModuleId& module) { /* Allocate net-related data structures */ net_names_[module].emplace_back(); net_src_ids_[module].emplace_back(); - net_src_module_ids_[module].emplace_back(); + net_src_terminal_ids_[module].emplace_back(); net_src_instance_ids_[module].emplace_back(); - net_src_port_ids_[module].emplace_back(); net_src_pin_ids_[module].emplace_back(); /* Reserve a source */ reserve_module_net_sources(module, net, 1); net_sink_ids_[module].emplace_back(); - net_sink_module_ids_[module].emplace_back(); + net_sink_terminal_ids_[module].emplace_back(); net_sink_instance_ids_[module].emplace_back(); - net_sink_port_ids_[module].emplace_back(); net_sink_pin_ids_[module].emplace_back(); /* Reserve a source */ @@ -706,9 +724,8 @@ void ModuleManager::reserve_module_net_sources(const ModuleId& module, const Mod VTR_ASSERT(valid_module_net_id(module, net)); net_src_ids_[module][net].reserve(num_sources); - net_src_module_ids_[module][net].reserve(num_sources); + net_src_terminal_ids_[module][net].reserve(num_sources); net_src_instance_ids_[module][net].reserve(num_sources); - net_src_port_ids_[module][net].reserve(num_sources); net_src_pin_ids_[module][net].reserve(num_sources); } @@ -725,7 +742,25 @@ ModuleNetSrcId ModuleManager::add_module_net_source(const ModuleId& module, cons /* Validate the source module */ VTR_ASSERT(valid_module_id(src_module)); - net_src_module_ids_[module][net].push_back(src_module); + + /* Validate the port exists in the src module */ + VTR_ASSERT(valid_module_port_id(src_module, src_port)); + + /* Create pair of module and port + * Search in the storage. If found, use the existing pair + * Otherwise, add the pair + */ + std::pair terminal(src_module, src_port); + std::vector>::iterator it = std::find(net_terminal_storage_.begin(), + net_terminal_storage_.end(), + terminal); + if (it == net_terminal_storage_.end()) { + net_src_terminal_ids_[module][net].push_back(net_terminal_storage_.size()); + net_terminal_storage_.push_back(terminal); + } else { + VTR_ASSERT_SAFE(it != net_terminal_storage_.end()); + net_src_terminal_ids_[module][net].push_back(std::distance(net_terminal_storage_.begin(), it)); + } /* if it has the same id as module, our instance id will be by default 0 */ size_t src_instance_id = instance_id; @@ -738,10 +773,6 @@ ModuleNetSrcId ModuleManager::add_module_net_source(const ModuleId& module, cons net_src_instance_ids_[module][net].push_back(src_instance_id); } - /* Validate the port exists in the src module */ - VTR_ASSERT(valid_module_port_id(src_module, src_port)); - net_src_port_ids_[module][net].push_back(src_port); - /* Validate the pin id is in the range of the port width */ VTR_ASSERT(src_pin < module_port(src_module, src_port).get_width()); net_src_pin_ids_[module][net].push_back(src_pin); @@ -758,9 +789,8 @@ void ModuleManager::reserve_module_net_sinks(const ModuleId& module, const Modul VTR_ASSERT(valid_module_net_id(module, net)); net_sink_ids_[module][net].reserve(num_sinks); - net_sink_module_ids_[module][net].reserve(num_sinks); + net_sink_terminal_ids_[module][net].reserve(num_sinks); net_sink_instance_ids_[module][net].reserve(num_sinks); - net_sink_port_ids_[module][net].reserve(num_sinks); net_sink_pin_ids_[module][net].reserve(num_sinks); } @@ -777,7 +807,25 @@ ModuleNetSinkId ModuleManager::add_module_net_sink(const ModuleId& module, const /* Validate the source module */ VTR_ASSERT(valid_module_id(sink_module)); - net_sink_module_ids_[module][net].push_back(sink_module); + + /* Validate the port exists in the sink module */ + VTR_ASSERT(valid_module_port_id(sink_module, sink_port)); + + /* Create pair of module and port + * Search in the storage. If found, use the existing pair + * Otherwise, add the pair + */ + std::pair terminal(sink_module, sink_port); + std::vector>::iterator it = std::find(net_terminal_storage_.begin(), + net_terminal_storage_.end(), + terminal); + if (it == net_terminal_storage_.end()) { + net_sink_terminal_ids_[module][net].push_back(net_terminal_storage_.size()); + net_terminal_storage_.push_back(terminal); + } else { + VTR_ASSERT_SAFE(it != net_terminal_storage_.end()); + net_sink_terminal_ids_[module][net].push_back(std::distance(net_terminal_storage_.begin(), it)); + } /* if it has the same id as module, our instance id will be by default 0 */ size_t sink_instance_id = instance_id; @@ -790,10 +838,6 @@ ModuleNetSinkId ModuleManager::add_module_net_sink(const ModuleId& module, const net_sink_instance_ids_[module][net].push_back(sink_instance_id); } - /* Validate the port exists in the sink module */ - VTR_ASSERT(valid_module_port_id(sink_module, sink_port)); - net_sink_port_ids_[module][net].push_back(sink_port); - /* Validate the pin id is in the range of the port width */ VTR_ASSERT(sink_pin < module_port(sink_module, sink_port).get_width()); net_sink_pin_ids_[module][net].push_back(sink_pin); diff --git a/openfpga/src/fabric/module_manager.h b/openfpga/src/fabric/module_manager.h index 792c790d9..3cd0c9635 100644 --- a/openfpga/src/fabric/module_manager.h +++ b/openfpga/src/fabric/module_manager.h @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -298,16 +299,14 @@ class ModuleManager { vtr::vector> net_names_; /* Name of net */ vtr::vector>> net_src_ids_; /* Unique id of the source that drive the net */ - vtr::vector>> net_src_module_ids_; /* Pin ids that drive the net */ + vtr::vector>> net_src_terminal_ids_; /* Pin ids that drive the net */ vtr::vector>> net_src_instance_ids_; /* Pin ids that drive the net */ - vtr::vector>> net_src_port_ids_; /* Pin ids that drive the net */ vtr::vector>> net_src_pin_ids_; /* Pin ids that drive the net */ vtr::vector>> net_sink_ids_; /* Unique ids of the sink that the net drives */ - vtr::vector>> net_sink_module_ids_; /* Pin ids that the net drives */ + vtr::vector>> net_sink_terminal_ids_; /* Pin ids that the net drives */ vtr::vector>> net_sink_instance_ids_; /* Pin ids that drive the net */ - vtr::vector>> net_sink_port_ids_; /* Pin ids that drive the net */ vtr::vector>> net_sink_pin_ids_; /* Pin ids that drive the net */ /* fast look-up for module */ @@ -319,6 +318,11 @@ class ModuleManager { /* fast look-up for nets */ typedef vtr::vector>>>> NetLookup; mutable NetLookup net_lookup_; /* [module_ids][module_ids][instance_ids][port_ids][pin_ids] */ + + /* Store pairs of a module and a port, which are frequently used in net terminals + * (either source or sink) + */ + std::vector> net_terminal_storage_; }; } /* end namespace openfpga */