Skip to content

Commit dcce60a

Browse files
[FlatPlacement] Updated Flat Placement Writing Code
Updated the code for writing a post-placement flat placement file. Updated the documentation to make this option easier to find.
1 parent e46e9c2 commit dcce60a

File tree

5 files changed

+126
-42
lines changed

5 files changed

+126
-42
lines changed

doc/src/vpr/command_line_usage.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,18 @@ Use the options below to override this default naming behaviour.
408408

409409
Prefix for output files
410410

411+
.. option:: --write_flat_place <file>
412+
413+
Writes the post-placement locations of each atom into a flat placement file.
414+
415+
For each atom in the netlist, the following information is stored into the
416+
flat placement file:
417+
418+
* The x, y, and sub_tile location of the cluster that contains this atom.
419+
* The flat site index of this atom in its cluster. The flat site index is a
420+
linearized ID of primitive locations in a cluster. This may be used as a
421+
hint to reconstruct clusters.
422+
411423
.. _netlist_options:
412424

413425
Netlist Options

libs/libvtrutil/src/vtr_vector_map.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#ifndef VTR_VECTOR_MAP
22
#define VTR_VECTOR_MAP
3+
#include <cstddef>
4+
#include <utility>
35
#include <vector>
46

57
#include "vtr_assert.h"

vpr/src/base/load_flat_place.cpp

Lines changed: 67 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,80 @@
1-
#include "globals.h"
2-
#include "load_flat_place.h"
3-
#include "clustered_netlist_utils.h"
1+
/**
2+
* @file
3+
* @author Alex Singer
4+
* @date January 2025
5+
* @brief Implementation of utility functions for reading and writing flat
6+
* (primitive-level) placements.
7+
*/
48

9+
#include "load_flat_place.h"
510

6-
/* @brief Prints flat placement file entries for the atoms in one placed cluster. */
7-
static void print_flat_cluster(FILE* fp, ClusterBlockId iblk,
8-
std::vector<AtomBlockId>& atoms);
11+
#include <unordered_set>
12+
#include "clustered_netlist.h"
13+
#include "globals.h"
14+
#include "vpr_context.h"
15+
#include "vpr_types.h"
916

