Skip to content

legalizer frontend #2615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions vpr/src/base/CheckSetup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,18 @@ void CheckSetup(const t_packer_opts& PackerOpts,
"Packing cannot be timing driven without timing analysis enabled\n");
}

if (PackerOpts.load_flat_placement) {
if (PackerOpts.device_layout == "auto") {
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
"Legalization requires a fixed device layout.\n");
}
if (!PlacerOpts.constraints_file.empty()) {
VPR_FATAL_ERROR(VPR_ERROR_OTHER,
"Cannot specify a fixed clusters file when running legalization.\n");
}
}


if ((GLOBAL == RouterOpts.route_type)
&& (PlacerOpts.place_algorithm.is_timing_driven())) {
/* Works, but very weird. Can't optimize timing well, since you're
Expand Down
5 changes: 3 additions & 2 deletions vpr/src/base/SetupGrid.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@
#include "physical_types.h"

///@brief Find the device satisfying the specified minimum resources
/// minimum_instance_counts and target_device_utilization are not required when specifying a fixed layout
DeviceGrid create_device_grid(const std::string& layout_name,
const std::vector<t_grid_def>& grid_layouts,
const std::map<t_logical_block_type_ptr, size_t>& minimum_instance_counts,
float target_device_utilization);
const std::map<t_logical_block_type_ptr, size_t>& minimum_instance_counts = {},
float target_device_utilization = 0.0);

///@brief Find the device close in size to the specified dimensions
DeviceGrid create_device_grid(const std::string& layout_name,
Expand Down
9 changes: 9 additions & 0 deletions vpr/src/base/SetupVPR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ void SetupVPR(const t_options* Options,
FileNameOpts->ArchFile = Options->ArchFile;
FileNameOpts->CircuitFile = Options->CircuitFile;
FileNameOpts->NetFile = Options->NetFile;
FileNameOpts->FlatPlaceFile = Options->FlatPlaceFile;
FileNameOpts->PlaceFile = Options->PlaceFile;
FileNameOpts->RouteFile = Options->RouteFile;
FileNameOpts->ActFile = Options->ActFile;
Expand All @@ -136,6 +137,8 @@ void SetupVPR(const t_options* Options,
FileNameOpts->out_file_prefix = Options->out_file_prefix;
FileNameOpts->read_vpr_constraints_file = Options->read_vpr_constraints_file;
FileNameOpts->write_vpr_constraints_file = Options->write_vpr_constraints_file;
FileNameOpts->write_constraints_file = Options->write_constraints_file;
FileNameOpts->write_flat_place_file = Options->write_flat_place_file;
FileNameOpts->write_block_usage = Options->write_block_usage;

FileNameOpts->verify_file_digests = Options->verify_file_digests;
Expand Down Expand Up @@ -239,6 +242,7 @@ void SetupVPR(const t_options* Options,
//Setup the default flow, if no specific stages specified
//do all
if (!Options->do_packing
&& !Options->do_legalize
&& !Options->do_placement
&& !Options->do_routing
&& !Options->do_analysis) {
Expand Down Expand Up @@ -275,6 +279,11 @@ void SetupVPR(const t_options* Options,
if (Options->do_packing) {
PackerOpts->doPacking = STAGE_DO;
}

if (Options->do_legalize) {
PackerOpts->doPacking = STAGE_LOAD;
PackerOpts->load_flat_placement = true;
}
}

ShowSetup(*vpr_setup);
Expand Down
55 changes: 55 additions & 0 deletions vpr/src/base/load_flat_place.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include "globals.h"
#include "load_flat_place.h"
#include "clustered_netlist_utils.h"


/* @brief Prints flat placement file entries for the atoms in one placed cluster. */
static void print_flat_cluster(FILE* fp, ClusterBlockId iblk,
std::vector<AtomBlockId>& atoms);

static void print_flat_cluster(FILE* fp, ClusterBlockId iblk,
std::vector<AtomBlockId>& atoms) {

auto& atom_ctx = g_vpr_ctx.atom();
t_pl_loc loc = g_vpr_ctx.placement().block_locs[iblk].loc;
size_t bnum = size_t(iblk);

for (auto atom : atoms) {
t_pb_graph_node* atom_pbgn = atom_ctx.lookup.atom_pb(atom)->pb_graph_node;
fprintf(fp, "%s %d %d %d %d #%zu %s\n", atom_ctx.nlist.block_name(atom).c_str(),
loc.x, loc.y, loc.sub_tile,
atom_pbgn->flat_site_index,
bnum,
atom_pbgn->pb_type->name);
}
}

/* prints a flat placement file */
void print_flat_placement(const char* flat_place_file) {

FILE* fp;

ClusterAtomsLookup atoms_lookup;
auto& cluster_ctx = g_vpr_ctx.clustering();

if (!g_vpr_ctx.placement().block_locs.empty()) {
fp = fopen(flat_place_file, "w");
for (auto iblk : cluster_ctx.clb_nlist.blocks()) {
auto atoms = atoms_lookup.atoms_in_cluster(iblk);
print_flat_cluster(fp, iblk, atoms);
}
fclose(fp);
}

}

/* ingests and legalizes a flat placement file */
bool load_flat_placement(t_vpr_setup& vpr_setup, const char* architecture_id) {
VTR_LOG("load_flat_placement(); when implemented, this function:");
VTR_LOG("\n\tLoads flat placement file: %s, ", vpr_setup.FileNameOpts.FlatPlaceFile.c_str());
VTR_LOG("\n\tArch id: %s, ", architecture_id);
VTR_LOG("\n\tPrints clustered netlist file: %s, ", vpr_setup.FileNameOpts.NetFile.c_str());
VTR_LOG("\n\tPrints fix clusters file: %s\n", vpr_setup.FileNameOpts.write_constraints_file.c_str());

return false;
}
16 changes: 16 additions & 0 deletions vpr/src/base/load_flat_place.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef LOAD_FLAT_PLACE_H
#define LOAD_FLAT_PLACE_H

#include "vpr_types.h"

/**
* @brief A function that prints a flat placement file
*/
void print_flat_placement(const char* flat_place_file);

/**
* @brief A function that loads and legalizes a flat placement file
*/
bool load_flat_placement(t_vpr_setup& vpr_setup, const char* archi_id);

#endif
21 changes: 21 additions & 0 deletions vpr/src/base/read_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,11 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
.action(argparse::Action::STORE_TRUE)
.default_value("off");

stage_grp.add_argument<bool, ParseOnOff>(args.do_legalize, "--legalize")
.help("Legalize a flat placement")
.action(argparse::Action::STORE_TRUE)
.default_value("off");

stage_grp.add_argument<bool, ParseOnOff>(args.do_placement, "--place")
.help("Run placement")
.action(argparse::Action::STORE_TRUE)
Expand Down Expand Up @@ -1590,6 +1595,10 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
.help("Path to packed netlist file")
.show_in(argparse::ShowIn::HELP_ONLY);

file_grp.add_argument(args.FlatPlaceFile, "--flat_place_file")
.help("Path to flat placement file")
.show_in(argparse::ShowIn::HELP_ONLY);

file_grp.add_argument(args.PlaceFile, "--place_file")
.help("Path to placement file")
.show_in(argparse::ShowIn::HELP_ONLY);
Expand Down Expand Up @@ -1627,6 +1636,18 @@ argparse::ArgumentParser create_arg_parser(const std::string& prog_name, t_optio
.help("Writes out new floorplanning constraints based on current placement to the specified XML file.")
.show_in(argparse::ShowIn::HELP_ONLY);

file_grp.add_argument(args.write_constraints_file, "--write_fix_clusters")
.help(
"Output file containing fixed locations of legalized input clusters.")
.default_value("fix_clusters.out")
.show_in(argparse::ShowIn::HELP_ONLY);

file_grp.add_argument(args.write_flat_place_file, "--write_flat_place")
.help(
"VPR's placement solution in flat placement file format.")
.default_value("flat_place.out")
.show_in(argparse::ShowIn::HELP_ONLY);

file_grp.add_argument(args.read_router_lookahead, "--read_router_lookahead")
.help(
"Reads the lookahead data from the specified file instead of computing it.")
Expand Down
4 changes: 4 additions & 0 deletions vpr/src/base/read_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ struct t_options {
argparse::ArgValue<std::string> ArchFile;
argparse::ArgValue<std::string> CircuitName;
argparse::ArgValue<std::string> NetFile;
argparse::ArgValue<std::string> FlatPlaceFile;
argparse::ArgValue<std::string> PlaceFile;
argparse::ArgValue<std::string> RouteFile;
argparse::ArgValue<std::string> CircuitFile;
Expand All @@ -30,6 +31,8 @@ struct t_options {
argparse::ArgValue<std::string> write_initial_place_file;
argparse::ArgValue<std::string> read_vpr_constraints_file;
argparse::ArgValue<std::string> write_vpr_constraints_file;
argparse::ArgValue<std::string> write_constraints_file;
argparse::ArgValue<std::string> write_flat_place_file;

argparse::ArgValue<std::string> write_placement_delay_lookup;
argparse::ArgValue<std::string> read_placement_delay_lookup;
Expand All @@ -44,6 +47,7 @@ struct t_options {

/* Stage Options */
argparse::ArgValue<bool> do_packing;
argparse::ArgValue<bool> do_legalize;
argparse::ArgValue<bool> do_placement;
argparse::ArgValue<bool> do_routing;
argparse::ArgValue<bool> do_analysis;
Expand Down
21 changes: 14 additions & 7 deletions vpr/src/base/read_place.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,8 @@ void read_place_body(std::ifstream& placement_file,
*/
void print_place(const char* net_file,
const char* net_id,
const char* place_file) {
const char* place_file,
bool is_place_file) {
FILE* fp;

auto& device_ctx = g_vpr_ctx.device();
Expand All @@ -318,15 +319,21 @@ void print_place(const char* net_file,

fp = fopen(place_file, "w");

fprintf(fp, "Netlist_File: %s Netlist_ID: %s\n",
net_file,
net_id);
fprintf(fp, "Array size: %zu x %zu logic blocks\n\n", device_ctx.grid.width(), device_ctx.grid.height());
fprintf(fp, "#block name\tx\ty\tsubblk\tlayer\tblock number\n");
fprintf(fp, "#----------\t--\t--\t------\t-----\t------------\n");
if (is_place_file) {
fprintf(fp, "Netlist_File: %s Netlist_ID: %s\n",
net_file,
net_id);
fprintf(fp, "Array size: %zu x %zu logic blocks\n\n", device_ctx.grid.width(), device_ctx.grid.height());
fprintf(fp, "#block name\tx\ty\tsubblk\tlayer\tblock number\n");
fprintf(fp, "#----------\t--\t--\t------\t-----\t------------\n");
}

if (!place_ctx.block_locs.empty()) { //Only if placement exists
for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
// if block is not placed, skip (useful for printing legalizer output)
if (!is_place_file && (place_ctx.block_locs[blk_id].loc.x == -1)) {
continue;
}
fprintf(fp, "%s\t", cluster_ctx.clb_nlist.block_pb(blk_id)->name);
if (strlen(cluster_ctx.clb_nlist.block_pb(blk_id)->name) < 8)
fprintf(fp, "\t");
Expand Down
9 changes: 8 additions & 1 deletion vpr/src/base/read_place.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,15 @@ void read_place(
*/
void read_constraints(const char* constraints_file);

/**
* This function prints out a place file.
* @param is_place_file: defaults to true. If false, does not print file header; this is useful if
* the output will be used as a constraints file. If is_place_file is false,
* net_file and net_id parameters are not used and can be set to nullptr.
*/
void print_place(const char* net_file,
const char* net_id,
const char* place_file);
const char* place_file,
bool is_place_file = true);

#endif
46 changes: 42 additions & 4 deletions vpr/src/base/vpr_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@
#include "log.h"
#include "iostream"

#include "load_flat_place.h"

#ifdef VPR_USE_TBB
# define TBB_PREVIEW_GLOBAL_CONTROL 1 /* Needed for compatibility with old TBB versions */
# include <tbb/task_arena.h>
Expand Down Expand Up @@ -393,6 +395,7 @@ bool vpr_flow(t_vpr_setup& vpr_setup, t_arch& arch) {
return false; //Unimplementable
}
}

// For the time being, we decided to create the flat graph after placement is done. Thus, the is_flat parameter for this function
//, since it is called before routing, should be false.
vpr_create_device(vpr_setup, arch, false);
Expand All @@ -410,6 +413,7 @@ bool vpr_flow(t_vpr_setup& vpr_setup, t_arch& arch) {
std::cout << "failed placement" << std::endl;
return false; //Unimplementable
}
print_flat_placement(vpr_setup.FileNameOpts.write_flat_place_file.c_str());
}
bool is_flat = vpr_setup.RouterOpts.flat_routing;
const Netlist<>& router_net_list = is_flat ? (const Netlist<>&)g_vpr_ctx.atom().nlist : (const Netlist<>&)g_vpr_ctx.clustering().clb_nlist;
Expand Down Expand Up @@ -595,6 +599,9 @@ bool vpr_pack_flow(t_vpr_setup& vpr_setup, const t_arch& arch) {
if (packer_opts.doPacking == STAGE_DO) {
//Do the actual packing
status = vpr_pack(vpr_setup, arch);
if (!status) {
return status;
}

//TODO: to be consistent with placement/routing vpr_pack should really
// load the netlist data structures itself, instead of re-loading
Expand All @@ -604,10 +611,41 @@ bool vpr_pack_flow(t_vpr_setup& vpr_setup, const t_arch& arch) {
vpr_load_packing(vpr_setup, arch);
} else {
VTR_ASSERT(packer_opts.doPacking == STAGE_LOAD);
//Load a previous packing from the .net file
vpr_load_packing(vpr_setup, arch);
//Load cluster_constraints data structure here since loading pack file
load_cluster_constraints();

// generate a .net file by legalizing an input flat placement file
if (packer_opts.load_flat_placement) {

// set up the device grid for the legalizer
auto& device_ctx = g_vpr_ctx.mutable_device();
device_ctx.arch = &arch;
device_ctx.grid = create_device_grid(vpr_setup.device_layout, arch.grid_layouts);

// load and legalize flat placement file, print .net and fix clusters files
status = load_flat_placement(vpr_setup, arch.architecture_id);
if (!status) {
return status;
}

// reset the device grid
device_ctx.grid.clear();

// if running placement, use the fix clusters file produced by the legalizer
if (vpr_setup.PlacerOpts.doPlacement) {
vpr_setup.PlacerOpts.constraints_file = vpr_setup.FileNameOpts.write_constraints_file;
}

//Load the result from the .net file
vpr_load_packing(vpr_setup, arch);

} else {

//Load a previous packing from the .net file
vpr_load_packing(vpr_setup, arch);

//Load cluster_constraints data structure here since loading pack file
load_cluster_constraints();
}

}

/* Sanity check the resulting netlist */
Expand Down
4 changes: 4 additions & 0 deletions vpr/src/base/vpr_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,7 @@ struct t_file_name_opts {
std::string CircuitName;
std::string CircuitFile;
std::string NetFile;
std::string FlatPlaceFile;
std::string PlaceFile;
std::string RouteFile;
std::string FPGAInterchangePhysicalFile;
Expand All @@ -912,6 +913,8 @@ struct t_file_name_opts {
std::string out_file_prefix;
std::string read_vpr_constraints_file;
std::string write_vpr_constraints_file;
std::string write_constraints_file;
std::string write_flat_place_file;
std::string write_block_usage;
bool verify_file_digests;
};
Expand Down Expand Up @@ -976,6 +979,7 @@ struct t_packer_opts {
bool use_attraction_groups;
int pack_num_moves;
std::string pack_move_type;
bool load_flat_placement;
};

/**
Expand Down