Skip to content

Commit 0c240d3

Browse files
[Packer] Updated Iterative Repacking Code
1 parent e8845bb commit 0c240d3

File tree

1 file changed

+124
-84
lines changed

1 file changed

+124
-84
lines changed

vpr/src/pack/pack.cpp

Lines changed: 124 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,122 @@
2222
#include "vtr_assert.h"
2323
#include "vtr_log.h"
2424

25+
namespace {
26+
27+
/**
28+
* @brief Enumeration for the state of the packer.
29+
*
30+
* If the packer fails to find a dense enough packing, depending on how the
31+
* packer failed, the packer may iteratively retry packing with different
32+
* settings to try and find a denser packing. These states represent a
33+
* different type of iteration.
34+
*/
35+
enum class e_packer_state {
36+
/// @brief Default packer state.
37+
DEFAULT,
38+
/// @brief Succcess state for the packer. The packing looks feasible to
39+
/// fit on the device (does not exceed number of blocks of each
40+
/// type in the grid) and meets floorplanning constraints.
41+
SUCCESS,
42+
/// @brief Standard fallback where there are no region constraints. Turns
43+
/// on unrelated clustering and balanced packing if it can.
44+
UNRELATED_AND_BALANCED,
45+
/// @brief Region constraints: Turns on attraction groups for overfilled regions.
46+
ATTRACTION_GROUPS,
47+
/// @brief Region constraints: Turns on more attraction groups for overfilled regions.
48+
MORE_ATTRACTION_GROUPS,
49+
/// @brief Region constraints: Turns on more attraction groups for all regions.
50+
ATTRACTION_GROUPS_ALL_REGIONS,
51+
/// @brief Region constraints: Turns on more attraction groups for all regions
52+
/// and increases the target density of "clb" blocks.
53+
/// TODO: This should increase the target density of all overused blocks.
54+
ATTRACTION_GROUPS_ALL_REGIONS_AND_INCREASED_TARGET_DENSITY,
55+
/// @brief The failure state.
56+
FAILURE
57+
};
58+
59+
} // namespace
60+
2561
static bool try_size_device_grid(const t_arch& arch,
2662
const std::map<t_logical_block_type_ptr, size_t>& num_type_instances,
2763
float target_device_utilization,
2864
const std::string& device_layout_name);
2965

