Skip to content

Commit dc5593c

Browse files
[AP][PartialLegalizer] Density Abstraction
Abstracted how density is managed in the AP flow into a manager class. This manager class contains two sub-classes: one for the bins and one for the mass calculation. Density is a function of mass and volume. The volume is related to how we break the FPGA chip into discrete bins. These bins contain atoms and they take up a rectangular amount of space on the FPGA. The mass is related to how "heavy" each APBlock is inside of the bin. This is computed using an M-dimensional vector where M is the number of models in the architecture. Each logical / physical tile has a capacity that it may hold. The density manager class manages how the bins are constructed, how much mass each bin can contain, and how much mass each bin currently contains. This current version of the density manager class creates a bin for each tile (with a unique root tile location). The capacity of each bin is related to the capacity of the physical tile at that location. Partial Legalizers can ask questions to the density manager class. They may ask for all of the overfilled bins, what bin is located at a given location, what bin contains a given atom, how overfilled / underfilled a bin is, etc. This abstraction will make it much easier to optimize the density of the flat placement, since it separates algorithm from denisty calculation. This will make writing future Partial Legalizers considerably easier.
1 parent ceae587 commit dc5593c

12 files changed

+1357
-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: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
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_range.h"
18+
#include "vtr_strong_id.h"
19+
#include "vtr_vector.h"
20+
#include "vtr_vector_map.h"
21+
22+
// The tag for the flat placement bin.
23+
struct flat_placement_bin_tag {};
24+
25+
/**
26+
* @brief A unique ID to a flat placement bin.
27+
*/
28+
typedef vtr::StrongId<flat_placement_bin_tag, size_t> FlatPlacementBinId;
29+
30+
/**
31+
* @brief A container of bins which hold AP blocks and take up space on the FPGA.
32+
*
33+
* For flat placement, blocks may be placed anywhere on the FPGA grid. This
34+
* placement is continuous; however, in order to compute quantities like density
35+
* and legality, there needs to be a way to bin blocks together spatially.
36+
*
37+
* This class maintains bins which hold AP blocks and take up a rectangular
38+
* amount of space on the FPGA grid.
39+
*
40+
* This class is only a container; it leaves how the FPGA is split into bins to
41+
* higher level classes.
42+
*/
43+
class FlatPlacementBins {
44+
public:
45+
// Iterator for the flat placement bin IDs
46+
typedef typename vtr::vector_map<FlatPlacementBinId, FlatPlacementBinId>::const_iterator bin_iterator;
47+
48+
// Range for the flat placement bin IDs
49+
typedef typename vtr::Range<bin_iterator> bin_range;
50+
51+
FlatPlacementBins(const APNetlist& ap_netlist)
52+
: block_bin_(ap_netlist.blocks().size(), FlatPlacementBinId::INVALID()) {}
53+
54+
/**
55+
* @brief Returns a range of all bins that have been created.
56+
*/
57+
bin_range bins() const {
58+
return vtr::make_range(bin_ids_.begin(), bin_ids_.end());
59+
}
60+
61+
/**
62+
* @brief Creates a bin which exists in the given bin_region.
63+
*
64+
* @param bin_region
65+
* The rectangular region of the FPGA device that this bin will
66+
* represent.
67+
*/
68+
inline FlatPlacementBinId create_bin(const vtr::Rect<double>& bin_region) {
69+
FlatPlacementBinId new_bin_id = FlatPlacementBinId(bin_ids_.size());
70+
bin_ids_.push_back(new_bin_id);
71+
bin_region_.push_back(bin_region);
72+
bin_contained_blocks_.resize(bin_contained_blocks_.size() + 1);
73+
return new_bin_id;
74+
}
75+
76+
/**
77+
* @brief Add the given block to the given bin.
78+
*/
79+
inline void add_block_to_bin(APBlockId blk_id, FlatPlacementBinId bin_id) {
80+
VTR_ASSERT(blk_id.is_valid());
81+
VTR_ASSERT(bin_id.is_valid());
82+
VTR_ASSERT(!block_bin_[blk_id].is_valid());
83+
bin_contained_blocks_[bin_id].insert(blk_id);
84+
block_bin_[blk_id] = bin_id;
85+
}
86+
87+
/**
88+
* @brief Remove the given block from the given bin. The bin must contain
89+
* this block.
90+
*/
91+
inline void remove_block_from_bin(APBlockId blk_id, FlatPlacementBinId bin_id) {
92+
VTR_ASSERT(blk_id.is_valid());
93+
VTR_ASSERT(bin_id.is_valid());
94+
VTR_ASSERT(block_bin_[blk_id] == bin_id);
95+
bin_contained_blocks_[bin_id].erase(blk_id);
96+
block_bin_[blk_id] = FlatPlacementBinId::INVALID();
97+
}
98+
99+
/**
100+
* @brief Get the blocks contained within the given bin.
101+
*/
102+
inline const std::unordered_set<APBlockId>& bin_contained_blocks(FlatPlacementBinId bin_id) const {
103+
VTR_ASSERT(bin_id.is_valid());
104+
return bin_contained_blocks_[bin_id];
105+
}
106+
107+
/**
108+
* @brief Get the region of the FPGA that the given bin covers.
109+
*/
110+
inline const vtr::Rect<double>& bin_region(FlatPlacementBinId bin_id) const {
111+
VTR_ASSERT(bin_id.is_valid());
112+
return bin_region_[bin_id];;
113+
}
114+
115+
/**
116+
* @brief Get the bin that contains the given AP block.
117+
*/
118+
inline FlatPlacementBinId block_bin(APBlockId blk_id) const {
119+
VTR_ASSERT(blk_id.is_valid());
120+
return block_bin_[blk_id];
121+
}
122+
123+
/**
124+
* @brief Remove all of the AP blocks from the given bin.
125+
*/
126+
inline void remove_all_blocks_from_bin(FlatPlacementBinId bin_id) {
127+
VTR_ASSERT(bin_id.is_valid());
128+
// Invalidate the block bin lookup for the blocks in the bin.
129+
for (APBlockId blk_id : bin_contained_blocks_[bin_id]) {
130+
block_bin_[blk_id] = FlatPlacementBinId::INVALID();
131+
}
132+
// Remove all of the blocks from the bin.
133+
bin_contained_blocks_[bin_id].clear();
134+
}
135+
136+
private:
137+
/// @brief A vector of the Flat Placement Bin IDs. If any of them are invalid,
138+
/// then that means that the bin has been destroyed.
139+
vtr::vector_map<FlatPlacementBinId, FlatPlacementBinId> bin_ids_;
140+
141+
/// @brief The contained AP blocks of each bin.
142+
vtr::vector_map<FlatPlacementBinId, std::unordered_set<APBlockId>> bin_contained_blocks_;
143+
144+
/// @brief The bin that contains each AP block.
145+
vtr::vector<APBlockId, FlatPlacementBinId> block_bin_;
146+
147+
/// @brief The region that each bin represents on the FPGA grid.
148+
// TODO: For 3D FPGAs, this should be a 3D rectangle.
149+
vtr::vector_map<FlatPlacementBinId, vtr::Rect<double>> bin_region_;
150+
};
151+

0 commit comments

Comments
 (0)