Skip to content

Commit e3d7d65

Browse files
committed
Removed find_affected_sink_pins() to eliminate the placer runtime increase. blocks_affected.affected_pins now only stores moved pins that have changed connection delays.
1 parent f6e809e commit e3d7d65

File tree

2 files changed

+91
-90
lines changed

2 files changed

+91
-90
lines changed

vpr/src/place/place.cpp

Lines changed: 87 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ static vtr::vector<ClusterNetId, char> bb_updated_before;
164164
*/
165165
static ClbNetPinsMatrix<float> connection_delay; //Delays based on committed block positions
166166
static ClbNetPinsMatrix<float> proposed_connection_delay; //Delays for proposed block positions (only
167-
// for connections effected by move, otherwise
168-
// INVALID_DELAY)
167+
// for connections effected by move, otherwise
168+
// INVALID_DELAY)
169169

170170
static ClbNetPinsMatrix<float> connection_setup_slack; //Setup slacks based on most recently updated timing graph
171171

@@ -175,18 +175,18 @@ static ClbNetPinsMatrix<float> connection_setup_slack; //Setup slacks based on m
175175
*/
176176
static PlacerTimingCosts connection_timing_cost; //Costs of committed block positions
177177
static ClbNetPinsMatrix<double> proposed_connection_timing_cost; //Costs for proposed block positions
178-
// (only for connection effected by
179-
// move, otherwise INVALID_DELAY)
178+
// (only for connection effected by
179+
// move, otherwise INVALID_DELAY)
180180

181181
/*
182182
* Timing cost of nets (i.e. sum of criticality * delay for each net sink/connection).
183183
* Index ranges: [0..cluster_ctx.clb_nlist.nets().size()-1]
184184
*/
185185
static vtr::vector<ClusterNetId, double> net_timing_cost; //Like connection_timing_cost, but summed
186-
// accross net pins. Used to allow more
187-
// efficient recalculation of timing cost
188-
// if only a sub-set of nets are changed
189-
// while maintaining numeric stability.
186+
// accross net pins. Used to allow more
187+
// efficient recalculation of timing cost
188+
// if only a sub-set of nets are changed
189+
// while maintaining numeric stability.
190190

