Skip to content

Commit ced1418

Browse files
Merge pull request #2899 from AlexandreSinger/feature-ap-bin-graph
[AP][PartialLegalizer] Density Abstraction
2 parents 43c1589 + b896475 commit ced1418

12 files changed

+1421
-822
lines changed

vpr/src/analytical_place/analytical_placement_flow.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ void run_analytical_placement_flow(t_vpr_setup& vpr_setup) {
8080
// Run the Global Placer
8181
std::unique_ptr<GlobalPlacer> global_placer = make_global_placer(e_global_placer::SimPL,
8282
ap_netlist,
83-
prepacker);
83+
prepacker,
84+
atom_nlist,
85+
device_ctx.grid,
86+
device_ctx.logical_block_types,
87+
device_ctx.physical_tile_types);
8488
PartialPlacement p_placement = global_placer->place();
8589

8690
// Verify that the partial placement is valid before running the full
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
/**
2+
* @file
3+
* @author Alex Singer
4+
* @date February 2025
5+
* @brief Flat Placement Bin Abstraction
6+
*
7+
* This file declares a class which can bin AP Blocks spatially throughout the
8+
* FPGA.
9+
*/
10+
11+
#pragma once
12+
13+
#include <unordered_set>
14+
#include "ap_netlist.h"
15+
#include "vtr_assert.h"
16+
#include "vtr_geometry.h"
17+
#include "vtr_log.h"
18+
#include "vtr_range.h"
19+
#include "vtr_strong_id.h"
20+
#include "vtr_vector.h"
21+
#include "vtr_vector_map.h"
22+
23+
// The tag for the flat placement bin.
24+
struct flat_placement_bin_tag {};
25+
26+
/**
27+
* @brief A unique ID to a flat placement bin.
28+
*/
29+
typedef vtr::StrongId<flat_placement_bin_tag, size_t> FlatPlacementBinId;
30+
31+
/**
32+
* @brief A container of bins which hold AP blocks and take up space on the FPGA.
33+
*
34+
* For flat placement, blocks may be placed anywhere on the FPGA grid. This
35+
* placement is continuous; however, in order to compute quantities like density
36+
* and legality, there needs to be a way to bin blocks together spatially.
37+
*
38+
* This class maintains bins which hold AP blocks and take up a rectangular
39+
* amount of space on the FPGA grid.
40+
*
41+
* This class is only a container; it leaves how the FPGA is split into bins to
42+
* higher level classes.
43+
*/
44+
class FlatPlacementBins {
45+
public:
46+
// Iterator for the flat placement bin IDs
47+
typedef typename vtr::vector_map<FlatPlacementBinId, FlatPlacementBinId>::const_iterator bin_iterator;
48+
49+
// Range for the flat placement bin IDs
50+
typedef typename vtr::Range<bin_iterator> bin_range;
51+
52+
FlatPlacementBins(const APNetlist& ap_netlist)
53+
: block_bin_(ap_netlist.blocks().size(), FlatPlacementBinId::INVALID()) {}
54+
55+
/**
56+
* @brief Returns a range of all bins that have been created.
57+
*/
58+
bin_range bins() const {
59+
return vtr::make_range(bin_ids_.begin(), bin_ids_.end());
60+
}
61+
62+
/**
63+
* @brief Creates a bin which exists in the given bin_region.
64+
*
65+
* @param bin_region
66+
* The rectangular region of the FPGA device that this bin will
67+
* represent.
68+
*/
69+
inline FlatPlacementBinId create_bin(const vtr::Rect<double>& bin_region) {
70+
FlatPlacementBinId new_bin_id = FlatPlacementBinId(bin_ids_.size());
71+
bin_ids_.push_back(new_bin_id);
72+
bin_region_.push_back(bin_region);
73+
bin_contained_blocks_.resize(bin_contained_blocks_.size() + 1);
74+
return new_bin_id;
75+
}
76+
77+
/**
78+
* @brief Add the given block to the given bin.
79+
*/
80+
inline void add_block_to_bin(APBlockId blk_id, FlatPlacementBinId bin_id) {
81+
VTR_ASSERT(blk_id.is_valid());
82+
VTR_ASSERT(bin_id.is_valid());
83+
VTR_ASSERT(!block_bin_[blk_id].is_valid());
84+
bin_contained_blocks_[bin_id].insert(blk_id);
85+
block_bin_[blk_id] = bin_id;
86+
}
87+
88+
/**
89+
* @brief Remove the given block from the given bin. The bin must contain
90+
* this block.
91+
*/
92+
inline void remove_block_from_bin(APBlockId blk_id, FlatPlacementBinId bin_id) {
93+
VTR_ASSERT(blk_id.is_valid());
94+
VTR_ASSERT(bin_id.is_valid());
95+
VTR_ASSERT(block_bin_[blk_id] == bin_id);
96+
bin_contained_blocks_[bin_id].erase(blk_id);
97+
block_bin_[blk_id] = FlatPlacementBinId::INVALID();
98+
}
99+
100+
/**
101+
* @brief Get the blocks contained within the given bin.
102+
*/
103+
inline const std::unordered_set<APBlockId>& bin_contained_blocks(FlatPlacementBinId bin_id) const {
104+
VTR_ASSERT(bin_id.is_valid());
105+
return bin_contained_blocks_[bin_id];
106+
}
107+
108+
/**
109+
* @brief Get the region of the FPGA that the given bin covers.
110+
*/
111+
inline const vtr::Rect<double>& bin_region(FlatPlacementBinId bin_id) const {
112+
VTR_ASSERT(bin_id.is_valid());
113+
return bin_region_[bin_id];;
114+
}
115+
116+
/**
117+
* @brief Get the bin that contains the given AP block.
118+
*/
119+
inline FlatPlacementBinId block_bin(APBlockId blk_id) const {
120+
VTR_ASSERT(blk_id.is_valid());
121+
return block_bin_[blk_id];
122+
}
123+
124+
/**
125+
* @brief Remove all of the AP blocks from the given bin.
126+
*/
127+
inline void remove_all_blocks_from_bin(FlatPlacementBinId bin_id) {
128+
VTR_ASSERT(bin_id.is_valid());
129+
// Invalidate the block bin lookup for the blocks in the bin.
130+
for (APBlockId blk_id : bin_contained_blocks_[bin_id]) {
131+
block_bin_[blk_id] = FlatPlacementBinId::INVALID();
132+
}
133+
// Remove all of the blocks from the bin.
134+
bin_contained_blocks_[bin_id].clear();
135+
}
136+
137+
/**
138+
* @brief Verify the internal members of this class are consistent.
139+
*/
140+
inline bool verify() const {
141+
// Ensure all bin IDs are valid and consistent.
142+
for (FlatPlacementBinId bin_id : bin_ids_) {
143+
if (!bin_id.is_valid()) {
144+
VTR_LOG("Bin Verify: Invalid bin ID in bins.\n");
145+
return false;
146+
}
147+
if (bin_ids_.count(bin_id) != 1) {
148+
VTR_LOG("Bin Verify: Found a bin ID not in the bin IDs array.\n");
149+
return false;
150+
}
151+
if (bin_ids_[bin_id] != bin_id) {
152+
VTR_LOG("Bin Verify: Bin ID found which is not consistent.\n");
153+
return false;
154+
}
155+
}
156+
157+
// Ensure the data members of this class are all the correct size.
158+
size_t num_bins = bin_ids_.size();
159+
if (bin_contained_blocks_.size() != num_bins) {
160+
VTR_LOG("Bin Verify: bin_constained_blocks_ not the correct size.\n");
161+
return false;
162+
}
163+
if (bin_region_.size() != num_bins) {
164+
VTR_LOG("Bin Verify: bin_region_ not the correct size.\n");
165+
return false;
166+
}
167+
168+
// Make sure that the bin_contained_blocks_ and the block_bin_ are
169+
// consistent.
170+
for (FlatPlacementBinId bin_id : bin_ids_) {
171+
for (APBlockId blk_id : bin_contained_blocks_[bin_id]) {
172+
if (block_bin_[blk_id] != bin_id) {
173+
VTR_LOG("Bin Verify: Block is contained within a bin but does not agree.\n");
174+
return false;
175+
}
176+
}
177+
}
178+
179+
return true;
180+
}
181+
182+
private:
183+
/// @brief A vector of the Flat Placement Bin IDs. If any of them are invalid,
184+
/// then that means that the bin has been destroyed.
185+
vtr::vector_map<FlatPlacementBinId, FlatPlacementBinId> bin_ids_;
186+
187+
/// @brief The contained AP blocks of each bin.
188+
vtr::vector_map<FlatPlacementBinId, std::unordered_set<APBlockId>> bin_contained_blocks_;
189+
190+
/// @brief The bin that contains each AP block.
191+
vtr::vector<APBlockId, FlatPlacementBinId> block_bin_;
192+
193+
/// @brief The region that each bin represents on the FPGA grid.
194+
// TODO: For 3D FPGAs, this should be a 3D rectangle.
195+
vtr::vector_map<FlatPlacementBinId, vtr::Rect<double>> bin_region_;
196+
};
197+

0 commit comments

Comments
 (0)