Skip to content

Commit d3967a6

Browse files
[APPack] Added Layer to Flat Placement
As per Vaughn's suggestions, added layer to the flat placement file specification to make it easier to upgrade to 3D FPGAs in the future. Fixed some small documentation issues.
1 parent 18097d4 commit d3967a6

File tree

5 files changed

+91
-27
lines changed

5 files changed

+91
-27
lines changed

doc/src/vpr/command_line_usage.rst

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -411,23 +411,42 @@ Use the options below to override this default naming behaviour.
411411
.. option:: --read_flat_place <file>
412412

413413
Reads a file containing the locations of each atom on the FPGA.
414-
415414
This is used by the packer to better cluster atoms together.
416415

417416
The flat placement file (which often ends in ``.fplace``) is a text file
418-
where each line describes the location of an atom. It has the following
419-
expected syntax:
417+
where each line describes the location of an atom. Each line in the flat
418+
placement file should have the following syntax:
420419

421420
.. code-block:: none
422421
423-
<atom_name : str> <atom_x_pos : float> <atom_y_pos : float> <atom_sub_tile? : int> <atom_site_idx? : int>
424-
n523 6 8 0 3
425-
n522 6 8 0 5
426-
n520 6 8 0 2
427-
n518 6 8 0 16
422+
<atom_name : str> <x : float> <y : float> <layer : float> <atom_sub_tile : int> <atom_site_idx? : int>
423+
424+
For example:
425+
426+
.. code-block:: none
428427
429-
The ``sub_tile`` and ``site_idx`` are optional parameters which may be used
430-
as a hint to reconstruct clusters.
428+
n523 6 8 0 0 3
429+
n522 6 8 0 0 5
430+
n520 6 8 0 0 2
431+
n518 6 8 0 0 16
432+
433+
The position of the atom on the FPGA is given by 3 floating point values
434+
(``x``, ``y``, ``layer``). We allow for the positions of atom to be not
435+
quite legal (ok to be off-grid) since this flat placement will be fed into
436+
the packer and placer, which will snap the positions to grid locations. By
437+
allowing for off-grid positions, the packer can better trade-off where to
438+
move atom blocks if they cannot be placed at the given position.
439+
For 2D FPGA architectures, the ``layer`` should be 0.
440+
441+
The ``sub_tile`` is a clustered placement construct: which cluster-level
442+
location at a given (x, y, layer) should these atoms go at (relevant when
443+
multiple clusters can be stacked there). A sub-tile of -1 may be used when
444+
the sub-tile of an atom is unkown (allowing the packing algorithm to choose
445+
any sub-tile at the given (x, y, layer) location).
446+
447+
The ``site_idx`` is an optional index into a linearized list of primitive
448+
locations within a cluster-level block which may be used as a hint to
449+
reconstruct clusters.
431450

432451
.. warning::
433452

