Skip to content

Commit 76564d2

Browse files
[ClusterLegalizer] Cluster Legalizer API
Isolated the cluster legalization logic out of the packer's clustering algorithm in such a way that it can be used externally to the clusterer with no issue. Once the ClusterLegalizer API is constructed, it will allocate all of the memory that it needs for legalization; it can then be used to legalize clusters; and when it is destroyed it will remove all state created for clustering. The cluster legalizer API maintains the legalized clusters internally as opposed to using the ClusterBlockId as an ID to the clusters. This allowed me to separate the ClusteredNetlist from the packing algorithm entirely. This importantly helper separate out all legalization logic from directly modifying the ClusteredNetlist generation code. I did my best to remove as much global state as I could from the API to make it as self-contained as possible. This change greatly cleaned up the packer code and removed many of its global variables (including the ClusterLegalizer itself, which is now a local variable!)
1 parent c7b9ce0 commit 76564d2

26 files changed

+2786
-2211
lines changed

vpr/src/base/vpr_api.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <cstring>
1616
#include <cmath>
1717

18+
#include "vpr_context.h"
1819
#include "vtr_assert.h"
1920
#include "vtr_math.h"
2021
#include "vtr_log.h"
@@ -613,12 +614,13 @@ bool vpr_pack_flow(t_vpr_setup& vpr_setup, const t_arch& arch) {
613614
//Load a previous packing from the .net file
614615
vpr_load_packing(vpr_setup, arch);
615616

616-
//Load cluster_constraints data structure here since loading pack file
617-
load_cluster_constraints();
618617
}
619618

620619
}
621620

621+
// Load cluster_constraints data structure here since loading pack file
622+
load_cluster_constraints();
623+
622624
/* Sanity check the resulting netlist */
623625
check_netlist(packer_opts.pack_verbosity);
624626

@@ -685,8 +687,7 @@ bool vpr_pack(t_vpr_setup& vpr_setup, const t_arch& arch) {
685687

686688
return try_pack(&vpr_setup.PackerOpts, &vpr_setup.AnalysisOpts,
687689
&arch, vpr_setup.user_models,
688-
vpr_setup.library_models, inter_cluster_delay,
689-
vpr_setup.PackerRRGraph);
690+
vpr_setup.library_models, inter_cluster_delay);
690691
}
691692

