vpr: Add fast node look-up support to RRGraph
diff --git a/vpr/src/route/rr_graph.cpp b/vpr/src/route/rr_graph.cpp
index 33e3d45..d7768e4 100644
--- a/vpr/src/route/rr_graph.cpp
+++ b/vpr/src/route/rr_graph.cpp
@@ -138,6 +138,36 @@
return RREdgeId::INVALID();
}
+RRNodeId RRGraph::find_node(short x, short y, t_rr_type type, int ptc, e_side side) const {
+ if (!valid_fast_node_lookup()) {
+ build_fast_node_lookup();
+ }
+ size_t itype = type;
+ size_t iside = side;
+ return node_lookup_[x][y][itype][ptc][iside];
+}
+
+RRGraph::node_range RRGraph::find_nodes(short x, short y, t_rr_type type, int ptc) const {
+ if (!valid_fast_node_lookup()) {
+ build_fast_node_lookup();
+ }
+
+ const auto& matching_nodes = node_lookup_[x][y][type][ptc];
+
+ return vtr::make_range(matching_nodes.begin(), matching_nodes.end());
+}
+
+bool RRGraph::is_dirty() const {
+ return dirty_;
+}
+
+void RRGraph::set_dirty() {
+ dirty_ = true;
+}
+
+void RRGraph::clear_dirty() {
+ dirty_ = false;
+}
//Mutators
RRNodeId RRGraph::create_node(t_rr_type type) {
@@ -161,6 +191,8 @@
node_in_edges_.emplace_back(); //Initially empty
node_out_edges_.emplace_back(); //Initially empty
+ invalidate_fast_node_lookup();
+
VTR_ASSERT(validate_sizes());
return node_id;
@@ -212,7 +244,10 @@
//Mark node invalid
node_ids_[node] = RRNodeId::INVALID();
- dirty_ = true;
+ //Invalidate the node look-up
+ invalidate_fast_node_lookup();
+
+ set_dirty();
}
void RRGraph::remove_edge(RREdgeId edge) {
@@ -237,7 +272,7 @@
//Mark edge invalid
edge_ids_[edge] = RREdgeId::INVALID();
- dirty_ = true;
+ set_dirty();
}
void RRGraph::set_node_xlow(RRNodeId node, short xlow) {
@@ -340,6 +375,54 @@
node_Cs_[node] = C;
}
+void RRGraph::build_fast_node_lookup() const {
+ invalidate_fast_node_lookup();
+
+ for (auto node : nodes()) {
+ size_t x = node_xlow(node);
+ if (x < node_lookup_.size()) {
+ node_lookup_.resize(x + 1);
+ }
+
+ size_t y = node_ylow(node);
+ if (y < node_lookup_[x].size()) {
+ node_lookup_[x].resize(y + 1);
+ }
+
+ size_t itype = node_type(node);
+ if (itype < node_lookup_[x][y].size()) {
+ node_lookup_[x][y].resize(itype + 1);
+ }
+
+ size_t ptc = node_ptc_num(node);
+ if (ptc < node_lookup_[x][y][itype].size()) {
+ node_lookup_[x][y][itype].resize(ptc + 1);
+ }
+
+ size_t iside = -1;
+ if (node_type(node) == OPIN || node_type(node) == IPIN) {
+ iside = node_side(node);
+ } else {
+ iside = NUM_SIDES;
+ }
+
+ if (iside < node_lookup_[x][y][itype][ptc].size()) {
+ node_lookup_[x][y][itype][ptc].resize(iside + 1);
+ }
+
+ //Save node in lookup
+ node_lookup_[x][y][itype][ptc][iside] = node;
+ }
+}
+
+void RRGraph::invalidate_fast_node_lookup() const {
+ node_lookup_.clear();
+}
+
+bool RRGraph::valid_fast_node_lookup() const {
+ return !node_lookup_.empty();
+}
+
bool RRGraph::validate() {
bool success = true;
success &= validate_sizes();
@@ -495,7 +578,9 @@
rebuild_node_refs(edge_id_map);
- dirty_ = false;
+ invalidate_fast_node_lookup();
+
+ clear_dirty();
}
void RRGraph::build_id_maps(vtr::vector<RRNodeId,RRNodeId>& node_id_map,
diff --git a/vpr/src/route/rr_graph.h b/vpr/src/route/rr_graph.h
index 1ef8c89..0dcf779 100644
--- a/vpr/src/route/rr_graph.h
+++ b/vpr/src/route/rr_graph.h
@@ -60,6 +60,9 @@
//Utilities
RREdgeId find_edge(RRNodeId src_node, RRNodeId sink_node) const;
+ RRNodeId find_node(short x, short y, t_rr_type type, int ptc, e_side side=NUM_SIDES) const;
+ node_range find_nodes(short x, short y, t_rr_type type, int ptc) const;
+ bool is_dirty() const;
public: //Mutators
RRNodeId create_node(t_rr_type type);
RREdgeId create_edge(RRNodeId source, RRNodeId sink, RRSwitchId switch_id);
@@ -90,6 +93,14 @@
void compress();
bool validate();
private: //Internal
+ void set_dirty();
+ void clear_dirty();
+
+ //Fast look-up
+ void build_fast_node_lookup() const;
+ void invalidate_fast_node_lookup() const;
+ bool valid_fast_node_lookup() const;
+
//Validation
bool valid_node_id(RRNodeId node) const;
bool valid_edge_id(RREdgeId edge) const;
@@ -143,6 +154,10 @@
//Misc.
bool dirty_ = false;
+
+ //Fast look-up
+ typedef std::vector<std::vector<std::vector<std::vector<std::vector<RRNodeId>>>>> NodeLookup;
+ mutable NodeLookup node_lookup_; //[0..xmax][0..ymax][0..NUM_TYPES-1][0..ptc_max][0..NUM_SIDES-1]
};
#endif