Skip to content

Commit d32ea3e

Browse files
authored
Merge pull request #1501 from Bill-hbrhbr/QuenchSlackDraft
Add raw setup slack analysis to placement quench
2 parents 4b86a9e + 06c9cf6 commit d32ea3e

File tree

15 files changed

+1356
-441
lines changed

15 files changed

+1356
-441
lines changed

doc/src/vpr/command_line_usage.rst

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -701,16 +701,24 @@ If any of init_t, exit_t or alpha_t is specified, the user schedule, with a fixe
701701

702702
**Default:** ````.
703703

704-
.. option:: --place_algorithm {bounding_box | path_timing_driven}
704+
.. option:: --place_algorithm {bounding_box | criticality_timing | slack_timing}
705705

706706
Controls the algorithm used by the placer.
707707

708-
``bounding_box`` focuses purely on minimizing the bounding box wirelength of the circuit.
708+
``bounding_box`` Focuses purely on minimizing the bounding box wirelength of the circuit. Turns off timing analysis if specified.
709709

710-
``path_timing_driven`` focuses on minimizing both wirelength and the critical path delay.
710+
``criticality_timing`` Focuses on minimizing both the wirelength and the connection timing costs (criticality * delay).
711711

712+
``slack_timing`` Focuses on improving the circuit slack values to reduce critical path delay.
712713

713-
**Default:** ``path_timing_driven``
714+
**Default:** ``criticality_timing``
715+
716+
.. option:: --place_quench_algorithm {bounding_box | criticality_timing | slack_timing}
717+
718+
Controls the algorithm used by the placer during placement quench.
719+
The algorithm options have identical functionality as the ones used by the option ``--place_algorithm``. If specified, it overrides the option ``--place_algorithm`` during placement quench.
720+
721+
**Default:** ``criticality_timing``
714722

715723
.. option:: --place_chan_width <int>
716724

vpr/src/base/CheckSetup.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ void CheckSetup(const t_packer_opts& PackerOpts,
2323
}
2424

