optimize memory efficiency for module net id storage
This commit is contained in:
parent
23bcad0678
commit
f49cabeeda
|
@ -35,7 +35,8 @@ ModuleManager::module_port_range ModuleManager::module_ports(const ModuleId& mod
|
||||||
ModuleManager::module_net_range ModuleManager::module_nets(const ModuleId& module) const {
|
ModuleManager::module_net_range ModuleManager::module_nets(const ModuleId& module) const {
|
||||||
/* Validate the module_id */
|
/* Validate the module_id */
|
||||||
VTR_ASSERT(valid_module_id(module));
|
VTR_ASSERT(valid_module_id(module));
|
||||||
return vtr::make_range(net_ids_[module].begin(), net_ids_[module].end());
|
return vtr::make_range(module_net_iterator(ModuleNetId(0), invalid_net_ids_[module]),
|
||||||
|
module_net_iterator(ModuleNetId(num_nets_[module]), invalid_net_ids_[module]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find all the child modules under a parent module */
|
/* Find all the child modules under a parent module */
|
||||||
|
@ -108,7 +109,7 @@ size_t ModuleManager::num_modules() const {
|
||||||
size_t ModuleManager::num_nets(const ModuleId& module) const {
|
size_t ModuleManager::num_nets(const ModuleId& module) const {
|
||||||
/* Validate the module_id */
|
/* Validate the module_id */
|
||||||
VTR_ASSERT(valid_module_id(module));
|
VTR_ASSERT(valid_module_id(module));
|
||||||
return net_ids_[module].size();
|
return num_nets_[module];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the name of a module */
|
/* Find the name of a module */
|
||||||
|
@ -458,7 +459,8 @@ ModuleId ModuleManager::add_module(const std::string& name) {
|
||||||
port_is_register_.emplace_back();
|
port_is_register_.emplace_back();
|
||||||
port_preproc_flags_.emplace_back();
|
port_preproc_flags_.emplace_back();
|
||||||
|
|
||||||
net_ids_.emplace_back();
|
num_nets_.emplace_back(0);
|
||||||
|
invalid_net_ids_.emplace_back();
|
||||||
net_names_.emplace_back();
|
net_names_.emplace_back();
|
||||||
net_src_ids_.emplace_back();
|
net_src_ids_.emplace_back();
|
||||||
net_src_module_ids_.emplace_back();
|
net_src_module_ids_.emplace_back();
|
||||||
|
@ -643,8 +645,6 @@ void ModuleManager::reserve_module_nets(const ModuleId& module,
|
||||||
/* Validate the module id */
|
/* Validate the module id */
|
||||||
VTR_ASSERT ( valid_module_id(module) );
|
VTR_ASSERT ( valid_module_id(module) );
|
||||||
|
|
||||||
net_ids_[module].reserve(num_nets);
|
|
||||||
|
|
||||||
net_names_[module].reserve(num_nets);
|
net_names_[module].reserve(num_nets);
|
||||||
net_src_ids_[module].reserve(num_nets);
|
net_src_ids_[module].reserve(num_nets);
|
||||||
net_src_module_ids_[module].reserve(num_nets);
|
net_src_module_ids_[module].reserve(num_nets);
|
||||||
|
@ -665,8 +665,8 @@ ModuleNetId ModuleManager::create_module_net(const ModuleId& module) {
|
||||||
VTR_ASSERT ( valid_module_id(module) );
|
VTR_ASSERT ( valid_module_id(module) );
|
||||||
|
|
||||||
/* Create an new id */
|
/* Create an new id */
|
||||||
ModuleNetId net = ModuleNetId(net_ids_[module].size());
|
ModuleNetId net = ModuleNetId(num_nets_[module]);
|
||||||
net_ids_[module].push_back(net);
|
num_nets_[module]++;
|
||||||
|
|
||||||
/* Allocate net-related data structures */
|
/* Allocate net-related data structures */
|
||||||
net_names_[module].emplace_back();
|
net_names_[module].emplace_back();
|
||||||
|
@ -832,7 +832,7 @@ bool ModuleManager::valid_module_net_id(const ModuleId& module, const ModuleNetI
|
||||||
if (false == valid_module_id(module)) {
|
if (false == valid_module_id(module)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return ( size_t(net) < net_ids_[module].size() ) && ( net == net_ids_[module][net] );
|
return ( size_t(net) < num_nets_[module] );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleManager::invalidate_name2id_map() {
|
void ModuleManager::invalidate_name2id_map() {
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "vtr_vector.h"
|
#include "vtr_vector.h"
|
||||||
#include "module_manager_fwd.h"
|
#include "module_manager_fwd.h"
|
||||||
#include "openfpga_port.h"
|
#include "openfpga_port.h"
|
||||||
|
@ -40,10 +43,61 @@ class ModuleManager {
|
||||||
|
|
||||||
public: /* Public Constructors */
|
public: /* Public Constructors */
|
||||||
|
|
||||||
|
public: /* Type implementations */
|
||||||
|
/*
|
||||||
|
* This class (forward delcared above) is a template used to represent a lazily calculated
|
||||||
|
* iterator of the specified ID type. The key assumption made is that the ID space is
|
||||||
|
* contiguous and can be walked by incrementing the underlying ID value. To account for
|
||||||
|
* invalid IDs, it keeps a reference to the invalid ID set and returns ID::INVALID() for
|
||||||
|
* ID values in the set.
|
||||||
|
*
|
||||||
|
* It is used to lazily create an iteration range (e.g. as returned by RRGraph::edges() RRGraph::nodes())
|
||||||
|
* just based on the count of allocated elements (i.e. RRGraph::num_nodes_ or RRGraph::num_edges_),
|
||||||
|
* and the set of any invalid IDs (i.e. RRGraph::invalid_node_ids_, RRGraph::invalid_edge_ids_).
|
||||||
|
*/
|
||||||
|
template<class ID>
|
||||||
|
class lazy_id_iterator : public std::iterator<std::bidirectional_iterator_tag, ID> {
|
||||||
|
public:
|
||||||
|
//Since we pass ID as a template to std::iterator we need to use an explicit 'typename'
|
||||||
|
//to bring the value_type and iterator names into scope
|
||||||
|
typedef typename std::iterator<std::bidirectional_iterator_tag, ID>::value_type value_type;
|
||||||
|
typedef typename std::iterator<std::bidirectional_iterator_tag, ID>::iterator iterator;
|
||||||
|
|
||||||
|
lazy_id_iterator(value_type init, const std::unordered_set<ID>& invalid_ids)
|
||||||
|
: value_(init)
|
||||||
|
, invalid_ids_(invalid_ids) {}
|
||||||
|
|
||||||
|
//Advance to the next ID value
|
||||||
|
iterator operator++() {
|
||||||
|
value_ = ID(size_t(value_) + 1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Advance to the previous ID value
|
||||||
|
iterator operator--() {
|
||||||
|
value_ = ID(size_t(value_) - 1);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Dereference the iterator
|
||||||
|
value_type operator*() const { return (invalid_ids_.count(value_)) ? ID::INVALID() : value_; }
|
||||||
|
|
||||||
|
friend bool operator==(const lazy_id_iterator<ID> lhs, const lazy_id_iterator<ID> rhs) { return lhs.value_ == rhs.value_; }
|
||||||
|
friend bool operator!=(const lazy_id_iterator<ID> lhs, const lazy_id_iterator<ID> rhs) { return !(lhs == rhs); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
value_type value_;
|
||||||
|
const std::unordered_set<ID>& invalid_ids_;
|
||||||
|
};
|
||||||
|
|
||||||
public: /* Types and ranges */
|
public: /* Types and ranges */
|
||||||
|
//Lazy iterator utility forward declaration
|
||||||
|
template<class ID>
|
||||||
|
class lazy_id_iterator;
|
||||||
|
|
||||||
typedef vtr::vector<ModuleId, ModuleId>::const_iterator module_iterator;
|
typedef vtr::vector<ModuleId, ModuleId>::const_iterator module_iterator;
|
||||||
typedef vtr::vector<ModulePortId, ModulePortId>::const_iterator module_port_iterator;
|
typedef vtr::vector<ModulePortId, ModulePortId>::const_iterator module_port_iterator;
|
||||||
typedef vtr::vector<ModuleNetId, ModuleNetId>::const_iterator module_net_iterator;
|
typedef lazy_id_iterator<ModuleNetId> module_net_iterator;
|
||||||
typedef vtr::vector<ModuleNetSrcId, ModuleNetSrcId>::const_iterator module_net_src_iterator;
|
typedef vtr::vector<ModuleNetSrcId, ModuleNetSrcId>::const_iterator module_net_src_iterator;
|
||||||
typedef vtr::vector<ModuleNetSinkId, ModuleNetSinkId>::const_iterator module_net_sink_iterator;
|
typedef vtr::vector<ModuleNetSinkId, ModuleNetSinkId>::const_iterator module_net_sink_iterator;
|
||||||
|
|
||||||
|
@ -239,7 +293,8 @@ class ModuleManager {
|
||||||
* To avoid large memory footprint, we do NOT create pins,
|
* To avoid large memory footprint, we do NOT create pins,
|
||||||
* To enable fast look-up on pins, we create a fast look-up
|
* To enable fast look-up on pins, we create a fast look-up
|
||||||
*/
|
*/
|
||||||
vtr::vector<ModuleId, vtr::vector<ModuleNetId, ModuleNetId>> net_ids_; /* List of nets for each Module */
|
vtr::vector<ModuleId, size_t> num_nets_; /* List of nets for each Module */
|
||||||
|
vtr::vector<ModuleId, std::unordered_set<ModuleNetId>> invalid_net_ids_; /* Invalid net ids */
|
||||||
vtr::vector<ModuleId, vtr::vector<ModuleNetId, std::string>> net_names_; /* Name of net */
|
vtr::vector<ModuleId, vtr::vector<ModuleNetId, std::string>> net_names_; /* Name of net */
|
||||||
|
|
||||||
vtr::vector<ModuleId, vtr::vector<ModuleNetId, vtr::vector<ModuleNetSrcId, ModuleNetSrcId>>> net_src_ids_; /* Unique id of the source that drive the net */
|
vtr::vector<ModuleId, vtr::vector<ModuleNetId, vtr::vector<ModuleNetSrcId, ModuleNetSrcId>>> net_src_ids_; /* Unique id of the source that drive the net */
|
||||||
|
|
Loading…
Reference in New Issue