Skip to content

Fix fixed clusters issue #2495

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 21 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8f524fb
const ref and c_str
soheilshahrouz Feb 12, 2024
5d01eb3
store movable blocks in placement context
soheilshahrouz Feb 12, 2024
5a11f2b
select random blocks from movable blocks
soheilshahrouz Feb 12, 2024
433b495
make reading placement file more robust
soheilshahrouz Feb 12, 2024
3d9ebdc
Merge branch 'master' into fix_fixed_clusters_issue
soheilshahrouz Feb 24, 2024
03fce64
Merge branch 'master' into fix_fixed_clusters_issue
soheilshahrouz Apr 10, 2024
15cf98e
address PR comments
soheilshahrouz Apr 10, 2024
8bd04e4
add movable_blocks_per_type()
soheilshahrouz Apr 10, 2024
14fd2da
call create_move_generators() after initial_placement()
soheilshahrouz Apr 11, 2024
edfc3cc
remove blocks_per_type() from clustered_netlist
soheilshahrouz Apr 11, 2024
0e0c633
RL agents selects empty block type when all blocks are locked
soheilshahrouz Apr 16, 2024
a26f328
warning message to say why mismatches are ignored
soheilshahrouz Apr 17, 2024
544d175
remove unused #includes
soheilshahrouz Apr 17, 2024
ebabb0d
Merge branch 'master' into fix_fixed_clusters_issue
soheilshahrouz Apr 17, 2024
419324e
Merge branch 'master' into fix_fixed_clusters_issue
soheilshahrouz May 1, 2024
2d34797
replace unordered_map with vector for storing movable blocks for each…
soheilshahrouz May 1, 2024
5625dcb
Merge branch 'master' into fix_fixed_clusters_issue
soheilshahrouz May 31, 2024
05beae3
resolve conflicts with master
soheilshahrouz Jun 15, 2024
6fa53e1
create move generators after movable blocks are determined
soheilshahrouz Jun 24, 2024
8641b86
Merge branch 'master' into fix_fixed_clusters_issue
soheilshahrouz Jun 24, 2024
0abbaa2
update min_chan_width_routing_area_total and min_chan_width_routing_a…
soheilshahrouz Jun 24, 2024
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
2 changes: 1 addition & 1 deletion libs/libarchfpga/src/arch_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const char* get_arch_file_name() {
return arch_file_name;
}

