Skip to content

Commit cc793dd

Browse files
[AP][DetailedPlacer] Added Detailed Placer Class
The Detailed Placer is a pass in the AP flow which takes a legal placement and optimizes it, while still remaining legal. Previously in the AP flow, the annealer from the Placement stage was always used to optimize the placement. Now the user can choose to not use the annealer, by selecting the "none" Detailed Placer. Other Detailed Placers can now also be added to explore other Detailed Placement algorithms in VTR.
1 parent 5f319ef commit cc793dd

24 files changed

+553
-69
lines changed

doc/src/vpr/command_line_usage.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,16 @@ Analytical Placement is generally split into three stages:
11981198

11991199
**Default:** ``appack``
12001200

1201+
.. option:: --ap_detailed_placer {none | annealer}
1202+
1203+
Controls which Detailed Placer to use in the AP Flow.
1204+
1205+
* ``none`` Do not use any Detailed Placer.
1206+
1207+
* ``annealer`` Use the Annealer from the Placement stage as a Detailed Placer. This will use the same Placer Options from the Place stage to configure the annealer.
1208+
1209+
**Default:** ``annealer``
1210+
12011211

12021212
.. _router_options:
12031213

vpr/src/analytical_place/analytical_placement_flow.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "analytical_solver.h"
1111
#include "ap_netlist.h"
1212
#include "atom_netlist.h"
13+
#include "detailed_placer.h"
1314
#include "full_legalizer.h"
1415
#include "gen_ap_netlist_from_atoms.h"
1516
#include "global_placer.h"
@@ -106,5 +107,19 @@ void run_analytical_placement_flow(t_vpr_setup& vpr_setup) {
106107
*device_ctx.arch,
107108
device_ctx.grid);
108109
full_legalizer->legalize(p_placement);
110+
111+
// Run the Detailed Placer.
112+
std::unique_ptr<DetailedPlacer> detailed_placer = make_detailed_placer(ap_opts.detailed_placer_type,
113+
g_vpr_ctx.placement().blk_loc_registry(),
114+
atom_nlist,
115+
g_vpr_ctx.clustering().clb_nlist,
116+
vpr_setup,
117+
*device_ctx.arch);
118+
detailed_placer->optimize_placement();
119+
120+
// Clean up some of the global variables that will no longer be used outside
121+
// of this flow.
122+
g_vpr_ctx.mutable_placement().clean_placement_context_post_place();
123+
g_vpr_ctx.mutable_floorplanning().clean_floorplanning_context_post_place();
109124
}
110125

vpr/src/analytical_place/ap_flow_enums.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,14 @@ enum class e_ap_full_legalizer {
1818
APPack ///< The APPack Full Legalizer, which uses the flat placement to improve the Packer and Placer.
1919
};
2020

