Skip to content

Commit 790b652

Browse files
move NoC-biased member vars from PlacementContext to CentroidMoveGenerator
1 parent c69b432 commit 790b652

10 files changed

+184
-246
lines changed

vpr/src/base/vpr_context.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -413,15 +413,6 @@ struct PlacementContext : public Context {
413413
* it would mean that per-layer bounding box is used. For the 2D architecture, the cube bounding box would be used.
414414
*/
415415
bool cube_bb = false;
416-
417-
418-
vtr::vector<NocGroupId, std::vector<ClusterBlockId>> noc_group_clusters;
419-
420-
vtr::vector<NocGroupId, std::vector<ClusterBlockId>> noc_group_routers;
421-
422-
vtr::vector<ClusterBlockId, NocGroupId> cluster_to_noc_grp;
423-
424-
std::map<ClusterBlockId, NocGroupId> noc_router_to_noc_group;
425416
};
426417

427418
/**

vpr/src/place/RL_agent_util.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,17 @@ void create_move_generators(std::unique_ptr<MoveGenerator>& move_generator,
7777
placer_opts.place_agent_epsilon);
7878
}
7979
karmed_bandit_agent1->set_step(placer_opts.place_agent_gamma, move_lim);
80-
move_generator = std::make_unique<SimpleRLMoveGenerator>(karmed_bandit_agent1, noc_attraction_weight);
80+
move_generator = std::make_unique<SimpleRLMoveGenerator>(karmed_bandit_agent1,
81+
noc_attraction_weight,
82+
placer_opts.place_high_fanout_net);
8183
//agent's 2nd state
8284
karmed_bandit_agent2 = std::make_unique<EpsilonGreedyAgent>(second_state_avail_moves,
8385
e_agent_space::MOVE_TYPE,
8486
placer_opts.place_agent_epsilon);
8587
karmed_bandit_agent2->set_step(placer_opts.place_agent_gamma, move_lim);
86-
move_generator2 = std::make_unique<SimpleRLMoveGenerator>(karmed_bandit_agent2, noc_attraction_weight);
88+
move_generator2 = std::make_unique<SimpleRLMoveGenerator>(karmed_bandit_agent2,
89+
noc_attraction_weight,
90+
placer_opts.place_high_fanout_net);
8791
} else {
8892
std::unique_ptr<SoftmaxAgent> karmed_bandit_agent1, karmed_bandit_agent2;
8993
//agent's 1st state
@@ -97,12 +101,16 @@ void create_move_generators(std::unique_ptr<MoveGenerator>& move_generator,
97101
e_agent_space::MOVE_TYPE);
98102
}
99103
karmed_bandit_agent1->set_step(placer_opts.place_agent_gamma, move_lim);
100-
move_generator = std::make_unique<SimpleRLMoveGenerator>(karmed_bandit_agent1, noc_attraction_weight);
104+
move_generator = std::make_unique<SimpleRLMoveGenerator>(karmed_bandit_agent1,
105+
noc_attraction_weight,
106+
placer_opts.place_high_fanout_net);
101107
//agent's 2nd state
102108
karmed_bandit_agent2 = std::make_unique<SoftmaxAgent>(second_state_avail_moves,
103109
e_agent_space::MOVE_TYPE);
104110
karmed_bandit_agent2->set_step(placer_opts.place_agent_gamma, move_lim);
105-
move_generator2 = std::make_unique<SimpleRLMoveGenerator>(karmed_bandit_agent2, noc_attraction_weight);
111+
move_generator2 = std::make_unique<SimpleRLMoveGenerator>(karmed_bandit_agent2,
112+
noc_attraction_weight,
113+
placer_opts.place_high_fanout_net);
106114
}
107115
}
108116
}

vpr/src/place/centroid_move_generator.cpp

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,127 @@
55
#include "place_constraints.h"
66
#include "move_utils.h"
77

8+
#include <queue>
9+
10+
11+
// Static member variable definitions
12+
vtr::vector<NocGroupId, std::vector<ClusterBlockId>> CentroidMoveGenerator::noc_group_clusters_;
13+
vtr::vector<NocGroupId, std::vector<ClusterBlockId>> CentroidMoveGenerator::noc_group_routers_;
14+
vtr::vector<ClusterBlockId, NocGroupId> CentroidMoveGenerator::cluster_to_noc_grp_;
15+
std::map<ClusterBlockId, NocGroupId> CentroidMoveGenerator::noc_router_to_noc_group_;
16+
17+
818
CentroidMoveGenerator::CentroidMoveGenerator()
919
: noc_attraction_w_(0.0f)
1020
, noc_attraction_enabled_(false) {}
1121

12-
CentroidMoveGenerator::CentroidMoveGenerator(float noc_attraction_weight)
22+
CentroidMoveGenerator::CentroidMoveGenerator(float noc_attraction_weight, size_t high_fanout_net)
1323
: noc_attraction_w_(noc_attraction_weight)
1424
, noc_attraction_enabled_(true) {
1525
VTR_ASSERT(noc_attraction_weight > 0.0 && noc_attraction_weight <= 1.0);
26+
27+
const auto& cluster_ctx = g_vpr_ctx.clustering();
28+
const auto& noc_ctx = g_vpr_ctx.noc();
29+
30+
// check if static member variables are already initialized
31+
if (!noc_group_clusters_.empty() && !noc_group_routers_.empty() &&
32+
!cluster_to_noc_grp_.empty() && !noc_router_to_noc_group_.empty()) {
33+
return;
34+
}
35+
36+
noc_group_clusters_.clear();
37+
noc_group_routers_.clear();
38+
cluster_to_noc_grp_.clear();
39+
noc_router_to_noc_group_.clear();
40+
41+
/*
42+
* Assume the clustered netlist is an undirected graph where nodes
43+
* represent clustered blocks, and edges are low fanout connections.
44+
* To determine NoC groups, we need to find components that include
45+
* at least one NoC router. To do this, we start a BFS traversal from
46+
* unvisited NoC routers and assign the starting NoC router and all the
47+
* blocks that are visited during the traversal to a NoC group.
48+
*/
49+
50+
// determines whether a block is visited
51+
vtr::vector<ClusterBlockId, bool> block_visited(cluster_ctx.clb_nlist.blocks().size(), false);
52+
53+
// NoCGroupIDs are sequential and start from zero. This counter specifies the value to be assigned to a new NoCGroupID
54+
int noc_group_cnt = 0;
55+
56+
// Initialize the associated NoC group for all blocks to INVALID. If a block is not visited during traversal,
57+
// it does not belong to any NoC groups. For other blocks, the associated NoC group is updated once they are visited.
58+
cluster_to_noc_grp_.resize(cluster_ctx.clb_nlist.blocks().size(), NocGroupId ::INVALID());
59+
60+
// Get all the router clusters and the NoC router logical block type
61+
const auto& router_blk_ids = noc_ctx.noc_traffic_flows_storage.get_router_clusters_in_netlist();
62+
const auto router_block_type = cluster_ctx.clb_nlist.block_type(router_blk_ids[0]);
63+
64+
// iterate over logical NoC routers and start a BFS
65+
for (auto router_blk_id : router_blk_ids) {
66+
67+
if (block_visited[router_blk_id]) {
68+
continue;
69+
}
70+
71+
NocGroupId noc_group_id(noc_group_cnt);
72+
noc_group_cnt++;
73+
noc_group_routers_.emplace_back();
74+
noc_group_clusters_.emplace_back();
75+
76+
// BFS frontier
77+
std::queue<ClusterBlockId> q;
78+
79+
// initialize the frontier with the NoC router
80+
q.push(router_blk_id);
81+
block_visited[router_blk_id] = true;
82+
83+
while (!q.empty()) {
84+
ClusterBlockId current_block_id = q.front();
85+
q.pop();
86+
87+
// get the logical block type for the block extracted from the frontier queue
88+
auto block_type = cluster_ctx.clb_nlist.block_type(current_block_id);
89+
90+
if (block_type->index == router_block_type->index) {
91+
noc_group_routers_[noc_group_id].push_back(current_block_id);
92+
noc_router_to_noc_group_[current_block_id] = noc_group_id;
93+
} else {
94+
noc_group_clusters_[noc_group_id].push_back(current_block_id);
95+
cluster_to_noc_grp_[current_block_id] = noc_group_id;
96+
}
97+
98+
// iterate over all low fanout nets of the current block to find its unvisited neighbors
99+
for (ClusterPinId pin_id : cluster_ctx.clb_nlist.block_pins(current_block_id)) {
100+
ClusterNetId net_id = cluster_ctx.clb_nlist.pin_net(pin_id);
101+
102+
if (cluster_ctx.clb_nlist.net_is_ignored(net_id)) {
103+
continue;
104+
}
105+
106+
if (cluster_ctx.clb_nlist.net_sinks(net_id).size() >= high_fanout_net) {
107+
continue;
108+
}
109+
110+
if (cluster_ctx.clb_nlist.pin_type(pin_id) == PinType::DRIVER) {
111+
for (auto sink_pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) {
112+
ClusterBlockId sink_block_id = cluster_ctx.clb_nlist.pin_block(sink_pin_id);
113+
if (!block_visited[sink_block_id]) {
114+
block_visited[sink_block_id] = true;
115+
q.push(sink_block_id);
116+
}
117+
}
118+
} else { //else the pin is sink --> only care about its driver
119+
ClusterPinId source_pin = cluster_ctx.clb_nlist.net_driver(net_id);
120+
ClusterBlockId source_blk_id = cluster_ctx.clb_nlist.pin_block(source_pin);
121+
if (!block_visited[source_blk_id]) {
122+
block_visited[source_blk_id] = true;
123+
q.push(source_blk_id);
124+
}
125+
}
126+
}
127+
}
128+
}
16129
}
17130