2525
if ((GLOBAL == RouterOpts.route_type)
26-
&& (BOUNDING_BOX_PLACE != PlacerOpts.place_algorithm)) {
26+
&& (PlacerOpts.place_algorithm.is_timing_driven())) {
2727
/* Works, but very weird. Can't optimize timing well, since you're
2828
* not doing proper architecture delay modelling. */
2929
VTR_LOG_WARN(
@@ -32,7 +32,7 @@ void CheckSetup(const t_packer_opts& PackerOpts,
3232
}
3333

3434
if ((false == Timing.timing_analysis_enabled)
35-
&& (PlacerOpts.place_algorithm == PATH_TIMING_DRIVEN_PLACE)) {
35+
&& (PlacerOpts.place_algorithm.is_timing_driven())) {
3636
/* May work, not tested */
3737
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
3838
"Timing analysis must be enabled for timing-driven placement.\n");

vpr/src/base/SetupVPR.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ static void SetupPlacerOpts(const t_options& Options, t_placer_opts* PlacerOpts)
534534
PlacerOpts->td_place_exp_last = Options.place_exp_last;
535535

536536
PlacerOpts->place_algorithm = Options.PlaceAlgorithm;
537+
PlacerOpts->place_quench_algorithm = Options.PlaceQuenchAlgorithm;
537538

538539
PlacerOpts->constraints_file = Options.constraints_file;
539540

vpr/src/base/ShowSetup.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -499,12 +499,15 @@ static void ShowPlacerOpts(const t_placer_opts& PlacerOpts,
499499
if ((PLACE_ONCE == PlacerOpts.place_freq)
500500
|| (PLACE_ALWAYS == PlacerOpts.place_freq)) {
501501
VTR_LOG("PlacerOpts.place_algorithm: ");
502-
switch (PlacerOpts.place_algorithm) {
502+
switch (PlacerOpts.place_algorithm.get()) {
503503
case BOUNDING_BOX_PLACE:
504504
VTR_LOG("BOUNDING_BOX_PLACE\n");
505505
break;
506-
case PATH_TIMING_DRIVEN_PLACE:
507-
VTR_LOG("PATH_TIMING_DRIVEN_PLACE\n");
506+
case CRITICALITY_TIMING_PLACE:
507+
VTR_LOG("CRITICALITY_TIMING_PLACE\n");
508+
break;
509+
case SLACK_TIMING_PLACE:
510+
VTR_LOG("SLACK_TIMING_PLACE\n");
508511
break;
509512
default:
510513
VTR_LOG_ERROR("Unknown placement algorithm\n");
@@ -533,7 +536,7 @@ static void ShowPlacerOpts(const t_placer_opts& PlacerOpts,
533536

534537
VTR_LOG("PlacerOpts.place_chan_width: %d\n", PlacerOpts.place_chan_width);
535538

536-
if (PATH_TIMING_DRIVEN_PLACE == PlacerOpts.place_algorithm) {
539+
if (PlacerOpts.place_algorithm.is_timing_driven()) {
537540
VTR_LOG("PlacerOpts.inner_loop_recompute_divider: %d\n", PlacerOpts.inner_loop_recompute_divider);
538541
VTR_LOG("PlacerOpts.recompute_crit_iter: %d\n", PlacerOpts.recompute_crit_iter);
539542
VTR_LOG("PlacerOpts.timing_tradeoff: %f\n", PlacerOpts.timing_tradeoff);

vpr/src/base/read_options.cpp

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -350,31 +350,42 @@ struct ParsePlaceDeltaDelayAlgorithm {
350350
struct ParsePlaceAlgorithm {
351351
ConvertedValue<e_place_algorithm> from_str(std::string str) {
352352
ConvertedValue<e_place_algorithm> conv_value;
353-
if (str == "bounding_box")
353+
if (str == "bounding_box") {
354354
conv_value.set_value(BOUNDING_BOX_PLACE);
355-
else if (str == "path_timing_driven")
356-
conv_value.set_value(PATH_TIMING_DRIVEN_PLACE);
357-
else {
355+
} else if (str == "criticality_timing") {
356+
conv_value.set_value(CRITICALITY_TIMING_PLACE);
357+
} else if (str == "slack_timing") {
358+
conv_value.set_value(SLACK_TIMING_PLACE);
359+
} else {
358360
std::stringstream msg;
359-
msg << "Invalid conversion from '" << str << "' to e_router_algorithm (expected one of: " << argparse::join(default_choices(), ", ") << ")";
361+
msg << "Invalid conversion from '" << str << "' to e_place_algorithm (expected one of: " << argparse::join(default_choices(), ", ") << ")";
362+
363+
//Deprecated option: "path_timing_driven" -> PATH_DRIVEN_TIMING_PLACE
364+
//New option: "criticality_timing" -> CRITICALITY_TIMING_PLACE
365+
if (str == "path_timing_driven") {
366+
msg << "\nDeprecated option: 'path_timing_driven'. It has been renamed to 'criticality_timing'";
367+
}
368+
360369
conv_value.set_error(msg.str());
361370
}
362371
return conv_value;
363372
}
364373

365374
ConvertedValue<std::string> to_str(e_place_algorithm val) {
366375
ConvertedValue<std::string> conv_value;
367-
if (val == BOUNDING_BOX_PLACE)
376+
if (val == BOUNDING_BOX_PLACE) {
368377
conv_value.set_value("bounding_box");
369-
else {
370-
VTR_ASSERT(val == PATH_TIMING_DRIVEN_PLACE);
371-
conv_value.set_value("path_timing_driven");
378+
} else if (val == CRITICALITY_TIMING_PLACE) {
379+
conv_value.set_value("criticality_timing");
380+
} else {
381+
VTR_ASSERT(val == SLACK_TIMING_PLACE);
382+
conv_value.set_value("slack_timing");
372383
}
373384
return conv_value;
374385
}
375386

376387
std::vector<std::string> default_choices() {
377-
return {"bounding_box", "path_timing_driven"};
388+
return {"bounding_box", "criticality_timing", "slack_timing"};
378389
}
379390
};
380391

@@ -1679,9 +1690,25 @@ argparse::ArgumentParser create_arg_parser(std::string prog_name, t_options& arg
16791690
.show_in(argparse::ShowIn::HELP_ONLY);
16801691

16811692
place_grp.add_argument<e_place_algorithm, ParsePlaceAlgorithm>(args.PlaceAlgorithm, "--place_algorithm")
1682-
.help("Controls which placement algorithm is used")
1683-
.default_value("path_timing_driven")
1684-
.choices({"bounding_box", "path_timing_driven"})
1693+
.help(
1694+
"Controls which placement algorithm is used. Valid options:\n"
1695+
" * bounding_box: Focuses purely on minimizing the bounding box wirelength of the circuit. Turns off timing analysis if specified.\n"
1696+
" * criticality_timing: Focuses on minimizing both the wirelength and the connection timing costs (criticality * delay).\n"
1697+
" * slack_timing: Focuses on improving the circuit slack values to reduce critical path delay.\n")
1698+
.default_value("criticality_timing")
1699+
.choices({"bounding_box", "criticality_timing", "slack_timing"})
1700+
.show_in(argparse::ShowIn::HELP_ONLY);
1701+
1702+
place_grp.add_argument<e_place_algorithm, ParsePlaceAlgorithm>(args.PlaceQuenchAlgorithm, "--place_quench_algorithm")
1703+
.help(
1704+
"Controls which placement algorithm is used during placement quench.\n"
1705+
"If specified, it overrides the option --place_algorithm during placement quench.\n"
1706+
"Valid options:\n"
1707+
" * bounding_box: Focuses purely on minimizing the bounding box wirelength of the circuit. Turns off timing analysis if specified.\n"
1708+
" * criticality_timing: Focuses on minimizing both the wirelength and the connection timing costs (criticality * delay).\n"
1709+
" * slack_timing: Focuses on improving the circuit slack values to reduce critical path delay.\n")
1710+
.default_value("criticality_timing")
1711+
.choices({"bounding_box", "criticality_timing", "slack_timing"})
16851712
.show_in(argparse::ShowIn::HELP_ONLY);
16861713

16871714
place_grp.add_argument(args.PlaceChanWidth, "--place_chan_width")
@@ -2314,12 +2341,17 @@ void set_conditional_defaults(t_options& args) {
23142341
//Which placement algorithm to use?
23152342
if (args.PlaceAlgorithm.provenance() != Provenance::SPECIFIED) {
23162343
if (args.timing_analysis) {
2317-
args.PlaceAlgorithm.set(PATH_TIMING_DRIVEN_PLACE, Provenance::INFERRED);
2344+
args.PlaceAlgorithm.set(CRITICALITY_TIMING_PLACE, Provenance::INFERRED);
23182345
} else {
23192346
args.PlaceAlgorithm.set(BOUNDING_BOX_PLACE, Provenance::INFERRED);
23202347
}
23212348
}
23222349

2350+
//Which placement algorithm to use during placement quench?
2351+
if (args.PlaceQuenchAlgorithm.provenance() != Provenance::SPECIFIED) {
2352+
args.PlaceQuenchAlgorithm.set(args.PlaceAlgorithm, Provenance::INFERRED);
2353+
}
2354+
23232355
//Place chan width follows Route chan width if unspecified
23242356
if (args.PlaceChanWidth.provenance() != Provenance::SPECIFIED && args.RouteChanWidth.provenance() == Provenance::SPECIFIED) {
23252357
args.PlaceChanWidth.set(args.RouteChanWidth.value(), Provenance::INFERRED);

vpr/src/base/read_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ struct t_options {
104104
argparse::ArgValue<float> PlaceSuccessTarget;
105105
argparse::ArgValue<sched_type> anneal_sched_type;
106106
argparse::ArgValue<e_place_algorithm> PlaceAlgorithm;
107+
argparse::ArgValue<e_place_algorithm> PlaceQuenchAlgorithm;
107108
argparse::ArgValue<e_pad_loc_type> pad_loc_type;
108109
argparse::ArgValue<int> PlaceChanWidth;
109110
argparse::ArgValue<float> place_rlim_escape_fraction;

vpr/src/base/vpr_types.h

Lines changed: 122 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -829,36 +829,90 @@ struct t_annealing_sched {
829829
float success_target;
830830
};
831831

832-
/* Various options for the placer. *
833-
* place_algorithm: BOUNDING_BOX_PLACE or PATH_TIMING_DRIVEN_PLACE *
834-
* timing_tradeoff: When TIMING_DRIVEN_PLACE mode, what is the tradeoff *
835-
* timing driven and BOUNDING_BOX_PLACE. *
836-
* place_cost_exp: Power to which denominator is raised for linear_cong. *
837-
* place_chan_width: The channel width assumed if only one placement is *
838-
* performed. *
839-
* pad_loc_type: Are pins free to move during placement or fixed randomly. *
840-
* constraints_file: File used to lock block locations during placement. *
841-
* place_freq: Should the placement be skipped, done once, or done for each *
842-
* channel width in the binary search. *
843-
* recompute_crit_iter: how many temperature stages pass before we recompute *
844-
* criticalities based on average point to point delay *
845-
* inner_loop_crit_divider: (move_lim/inner_loop_crit_divider) determines how*
846-
* many inner_loop iterations pass before a recompute of *
847-
* criticalities is done. *
848-
* td_place_exp_first: exponent that is used on the timing_driven criticlity *
849-
* it is the value that the exponent starts at. *
850-
* td_place_exp_last: value that the criticality exponent will be at the end *
851-
* doPlacement: true if placement is supposed to be done in the CAD flow, false otherwise */
832+
/******************************************************************
833+
* Placer data types
834+
*******************************************************************/
835+
836+
/**
837+
* @brief Types of placement algorithms used in the placer.
838+
*
839+
* @param BOUNDING_BOX_PLACE
840+
* Focuses purely on minimizing the bounding
841+
* box wirelength of the circuit.
842+
* @param CRITICALITY_TIMING_PLACE
843+
* Focuses on minimizing both the wirelength and the
844+
* connection timing costs (criticality * delay).
845+
* @param SLACK_TIMING_PLACE
846+
* Focuses on improving the circuit slack values
847+
* to reduce critical path delay.
848+
*
849+
* The default is to use CRITICALITY_TIMING_PLACE. BOUNDING_BOX_PLACE
850+
* is used when there is no timing information available (wiring only).
851+
* SLACK_TIMING_PLACE is mainly feasible during placement quench.
852+
*/
852853
enum e_place_algorithm {
853854
BOUNDING_BOX_PLACE,
854-
PATH_TIMING_DRIVEN_PLACE
855+
CRITICALITY_TIMING_PLACE,
856+
SLACK_TIMING_PLACE
857+
};
858+
859+
/**
860+
* @brief Provides a wrapper around enum e_place_algorithm.
861+
*
862+
* Supports the method is_timing_driven(), which allows flexible updates
863+
* to the placer algorithms if more timing driven placement strategies
864+
* are added in tht future. This method is used across various placement
865+
* setup files, and it can be useful for major placer routines as well.
866+
*
867+
* More methods can be added to this class if the placement strategies
868+
* will be further divided into more categories the future.
869+
*
870+
* Also supports assignments and comparisons between t_place_algorithm
871+
* and e_place_algorithm so as not to break down previous codes.
872+
*/
873+
class t_place_algorithm {
874+
public:
875+
//Constructors
876+
t_place_algorithm() = default;
877+
t_place_algorithm(e_place_algorithm _algo)
878+
: algo(_algo) {}
879+
~t_place_algorithm() = default;
880+
881+
//Assignment operators
882+
t_place_algorithm& operator=(const t_place_algorithm& rhs) {
883+
algo = rhs.algo;
884+
return *this;
885+
}
886+
t_place_algorithm& operator=(e_place_algorithm rhs) {
887+
algo = rhs;
888+
return *this;
889+
}
890+
891+
//Equality operators
892+
bool operator==(const t_place_algorithm& rhs) const { return algo == rhs.algo; }
893+
bool operator==(e_place_algorithm rhs) const { return algo == rhs; }
894+
bool operator!=(const t_place_algorithm& rhs) const { return algo != rhs.algo; }
895+
bool operator!=(e_place_algorithm rhs) const { return algo != rhs; }
896+
897+
///@brief Check if the algorithm belongs to the timing driven category.
898+
inline bool is_timing_driven() const {
899+
return algo == CRITICALITY_TIMING_PLACE || algo == SLACK_TIMING_PLACE;
900+
}
901+
902+
///@brief Accessor: returns the underlying e_place_algorithm enum value.
903+
e_place_algorithm get() const { return algo; }
904+
905+
private:
906+
///@brief The underlying algorithm. Default set to CRITICALITY_TIMING_PLACE.
907+
e_place_algorithm algo = e_place_algorithm::CRITICALITY_TIMING_PLACE;
855908
};
856909

857910
enum e_pad_loc_type {
858911
FREE,
859912
RANDOM
860913
};
861914

915+
///@brief Used to calculate the inner placer loop's block swapping limit move_lim.
862916
enum e_place_effort_scaling {
863917
CIRCUIT, ///<Effort scales based on circuit size only
864918
DEVICE_CIRCUIT ///<Effort scales based on both circuit and device size
@@ -889,8 +943,54 @@ enum class e_place_delta_delay_algorithm {
889943
DIJKSTRA_EXPANSION,
890944
};
891945

946+
/**
947+
* @brief Various options for the placer.
948+
*
949+
* @param place_algorithm
950+
* Controls which placement algorithm is used.
951+
* @param place_quench_algorithm
952+
* Controls which placement algorithm is used
953+
* during placement quench.
954+
* @param timing_tradeoff
955+
* When in CRITICALITY_TIMING_PLACE mode, what is the
956+
* tradeoff between timing and wiring costs.
957+
* @param place_cost_exp
958+
* Power to which denominator is raised for linear_cong.
959+
* @param place_chan_width
960+
* The channel width assumed if only one placement is performed.
961+
* @param pad_loc_type
962+
* Are pins FREE or fixed randomly.
963+
* @param constraints_file
964+
* File that specifies locations of locked down (constrained)
965+
* blocks for placement. Empty string means no constraints file.
966+
* @param pad_loc_file
967+
* File to read pad locations from if pad_loc_type is USER.
968+
* @param place_freq
969+
* Should the placement be skipped, done once, or done
970+
* for each channel width in the binary search.
971+
* @param recompute_crit_iter
972+
* How many temperature stages pass before we recompute
973+
* criticalities based on the current placement and its
974+
* estimated point-to-point delays.
975+
* @param inner_loop_crit_divider
976+
* (move_lim/inner_loop_crit_divider) determines how
977+
* many inner_loop iterations pass before a recompute
978+
* of criticalities is done.
979+
* @param td_place_exp_first
980+
* Exponent that is used in the CRITICALITY_TIMING_PLACE
981+
* mode to specify the initial value of `crit_exponent`.
982+
* After we map the slacks to criticalities, this value
983+
* is used to `sharpen` the criticalities, making connections
984+
* with worse slacks more critical.
985+
* @param td_place_exp_last
986+
* Value that the crit_exponent will be at the end.
987+
* @param doPlacement
988+
* True if placement is supposed to be done in the CAD flow.
989+
* False if otherwise.
990+
*/
892991
struct t_placer_opts {
893-
enum e_place_algorithm place_algorithm;
992+
t_place_algorithm place_algorithm;
993+
t_place_algorithm place_quench_algorithm;
894994
float timing_tradeoff;
895995
float place_cost_exp;
896996
int place_chan_width;

0 commit comments

Comments
 (0)