21+
/**
22+
* @brief The type of a Detailed Placer.
23+
*
24+
* The Analytical Placement flow may implement different Detailed Placers. This
25+
* enum can select between these different Detailed Placers.
26+
*/
27+
enum class e_ap_detailed_placer {
28+
Identity, ///< The Identity Detailed Placer, which does not perform any optimizations on the legalized placement. Needed as a placeholder.
29+
Annealer ///< The Annealer Detailed Placer, which runs the annealer found in the Place part of the VPR flow (using the same options as the Placement stage).
30+
};
31+
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/**
2+
* @file
3+
* @author Alex Singer
4+
* @date February 2025
5+
* @brief Implementation of the Detailed Placers.
6+
*/
7+
8+
#include "detailed_placer.h"
9+
#include <memory>
10+
#include "FlatPlacementInfo.h"
11+
#include "PlacementDelayModelCreator.h"
12+
#include "ap_flow_enums.h"
13+
#include "atom_netlist.h"
14+
#include "clustered_netlist.h"
15+
#include "clustered_netlist_utils.h"
16+
#include "echo_files.h"
17+
#include "globals.h"
18+
#include "physical_types.h"
19+
#include "place_and_route.h"
20+
#include "place_delay_model.h"
21+
#include "placer.h"
22+
#include "vpr_error.h"
23+
#include "vpr_types.h"
24+
#include "vpr_utils.h"
25+
26+
std::unique_ptr<DetailedPlacer> make_detailed_placer(
27+
e_ap_detailed_placer detailed_placer_type,
28+
const BlkLocRegistry& curr_clustered_placement,
29+
const AtomNetlist& atom_netlist,
30+
const ClusteredNetlist& clustered_netlist,
31+
t_vpr_setup& vpr_setup,
32+
const t_arch& arch) {
33+
switch (detailed_placer_type) {
34+
case e_ap_detailed_placer::Identity:
35+
return std::make_unique<IdentityDetailedPlacer>();
36+
case e_ap_detailed_placer::Annealer:
37+
return std::make_unique<AnnealerDetailedPlacer>(
38+
curr_clustered_placement,
39+
atom_netlist,
40+
clustered_netlist,
41+
vpr_setup,
42+
arch);
43+
default:
44+
VPR_FATAL_ERROR(VPR_ERROR_AP,
45+
"Unrecognized detailed placer type");
46+
}
47+
}
48+
49+
AnnealerDetailedPlacer::AnnealerDetailedPlacer(
50+
const BlkLocRegistry& curr_clustered_placement,
51+
const AtomNetlist& atom_netlist,
52+
const ClusteredNetlist& clustered_netlist,
53+
t_vpr_setup& vpr_setup,
54+
const t_arch& arch)
55+
: DetailedPlacer(),
56+
// TODO: These two variables needed to be stored in the class since
57+
// the Placer stores a reference to these objects. These
58+
// should really be initialized and stored into the Placer
59+
// class directly.
60+
pb_gpin_lookup_(g_vpr_ctx.device().logical_block_types),
61+
netlist_pin_lookup_(clustered_netlist, atom_netlist, pb_gpin_lookup_) {
62+
// Initialize the place delay model.
63+
// TODO: This initialization is complicated. Should be moved within create_delay_model
64+
// or something.
65+
std::shared_ptr<PlaceDelayModel> place_delay_model;
66+
if (vpr_setup.PlacerOpts.place_algorithm.is_timing_driven()) {
67+
place_delay_model = PlacementDelayModelCreator::create_delay_model(vpr_setup.PlacerOpts,
68+
vpr_setup.RouterOpts,
69+
(const Netlist<>&)clustered_netlist,
70+
&vpr_setup.RoutingArch,
71+
vpr_setup.Segments,
72+
arch.Chans,
73+
arch.directs,
74+
false /*is_flat*/);
75+
if (isEchoFileEnabled(E_ECHO_PLACEMENT_DELTA_DELAY_MODEL)) {
76+
place_delay_model->dump_echo(getEchoFileName(E_ECHO_PLACEMENT_DELTA_DELAY_MODEL));
77+
}
78+
}
79+
80+
placer_ = std::make_unique<Placer>((const Netlist<>&)clustered_netlist,
81+
curr_clustered_placement,
82+
vpr_setup.PlacerOpts,
83+
vpr_setup.AnalysisOpts,
84+
vpr_setup.NocOpts,
85+
pb_gpin_lookup_,
86+
netlist_pin_lookup_,
87+
FlatPlacementInfo(),
88+
place_delay_model,
89+
g_vpr_ctx.placement().cube_bb,
90+
false /*is_flat*/,
91+
false /*quiet*/);
92+
}
93+
94+
void AnnealerDetailedPlacer::optimize_placement() {
95+
// Prevent the annealer from directly modifying the global legal placement.
96+
// It should only modify its own, local placement.
97+
g_vpr_ctx.mutable_placement().lock_loc_vars();
98+
99+
// Run the simulated annealer.
100+
placer_->place();
101+
102+
// Copy the placement solution into the global placement solution.
103+
placer_->copy_locs_to_global_state(g_vpr_ctx.mutable_placement());
104+
105+
// Since the placement was modified, need to resyncronize the pins in the
106+
// clusters.
107+
post_place_sync();
108+
}
109+
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/**
2+
* @file
3+
* @author Alex Singer
4+
* @date February 2025
5+
* @brief Defines the DetailedPlacer class which takes a fully legal clustering
6+
* and placement and optimizes them while remaining legal.
7+
*/
8+
9+
#pragma once
10+
11+
#include <memory>
12+
#include "ap_flow_enums.h"
13+
#include "clustered_netlist_utils.h"
14+
#include "placer.h"
15+
#include "vpr_utils.h"
16+
17+
/**
18+
* @brief The detailed placer in an AP flow.
19+
*
20+
* Given a fully legal clustering and clustered placement, will optimize the
21+
* solution while remaining fully legal (able to be used in the rest of the VPR
22+
* flow).
23+
*/
24+
class DetailedPlacer {
25+
public:
26+
virtual ~DetailedPlacer() {}
27+
28+
DetailedPlacer() = default;
29+
30+
/**
31+
* @brief Optimize the current legal placement.
32+
*/
33+
virtual void optimize_placement() = 0;
34+
};
35+
36+
/**
37+
* @brief A factory method which creates a Detailed Placer of the given type.
38+
*/
39+
std::unique_ptr<DetailedPlacer> make_detailed_placer(
40+
e_ap_detailed_placer detailed_placer_type,
41+
const BlkLocRegistry& curr_clustered_placement,
42+
const AtomNetlist& atom_netlist,
43+
const ClusteredNetlist& clustered_netlist,
44+
t_vpr_setup& vpr_setup,
45+
const t_arch& arch);
46+
47+
48+
/**
49+
* @brief The Identity Detailed Placer.
50+
*
51+
* This detailed placer does literally nothing to the legal placement. This
52+
* class is used as a placeholder to make the higher-level code easier to work
53+
* with.
54+
*/
55+
class IdentityDetailedPlacer : public DetailedPlacer {
56+
public:
57+
using DetailedPlacer::DetailedPlacer;
58+
59+
void optimize_placement() final {}
60+
};
61+
62+
/**
63+
* @brief The Annealer Detailed Placer.
64+
*
65+
* This Detailed Placer passes the legal solution into the Annealer in the
66+
* VPR flow (uses the legal solution as the initial placement). This performs
67+
* the Simulated Annealing algorithm on the solution at the cluster level to
68+
* try and find a better clustered placement.
69+
*
70+
* This Detailed Placer reuses the options from the Placer stage of VPR for this
71+
* stage. So options passed to the Placer will be used in here.
72+
*/
73+
class AnnealerDetailedPlacer : public DetailedPlacer {
74+
public:
75+
/**
76+
* @brief Construct the Annealer Detailed Placer class.
77+
*
78+
* @param curr_clustered_placement
79+
* The legalized placement solution to pass as the initial placement
80+
* into the annealer.
81+
* @param atom_netlist
82+
* The netlist of atoms in the circuit.
83+
* @param clustered_netlist
84+
* The netlist of clusters created by the Full Legalizer.
85+
* @param vpr_setup
86+
* The setup variables, used to get the params from the user.
87+
* @param arch
88+
* The FPGA architecture to optimize onto.
89+
*/
90+
AnnealerDetailedPlacer(const BlkLocRegistry& curr_clustered_placement,
91+
const AtomNetlist& atom_netlist,
92+
const ClusteredNetlist& clustered_netlist,
93+
t_vpr_setup& vpr_setup,
94+
const t_arch& arch);
95+
96+
/**
97+
* @brief Run the annealer.
98+
*/
99+
void optimize_placement() final;
100+
101+
private:
102+
/// @brief The placer class, which contains the annealer.
103+
std::unique_ptr<Placer> placer_;
104+
105+
/// @brief A lookup between the block pin indices and pb graph pins.
106+
IntraLbPbPinLookup pb_gpin_lookup_;
107+
108+
/// @brief A lookup between CLB pins and atom pins.
109+
ClusteredPinAtomPinsLookup netlist_pin_lookup_;
110+
};
111+

0 commit comments

Comments
 (0)