Skip to content

Commit 80dcdeb

Browse files
add comments and subroutines
1 parent 8338c90 commit 80dcdeb

File tree

8 files changed

+135
-74
lines changed

8 files changed

+135
-74
lines changed

vpr/src/base/vpr_context.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,9 @@ struct ClusteringHelperContext : public Context {
353353
// unordered_set for faster insertion/deletion during the iterative improvement process of packing
354354
vtr::vector<ClusterBlockId, std::unordered_set<AtomBlockId>> atoms_lookup;
355355

356+
/** Stores the NoC group ID of each atom block. Atom blocks that belong
357+
* to different NoC groups can't be clustered with each other into the
358+
* same clustered block.*/
356359
vtr::vector<AtomBlockId, NocGroupId> atom_noc_grp_id;
357360

358361
~ClusteringHelperContext() {

vpr/src/base/vpr_types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1501,7 +1501,7 @@ struct t_noc_opts {
15011501
double noc_latency_constraints_weighting; ///<controls the significance of meeting the traffic flow constraints range:[0-inf)
15021502
double noc_latency_weighting; ///<controls the significance of the traffic flow latencies relative to the other NoC placement costs range:[0-inf)
15031503
double noc_congestion_weighting; ///<controls the significance of the link congestions relative to the other NoC placement costs range:[0-inf)
1504-
double noc_centroid_weight;
1504+
double noc_centroid_weight; ///<controls how much the centroid location is adjusted towards NoC routers in NoC-biased centroid move:[0, 1]
15051505
int noc_swap_percentage; ///<controls the number of NoC router block swap attempts relative to the total number of swaps attempted by the placer range:[0-100]
15061506
std::string noc_placement_file_name; ///<is the name of the output file that contains the NoC placement information
15071507
};

vpr/src/noc/noc_data_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct noc_traffic_flow_id_tag;
2424
/** Datatype to index traffic flows within the application */
2525
typedef vtr::StrongId<noc_traffic_flow_id_tag, int> NocTrafficFlowId;
2626

27+
/** Data type to index NoC groups. */
2728
struct noc_group_id_tag;
2829
typedef vtr::StrongId<noc_group_id_tag, int> NocGroupId;
2930

vpr/src/pack/cluster.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
* t_pb:
2020
* Represents a clustered instance of a t_pb_graph_node containing netlist primitives
2121
*
22-
* t_pb_type and t_pb_graph_node (and related types) describe the targetted FPGA architecture, while t_pb represents
22+
* t_pb_type and t_pb_graph_node (and related types) describe the targeted FPGA architecture, while t_pb represents
2323
* the actual clustering of the user netlist.
2424
*
2525
* For example:
@@ -82,7 +82,7 @@
8282
* cluster until a nullptr is returned. So, the number of repeated molecules is changed from 1 to 500,
8383
* effectively making the clusterer pack a cluster until a nullptr is returned.
8484
*/
85-
#define ATTRACTION_GROUPS_MAX_REPEATED_MOLECULES 500
85+
static constexpr int ATTRACTION_GROUPS_MAX_REPEATED_MOLECULES = 500;
8686

8787
std::map<t_logical_block_type_ptr, size_t> do_clustering(const t_packer_opts& packer_opts,
8888
const t_analysis_opts& analysis_opts,
@@ -243,6 +243,11 @@ std::map<t_logical_block_type_ptr, size_t> do_clustering(const t_packer_opts& pa
243243
* Since some of the primitives might fail legality, this structure temporarily
244244
* stores PartitionRegion information while the cluster is packed*/
245245
PartitionRegion temp_cluster_pr;
246+
/*
247+
* Stores the cluster's NoC group ID as more primitives are added to it.
248+
* This is used to check if a candidate primitive is in the same NoC group
249+
* as the atom blocks that have already been added to the primitive.
250+
*/
246251
NocGroupId temp_cluster_noc_grp_id = NocGroupId::INVALID();
247252

248253
start_new_cluster(helper_ctx.cluster_placement_stats, helper_ctx.primitives_list,

vpr/src/pack/noc_aware_cluster_util.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ void update_noc_reachability_partitions(const std::vector<AtomBlockId>& noc_atom
4343

4444
int noc_grp_id_cnt = 0;
4545

46+
/*
47+
* Assume that the atom netlist is represented as an undirected graph
48+
* with all high fanout nets removed. In this graph, we want to find all
49+
* connected components that include at least one NoC router. We start a
50+
* BFS from each NoC router and traverse all nets below the high_fanout_threshold,
51+
* and mark each atom block with a NoC group ID.
52+
*/
53+
4654
for (auto noc_atom_id : noc_atoms) {
4755
// check if this NoC router has already been visited
4856
if (atom_visited[noc_atom_id]) {
Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,42 @@
1-
21
#ifndef VTR_NOC_AWARE_CLUSTER_UTIL_H
32
#define VTR_NOC_AWARE_CLUSTER_UTIL_H
43

4+
/**
5+
* @file This file includes helper functions used to find NoC groups
6+
* in the atom netlist and assign NoC group IDs to atom blocks.
7+
*
8+
* A NoC group is a set of atom blocks that are reachable from a NoC router
9+
* through low fanout nets. During packing, atom blocks that belong to two different
10+
* NoC group IDs cannot be packed with each other into the same clustered block.
11+
* This prevents atom blocks that belong to two separate NoC-attached modules from
12+
* being packed with each other, and helps with more localized placement of NoC-attached
13+
* modules around their corresponding NoC routers.
14+
*
15+
* For more details refer to the following paper:
16+
* The Road Less Traveled: Congestion-Aware NoC Placement and Packet Routing for FPGAs
17+
*/
18+
519
#include <vector>
620

721
#include "vpr_types.h"
822

23+
/**
24+
* @brief Iterates over all atom blocks and check whether
25+
* their blif model is the same as a NoC routers.
26+
*
27+
* @return The atom block IDs of the NoC router blocks in the netlist.
28+
*/
929
std::vector<AtomBlockId> find_noc_router_atoms();
1030

31+
32+
/**
33+
* @brief Runs BFS starting from NoC routers to find all connected
34+
* components that include a NoC router. Each connected component
35+
* containing a NoC router is marked as a NoC group. The NoC group ID
36+
* for each atom block is updated in the global state.
37+
*
38+
* @param noc_atoms The atom block IDs of the NoC router blocks in the netlist.
39+
*/
1140
void update_noc_reachability_partitions(const std::vector<AtomBlockId>& noc_atoms);
1241

1342
#endif

vpr/src/place/centroid_move_generator.cpp

Lines changed: 75 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,88 @@ CentroidMoveGenerator::CentroidMoveGenerator(float noc_attraction_weight, size_t
2424
, noc_attraction_enabled_(true) {
2525
VTR_ASSERT(noc_attraction_weight > 0.0 && noc_attraction_weight <= 1.0);
2626

27-
const auto& cluster_ctx = g_vpr_ctx.clustering();
28-
const auto& noc_ctx = g_vpr_ctx.noc();
2927

3028
// check if static member variables are already initialized
3129
if (!noc_group_clusters_.empty() && !noc_group_routers_.empty() &&
3230
!cluster_to_noc_grp_.empty() && !noc_router_to_noc_group_.empty()) {
3331
return;
32+
} else {
33+
initialize_noc_groups(high_fanout_net);
34+
}
35+
}
36+
37+
e_create_move CentroidMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected,
38+
t_propose_action& proposed_action,
39+
float rlim,
40+
const t_placer_opts& placer_opts,
41+
const PlacerCriticalities* /*criticalities*/) {
42+
// Find a movable block based on blk_type
43+
ClusterBlockId b_from = propose_block_to_move(placer_opts,
44+
proposed_action.logical_blk_type_index,
45+
false,
46+
nullptr,
47+
nullptr);
48+
49+
VTR_LOGV_DEBUG(g_vpr_ctx.placement().f_placer_debug,
50+
"Centroid Move Choose Block %d - rlim %f\n",
51+
size_t(b_from),
52+
rlim);
53+
54+
if (!b_from) { //No movable block found
55+
VTR_LOGV_DEBUG(g_vpr_ctx.placement().f_placer_debug,
56+
"\tNo movable block found\n");
57+
return e_create_move::ABORT;
3458
}
3559

60+
const auto& device_ctx = g_vpr_ctx.device();
61+
const auto& place_ctx = g_vpr_ctx.placement();
62+
const auto& cluster_ctx = g_vpr_ctx.clustering();
63+
auto& place_move_ctx = g_placer_ctx.mutable_move();
64+
65+
t_pl_loc from = place_ctx.block_locs[b_from].loc;
66+
auto cluster_from_type = cluster_ctx.clb_nlist.block_type(b_from);
67+
auto grid_from_type = device_ctx.grid.get_physical_type({from.x, from.y, from.layer});
68+
VTR_ASSERT(is_tile_compatible(grid_from_type, cluster_from_type));
69+
70+
t_range_limiters range_limiters{rlim,
71+
place_move_ctx.first_rlim,
72+
placer_opts.place_dm_rlim};
73+
74+
t_pl_loc to, centroid;
75+
76+
/* Calculate the centroid location*/
77+
calculate_centroid_loc(b_from, false, centroid, nullptr, noc_attraction_enabled_, noc_attraction_w_);
78+
79+
// Centroid location is not necessarily a valid location, and the downstream location expect a valid
80+
// layer for "to" location. So if the layer is not valid, we set it to the same layer as from loc.
81+
to.layer = (centroid.layer < 0) ? from.layer : centroid.layer;
82+
/* Find a location near the weighted centroid_loc */
83+
if (!find_to_loc_centroid(cluster_from_type, from, centroid, range_limiters, to, b_from)) {
84+
return e_create_move::ABORT;
85+
}
86+
87+
e_create_move create_move = ::create_move(blocks_affected, b_from, to);
88+
89+
//Check that all the blocks affected by the move would still be in a legal floorplan region after the swap
90+
if (!floorplan_legal(blocks_affected)) {
91+
return e_create_move::ABORT;
92+
}
93+
94+
return create_move;
95+
}
96+
97+
const std::vector<ClusterBlockId>& CentroidMoveGenerator::get_noc_group_routers(NocGroupId noc_grp_id) {
98+
return CentroidMoveGenerator::noc_group_routers_[noc_grp_id];
99+
}
100+
101+
NocGroupId CentroidMoveGenerator::get_cluster_noc_group(ClusterBlockId blk_id) {
102+
return CentroidMoveGenerator::cluster_to_noc_grp_[blk_id];
103+
}
104+
105+
void CentroidMoveGenerator::initialize_noc_groups(size_t high_fanout_net) {
106+
const auto& cluster_ctx = g_vpr_ctx.clustering();
107+
const auto& noc_ctx = g_vpr_ctx.noc();
108+
36109
noc_group_clusters_.clear();
37110
noc_group_routers_.clear();
38111
cluster_to_noc_grp_.clear();
@@ -127,71 +200,3 @@ CentroidMoveGenerator::CentroidMoveGenerator(float noc_attraction_weight, size_t
127200
}
128201
}
129202
}
130-
131-
e_create_move CentroidMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected,
132-
t_propose_action& proposed_action,
133-
float rlim,
134-
const t_placer_opts& placer_opts,
135-
const PlacerCriticalities* /*criticalities*/) {
136-
// Find a movable block based on blk_type
137-
ClusterBlockId b_from = propose_block_to_move(placer_opts,
138-
proposed_action.logical_blk_type_index,
139-
false,
140-
nullptr,
141-
nullptr);
142-
143-
VTR_LOGV_DEBUG(g_vpr_ctx.placement().f_placer_debug,
144-
"Centroid Move Choose Block %d - rlim %f\n",
145-
size_t(b_from),
146-
rlim);
147-
148-
if (!b_from) { //No movable block found
149-
VTR_LOGV_DEBUG(g_vpr_ctx.placement().f_placer_debug,
150-
"\tNo movable block found\n");
151-
return e_create_move::ABORT;
152-
}
153-
154-
const auto& device_ctx = g_vpr_ctx.device();
155-
const auto& place_ctx = g_vpr_ctx.placement();
156-
const auto& cluster_ctx = g_vpr_ctx.clustering();
157-
auto& place_move_ctx = g_placer_ctx.mutable_move();
158-
159-
t_pl_loc from = place_ctx.block_locs[b_from].loc;
160-
auto cluster_from_type = cluster_ctx.clb_nlist.block_type(b_from);
161-
auto grid_from_type = device_ctx.grid.get_physical_type({from.x, from.y, from.layer});
162-
VTR_ASSERT(is_tile_compatible(grid_from_type, cluster_from_type));
163-
164-
t_range_limiters range_limiters{rlim,
165-
place_move_ctx.first_rlim,
166-
placer_opts.place_dm_rlim};
167-
168-
t_pl_loc to, centroid;
169-
170-
/* Calculate the centroid location*/
171-
calculate_centroid_loc(b_from, false, centroid, nullptr, noc_attraction_enabled_, noc_attraction_w_);
172-
173-
// Centroid location is not necessarily a valid location, and the downstream location expect a valid
174-
// layer for "to" location. So if the layer is not valid, we set it to the same layer as from loc.
175-
to.layer = (centroid.layer < 0) ? from.layer : centroid.layer;
176-
/* Find a location near the weighted centroid_loc */
177-
if (!find_to_loc_centroid(cluster_from_type, from, centroid, range_limiters, to, b_from)) {
178-
return e_create_move::ABORT;
179-
}
180-
181-
e_create_move create_move = ::create_move(blocks_affected, b_from, to);
182-
183-
//Check that all the blocks affected by the move would still be in a legal floorplan region after the swap
184-
if (!floorplan_legal(blocks_affected)) {
185-
return e_create_move::ABORT;
186-
}
187-
188-
return create_move;
189-
}
190-
191-
const std::vector<ClusterBlockId>& CentroidMoveGenerator::get_noc_group_routers(NocGroupId noc_grp_id) {
192-
return CentroidMoveGenerator::noc_group_routers_[noc_grp_id];
193-
}
194-
195-
NocGroupId CentroidMoveGenerator::get_cluster_noc_group(ClusterBlockId blk_id) {
196-
return CentroidMoveGenerator::cluster_to_noc_grp_[blk_id];
197-
}

vpr/src/place/centroid_move_generator.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,16 @@ class CentroidMoveGenerator : public MoveGenerator {
8787

8888
/** Specifies the NoC group for each NoC router*/
8989
static std::map<ClusterBlockId, NocGroupId> noc_router_to_noc_group_;
90+
91+
/**
92+
* @brief This function forms NoC groups by finding connected components
93+
* in the graph representing the clustered netlist. When finding connected
94+
* components, none of the nets whose fanout is larger than high_fanout_net
95+
* are traversed.
96+
* @param high_fanout_net All nets with a fanout larger than this number are
97+
* ignored when forming NoC groups.
98+
*/
99+
static void initialize_noc_groups(size_t high_fanout_net);
90100
};
91101

92102
#endif

0 commit comments

Comments
 (0)