10-
static void print_flat_cluster(FILE* fp, ClusterBlockId iblk,
11-
std::vector<AtomBlockId>& atoms) {
12-
const auto& atom_ctx = g_vpr_ctx.atom();
13-
const auto& block_locs = g_vpr_ctx.placement().block_locs();
17+
/**
18+
* @brief Prints flat placement file entries for the atoms in one placed
19+
* cluster.
20+
*
21+
* @param fp
22+
* File pointer to the file the cluster is printed to.
23+
* @param blk_id
24+
* The ID of the cluster block to print.
25+
* @param block_locs
26+
* The locations of all cluster blocks.
27+
* @param atoms_lookup
28+
* A lookup between all clusters and the atom blocks that they
29+
* contain.
30+
*/
31+
static void print_flat_cluster(FILE* fp,
32+
ClusterBlockId blk_id,
33+
const vtr::vector_map<ClusterBlockId, t_block_loc> &block_locs,
34+
const vtr::vector<ClusterBlockId, std::unordered_set<AtomBlockId>>& atoms_lookup) {
35+
// Atom context used to get the atom_pb for each atom in the cluster.
36+
// NOTE: This is only used for getting the flat site index.
37+
const AtomContext& atom_ctx = g_vpr_ctx.atom();
1438

15-
t_pl_loc loc = block_locs[iblk].loc;
16-
size_t bnum = size_t(iblk);
39+
// Get the location of this cluster.
40+
const t_pl_loc& blk_loc = block_locs[blk_id].loc;
1741

18-
for (AtomBlockId atom : atoms) {
42+
// Print a line for each atom.
43+
for (AtomBlockId atom : atoms_lookup[blk_id]) {
44+
// Get the atom pb graph node.
1945
t_pb_graph_node* atom_pbgn = atom_ctx.lookup.atom_pb(atom)->pb_graph_node;
20-
fprintf(fp, "%s %d %d %d %d #%zu %s\n", atom_ctx.nlist.block_name(atom).c_str(),
21-
loc.x, loc.y, loc.sub_tile,
22-
atom_pbgn->flat_site_index,
23-
bnum,
24-
atom_pbgn->pb_type->name);
46+
47+
// Print the flat placement information for this atom.
48+
fprintf(fp, "%s %d %d %d %d #%zu %s\n",
49+
atom_ctx.nlist.block_name(atom).c_str(),
50+
blk_loc.x, blk_loc.y, blk_loc.sub_tile,
51+
atom_pbgn->flat_site_index,
52+
static_cast<size_t>(blk_id),
53+
atom_pbgn->pb_type->name);
2554
}
2655
}
2756

28-
/* prints a flat placement file */
29-
void print_flat_placement(const char* flat_place_file) {
30-
const auto& block_locs = g_vpr_ctx.placement().block_locs();
31-
32-
FILE* fp;
33-
34-
ClusterAtomsLookup atoms_lookup;
35-
auto& cluster_ctx = g_vpr_ctx.clustering();
36-
37-
if (!block_locs.empty()) {
38-
fp = fopen(flat_place_file, "w");
39-
for (ClusterBlockId iblk : cluster_ctx.clb_nlist.blocks()) {
40-
auto atoms = atoms_lookup.atoms_in_cluster(iblk);
41-
print_flat_cluster(fp, iblk, atoms);
42-
}
43-
fclose(fp);
57+
void write_flat_placement(const char* flat_place_file_path,
58+
const ClusteredNetlist& cluster_netlist,
59+
const vtr::vector_map<ClusterBlockId, t_block_loc> &block_locs,
60+
const vtr::vector<ClusterBlockId, std::unordered_set<AtomBlockId>>& atoms_lookup) {
61+
// Writes the flat placement to the given flat_place_file_path.
62+
63+
// Only print a flat placement if the clusters have been placed.
64+
if (block_locs.empty())
65+
return;
66+
67+
// Create a file in write mode for the flat placement.
68+
FILE* fp = fopen(flat_place_file_path, "w");
69+
70+
// For each cluster, write out the atoms in the cluster at this cluster's
71+
// location.
72+
for (ClusterBlockId iblk : cluster_netlist.blocks()) {
73+
print_flat_cluster(fp, iblk, block_locs, atoms_lookup);
4474
}
4575

76+
// Close the file.
77+
fclose(fp);
4678
}
4779

4880
/* ingests and legalizes a flat placement file */
@@ -55,3 +87,4 @@ bool load_flat_placement(t_vpr_setup& vpr_setup, const t_arch& arch) {
5587

5688
return false;
5789
}
90+

vpr/src/base/load_flat_place.h

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,47 @@
1-
#ifndef LOAD_FLAT_PLACE_H
2-
#define LOAD_FLAT_PLACE_H
1+
/**
2+
* @file
3+
* @author Alex Singer
4+
* @date January 2025
5+
* @brief Utility functions for reading and writing flat placements.
6+
*
7+
* Flat placements are atom-level placements. These utilities can read and write
8+
* flat placement information to different parts of the VPR flow.
9+
*/
10+
11+
#pragma once
12+
13+
#include <unordered_set>
14+
#include "vtr_vector_map.h"
15+
#include "vtr_vector.h"
316

4-
#include "vpr_types.h"
17+
// Forward declarations
18+
class AtomBlockId;
19+
class ClusterBlockId;
20+
class ClusteredNetlist;
21+
struct t_arch;
22+
struct t_block_loc;
23+
struct t_vpr_setup;
524

625
/**
7-
* @brief A function that prints a flat placement file
26+
* @brief A function that writes a flat placement file after clustering and
27+
* placement.
28+
*
29+
* @param flat_place_file_path
30+
* Path to the file to write the flat placement to.
31+
* @param cluster_netlist
32+
* The clustered netlist to write to the file path.
33+
* @param block_locs
34+
* The locations of all of the blocks in the cluster_netlist.
35+
* @param atoms_lookup
36+
* A lookup between each cluster and the atoms within it.
837
*/
9-
void print_flat_placement(const char* flat_place_file);
38+
void write_flat_placement(const char* flat_place_file_path,
39+
const ClusteredNetlist& cluster_netlist,
40+
const vtr::vector_map<ClusterBlockId, t_block_loc> &block_locs,
41+
const vtr::vector<ClusterBlockId, std::unordered_set<AtomBlockId>>& atoms_lookup);
1042

1143
/**
1244
* @brief A function that loads and legalizes a flat placement file
1345
*/
1446
bool load_flat_placement(t_vpr_setup& vpr_setup, const t_arch& arch);
1547

16-
#endif

vpr/src/base/vpr_api.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,10 @@ bool vpr_load_flat_placement(t_vpr_setup& vpr_setup, const t_arch& arch) {
769769

770770
// echo flat placement (orphan clusters will have -1 for X, Y, subtile coordinates)
771771
if (getEchoEnabled() && isEchoFileEnabled(E_ECHO_FLAT_PLACE)) {
772-
print_flat_placement(getEchoFileName(E_ECHO_FLAT_PLACE));
772+
write_flat_placement(getEchoFileName(E_ECHO_FLAT_PLACE),
773+
g_vpr_ctx.clustering().clb_nlist,
774+
g_vpr_ctx.placement().block_locs(),
775+
g_vpr_ctx.clustering().atoms_lookup);
773776
}
774777

775778
// reset the device grid
@@ -813,7 +816,10 @@ bool vpr_place_flow(const Netlist<>& net_list, t_vpr_setup& vpr_setup, const t_a
813816
// A flat placement file includes cluster and intra-cluster placement coordinates for
814817
// each primitive and can be used to reconstruct a clustering and placement solution.
815818
if (!filename_opts.write_flat_place_file.empty()) {
816-
print_flat_placement(vpr_setup.FileNameOpts.write_flat_place_file.c_str());
819+
write_flat_placement(filename_opts.write_flat_place_file.c_str(),
820+
g_vpr_ctx.clustering().clb_nlist,
821+
g_vpr_ctx.placement().block_locs(),
822+
g_vpr_ctx.clustering().atoms_lookup);
817823
}
818824

819825
return true;

0 commit comments

Comments
 (0)