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+
2561static 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+
30141bool 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