191191
/* [0..cluster_ctx.clb_nlist.nets().size()-1]. Store the bounding box coordinates and the number of *
192192
* blocks on each of a net's bounding box (to allow efficient updates), *
@@ -403,9 +403,9 @@ static void commit_td_cost(const t_pl_blocks_to_be_moved& blocks_affected);
403403

404404
static void revert_td_cost(const t_pl_blocks_to_be_moved& blocks_affected);
405405

406-
static void invalidate_affected_connection_delays(const std::vector<ClusterPinId>& sink_pins_affected,
407-
ClusteredPinTimingInvalidator* pin_tedges_invalidator,
408-
TimingInfo* timing_info);
406+
static void invalidate_affected_connections(const t_pl_blocks_to_be_moved& blocks_affected,
407+
ClusteredPinTimingInvalidator* pin_tedges_invalidator,
408+
TimingInfo* timing_info);
409409

410410
static bool driven_by_moved_block(const ClusterNetId net, const t_pl_blocks_to_be_moved& blocks_affected);
411411

@@ -417,9 +417,6 @@ static double comp_td_connection_cost(const PlaceDelayModel* delay_mode, const P
417417
static double sum_td_net_cost(ClusterNetId net);
418418
static double sum_td_costs();
419419

420-
static void find_affected_sink_pins(const t_pl_blocks_to_be_moved& blocks_affected,
421-
std::vector<ClusterPinId>& sink_pins_affected);
422-
423420
static float analyze_setup_slack_cost(const PlacerSetupSlacks* setup_slacks);
424421

425422
static e_move_result assess_swap(double delta_c, double t);
@@ -690,9 +687,9 @@ void try_place(const t_placer_opts& placer_opts,
690687
prev_inverse_costs.timing_cost = 1 / costs.timing_cost;
691688
prev_inverse_costs.bb_cost = 1 / costs.bb_cost;
692689
costs.cost = 1; /*our new cost function uses normalized values of */
693-
/*bb_cost and timing_cost, the value of cost will be reset */
694-
/*to 1 at each temperature when *_TIMING_DRIVEN_PLACE is true */
695-
} else { /*BOUNDING_BOX_PLACE */
690+
/*bb_cost and timing_cost, the value of cost will be reset */
691+
/*to 1 at each temperature when *_TIMING_DRIVEN_PLACE is true */
692+
} else { /*BOUNDING_BOX_PLACE */
696693
costs.cost = costs.bb_cost = comp_bb_cost(NORMAL);
697694
costs.timing_cost = 0;
698695
outer_crit_iter_count = 0;
@@ -1647,22 +1644,16 @@ static e_move_result try_swap(float t,
16471644
bb_delta_c,
16481645
timing_delta_c);
16491646

1650-
//Find all the sink pins with changed connection delays from the affected blocks.
1651-
//These sink pins will be passed into the pin_timing_invalidator for timing update.
1652-
//They will also be added to the pin invalidator when we wish to revert a timing update.
1653-
std::vector<ClusterPinId> sink_pins_affected;
1654-
find_affected_sink_pins(blocks_affected, sink_pins_affected);
1655-
16561647
//For setup slack analysis, we first do a timing analysis to get the newest slack values
16571648
//resulted from the proposed block moves. If the move turns out to be accepted, we keep
16581649
//the updated slack values and commit the block moves. If rejected, we reject the proposed
16591650
//block moves and revert this timing analysis.
16601651
if (place_algorithm == SLACK_TIMING_PLACE) {
16611652
//Gather all the connections with modified delays for incremental timing updates.
16621653
//This routine relies on comparing proposed_connection_delay and connection_delay.
1663-
invalidate_affected_connection_delays(sink_pins_affected,
1664-
pin_timing_invalidator,
1665-
timing_info);
1654+
invalidate_affected_connections(blocks_affected,
1655+
pin_timing_invalidator,
1656+
timing_info);
16661657

16671658
//Update the connection_timing_cost and connection_delay
16681659
//values from the temporary values.
@@ -1723,9 +1714,9 @@ static e_move_result try_swap(float t,
17231714
//This routine relies on comparing proposed_connection_delay and connection_delay
17241715
//If the setup slack analysis was not performed, the
17251716
//sink pins are yet to be invalidated.
1726-
invalidate_affected_connection_delays(sink_pins_affected,
1727-
pin_timing_invalidator,
1728-
timing_info);
1717+
invalidate_affected_connections(blocks_affected,
1718+
pin_timing_invalidator,
1719+
timing_info);
17291720

17301721
//update the connection_timing_cost and connection_delay
17311722
//values from the temporary values
@@ -1756,9 +1747,9 @@ static e_move_result try_swap(float t,
17561747
//Re-invalidate the affected sink pins since the proposed move is
17571748
//rejected, and the same blocks are reverted to their original
17581749
//positions. The affected sink pins should stay the same.
1759-
invalidate_affected_connection_delays(sink_pins_affected,
1760-
pin_timing_invalidator,
1761-
timing_info);
1750+
invalidate_affected_connections(blocks_affected,
1751+
pin_timing_invalidator,
1752+
timing_info);
17621753

17631754
/* Revert the timing update */
17641755
update_timing_classes(crit_exponent,
@@ -1845,7 +1836,7 @@ static int find_affected_nets_and_update_costs(const t_place_algorithm& place_al
18451836
update_net_bb(net_id, blocks_affected, iblk, blk, blk_pin);
18461837

18471838
if (place_algorithm.is_timing_driven()) {
1848-
//Determine the change in timing costs if required
1839+
/* Determine the change in connection delay and timing cost */
18491840
update_td_delta_costs(delay_model, *criticalities, net_id, blk_pin, blocks_affected, timing_delta_c);
18501841
}
18511842
}
@@ -1907,6 +1898,35 @@ static void update_net_bb(const ClusterNetId net,
19071898
}
19081899
}
19091900

1901+
/**
1902+
* @brief Calculate the new connection delay and timing cost of all the
1903+
* sink pins affected by moving a specific pin to a new location.
1904+
* Also calculates the total change in the timing cost.
1905+
*
1906+
* Assumes that the blocks have been moved to the proposed new locations.
1907+
* Otherwise, the routine comp_td_connection_delay() will not be able to
1908+
* calculate the most up to date connection delay estimation value.
1909+
*
1910+
* If the moved pin is a driver pin, then all the sink connections that are
1911+
* driven by this driver pin are considered.
1912+
*
1913+
* If the moved pin is a sink pin, then it is the only pin considered. But
1914+
* in some cases, the sink is already accounted for if it is also driven
1915+
* by a driver pin located on a moved block. Computing it again would double
1916+
* count its affect on the total timing cost change (delta_timing_cost).
1917+
*
1918+
* It is possible for some connections to have unchanged delays. For instance,
1919+
* if we are using a dx/dy delay model, this could occur if a sink pin moved
1920+
* to a new position with the same dx/dy from its net's driver pin.
1921+
*
1922+
* We skip these connections with unchanged delay values as their delay need
1923+
* not be updated. Their timing costs also do not require any update, since
1924+
* the criticalities values are always kept stale/unchanged during an block
1925+
* swap attempt. (Unchanged Delay * Unchanged Criticality = Unchanged Cost)
1926+
*
1927+
* This is also done to minimize the number of timing node/edge invalidations
1928+
* for incremental static timing analysis (incremental STA).
1929+
*/
19101930
static void update_td_delta_costs(const PlaceDelayModel* delay_model,
19111931
const PlacerCriticalities& criticalities,
19121932
const ClusterNetId net,
@@ -1916,69 +1936,50 @@ static void update_td_delta_costs(const PlaceDelayModel* delay_model,
19161936
auto& cluster_ctx = g_vpr_ctx.clustering();
19171937

19181938
if (cluster_ctx.clb_nlist.pin_type(pin) == PinType::DRIVER) {
1919-
//This pin is a net driver on a moved block.
1920-
//Re-compute all point to point connections for this net.
1939+
/* This pin is a net driver on a moved block. */
1940+
/* Recompute all point to point connection delays for the net sinks. */
19211941
for (size_t ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net).size(); ipin++) {
19221942
float temp_delay = comp_td_connection_delay(delay_model, net, ipin);
1923-
proposed_connection_delay[net][ipin] = temp_delay;
1943+
/* If the delay hasn't changed, do not mark this pin as affected */
1944+
if (temp_delay == connection_delay[net][ipin]) {
1945+
continue;
1946+
}
19241947

1948+
/* Calculate proposed delay and cost values */
1949+
proposed_connection_delay[net][ipin] = temp_delay;
19251950
proposed_connection_timing_cost[net][ipin] = criticalities.criticality(net, ipin) * temp_delay;
19261951
delta_timing_cost += proposed_connection_timing_cost[net][ipin] - connection_timing_cost[net][ipin];
19271952

1953+
/* Record this connection in blocks_affected.affected_pins */
19281954
ClusterPinId sink_pin = cluster_ctx.clb_nlist.net_pin(net, ipin);
19291955
blocks_affected.affected_pins.push_back(sink_pin);
19301956
}
19311957
} else {
1932-
//This pin is a net sink on a moved block
1958+
/* This pin is a net sink on a moved block */
19331959
VTR_ASSERT_SAFE(cluster_ctx.clb_nlist.pin_type(pin) == PinType::SINK);
19341960

1935-
//If this net is being driven by a moved block, we do not
1936-
//need to compute the change in the timing cost (here) since it will
1937-
//be computed by the net's driver pin (since the driver block moved).
1938-
//
1939-
//Computing it here would double count the change, and mess up the
1940-
//delta_timing_cost value.
1961+
/* Check if this sink's net is driven by a moved block */
19411962
if (!driven_by_moved_block(net, blocks_affected)) {
1942-
int net_pin = cluster_ctx.clb_nlist.pin_net_index(pin);
1963+
/* Get the sink pin index in the net */
1964+
int ipin = cluster_ctx.clb_nlist.pin_net_index(pin);
19431965

1944-
float temp_delay = comp_td_connection_delay(delay_model, net, net_pin);
1945-
proposed_connection_delay[net][net_pin] = temp_delay;
1966+
float temp_delay = comp_td_connection_delay(delay_model, net, ipin);
1967+
/* If the delay hasn't changed, do not mark this pin as affected */
1968+
if (temp_delay == connection_delay[net][ipin]) {
1969+
return;
1970+
}
19461971

1947-
proposed_connection_timing_cost[net][net_pin] = criticalities.criticality(net, net_pin) * temp_delay;
1948-
delta_timing_cost += proposed_connection_timing_cost[net][net_pin] - connection_timing_cost[net][net_pin];
1972+
/* Calculate proposed delay and cost values */
1973+
proposed_connection_delay[net][ipin] = temp_delay;
1974+
proposed_connection_timing_cost[net][ipin] = criticalities.criticality(net, ipin) * temp_delay;
1975+
delta_timing_cost += proposed_connection_timing_cost[net][ipin] - connection_timing_cost[net][ipin];
19491976

1977+
/* Record this connection in blocks_affected.affected_pins */
19501978
blocks_affected.affected_pins.push_back(pin);
19511979
}
19521980
}
19531981
}
19541982

1955-
/**
1956-
* @brief Find all the sink pins with changed connection delays from the affected blocks.
1957-
*
1958-
* These sink pins will be passed into the pin_timing_invalidator for timing update.
1959-
* They will also be added to the pin invalidator when we wish to revert a timing update.
1960-
*
1961-
* It is possible that some connections may not have changed delay. For instance, if
1962-
* using a dx/dy delay model, this could occur if a sink moved to a new position with
1963-
* the same dx/dy from it's driver. To minimize work during the incremental STA update
1964-
* we do not invalidate such unchanged connections.
1965-
*/
1966-
static void find_affected_sink_pins(const t_pl_blocks_to_be_moved& blocks_affected,
1967-
std::vector<ClusterPinId>& sink_pins_affected) {
1968-
auto& cluster_ctx = g_vpr_ctx.clustering();
1969-
auto& clb_nlist = cluster_ctx.clb_nlist;
1970-
1971-
for (ClusterPinId clb_pin : blocks_affected.affected_pins) {
1972-
ClusterNetId net = clb_nlist.pin_net(clb_pin);
1973-
int ipin = clb_nlist.pin_net_index(clb_pin);
1974-
1975-
if (proposed_connection_delay[net][ipin] != connection_delay[net][ipin]) {
1976-
//Delay has changed. Must invalidate this sink pin.
1977-
sink_pins_affected.push_back(clb_pin);
1978-
}
1979-
}
1980-
}
1981-
19821983
/**
19831984
* @brief Check if the setup slack has gotten better or worse due to block swap.
19841985
*
@@ -2233,23 +2234,23 @@ static void revert_td_cost(const t_pl_blocks_to_be_moved& blocks_affected) {
22332234
}
22342235

22352236
/**
2236-
* @brief Invalidates the delays of connections effected by the specified move.
2237+
* @brief Invalidates the connections affected by the specified block moves.
22372238
*
2238-
* Relies on find_affected_sink_pins() to find all the connections with different
2239-
* `proposed_connection_delay` and `connection_delay`.
2239+
* All the connections recorded in blocks_affected.affected_pins have different
2240+
* values for `proposed_connection_delay` and `connection_delay`.
22402241
*
2241-
* Invalidate all the timing graph edges associated with these sink pins via the
2242-
* ClusteredPinTimingInvalidator class.
2242+
* Invalidate all the timing graph edges associated with these connections via
2243+
* the ClusteredPinTimingInvalidator class.
22432244
*/
2244-
static void invalidate_affected_connection_delays(const std::vector<ClusterPinId>& sink_pins_affected,
2245-
ClusteredPinTimingInvalidator* pin_tedges_invalidator,
2246-
TimingInfo* timing_info) {
2245+
static void invalidate_affected_connections(const t_pl_blocks_to_be_moved& blocks_affected,
2246+
ClusteredPinTimingInvalidator* pin_tedges_invalidator,
2247+
TimingInfo* timing_info) {
22472248
VTR_ASSERT_SAFE(timing_info);
22482249
VTR_ASSERT_SAFE(pin_tedges_invalidator);
22492250

2250-
//Invalidate timing graph edges affected by the move
2251-
for (ClusterPinId clb_pin : sink_pins_affected) {
2252-
pin_tedges_invalidator->invalidate_connection(clb_pin, timing_info);
2251+
/* Invalidate timing graph edges affected by the move */
2252+
for (ClusterPinId pin : blocks_affected.affected_pins) {
2253+
pin_tedges_invalidator->invalidate_connection(pin, timing_info);
22532254
}
22542255
}
22552256

vpr/src/place/timing_place.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ void PlacerCriticalities::recompute_criticalities() {
121121

122122
///@brief Override the criticality of a particular connection.
123123
void PlacerCriticalities::set_criticality(ClusterNetId net_id, int ipin, float crit_val) {
124-
VTR_ASSERT_SAFE_MSG(ipin > 0, "The pin should not be a driver pin (ipin = 0)");
125-
VTR_ASSERT_SAFE_MSG(ipin < clb_nlist_.net_pins(net_id).size(), "The pin index in net should be smaller than fanout");
124+
VTR_ASSERT_SAFE_MSG(ipin > 0, "The pin should not be a driver pin (ipin != 0)");
125+
VTR_ASSERT_SAFE_MSG(ipin < int(clb_nlist_.net_pins(net_id).size()), "The pin index in net should be smaller than fanout");
126126

127127
timing_place_crit_[net_id][ipin] = crit_val;
128128
}
@@ -224,8 +224,8 @@ void PlacerSetupSlacks::recompute_setup_slacks() {
224224

225225
///@brief Override the setup slack of a particular connection.
226226
void PlacerSetupSlacks::set_setup_slack(ClusterNetId net_id, int ipin, float slack_val) {
227-
VTR_ASSERT_SAFE_MSG(ipin > 0, "The pin should not be a driver pin (ipin = 0)");
228-
VTR_ASSERT_SAFE_MSG(ipin < clb_nlist_.net_pins(net_id).size(), "The pin index in net should be smaller than fanout");
227+
VTR_ASSERT_SAFE_MSG(ipin > 0, "The pin should not be a driver pin (ipin != 0)");
228+
VTR_ASSERT_SAFE_MSG(ipin < int(clb_nlist_.net_pins(net_id).size()), "The pin index in net should be smaller than fanout");
229229

230230
timing_place_setup_slacks_[net_id][ipin] = slack_val;
231231
}

0 commit comments

Comments
 (0)