From 9608cefa8650b3630f05482f476448dc1cb19ecd Mon Sep 17 00:00:00 2001 From: tangxifan Date: Thu, 2 Jul 2020 16:08:50 -0600 Subject: [PATCH] remove id vector in fabric bitstream database and replace with more memory efficient implementation --- .../src/fpga_bitstream/fabric_bitstream.cpp | 18 ++++-- .../src/fpga_bitstream/fabric_bitstream.h | 61 ++++++++++++++++++- 2 files changed, 71 insertions(+), 8 deletions(-) diff --git a/openfpga/src/fpga_bitstream/fabric_bitstream.cpp b/openfpga/src/fpga_bitstream/fabric_bitstream.cpp index bc6b13d09..962fe02f6 100644 --- a/openfpga/src/fpga_bitstream/fabric_bitstream.cpp +++ b/openfpga/src/fpga_bitstream/fabric_bitstream.cpp @@ -9,12 +9,20 @@ /* begin namespace openfpga */ namespace openfpga { +/************************************************** + * Public Constructor + *************************************************/ +FabricBitstream::FabricBitstream() { + num_bits_ = 0; +} + /************************************************** * Public Accessors : Aggregates *************************************************/ /* Find all the configuration bits */ FabricBitstream::fabric_bit_range FabricBitstream::bits() const { - return vtr::make_range(bit_ids_.begin(), bit_ids_.end()); + return vtr::make_range(fabric_bit_iterator(FabricBitId(0), invalid_bit_ids_), + fabric_bit_iterator(FabricBitId(num_bits_), invalid_bit_ids_)); } /****************************************************************************** @@ -56,16 +64,15 @@ char FabricBitstream::bit_din(const FabricBitId& bit_id) const { * Public Mutators ******************************************************************************/ void FabricBitstream::reserve(const size_t& num_bits) { - bit_ids_.reserve(num_bits); config_bit_ids_.reserve(num_bits); bit_addresses_.reserve(num_bits); bit_dins_.reserve(num_bits); } FabricBitId FabricBitstream::add_bit(const ConfigBitId& config_bit_id) { - FabricBitId bit = FabricBitId(bit_ids_.size()); + FabricBitId bit = FabricBitId(num_bits_); /* Add a new bit, and allocate associated data structures */ - bit_ids_.push_back(bit); + num_bits_++; config_bit_ids_.push_back(config_bit_id); bit_addresses_.emplace_back(); bit_dins_.push_back(false); @@ -97,7 +104,6 @@ void FabricBitstream::set_bit_din(const FabricBitId& bit_id, } void FabricBitstream::reverse() { - std::reverse(config_bit_ids_.begin(), config_bit_ids_.end()); std::reverse(bit_addresses_.begin(), bit_addresses_.end()); std::reverse(bit_dins_.begin(), bit_dins_.end()); } @@ -106,7 +112,7 @@ void FabricBitstream::reverse() { * Public Validators ******************************************************************************/ char FabricBitstream::valid_bit_id(const FabricBitId& bit_id) const { - return (size_t(bit_id) < bit_ids_.size()) && (bit_id == bit_ids_[bit_id]); + return (size_t(bit_id) < num_bits_); } } /* end namespace openfpga */ diff --git a/openfpga/src/fpga_bitstream/fabric_bitstream.h b/openfpga/src/fpga_bitstream/fabric_bitstream.h index 9c8f492b5..ee0699b2d 100644 --- a/openfpga/src/fpga_bitstream/fabric_bitstream.h +++ b/openfpga/src/fpga_bitstream/fabric_bitstream.h @@ -29,6 +29,8 @@ #define FABRIC_BITSTREAM_H #include +#include +#include #include "vtr_vector.h" #include "bitstream_manager_fwd.h" @@ -38,11 +40,65 @@ namespace openfpga { class FabricBitstream { + 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 lazy_id_iterator : public std::iterator { + 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::value_type value_type; + typedef typename std::iterator::iterator iterator; + + lazy_id_iterator(value_type init, const std::unordered_set& 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 lhs, const lazy_id_iterator rhs) { return lhs.value_ == rhs.value_; } + friend bool operator!=(const lazy_id_iterator lhs, const lazy_id_iterator rhs) { return !(lhs == rhs); } + + private: + value_type value_; + const std::unordered_set& invalid_ids_; + }; + public: /* Types and ranges */ - typedef vtr::vector::const_iterator fabric_bit_iterator; + //Lazy iterator utility forward declaration + template + class lazy_id_iterator; + + typedef lazy_id_iterator fabric_bit_iterator; typedef vtr::Range fabric_bit_range; + public: /* Public constructor */ + FabricBitstream(); + public: /* Public aggregators */ /* Find all the configuration bits */ fabric_bit_range bits() const; @@ -88,7 +144,8 @@ class FabricBitstream { private: /* Internal data */ /* Unique id of a bit in the Bitstream */ - vtr::vector bit_ids_; + size_t num_bits_; + std::unordered_set invalid_bit_ids_; vtr::vector config_bit_ids_; /* Address bits: this is designed for memory decoders