InstPort::InstPort(std::string str) {
InstPort::InstPort(const std::string& str) {
std::vector<std::string> inst_port = vtr::split(str, ".");

if (inst_port.size() == 1) {
Expand Down
2 changes: 1 addition & 1 deletion libs/libarchfpga/src/arch_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class InstPort {
static constexpr int UNSPECIFIED = -1;

InstPort() = default;
InstPort(std::string str);
InstPort(const std::string& str);
std::string instance_name() const { return instance_.name; }
std::string port_name() const { return port_.name; }

Expand Down
149 changes: 76 additions & 73 deletions libs/libarchfpga/src/read_xml_arch_file.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion vpr/src/base/SetupVPR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ static void SetupRoutingArch(const t_arch& Arch,
RoutingArch->R_minW_pmos = Arch.R_minW_pmos;
RoutingArch->Fs = Arch.Fs;
RoutingArch->directionality = BI_DIRECTIONAL;
if (Arch.Segments.size()) {
if (!Arch.Segments.empty()) {
RoutingArch->directionality = Arch.Segments[0].directionality;
}

Expand Down
18 changes: 0 additions & 18 deletions vpr/src/base/clustered_netlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,6 @@ t_logical_block_type_ptr ClusteredNetlist::block_type(const ClusterBlockId id) c
return block_types_[id];
}

const std::vector<ClusterBlockId>& ClusteredNetlist::blocks_per_type(const t_logical_block_type& blk_type) const {
// empty vector is declared static to avoid re-allocation every time the function is called
static std::vector<ClusterBlockId> empty_vector;
if (blocks_per_type_.count(blk_type.index) == 0) {
return empty_vector;
}

// the vector is returned as const reference to avoid unnecessary copies,
// especially that returned vectors may be very large as they contain
// all clustered blocks with a specific block type
return blocks_per_type_.at(blk_type.index);
}

ClusterNetId ClusteredNetlist::block_net(const ClusterBlockId blk_id, const int logical_pin_index) const {
auto pin_id = block_pin(blk_id, logical_pin_index);

Expand Down Expand Up @@ -123,8 +110,6 @@ ClusterBlockId ClusteredNetlist::create_block(const char* name, t_pb* pb, t_logi
block_pbs_.insert(blk_id, pb);
block_types_.insert(blk_id, type);

blocks_per_type_[type->index].push_back(blk_id);

//Allocate and initialize every potential pin of the block
block_logical_pins_.insert(blk_id, std::vector<ClusterPinId>(get_max_num_pins(type), ClusterPinId::INVALID()));
}
Expand Down Expand Up @@ -185,14 +170,11 @@ ClusterNetId ClusteredNetlist::create_net(const std::string& name) {
}

void ClusteredNetlist::remove_block_impl(const ClusterBlockId blk_id) {
//find the block type, so we can remove it from blocks_per_type_ data structure
auto blk_type = block_type(blk_id);
//Remove & invalidate pointers
free_pb(block_pbs_[blk_id]);
delete block_pbs_[blk_id];
block_pbs_.insert(blk_id, NULL);
block_types_.insert(blk_id, NULL);
std::remove(blocks_per_type_[blk_type->index].begin(), blocks_per_type_[blk_type->index].end(), blk_id);
block_logical_pins_.insert(blk_id, std::vector<ClusterPinId>());
}

Expand Down
3 changes: 0 additions & 3 deletions vpr/src/base/clustered_netlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,6 @@ class ClusteredNetlist : public Netlist<ClusterBlockId, ClusterPortId, ClusterPi
///@brief Returns the type of CLB (Logic block, RAM, DSP, etc.)
t_logical_block_type_ptr block_type(const ClusterBlockId id) const;

///@brief Returns the blocks with the specific block types in the netlist
const std::vector<ClusterBlockId>& blocks_per_type(const t_logical_block_type& blk_type) const;

///@brief Returns the net of the block attached to the specific pin index
ClusterNetId block_net(const ClusterBlockId blk_id, const int pin_index) const;

Expand Down
8 changes: 4 additions & 4 deletions vpr/src/base/read_circuit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,22 +191,22 @@ static void show_circuit_stats(const AtomNetlist& netlist) {

//Determine the maximum length of a type name for nice formatting
size_t max_block_type_len = 0;
for (auto kv : block_type_counts) {
for (const auto& kv : block_type_counts) {
max_block_type_len = std::max(max_block_type_len, kv.first.size());
}
size_t max_net_type_len = 0;
for (auto kv : net_stats) {
for (const auto& kv : net_stats) {
max_net_type_len = std::max(max_net_type_len, kv.first.size());
}

//Print the statistics
VTR_LOG("Circuit Statistics:\n");
VTR_LOG(" Blocks: %zu\n", netlist.blocks().size());
for (auto kv : block_type_counts) {
for (const auto& kv : block_type_counts) {
VTR_LOG(" %-*s: %7zu\n", max_block_type_len, kv.first.c_str(), kv.second);
}
VTR_LOG(" Nets : %zu\n", netlist.nets().size());
for (auto kv : net_stats) {
for (const auto& kv : net_stats) {
VTR_LOG(" %-*s: %7.1f\n", max_net_type_len, kv.first.c_str(), kv.second);
}
VTR_LOG(" Netlist Clocks: %zu\n", find_netlist_logical_clock_drivers(netlist).size());
Expand Down
77 changes: 58 additions & 19 deletions vpr/src/base/read_place.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,12 @@ void read_place_header(std::ifstream& placement_file,
bool seen_netlist_id = false;
bool seen_grid_dimensions = false;

// store the current position in file
// if an invalid line is read, we might need to return to the beginning of that line
std::streampos file_pos = placement_file.tellg();

while (std::getline(placement_file, line) && (!seen_netlist_id || !seen_grid_dimensions)) { //Parse line-by-line
++lineno;
++lineno;

std::vector<std::string> tokens = vtr::split(line);

Expand All @@ -103,9 +107,9 @@ void read_place_header(std::ifstream& placement_file,
} else if (tokens[0][0] == '#') {
continue; //Skip commented lines

} else if (tokens.size() == 4
&& tokens[0] == "Netlist_File:"
&& tokens[2] == "Netlist_ID:") {
} else if (tokens.size() == 4 &&
tokens[0] == "Netlist_File:" &&
tokens[2] == "Netlist_ID:") {
//Check that the netlist used to generate this placement matches the one loaded
//
//NOTE: this is an optional check which causes no errors if this line is missing.
Expand All @@ -120,45 +124,76 @@ void read_place_header(std::ifstream& placement_file,
std::string place_netlist_id = tokens[3];
std::string place_netlist_file = tokens[1];

if (place_netlist_id != cluster_ctx.clb_nlist.netlist_id().c_str()) {
if (place_netlist_id != cluster_ctx.clb_nlist.netlist_id()) {
auto msg = vtr::string_fmt(
"The packed netlist file that generated placement (File: '%s' ID: '%s')"
" does not match current netlist (File: '%s' ID: '%s')",
place_netlist_file.c_str(), place_netlist_id.c_str(),
net_file, cluster_ctx.clb_nlist.netlist_id().c_str());
if (verify_file_digests) {
msg += " To ignore the packed netlist mismatch, use '--verify_file_digests off' command line option.";
vpr_throw(VPR_ERROR_PLACE_F, place_file, lineno, msg.c_str());
} else {
VTR_LOGF_WARN(place_file, lineno, "%s\n", msg.c_str());
VTR_LOG_WARN("The packed netlist mismatch is ignored because"
"--verify_file_digests command line option is off.");
}
}

seen_netlist_id = true;

} else if (tokens.size() == 7
&& tokens[0] == "Array"
&& tokens[1] == "size:"
&& tokens[3] == "x"
&& tokens[5] == "logic"
&& tokens[6] == "blocks") {
} else if (tokens.size() == 7 &&
tokens[0] == "Array" &&
tokens[1] == "size:" &&
tokens[3] == "x" &&
tokens[5] == "logic" &&
tokens[6] == "blocks") {
//Load the device grid dimensions

size_t place_file_width = vtr::atou(tokens[2]);
size_t place_file_height = vtr::atou(tokens[4]);
if (grid.width() != place_file_width || grid.height() != place_file_height) {
vpr_throw(VPR_ERROR_PLACE_F, place_file, lineno,
"Current FPGA size (%d x %d) is different from size when placement generated (%d x %d)",
grid.width(), grid.height(), place_file_width, place_file_height);
auto msg = vtr::string_fmt(
"Current FPGA size (%d x %d) is different from size when placement generated (%d x %d)",
grid.width(), grid.height(), place_file_width, place_file_height);
if (verify_file_digests) {
msg += " To ignore this size mismatch, use '--verify_file_digests off' command line option.";
vpr_throw(VPR_ERROR_PLACE_F, place_file, lineno, msg.c_str());
} else {
VTR_LOGF_WARN(place_file, lineno, "%s\n", msg.c_str());
VTR_LOG_WARN("The FPGA size mismatch is ignored because"
"--verify_file_digests command line option is off.");
}
}

seen_grid_dimensions = true;

} else {
//Unrecognized
vpr_throw(VPR_ERROR_PLACE_F, place_file, lineno,
"Invalid line '%s' in placement file header",
line.c_str());
auto msg = vtr::string_fmt(
"Invalid line '%s' in placement file header. "
"Expected to see netlist filename and device size first.",
line.c_str());

if (verify_file_digests) {
msg += " To ignore this unexpected line, use '--verify_file_digests off' command line option.";
vpr_throw(VPR_ERROR_PLACE_F, place_file, lineno, msg.c_str());
} else {
VTR_LOGF_WARN(place_file, lineno, "%s\n", msg.c_str());
VTR_LOG_WARN("Unexpected line in the placement file header is ignored because"
"--verify_file_digests command line option is off.");
}

if ((tokens.size() == 4 || (tokens.size() > 4 && tokens[4][0] == '#')) ||
(tokens.size() == 5 || (tokens.size() > 5 && tokens[5][0] == '#'))) {
placement_file.seekg(file_pos);
break;
}
}

// store the current position in the file before reading the next line
// we might need to return to this position
file_pos = placement_file.tellg();
}
}

Expand Down Expand Up @@ -200,7 +235,8 @@ void read_place_body(std::ifstream& placement_file,
} else if (tokens[0][0] == '#') {
continue; //Skip commented lines

} else if ((tokens.size() == 4 || (tokens.size() > 4 && tokens[4][0] == '#')) || (tokens.size() == 5 || (tokens.size() > 5 && tokens[5][0] == '#'))) {
} else if ((tokens.size() == 4 || (tokens.size() > 4 && tokens[4][0] == '#')) ||
(tokens.size() == 5 || (tokens.size() > 5 && tokens[5][0] == '#'))) {
//Load the block location
//
// If the place file corresponds to a 3D architecture, it should contain 5 tokens of actual data, with an optional 6th (commented) token indicating VPR's internal block number.
Expand Down Expand Up @@ -250,7 +286,10 @@ void read_place_body(std::ifstream& placement_file,

//Check if block is listed multiple times with conflicting locations in constraints file
if (seen_blocks[blk_id] > 0) {
if (block_x != place_ctx.block_locs[blk_id].loc.x || block_y != place_ctx.block_locs[blk_id].loc.y || sub_tile_index != place_ctx.block_locs[blk_id].loc.sub_tile || block_layer != place_ctx.block_locs[blk_id].loc.layer) {
if (block_x != place_ctx.block_locs[blk_id].loc.x ||
block_y != place_ctx.block_locs[blk_id].loc.y ||
sub_tile_index != place_ctx.block_locs[blk_id].loc.sub_tile ||
block_layer != place_ctx.block_locs[blk_id].loc.layer) {
std::string cluster_name = cluster_ctx.clb_nlist.block_name(blk_id);
VPR_THROW(VPR_ERROR_PLACE,
"The location of cluster %s (#%d) is specified %d times in the constraints file with conflicting locations. \n"
Expand Down
18 changes: 3 additions & 15 deletions vpr/src/base/vpr_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,13 @@

#include <cstdio>
#include <cstring>
#include <ctime>
#include <chrono>
#include <cmath>
#include <sstream>

#include "vtr_assert.h"
#include "vtr_math.h"
#include "vtr_log.h"
#include "vtr_version.h"
#include "vtr_time.h"
#include "vtr_path.h"

#include "vpr_types.h"
#include "vpr_utils.h"
Expand All @@ -44,15 +40,12 @@
#include "stats.h"
#include "read_options.h"
#include "echo_files.h"
#include "read_xml_arch_file.h"
#include "SetupVPR.h"
#include "ShowSetup.h"
#include "CheckArch.h"
#include "CheckSetup.h"
#include "rr_graph.h"
#include "pb_type_graph.h"
#include "route_common.h"
#include "timing_place_lookup.h"
#include "route.h"
#include "route_export.h"
#include "vpr_api.h"
Expand All @@ -65,7 +58,6 @@
#include "concrete_timing_info.h"
#include "netlist_writer.h"
#include "AnalysisDelayCalculator.h"
#include "RoutingDelayCalculator.h"
#include "check_route.h"
#include "constant_nets.h"
#include "atom_netlist_utils.h"
Expand All @@ -86,15 +78,12 @@
#include "tatum/echo_writer.hpp"

#include "read_route.h"
#include "read_blif.h"
#include "read_place.h"

#include "arch_util.h"

#include "post_routing_pb_pin_fixup.h"

#include "log.h"
#include "iostream"

#ifdef VPR_USE_TBB
# define TBB_PREVIEW_GLOBAL_CONTROL 1 /* Needed for compatibility with old TBB versions */
Expand Down Expand Up @@ -392,7 +381,6 @@ bool vpr_flow(t_vpr_setup& vpr_setup, t_arch& arch) {
bool place_success = vpr_place_flow(placement_net_list, vpr_setup, arch);

if (!place_success) {
std::cout << "failed placement" << std::endl;
return false; //Unimplementable
}
}
Expand Down Expand Up @@ -1359,7 +1347,7 @@ bool vpr_analysis_flow(const Netlist<>& net_list,
Arch.architecture_id,
post_routing_packing_output_file_name.c_str());
} else {
VTR_LOG_WARN("Sychronization between packing and routing results is not applied due to illegal circuit implementation\n");
VTR_LOG_WARN("Synchronization between packing and routing results is not applied due to illegal circuit implementation\n");
}
VTR_LOG("\n");
}
Expand Down Expand Up @@ -1423,13 +1411,13 @@ void vpr_analysis(const Netlist<>& net_list,

//Write the post-syntesis netlist
if (vpr_setup.AnalysisOpts.gen_post_synthesis_netlist) {
netlist_writer(atom_ctx.nlist.netlist_name().c_str(), analysis_delay_calc,
netlist_writer(atom_ctx.nlist.netlist_name(), analysis_delay_calc,
vpr_setup.AnalysisOpts);
}

//Write the post-implementation merged netlist
if (vpr_setup.AnalysisOpts.gen_post_implementation_merged_netlist) {
merged_netlist_writer(atom_ctx.nlist.netlist_name().c_str(), analysis_delay_calc, vpr_setup.AnalysisOpts);
merged_netlist_writer(atom_ctx.nlist.netlist_name(), analysis_delay_calc, vpr_setup.AnalysisOpts);
}

//Do power analysis
Expand Down
8 changes: 7 additions & 1 deletion vpr/src/base/vpr_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ struct ClusteringHelperContext : public Context {
t_ext_pin_util_targets target_external_pin_util;

// During clustering, a block is related to un-clustered primitives with nets.
// This relation has three types: low fanout, high fanout, and trasitive
// This relation has three types: low fanout, high fanout, and transitive
// high_fanout_thresholds stores the threshold for nets to a block type to be considered high fanout
t_pack_high_fanout_thresholds high_fanout_thresholds;

Expand Down Expand Up @@ -386,6 +386,12 @@ struct PlacementContext : public Context {
///@brief The pl_macros array stores all the placement macros (usually carry chains).
std::vector<t_pl_macro> pl_macros;

///@brief Stores ClusterBlockId of all movable clustered blocks (blocks that are not locked down to a single location)
std::vector<ClusterBlockId> movable_blocks;

///@brief Stores ClusterBlockId of all movable clustered of each block type
std::unordered_map<int, std::vector<ClusterBlockId>> movable_blocks_per_type;

/**
* @brief Compressed grid space for each block type
*
Expand Down
Loading
Loading