692693
void vpr_load_packing(t_vpr_setup& vpr_setup, const t_arch& arch) {
@@ -696,6 +697,7 @@ void vpr_load_packing(t_vpr_setup& vpr_setup, const t_arch& arch) {
696697
"Must have valid .net filename to load packing");
697698

698699
auto& cluster_ctx = g_vpr_ctx.mutable_clustering();
700+
const AtomContext& atom_ctx = g_vpr_ctx.atom();
699701

700702
/* Ensure we have a clean start with void net remapping information */
701703
cluster_ctx.post_routing_clb_pin_nets.clear();
@@ -706,8 +708,15 @@ void vpr_load_packing(t_vpr_setup& vpr_setup, const t_arch& arch) {
706708
vpr_setup.FileNameOpts.verify_file_digests,
707709
vpr_setup.PackerOpts.pack_verbosity);
708710

711+
/* Load the mapping between clusters and their atoms */
712+
cluster_ctx.atoms_lookup.resize(cluster_ctx.clb_nlist.blocks().size());
713+
for (AtomBlockId atom_blk_id : atom_ctx.nlist.blocks()) {
714+
ClusterBlockId atom_cluster_blk_id = atom_ctx.lookup.atom_clb(atom_blk_id);
715+
cluster_ctx.atoms_lookup[atom_cluster_blk_id].insert(atom_blk_id);
716+
}
717+
709718
process_constant_nets(g_vpr_ctx.mutable_atom().nlist,
710-
g_vpr_ctx.atom().lookup,
719+
atom_ctx.lookup,
711720
cluster_ctx.clb_nlist,
712721
vpr_setup.constant_net_method,
713722
vpr_setup.PackerOpts.pack_verbosity);

vpr/src/base/vpr_constraints_writer.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,15 @@
77
#include "vpr_constraints_serializer.h"
88
#include "vpr_constraints_uxsdcxx.h"
99

10-
#include "vtr_time.h"
10+
#include "vpr_context.h"
1111

1212
#include "globals.h"
1313
#include "pugixml.hpp"
14-
#include "pugixml_util.hpp"
15-
#include "clustered_netlist_utils.h"
1614

1715
#include <fstream>
16+
#include <unordered_set>
1817
#include "vpr_constraints_writer.h"
1918
#include "region.h"
20-
#include "re_cluster_util.h"
2119

2220
/**
2321
* @brief Create a partition with the given name and a single region.
@@ -30,7 +28,6 @@ static Partition create_partition(const std::string& part_name, const Region& re
3028

3129
void write_vpr_floorplan_constraints(const char* file_name, int expand, bool subtile, int horizontal_partitions, int vertical_partitions) {
3230
VprConstraints constraints;
33-
3431
if (horizontal_partitions != 0 && vertical_partitions != 0) {
3532
setup_vpr_floorplan_constraints_cutpoints(constraints, horizontal_partitions, vertical_partitions);
3633
} else {
@@ -83,16 +80,17 @@ void setup_vpr_floorplan_constraints_one_loc(VprConstraints& constraints, int ex
8380
part.set_part_region(pr);
8481
constraints.mutable_place_constraints().add_partition(part);
8582

86-
const std::unordered_set<AtomBlockId>& atoms = cluster_to_atoms(blk_id);
87-
83+
const std::unordered_set<AtomBlockId>& atoms = cluster_ctx.atoms_lookup[blk_id];
8884
for (AtomBlockId atom_id : atoms) {
8985
constraints.mutable_place_constraints().add_constrained_atom(atom_id, partid);
9086
}
9187
part_id++;
9288
}
9389
}
9490

95-
void setup_vpr_floorplan_constraints_cutpoints(VprConstraints& constraints, int horizontal_cutpoints, int vertical_cutpoints) {
91+
void setup_vpr_floorplan_constraints_cutpoints(VprConstraints& constraints,
92+
int horizontal_cutpoints,
93+
int vertical_cutpoints) {
9694
auto& cluster_ctx = g_vpr_ctx.clustering();
9795
auto& block_locs = g_vpr_ctx.placement().block_locs();
9896
auto& device_ctx = g_vpr_ctx.device();
@@ -158,7 +156,7 @@ void setup_vpr_floorplan_constraints_cutpoints(VprConstraints& constraints, int
158156
* appropriate region accordingly
159157
*/
160158
for (ClusterBlockId blk_id : cluster_ctx.clb_nlist.blocks()) {
161-
const std::unordered_set<AtomBlockId>& atoms = cluster_to_atoms(blk_id);
159+
const std::unordered_set<AtomBlockId>& atoms = cluster_ctx.atoms_lookup[blk_id];
162160
int x = block_locs[blk_id].loc.x;
163161
int y = block_locs[blk_id].loc.y;
164162
int width = device_ctx.grid.width();

vpr/src/base/vpr_constraints_writer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#ifndef VPR_SRC_BASE_VPR_CONSTRAINTS_WRITER_H_
2626
#define VPR_SRC_BASE_VPR_CONSTRAINTS_WRITER_H_
2727

28+
class VprConstraints;
29+
2830
/**
2931
* @brief Write out floorplan constraints to an XML file based on current placement
3032
*

vpr/src/base/vpr_context.h

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "noc_routing.h"
3636
#include "tatum/report/TimingPath.hpp"
3737
#include "blk_loc_registry.h"
38+
#include "vtr_vector_map.h"
3839

3940
#ifndef NO_SERVER
4041

@@ -83,6 +84,7 @@ struct AtomContext : public Context {
8384
/// molecules. Has a method to get the pack molecule of an AtomBlock.
8485
/// TODO: This is mainly only used in the clusterer. It can probably be
8586
/// removed from the AtomContext entirely.
87+
/// FIXME: Move this to the clustering helper context. It makes more sense there.
8688
Prepacker prepacker;
8789
};
8890

@@ -298,6 +300,11 @@ struct ClusteringContext : public Context {
298300
*/
299301
std::map<ClusterBlockId, std::map<int, ClusterNetId>> post_routing_clb_pin_nets;
300302
std::map<ClusterBlockId, std::map<int, int>> pre_routing_net_pin_mapping;
303+
304+
// A vector of unordered_sets of AtomBlockIds that are inside each clustered
305+
// block [0 .. num_clustered_blocks-1]
306+
// This is populated when the packing is loaded.
307+
vtr::vector<ClusterBlockId, std::unordered_set<AtomBlockId>> atoms_lookup;
301308
};
302309

303310
/**
@@ -308,47 +315,10 @@ struct ClusteringContext : public Context {
308315
* in packing or placement stages.
309316
*/
310317
struct ClusteringHelperContext : public Context {
311-
// A map used to save the number of used instances from each logical block type.
312-
std::map<t_logical_block_type_ptr, size_t> num_used_type_instances;
313-
314-
// Stats keeper for placement information during packing/clustering
315-
t_cluster_placement_stats* cluster_placement_stats;
316-
317-
// total number of models in the architecture
318-
int num_models;
319-
320-
int max_cluster_size;
321-
t_pb_graph_node** primitives_list;
322-
323-
bool enable_pin_feasibility_filter;
324-
int feasible_block_array_size;
325-
326-
// total number of CLBs
327-
int total_clb_num;
328-
329-
// A vector of routing resource nodes within each of logic cluster_ctx.blocks types [0 .. num_logical_block_type-1]
318+
// A vector of routing resource nodes within each of logic cluster_ctx.blocks types [1 .. num_logical_block_type-1]
319+
// FIXME: This is only used for a handoff between the vpr_setup and the packer.
320+
// This can be made cleaner.
330321
std::vector<t_lb_type_rr_node>* lb_type_rr_graphs;
331-
332-
// the utilization of external input/output pins during packing (between 0 and 1)
333-
t_ext_pin_util_targets target_external_pin_util;
334-
335-
// During clustering, a block is related to un-clustered primitives with nets.
336-
// This relation has three types: low fanout, high fanout, and transitive
337-
// high_fanout_thresholds stores the threshold for nets to a block type to be considered high fanout
338-
t_pack_high_fanout_thresholds high_fanout_thresholds;
339-
340-
// A vector of unordered_sets of AtomBlockIds that are inside each clustered block [0 .. num_clustered_blocks-1]
341-
// unordered_set for faster insertion/deletion during the iterative improvement process of packing
342-
vtr::vector<ClusterBlockId, std::unordered_set<AtomBlockId>> atoms_lookup;
343-
344-
/** Stores the NoC group ID of each atom block. Atom blocks that belong
345-
* to different NoC groups can't be clustered with each other into the
346-
* same clustered block.*/
347-
vtr::vector<AtomBlockId, NocGroupId> atom_noc_grp_id;
348-
349-
~ClusteringHelperContext() {
350-
delete[] primitives_list;
351-
}
352322
};
353323

354324
/**

vpr/src/base/vpr_types.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -168,15 +168,6 @@ enum class e_cluster_seed {
168168
BLEND2
169169
};
170170

171-
enum class e_block_pack_status {
172-
BLK_PASSED,
173-
BLK_FAILED_FEASIBLE,
174-
BLK_FAILED_ROUTE,
175-
BLK_FAILED_FLOORPLANNING,
176-
BLK_FAILED_NOC_GROUP,
177-
BLK_STATUS_UNDEFINED
178-
};
179-
180171
struct t_ext_pin_util {
181172
t_ext_pin_util() = default;
182173
t_ext_pin_util(float in, float out)

0 commit comments

Comments
 (0)