18131
e_create_move CentroidMoveGenerator::propose_move(t_pl_blocks_to_be_moved& blocks_affected,
@@ -74,3 +187,11 @@ e_create_move CentroidMoveGenerator::propose_move(t_pl_blocks_to_be_moved& block
74187

75188
return create_move;
76189
}
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: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#ifndef VPR_CENTROID_MOVE_GEN_H
22
#define VPR_CENTROID_MOVE_GEN_H
3+
34
#include "move_generator.h"
45

56
/**
@@ -10,12 +11,22 @@
1011
* This move picks a random block and moves it (swapping with what's there if necessary) to the zero force location
1112
* It calculates forces/weighs acting on the block based on its connections to other blocks.
1213
*
14+
* The computed centroid location can be optionally biased towards the location of NoC routers
15+
* that are reachable from the selected block. A NoC router is reachable from a block if one can
16+
* start from the block and reach the NoC router only by traversing low fanout nets. All the blocks
17+
* (including NoC routers) that can reach a NoC router form a NoC group.
18+
*
1319
* Returns its choices by filling in affected_blocks.
1420
*/
1521
class CentroidMoveGenerator : public MoveGenerator {
1622
public:
1723
CentroidMoveGenerator();
18-
CentroidMoveGenerator(float noc_attraction_weight);
24+
CentroidMoveGenerator(float noc_attraction_weight, size_t high_fanout_net);
25+
26+
27+
static const std::vector<ClusterBlockId>& get_noc_group_routers(NocGroupId noc_grp_id);
28+
29+
static NocGroupId get_cluster_noc_group(ClusterBlockId blk_id);
1930

2031
private:
2132
e_create_move propose_move(t_pl_blocks_to_be_moved& blocks_affected,
@@ -25,8 +36,28 @@ class CentroidMoveGenerator : public MoveGenerator {
2536
const PlacerCriticalities* /*criticalities*/) override;
2637

2738
private:
39+
/** A value in range [0, 1] that specifies how much the centroid location
40+
* computation is biased towards the associated NoC routers*/
2841
float noc_attraction_w_;
42+
43+
/** Indicates whether the centroid calculation is NoC-biased.*/
2944
bool noc_attraction_enabled_;
45+
46+
/** Stores all non-router blocks for each NoC group*/
47+
static vtr::vector<NocGroupId, std::vector<ClusterBlockId>> noc_group_clusters_;
48+
49+
/** Stores NoC routers in each NoC group*/
50+
static vtr::vector<NocGroupId, std::vector<ClusterBlockId>> noc_group_routers_;
51+
52+
/** Specifies the NoC group that each block belongs to. A block cannot belong to more
53+
* than one NoC because this means those NoC groups can reach each other and form
54+
* a single NoC group. We use NocGroupId::INVALID to show that a block does not belong
55+
* to any NoC groups. This happens when a block is not reachable from any NoC router.
56+
* */
57+
static vtr::vector<ClusterBlockId, NocGroupId> cluster_to_noc_grp_;
58+
59+
/** Specifies the NoC group for each NoC router*/
60+
static std::map<ClusterBlockId, NocGroupId> noc_router_to_noc_group_;
3061
};
3162

3263
#endif

vpr/src/place/directed_moves_util.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
12
#include "directed_moves_util.h"
3+
#include "centroid_move_generator.h"
24

35
void get_coordinate_of_pin(ClusterPinId pin, t_physical_tile_loc& tile_loc) {
46
auto& device_ctx = g_vpr_ctx.device();
@@ -98,16 +100,19 @@ void calculate_centroid_loc(ClusterBlockId b_from,
98100
}
99101

100102
if (noc_attraction_enabled) {
101-
if (place_ctx.cluster_to_noc_grp[b_from] != NocGroupId::INVALID()) {
103+
NocGroupId noc_grp_id = CentroidMoveGenerator::get_cluster_noc_group(b_from);
102104

103-
NocGroupId noc_grp_id = place_ctx.cluster_to_noc_grp[b_from];
104-
float single_noc_weight = (acc_weight * noc_attraction_weight) / place_ctx.noc_group_routers[noc_grp_id].size();
105+
// check if the block belongs to a NoC group
106+
if (noc_grp_id != NocGroupId::INVALID()) {
107+
// get the routers in the associated NoC group
108+
const auto& noc_routers = CentroidMoveGenerator::get_noc_group_routers(noc_grp_id);
109+
float single_noc_weight = (acc_weight * noc_attraction_weight) / (float)noc_routers.size();
105110

106111
acc_x *= (1.0f - noc_attraction_weight);
107112
acc_y *= (1.0f - noc_attraction_weight);
108113
acc_weight *= (1.0f - noc_attraction_weight);
109114

110-
for (ClusterBlockId router_blk_id : place_ctx.noc_group_routers[noc_grp_id]) {
115+
for (ClusterBlockId router_blk_id : noc_routers) {
111116
t_block_loc router_loc = place_ctx.block_locs[router_blk_id];
112117
acc_x += router_loc.loc.x * single_noc_weight;
113118
acc_y += router_loc.loc.y * single_noc_weight;

vpr/src/place/initial_noc_placement.cpp

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,9 @@ static void noc_routers_anneal(const t_noc_opts& noc_opts) {
255255

256256
void initial_noc_placement(const t_noc_opts& noc_opts, const t_placer_opts& placer_opts) {
257257
auto& noc_ctx = g_vpr_ctx.noc();
258-
auto& cluster_ctx = g_vpr_ctx.clustering();
259258

260259
// Get all the router clusters
261260
const std::vector<ClusterBlockId>& router_blk_ids = noc_ctx.noc_traffic_flows_storage.get_router_clusters_in_netlist();
262-
const auto router_block_type = cluster_ctx.clb_nlist.block_type(router_blk_ids[0]);
263261

264262
// Holds all the routers that are not fixed into a specific location by constraints
265263
std::vector<ClusterBlockId> unfixed_routers;
@@ -294,72 +292,4 @@ void initial_noc_placement(const t_noc_opts& noc_opts, const t_placer_opts& plac
294292
"At least one cycle was found in NoC channel dependency graph. This may cause a deadlock "
295293
"when packets wait on each other in a cycle.\n");
296294
}
297-
298-
vtr::vector<ClusterBlockId, bool> block_visited(cluster_ctx.clb_nlist.blocks().size(), false);
299-
auto& place_ctx = g_vpr_ctx.mutable_placement();
300-
int noc_group_cnt = 0;
301-
place_ctx.cluster_to_noc_grp.resize(cluster_ctx.clb_nlist.blocks().size(), NocGroupId ::INVALID());
302-
303-
for (auto router_blk_id : router_blk_ids) {
304-
305-
if (block_visited[router_blk_id]) {
306-
continue;
307-
}
308-
309-
NocGroupId noc_group_id(noc_group_cnt);
310-
noc_group_cnt++;
311-
place_ctx.noc_group_routers.emplace_back();
312-
place_ctx.noc_group_clusters.emplace_back();
313-
314-
std::queue<ClusterBlockId> q;
315-
q.push(router_blk_id);
316-
block_visited[router_blk_id] = true;
317-
318-
while (!q.empty()) {
319-
ClusterBlockId current_block_id = q.front();
320-
q.pop();
321-
322-
auto block_type = cluster_ctx.clb_nlist.block_type(current_block_id);
323-
if (block_type->index == router_block_type->index) {
324-
place_ctx.noc_group_routers[noc_group_id].push_back(current_block_id);
325-
place_ctx.noc_router_to_noc_group[current_block_id] = noc_group_id;
326-
} else {
327-
place_ctx.noc_group_clusters[noc_group_id].push_back(current_block_id);
328-
place_ctx.cluster_to_noc_grp[current_block_id] = noc_group_id;
329-
}
330-
331-
332-
for (ClusterPinId pin_id : cluster_ctx.clb_nlist.block_pins(current_block_id)) {
333-
ClusterNetId net_id = cluster_ctx.clb_nlist.pin_net(pin_id);
334-
335-
if (cluster_ctx.clb_nlist.net_is_ignored(net_id)) {
336-
continue;
337-
}
338-
339-
if (cluster_ctx.clb_nlist.net_sinks(net_id).size() >= placer_opts.place_high_fanout_net) {
340-
continue;
341-
}
342-
343-
if (cluster_ctx.clb_nlist.pin_type(pin_id) == PinType::DRIVER) {
344-
//ignore nets that are globally routed
345-
346-
for (auto sink_pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) {
347-
auto sink_block_id = cluster_ctx.clb_nlist.pin_block(sink_pin_id);
348-
if (!block_visited[sink_block_id]) {
349-
block_visited[sink_block_id] = true;
350-
q.push(sink_block_id);
351-
}
352-
}
353-
} else { //else the pin is sink --> only care about its driver
354-
ClusterPinId source_pin = cluster_ctx.clb_nlist.net_driver(net_id);
355-
auto source_blk_id = cluster_ctx.clb_nlist.pin_block(source_pin);
356-
if (!block_visited[source_blk_id]) {
357-
block_visited[source_blk_id] = true;
358-
q.push(source_blk_id);
359-
}
360-
}
361-
}
362-
}
363-
364-
}
365295
}

0 commit comments

Comments
 (0)