66+
/**
67+
* @brief The packer iteratively re-packes the netlist if it fails to find a
68+
* valid clustering. Each iteration is a state the packer is in, where
69+
* each state uses a different set of options. This method gets the next
70+
* state of the packer given the current state of the packer.
71+
*
72+
* @param current_packer_state
73+
* The current state of the packer (the state used to make the most recent
74+
* clustering).
75+
* @param fits_on_device
76+
* Whether the current clustering fits on the device or not.
77+
* @param floorplan_regions_overfull
78+
* Whether the current clustering has overfilled regions.
79+
* @param floorplan_not_fitting
80+
* Whether the current clustering is fitting on the current floorplan.
81+
*/
82+
static e_packer_state get_next_packer_state(e_packer_state current_packer_state,
83+
bool fits_on_device,
84+
bool floorplan_regions_overfull,
85+
bool floorplan_not_fitting) {
86+
// Next packer state logic
87+
e_packer_state next_packer_state = e_packer_state::FAILURE;
88+
if (fits_on_device && !floorplan_regions_overfull) {
89+
// If everything fits on the device and the floorplan regions are
90+
// not overfilled, the next state is success.
91+
next_packer_state = e_packer_state::SUCCESS;
92+
} else {
93+
if (floorplan_not_fitting) {
94+
// If there are overfilled region constraints.
95+
96+
// When running with tight floorplan constraints, some regions may become overfull with clusters (i.e.
97+
// the number of blocks assigned to the region exceeds the number of blocks available). When this occurs, we
98+
// cluster more densely to be able to adhere to the floorplan constraints. However, we do not want to cluster more
99+
// densely unnecessarily, as this can negatively impact wirelength. So, we have iterative approach. We check at the end
100+
// of every iteration if any floorplan regions are overfull. In the first iteration, we run
101+
// with no attraction groups (not packing more densely). If regions are overfull at the end of the first iteration,
102+
// we create attraction groups for partitions with overfull regions (pack those atoms more densely). We continue this way
103+
// until the last iteration, when we create attraction groups for every partition, if needed.
104+
105+
switch (current_packer_state) {
106+
case e_packer_state::DEFAULT:
107+
next_packer_state = e_packer_state::ATTRACTION_GROUPS;
108+
break;
109+
case e_packer_state::UNRELATED_AND_BALANCED:
110+
case e_packer_state::ATTRACTION_GROUPS:
111+
next_packer_state = e_packer_state::MORE_ATTRACTION_GROUPS;
112+
break;
113+
case e_packer_state::MORE_ATTRACTION_GROUPS:
114+
next_packer_state = e_packer_state::ATTRACTION_GROUPS_ALL_REGIONS;
115+
break;
116+
case e_packer_state::ATTRACTION_GROUPS_ALL_REGIONS:
117+
next_packer_state = e_packer_state::ATTRACTION_GROUPS_ALL_REGIONS_AND_INCREASED_TARGET_DENSITY;
118+
break;
119+
case e_packer_state::ATTRACTION_GROUPS_ALL_REGIONS_AND_INCREASED_TARGET_DENSITY:
120+
default:
121+
next_packer_state = e_packer_state::FAILURE;
122+
break;
123+
}
124+
} else {
125+
// If there are no overfilled region constraints, but some block
126+
// types on the grid are overfilled.
127+
switch (current_packer_state) {
128+
case e_packer_state::DEFAULT:
129+
next_packer_state = e_packer_state::UNRELATED_AND_BALANCED;
130+
break;
131+
default:
132+
next_packer_state = e_packer_state::FAILURE;
133+
break;
134+
}
135+
}
136+
}
137+
138+
return next_packer_state;
139+
}
140+
30141
bool try_pack(const t_packer_opts& packer_opts,
31142
const t_analysis_opts& analysis_opts,
32143
const t_ap_opts& ap_opts,
@@ -145,35 +256,6 @@ bool try_pack(const t_packer_opts& packer_opts,
145256

146257
g_vpr_ctx.mutable_atom().mutable_lookup().set_atom_pb_bimap_lock(true);
147258

148-
/**
149-
* @brief Enumeration for the state of the packer.
150-
*
151-
* If the packer fails to find a dense enough packing, depending on how the
152-
* packer failed, the packer may iteratively retry packing with different
153-
* setting to try and find a denser packing. These states represent a
154-
* different type of iteration.
155-
*/
156-
enum class e_packer_state {
157-
/// @brief Default packer state.
158-
DEFAULT,
159-
/// @brief Succcess state for the packer.
160-
SUCCESS,
161-
/// @brief Standard fallback where there is not region constraints. Turns
162-
/// on unrelated clustering and balanced packing if it can.
163-
UNRELATED_AND_BALANCED,
164-
/// @brief Region constraints: Turns on attraction groups for overfilled regions.
165-
ATTRACTION_GROUPS,
166-
/// @brief Region constraints: Turns on more attraction groups for overfilled regions.
167-
MORE_ATTRACTION_GROUPS,
168-
/// @brief Region constraints: Turns on more attraction groups for all regions.
169-
ATTRACTION_GROUPS_ALL_REGIONS,
170-
/// @brief Region constraints: Turns on more attraction groups for all regions
171-
/// and increases the target density of clb blocks.
172-
ATTRACTION_GROUPS_ALL_REGIONS_AND_INCREASED_TARGET_DENSITY,
173-
/// @brief The failure state.
174-
FAILURE
175-
};
176-
177259
// The current state of the packer during iterative packing.
178260
e_packer_state current_packer_state = e_packer_state::DEFAULT;
179261

@@ -189,7 +271,7 @@ bool try_pack(const t_packer_opts& packer_opts,
189271
attraction_groups,
190272
mutable_device_ctx);
191273

192-
//Try to size/find a device
274+
// Try to size/find a device
193275
bool fits_on_device = try_size_device_grid(arch, num_used_type_instances, packer_opts.target_device_utilization, packer_opts.device_layout);
194276

195277
/* We use this bool to determine the cause for the clustering not being dense enough. If the clustering
@@ -203,62 +285,20 @@ bool try_pack(const t_packer_opts& packer_opts,
203285
bool floorplan_not_fitting = (floorplan_regions_overfull || g_vpr_ctx.floorplanning().constraints.get_num_partitions() > 0);
204286

205287
// Next packer state logic
206-
e_packer_state next_packer_state = e_packer_state::FAILURE;
207-
if (fits_on_device && !floorplan_regions_overfull) {
208-
// If everything fits on the device and the floorplan regions are
209-
// not overfilled, the next state is success.
210-
next_packer_state = e_packer_state::SUCCESS;
211-
} else {
212-
if (floorplan_not_fitting) {
213-
// If there are overfilled region constraints.
214-
/*
215-
* When running with tight floorplan constraints, some regions may become overfull with clusters (i.e.
216-
* the number of blocks assigned to the region exceeds the number of blocks available). When this occurs, we
217-
* cluster more densely to be able to adhere to the floorplan constraints. However, we do not want to cluster more
218-
* densely unnecessarily, as this can negatively impact wirelength. So, we have iterative approach. We check at the end
219-
* of every iteration if any floorplan regions are overfull. In the first iteration, we run
220-
* with no attraction groups (not packing more densely). If regions are overfull at the end of the first iteration,
221-
* we create attraction groups for partitions with overfull regions (pack those atoms more densely). We continue this way
222-
* until the last iteration, when we create attraction groups for every partition, if needed.
223-
*/
224-
switch (current_packer_state) {
225-
case e_packer_state::DEFAULT:
226-
next_packer_state = e_packer_state::ATTRACTION_GROUPS;
227-
break;
228-
case e_packer_state::UNRELATED_AND_BALANCED:
229-
case e_packer_state::ATTRACTION_GROUPS:
230-
next_packer_state = e_packer_state::MORE_ATTRACTION_GROUPS;
231-
break;
232-
case e_packer_state::MORE_ATTRACTION_GROUPS:
233-
next_packer_state = e_packer_state::ATTRACTION_GROUPS_ALL_REGIONS;
234-
break;
235-
case e_packer_state::ATTRACTION_GROUPS_ALL_REGIONS:
236-
next_packer_state = e_packer_state::ATTRACTION_GROUPS_ALL_REGIONS_AND_INCREASED_TARGET_DENSITY;
237-
break;
238-
case e_packer_state::ATTRACTION_GROUPS_ALL_REGIONS_AND_INCREASED_TARGET_DENSITY:
239-
default:
240-
next_packer_state = e_packer_state::FAILURE;
241-
break;
242-
}
243-
} else {
244-
// If there are no overfilled region constraints.
245-
switch (current_packer_state) {
246-
case e_packer_state::DEFAULT:
247-
next_packer_state = e_packer_state::UNRELATED_AND_BALANCED;
248-
break;
249-
default:
250-
next_packer_state = e_packer_state::FAILURE;
251-
break;
252-
}
253-
}
254-
}
255-
256-
// Set up for the next packer state.
288+
e_packer_state next_packer_state = get_next_packer_state(current_packer_state,
289+
fits_on_device,
290+
floorplan_regions_overfull,
291+
floorplan_not_fitting);
292+
293+
// Set up for the options used for the next packer state.
294+
// NOTE: This must be done here (and not at the start of the next packer
295+
// iteration) since we need to know information about the current
296+
// clustering to change the options for the next iteration.
257297
switch (next_packer_state) {
258298
case e_packer_state::UNRELATED_AND_BALANCED: {
259-
//1st pack attempt was unsuccessful (i.e. not dense enough) and we have control of unrelated clustering
299+
// 1st pack attempt was unsuccessful (i.e. not dense enough) and we have control of unrelated clustering
260300
//
261-
//Turn it on to increase packing density
301+
// Turn it on to increase packing density
262302
// TODO: This will have no affect if unrelated clustering and
263303
// balance block type utilization is not auto. Should update
264304
// the next state logic.
@@ -348,7 +388,7 @@ bool try_pack(const t_packer_opts& packer_opts,
348388

349389
// If the packer was unsuccessful, reset the packed solution and try again.
350390
if (next_packer_state != e_packer_state::SUCCESS) {
351-
//Reset floorplanning constraints for re-packing
391+
// Reset floorplanning constraints for re-packing
352392
g_vpr_ctx.mutable_floorplanning().cluster_constraints.clear();
353393

354394
// Reset the cluster legalizer for re-clustering.

0 commit comments

Comments
 (0)