vpr/src/base/FlatPlacementInfo.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,27 @@ class FlatPlacementInfo {
2626
/// @brief Identifier for an undefined site idx.
2727
static constexpr int UNDEFINED_SITE_IDX = -1;
2828

29+
// The following three floating point numbers describe the flat position of
30+
// an atom block. These are floats instead of integers to allow for flat
31+
// placements which are not quite legal (ok to be off-grid). This allows
32+
// the flat placement to encode information about where atom blocks would
33+
// want to go if they cannot be placed at the grid position they are at.
34+
// (for example, a block placed at (0.9, 0.9) wants to be at tile (0, 0),
35+
// but if thats not possible it would prefer (1, 1) over anything else.
36+
2937
/// @brief The x-positions of each atom block. Is UNDEFINED_POS if undefined.
3038
vtr::vector<AtomBlockId, float> blk_x_pos;
3139
/// @brief The y-positions of each atom block. Is UNDEFINED_POS if undefined.
3240
vtr::vector<AtomBlockId, float> blk_y_pos;
41+
/// @brief The layer of each atom block. Is UNDEFINED_POS if undefined.
42+
vtr::vector<AtomBlockId, float> blk_layer;
43+
3344
/// @brief The sub tile location of each atom block. Is UNDEFINED_SUB_TILE
3445
/// if undefined.
3546
vtr::vector<AtomBlockId, int> blk_sub_tile;
36-
/// @brief The flat site idx of each atom block. Is UNDEFINED_SITE_IDX if
37-
/// undefined.
47+
/// @brief The flat site idx of each atom block. This is an optional index
48+
/// into a linearized list of primitive locations within a cluster-
49+
/// level block. Is UNDEFINED_SITE_IDX if undefined.
3850
vtr::vector<AtomBlockId, int> blk_site_idx;
3951

4052
/// @brief A flag to signify if this object has been constructed with data
@@ -64,6 +76,7 @@ class FlatPlacementInfo {
6476
FlatPlacementInfo(const AtomNetlist& atom_netlist)
6577
: blk_x_pos(atom_netlist.blocks().size(), UNDEFINED_POS),
6678
blk_y_pos(atom_netlist.blocks().size(), UNDEFINED_POS),
79+
blk_layer(atom_netlist.blocks().size(), UNDEFINED_POS),
6780
blk_sub_tile(atom_netlist.blocks().size(), UNDEFINED_SUB_TILE),
6881
blk_site_idx(atom_netlist.blocks().size(), UNDEFINED_SITE_IDX),
6982
valid(true) {}

vpr/src/base/load_flat_place.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,10 @@ static void print_flat_cluster(FILE* fp,
5050
t_pb_graph_node* atom_pbgn = atom_ctx.lookup.atom_pb(atom)->pb_graph_node;
5151

5252
// Print the flat placement information for this atom.
53-
fprintf(fp, "%s %d %d %d %d #%zu %s\n",
53+
fprintf(fp, "%s %d %d %d %d %d #%zu %s\n",
5454
atom_ctx.nlist.block_name(atom).c_str(),
55-
blk_loc.x, blk_loc.y, blk_loc.sub_tile,
55+
blk_loc.x, blk_loc.y, blk_loc.layer,
56+
blk_loc.sub_tile,
5657
atom_pbgn->flat_site_index,
5758
static_cast<size_t>(blk_id),
5859
atom_pbgn->pb_type->name);
@@ -111,9 +112,11 @@ FlatPlacementInfo read_flat_placement(const std::string& read_flat_place_file_pa
111112
// - Atom name
112113
// - Atom x-pos
113114
// - Atom y-pos
114-
if (tokens.size() < 3) {
115+
// - Atom layer
116+
// - Atom sub-tile
117+
if (tokens.size() < 5) {
115118
VTR_LOG_WARN("Flat placement file, line %d has too few arguments. "
116-
"Requires at least: <atom_name> <atom_x_pos> <atom_y_pos>\n",
119+
"Requires at least: <atom_name> <x> <y> <layer> <sub_tile>\n",
117120
line_num);
118121
continue;
119122
}
@@ -137,19 +140,19 @@ FlatPlacementInfo read_flat_placement(const std::string& read_flat_place_file_pa
137140
continue;
138141
}
139142

140-
// Get the x and y position of the atom. These functions have error
141-
// checking built in. We parse x and y as floats to allow for reading
142-
// in more global atom positions.
143+
// Get the (x, y, layer) position of the atom. These functions have
144+
// error checking built in. We parse these as floats to allow for
145+
// reading in more global atom positions.
143146
flat_placement_info.blk_x_pos[atom_blk_id] = vtr::atof(tokens[1]);
144147
flat_placement_info.blk_y_pos[atom_blk_id] = vtr::atof(tokens[2]);
148+
flat_placement_info.blk_layer[atom_blk_id] = vtr::atof(tokens[3]);
145149

146-
// If a sub-tile is given, parse the sub-tile as an integer.
147-
if (tokens.size() >= 4 && tokens[3][0] != '#')
148-
flat_placement_info.blk_sub_tile[atom_blk_id] = vtr::atoi(tokens[3]);
150+
// Parse the sub-tile as an integer.
151+
flat_placement_info.blk_sub_tile[atom_blk_id] = vtr::atoi(tokens[4]);
149152

150153
// If a site index is given, parse the site index as an integer.
151-
if (tokens.size() >= 5 && tokens[4][0] != '#')
152-
flat_placement_info.blk_site_idx[atom_blk_id] = vtr::atoi(tokens[4]);
154+
if (tokens.size() >= 6 && tokens[5][0] != '#')
155+
flat_placement_info.blk_site_idx[atom_blk_id] = vtr::atoi(tokens[5]);
153156

154157
// Ignore any further tokens.
155158

vpr/src/pack/pack.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,28 @@ struct t_lb_type_rr_node;
1212
struct t_model;
1313
struct t_packer_opts;
1414

15+
/**
16+
* @brief Try to pack the atom netlist into legal clusters on the given
17+
* architecture. Will return true if successful, false otherwise.
18+
*
19+
* @param packer_opts
20+
* Options passed by the user to configure the packing algorithm.
21+
* @param analysis_opts
22+
* Options passed by the user to configure how analysis is
23+
* performed in the packer.
24+
* @param arch
25+
* A pointer to the architecture to create clusters for.
26+
* @param user_models
27+
* A list of architecture models provided by the architecture file.
28+
* @param library_models
29+
* A list of architecture models provided by the library.
30+
* @param interc_delay
31+
* @param lb_type_rr_graphs
32+
* @param flat_placement_info
33+
* Flat (primitive-level) placement information that may be
34+
* provided by the user as a hint for packing. Will be invalid if
35+
* there is no flat placement information provided.
36+
*/
1537
bool try_pack(t_packer_opts* packer_opts,
1638
const t_analysis_opts* analysis_opts,
1739
const t_arch* arch,

vpr/src/pack/verify_flat_placement.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ unsigned verify_flat_placement_for_packing(const FlatPlacementInfo& flat_placeme
1616
// for each piece of information.
1717
if (flat_placement_info.blk_x_pos.size() != atom_netlist.blocks().size() ||
1818
flat_placement_info.blk_y_pos.size() != atom_netlist.blocks().size() ||
19+
flat_placement_info.blk_layer.size() != atom_netlist.blocks().size() ||
1920
flat_placement_info.blk_sub_tile.size() != atom_netlist.blocks().size() ||
2021
flat_placement_info.blk_site_idx.size() != atom_netlist.blocks().size()) {
2122
VTR_LOG_ERROR(
@@ -26,14 +27,14 @@ unsigned verify_flat_placement_for_packing(const FlatPlacementInfo& flat_placeme
2627
return num_errors;
2728
}
2829

29-
// 1. Verify that every atom has an x and y position on the device. This is
30-
// the only information we require for the flat placement during packing.
30+
// 1. Verify that every atom has an (x, y, layer) position on the device.
3131
//
3232
// TODO: In the future, we may be able to allow some blocks to have
3333
// undefined positions.
3434
for (AtomBlockId blk_id : atom_netlist.blocks()) {
3535
if (flat_placement_info.blk_x_pos[blk_id] == FlatPlacementInfo::UNDEFINED_POS ||
36-
flat_placement_info.blk_y_pos[blk_id] == FlatPlacementInfo::UNDEFINED_POS) {
36+
flat_placement_info.blk_y_pos[blk_id] == FlatPlacementInfo::UNDEFINED_POS ||
37+
flat_placement_info.blk_layer[blk_id] == FlatPlacementInfo::UNDEFINED_POS) {
3738
VTR_LOG_ERROR(
3839
"Atom block %s has an undefined position in the flat placement.\n",
3940
atom_netlist.block_name(blk_id).c_str());
@@ -49,10 +50,12 @@ unsigned verify_flat_placement_for_packing(const FlatPlacementInfo& flat_placeme
4950
for (AtomBlockId blk_id : atom_netlist.blocks()) {
5051
float blk_x_pos = flat_placement_info.blk_x_pos[blk_id];
5152
float blk_y_pos = flat_placement_info.blk_y_pos[blk_id];
53+
float blk_layer = flat_placement_info.blk_layer[blk_id];
5254
int blk_sub_tile = flat_placement_info.blk_sub_tile[blk_id];
5355
int blk_site_idx = flat_placement_info.blk_site_idx[blk_id];
5456
if ((blk_x_pos < 0.f && blk_x_pos != FlatPlacementInfo::UNDEFINED_POS) ||
5557
(blk_y_pos < 0.f && blk_y_pos != FlatPlacementInfo::UNDEFINED_POS) ||
58+
(blk_layer < 0.f && blk_layer != FlatPlacementInfo::UNDEFINED_POS) ||
5659
(blk_sub_tile < 0 && blk_sub_tile != FlatPlacementInfo::UNDEFINED_SUB_TILE) ||
5760
(blk_site_idx < 0 && blk_site_idx != FlatPlacementInfo::UNDEFINED_SITE_IDX)) {
5861
VTR_LOG_ERROR(
@@ -71,12 +74,14 @@ unsigned verify_flat_placement_for_packing(const FlatPlacementInfo& flat_placeme
7174
AtomBlockId root_blk_id = mol->atom_block_ids[mol->root];
7275
float root_pos_x = flat_placement_info.blk_x_pos[root_blk_id];
7376
float root_pos_y = flat_placement_info.blk_y_pos[root_blk_id];
77+
float root_layer = flat_placement_info.blk_layer[root_blk_id];
7478
int root_sub_tile = flat_placement_info.blk_sub_tile[root_blk_id];
7579
for (AtomBlockId mol_blk_id : mol->atom_block_ids) {
7680
if (!mol_blk_id.is_valid())
7781
continue;
7882
if (flat_placement_info.blk_x_pos[mol_blk_id] != root_pos_x ||
7983
flat_placement_info.blk_y_pos[mol_blk_id] != root_pos_y ||
84+
flat_placement_info.blk_layer[mol_blk_id] != root_layer ||
8085
flat_placement_info.blk_sub_tile[mol_blk_id] != root_sub_tile) {
8186
VTR_LOG_ERROR(
8287
"Molecule with root atom block %s contains atom block %s "
@@ -89,6 +94,8 @@ unsigned verify_flat_placement_for_packing(const FlatPlacementInfo& flat_placeme
8994
}
9095
}
9196

97+
// TODO: May want to verify that the layer is all 0 in the case of 2D FPGAs.
98+
9299
return num_errors;
93100
}
94101

0 commit comments

Comments
 (0)