Skip to content

Commit a135426

Browse files
committed
Merge branch 'remove_node' of https://github.com/verilog-to-routing/vtr-verilog-to-routing into add_crr
2 parents 19cf552 + d5a5555 commit a135426

File tree

8 files changed

+119
-70
lines changed

8 files changed

+119
-70
lines changed

libs/librrgraph/src/base/rr_graph_builder.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -225,12 +225,8 @@ std::vector<RREdgeId> RRGraphBuilder::node_in_edges(RRNodeId node) const {
225225
return node_in_edges_[node];
226226
}
227227

228-
void RRGraphBuilder::set_node_ptc_nums(RRNodeId node, const std::string& ptc_str) {
229-
node_storage_.set_node_ptc_nums(node, ptc_str);
230-
}
231-
232-
std::string RRGraphBuilder::node_ptc_nums_to_string(RRNodeId node) const {
233-
return node_storage_.node_ptc_nums_to_string(node);
228+
void RRGraphBuilder::set_node_ptc_nums(RRNodeId node, const std::vector<int>& ptc_numbers) {
229+
node_storage_.set_node_ptc_nums(node, ptc_numbers);
234230
}
235231

236232
bool RRGraphBuilder::node_contain_multiple_ptc(RRNodeId node) const {
@@ -266,8 +262,12 @@ void RRGraphBuilder::add_track_node_to_lookup(RRNodeId node) {
266262
// Find the track ids using the x/y offset
267263
if (e_rr_type::CHANX == node_type || e_rr_type::CHANY == node_type) {
268264
const std::vector<short>& track_nums = node_storage_.node_tilable_track_nums(node);
269-
ptc = (node_type == e_rr_type::CHANX) ? track_nums[x - node_storage_.node_xlow(node)] :
270-
track_nums[y - node_storage_.node_ylow(node)];
265+
if (node_type == e_rr_type::CHANX) {
266+
ptc = track_nums[x - node_storage_.node_xlow(node)];
267+
} else {
268+
VTR_ASSERT_DEBUG(node_type == e_rr_type::CHANY);
269+
ptc = track_nums[y - node_storage_.node_ylow(node)];
270+
}
271271
node_lookup_.add_node(node, node_storage_.node_layer_low(node), x, y, node_type, ptc);
272272
}
273273
}

libs/librrgraph/src/base/rr_graph_builder.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -276,11 +276,8 @@ class RRGraphBuilder {
276276
node_storage_.set_node_mux_num(id, new_mux_num);
277277
}
278278

279-
/** @brief Add a list of ptc number in string (split by comma) to a given node. This function is used by rr graph reader only. */
280-
void set_node_ptc_nums(RRNodeId node, const std::string& ptc_str);
281-
282-
/** @brief With a given node, output ptc numbers into a string (use comma as delima). This function is used by rr graph writer only. */
283-
std::string node_ptc_nums_to_string(RRNodeId node) const;
279+
/** @brief Add a list of ptc numbers to a given node. This function is used by rr graph reader only. */
280+
void set_node_ptc_nums(RRNodeId node, const std::vector<int>& ptc_numbers);
284281

285282
/** @brief Identify if a node contains multiple ptc numbers. It is used for tileable RR Graph and mainly used by I/O reader only. */
286283
bool node_contain_multiple_ptc(RRNodeId node) const;

libs/librrgraph/src/base/rr_graph_storage.cpp

Lines changed: 46 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ void t_rr_graph_storage::init_fan_in() {
186186
node_fan_in_.resize(node_storage_.size(), 0);
187187
node_fan_in_.shrink_to_fit();
188188
//Walk the graph and increment fanin on all downstream nodes
189-
for(const auto& edge_id : edge_dest_node_.keys()) {
190-
node_fan_in_[edge_dest_node_[edge_id]] += 1;
189+
for(const auto& [_, dest_node] : edge_dest_node_.pairs()) {
190+
node_fan_in_[dest_node] += 1;
191191
}
192192
}
193193

@@ -629,16 +629,22 @@ void t_rr_graph_storage::set_node_direction(RRNodeId id, Direction new_direction
629629
node_storage_[id].dir_side_.direction = new_direction;
630630
}
631631

632-
void t_rr_graph_storage::set_node_ptc_nums(RRNodeId node, const std::string& ptc_str) {
632+
void t_rr_graph_storage::set_node_ptc_nums(RRNodeId node, const std::vector<int>& ptc_numbers) {
633633
VTR_ASSERT(size_t(node) < node_storage_.size());
634-
std::vector<std::string> ptc_tokens = vtr::StringToken(ptc_str).split(",");
635-
VTR_ASSERT(ptc_tokens.size() >= 1);
636-
set_node_ptc_num(node, std::stoi(ptc_tokens[0]));
637-
if (ptc_tokens.size() > 1) {
634+
VTR_ASSERT(!ptc_numbers.empty());
635+
// The default VTR RR graph generator assigns only one PTC number per node, which is
636+
// stored in the node_ptc_ field of rr_graph_storage. However, when the tileable RR
637+
// graph is used, CHANX/CHANY nodes can have multiple PTC numbers.
638+
//
639+
// To satisfy VPR's requirements, we store the PTC number for offset = 0 in the
640+
// node_ptc_ field, and store all PTC numbers assigned to the node in the
641+
// node_tileable_track_nums_ field.
642+
set_node_ptc_num(node, ptc_numbers[0]);
643+
if (ptc_numbers.size() > 1) {
638644
VTR_ASSERT(size_t(node) < node_tilable_track_nums_.size());
639-
node_tilable_track_nums_[node].resize(ptc_tokens.size());
640-
for (size_t iptc = 0; iptc < ptc_tokens.size(); iptc++) {
641-
node_tilable_track_nums_[node][iptc] = std::stoi(ptc_tokens[iptc]);
645+
node_tilable_track_nums_[node].resize(ptc_numbers.size());
646+
for (size_t iptc = 0; iptc < ptc_numbers.size(); iptc++) {
647+
node_tilable_track_nums_[node][iptc] = ptc_numbers[iptc];
642648
}
643649
}
644650
}
@@ -650,33 +656,17 @@ void t_rr_graph_storage::add_node_tilable_track_num(RRNodeId node, size_t node_o
650656
"Track number valid only for CHANX/CHANY RR nodes");
651657

652658
size_t node_length = std::abs(node_xhigh(node) - node_xlow(node))
653-
+ std::abs(node_yhigh(node) - node_ylow(node));
654-
if (node_length + 1 != node_tilable_track_nums_[node].size()) {
655-
node_tilable_track_nums_[node].resize(node_length + 1);
656-
}
659+
+ std::abs(node_yhigh(node) - node_ylow(node))
660+
+ 1;
661+
VTR_ASSERT(node_offset < node_length);
657662

658-
VTR_ASSERT(node_offset < node_tilable_track_nums_[node].size());
663+
if (node_length != node_tilable_track_nums_[node].size()) {
664+
node_tilable_track_nums_[node].resize(node_length);
665+
}
659666

660667
node_tilable_track_nums_[node][node_offset] = track_id;
661668
}
662669

663-
std::string t_rr_graph_storage::node_ptc_nums_to_string(RRNodeId node) const {
664-
if (node_tilable_track_nums_.empty()) {
665-
return std::to_string(size_t(node_ptc_num(node)));
666-
}
667-
VTR_ASSERT(size_t(node) < node_tilable_track_nums_.size());
668-
if (node_tilable_track_nums_[node].empty()) {
669-
return std::to_string(size_t(node_ptc_num(node)));
670-
}
671-
std::string ret;
672-
for (size_t iptc = 0; iptc < node_tilable_track_nums_[node].size(); iptc++) {
673-
ret += std::to_string(size_t(node_tilable_track_nums_[node][iptc])) + ",";
674-
}
675-
// Remove the last comma
676-
ret.pop_back();
677-
return ret;
678-
}
679-
680670
void t_rr_graph_storage::add_node_side(RRNodeId id, e_side new_side) {
681671
if (node_type(id) != e_rr_type::IPIN && node_type(id) != e_rr_type::OPIN) {
682672
VTR_LOG_ERROR("Attempted to set RR node 'side' for non-pin type '%s'", node_type_string(id));
@@ -703,26 +693,26 @@ void t_rr_graph_storage::set_virtual_clock_network_root_idx(RRNodeId virtual_clo
703693
}
704694
}
705695

706-
void t_rr_graph_storage::remove_nodes(const std::vector<RRNodeId>& nodes) {
696+
void t_rr_graph_storage::remove_nodes(std::vector<RRNodeId> nodes_to_remove) {
707697
VTR_ASSERT(!edges_read_);
698+
VTR_ASSERT(!partitioned_);
708699
// To remove the nodes, we first sort them in ascending order. This makes it easy
709700
// to calculate the offset by which other node IDs need to be adjusted.
710701
// For example, after sorting the nodes to be removed, if a node ID falls between
711702
// the first and second element, its ID should be reduced by 1.
712703
// If a node ID is larger than the last element, its ID should be reduced by
713704
// the total number of nodes being removed.
714-
std::vector<RRNodeId> sorted_nodes = nodes;
715-
std::sort(sorted_nodes.begin(), sorted_nodes.end());
705+
std::sort(nodes_to_remove.begin(), nodes_to_remove.end());
716706

717707
// Iterate over the nodes to be removed and adjust the IDs of nodes
718708
// that fall between them.
719-
for (size_t i = 0; i < sorted_nodes.size(); ++i) {
720-
size_t start_rr_node_index = size_t(sorted_nodes[i]) + 1;
721-
size_t end_rr_node_index = (i == sorted_nodes.size() - 1) ? node_storage_.size() : size_t(sorted_nodes[i + 1]);
722-
for (size_t j = start_rr_node_index; j < end_rr_node_index; ++j) {
723-
RRNodeId old_node = RRNodeId(j);
709+
for (size_t removal_idx = 0; removal_idx < nodes_to_remove.size(); ++removal_idx) {
710+
size_t start_rr_node_index = size_t(nodes_to_remove[removal_idx]) + 1;
711+
size_t end_rr_node_index = (removal_idx == nodes_to_remove.size() - 1) ? node_storage_.size() : size_t(nodes_to_remove[removal_idx + 1]);
712+
for (size_t node_idx = start_rr_node_index; node_idx < end_rr_node_index; ++node_idx) {
713+
RRNodeId old_node = RRNodeId(node_idx);
724714
// New node index is equal to the old nodex index minus the number of nodes being removed before it.
725-
RRNodeId new_node = RRNodeId(j-(i+1));
715+
RRNodeId new_node = RRNodeId(node_idx-(removal_idx+1));
726716
node_storage_[new_node] = node_storage_[old_node];
727717
node_ptc_[new_node] = node_ptc_[old_node];
728718
node_layer_[new_node] = node_layer_[old_node];
@@ -736,11 +726,15 @@ void t_rr_graph_storage::remove_nodes(const std::vector<RRNodeId>& nodes) {
736726
}
737727

738728
// Now that the data structures are adjusted, we can shrink the size of them
739-
size_t num_nodes_to_remove = sorted_nodes.size();
729+
size_t num_nodes_to_remove = nodes_to_remove.size();
740730
VTR_ASSERT(num_nodes_to_remove <= node_storage_.size());
741731
node_storage_.erase(node_storage_.end()-num_nodes_to_remove, node_storage_.end());
742732
node_ptc_.erase(node_ptc_.end()-num_nodes_to_remove, node_ptc_.end());
743733
node_layer_.erase(node_layer_.end()-num_nodes_to_remove, node_layer_.end());
734+
// After shifting the IDs of nodes that are not removed to the left, the last
735+
// `num_nodes_to_remove` node IDs become invalid (their names have already been
736+
// updated for other nodes). Therefore, the corresponding entries in `node_name_`
737+
// must be removed.
744738
for (size_t node_index = node_name_.size()-num_nodes_to_remove; node_index < node_name_.size(); ++node_index) {
745739
RRNodeId node = RRNodeId(node_index);
746740
node_name_.erase(node);
@@ -752,19 +746,25 @@ void t_rr_graph_storage::remove_nodes(const std::vector<RRNodeId>& nodes) {
752746
}
753747

754748
std::vector<RREdgeId> removed_edges;
749+
// This function iterates over edge_src_node_ and edge_dest_node_ to remove
750+
// entries where either endpoint of an edge is in the nodes_to_remove list.
751+
// It also updates the node IDs of the remaining edges, since node IDs have
752+
// been shifted.
755753
auto adjust_edges = [&](vtr::vector<RREdgeId, RRNodeId>& edge_nodes) {
756754
for (size_t edge_index = 0; edge_index < edge_nodes.size(); ++edge_index) {
757755
RREdgeId edge_id = RREdgeId(edge_index);
758756
RRNodeId node = edge_nodes[edge_id];
759757

760758
// Find insertion point in the sorted vector
761-
auto node_it = std::lower_bound(sorted_nodes.begin(), sorted_nodes.end(), node);
759+
auto node_it = std::lower_bound(nodes_to_remove.begin(), nodes_to_remove.end(), node);
762760

763-
if (node_it != sorted_nodes.end() && *node_it == node) {
764-
// Node exists in sorted_nodes, mark edge for removal
761+
if (node_it != nodes_to_remove.end() && *node_it == node) {
762+
// Node exists in nodes_to_remove, mark edge for removal
765763
removed_edges.push_back(edge_id);
766764
} else {
767-
size_t node_offset = std::distance(sorted_nodes.begin(), node_it);
765+
// If the node is not in the nodes_to_remove list, update the node ID of the edge
766+
// by finding how many nodes are there in nodes_to_remove before the node.
767+
size_t node_offset = std::distance(nodes_to_remove.begin(), node_it);
768768
size_t new_node_index = size_t(node) - node_offset;
769769
edge_nodes[edge_id] = RRNodeId(new_node_index);
770770
}

libs/librrgraph/src/base/rr_graph_storage.h

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -705,10 +705,20 @@ class t_rr_graph_storage {
705705
void set_node_capacity(RRNodeId, short new_capacity);
706706
void set_node_direction(RRNodeId, Direction new_direction);
707707

708-
void set_node_ptc_nums(RRNodeId node, const std::string& ptc_str);
709-
void add_node_tilable_track_num(RRNodeId node, size_t node_offset, short track_id);
708+
/**
709+
* @brief Set the ptc numbers for a node.
710+
* @param node The node id
711+
* @param ptc_numbers The ptc numbers vector to be set for the node.
712+
*/
713+
void set_node_ptc_nums(RRNodeId node, const std::vector<int>& ptc_numbers);
710714

711-
void emplace_back_node_tilable_track_num();
715+
/**
716+
* @brief Add a track number to a node.
717+
* @param node The node id
718+
* @param node_offset The offset of the node from the beginning of the node.
719+
* @param track_id The track number (ptc number) of the node at the given offset.
720+
*/
721+
void add_node_tilable_track_num(RRNodeId node, size_t node_offset, short track_id);
712722

713723
bool node_contain_multiple_ptc(RRNodeId node) const {
714724
if (node_tilable_track_nums_.empty()) {
@@ -718,8 +728,6 @@ class t_rr_graph_storage {
718728
}
719729
}
720730

721-
std::string node_ptc_nums_to_string(RRNodeId node) const;
722-
723731
const std::vector<short>& node_tilable_track_nums(RRNodeId node) const {
724732
return node_tilable_track_nums_[node];
725733
}
@@ -743,10 +751,13 @@ class t_rr_graph_storage {
743751
* If init_fan_in has been called, you need to call it again after removing the nodes.
744752
* @note This a very expensive method, so should be called only when necessary. It is better
745753
* to not add nodes in the first place, instead of relying on this method to remove nodes.
754+
*
755+
* @note This operation is O(|V| + |E|·log k), where k is the number of nodes to remove,
756+
* and should not be called frequently.
746757
*
747-
* @param nodes list of RRNodes to be removed
758+
* @param nodes_to_remove list of RRNodes to be removed
748759
*/
749-
void remove_nodes(const std::vector<RRNodeId>& nodes);
760+
void remove_nodes(std::vector<RRNodeId> nodes_to_remove);
750761

751762
/****************
752763
* Edge methods *

libs/librrgraph/src/base/rr_graph_utils.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,4 +390,30 @@ bool chan_same_type_are_adjacent(const RRGraphView& rr_graph, RRNodeId node1, RR
390390
}
391391

392392
return false; // unreachable
393-
}
393+
}
394+
395+
std::vector<int> parse_ptc_numbers(const std::string& ptc_str) {
396+
std::vector<int> ptc_numbers;
397+
std::vector<std::string> ptc_tokens = vtr::StringToken(ptc_str).split(",");
398+
for (const std::string& ptc_token : ptc_tokens) {
399+
ptc_numbers.push_back(std::stoi(ptc_token));
400+
}
401+
return ptc_numbers;
402+
}
403+
404+
std::string node_ptc_number_to_string(const RRGraphView& rr_graph, RRNodeId node) {
405+
const t_rr_graph_storage& node_storage = rr_graph.rr_nodes();
406+
407+
if (!node_storage.node_contain_multiple_ptc(node)) {
408+
return std::to_string(size_t(node_storage.node_ptc_num(node)));
409+
}
410+
411+
std::string ret;
412+
const std::vector<short>& track_nums = node_storage.node_tilable_track_nums(node);
413+
for (size_t iptc = 0; iptc < track_nums.size(); iptc++) {
414+
ret += std::to_string(track_nums[iptc]) + ",";
415+
}
416+
// Remove the last comma
417+
ret.pop_back();
418+
return ret;
419+
}

libs/librrgraph/src/base/rr_graph_utils.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,17 @@ bool chanxy_chanz_adjacent(const RRGraphView& rr_graph, RRNodeId node1, RRNodeId
125125

126126
bool chan_same_type_are_adjacent(const RRGraphView& rr_graph, RRNodeId node1, RRNodeId node2);
127127

128+
/**
129+
* @brief Parse the ptc numbers string into a vector of integers.
130+
* @param ptc_str The ptc numbers string in the format of "ptc1,ptc2,ptc3,...ptcn".
131+
* @return A vector of integers representing the ptc numbers.
132+
*/
133+
std::vector<int> parse_ptc_numbers(const std::string& ptc_str);
134+
135+
/**
136+
* @brief Convert the ptc numbers of a node to a string.
137+
* @param rr_graph The routing resource graph
138+
* @param node The node id
139+
* @return A string representing the ptc numbers of the node in the format of "ptc1,ptc2,ptc3,...ptcn".
140+
*/
141+
std::string node_ptc_number_to_string(const RRGraphView& rr_graph, RRNodeId node);

libs/librrgraph/src/io/rr_graph_uxsdcxx_serializer.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -713,11 +713,12 @@ class RrGraphSerializer final : public uxsd::RrGraphBase<RrGraphContextTypes> {
713713
inline void set_node_loc_ptc(const char* ptc, int& inode) final {
714714
t_rr_node node = (*rr_nodes_)[inode];
715715
RRNodeId node_id = node.id();
716-
return rr_graph_builder_->set_node_ptc_nums(node_id, std::string(ptc));
716+
std::vector<int> ptc_numbers = parse_ptc_numbers(ptc);
717+
return rr_graph_builder_->set_node_ptc_nums(node_id, ptc_numbers);
717718
}
718719

719720
inline const char* get_node_loc_ptc(const t_rr_node& node) final {
720-
temp_string_ = rr_graph_builder_->node_ptc_nums_to_string(node.id());
721+
temp_string_ = node_ptc_number_to_string(*rr_graph_, node.id());
721722
return temp_string_.c_str();
722723
}
723724
inline int get_node_loc_layer_low(const t_rr_node& node) final {

0 commit comments

Comments
 (0)