|
10 | 10 |
|
11 | 11 | #include <fstream>
|
12 | 12 | #include <unordered_set>
|
| 13 | +#include "atom_lookup.h" |
13 | 14 | #include "atom_netlist.h"
|
14 | 15 | #include "clustered_netlist.h"
|
15 | 16 | #include "FlatPlacementInfo.h"
|
16 | 17 | #include "globals.h"
|
17 | 18 | #include "vpr_context.h"
|
18 | 19 | #include "vpr_error.h"
|
19 | 20 | #include "vpr_types.h"
|
| 21 | +#include "vtr_assert.h" |
20 | 22 | #include "vtr_log.h"
|
| 23 | +#include "vtr_vector_map.h" |
| 24 | +#include "vtr_version.h" |
| 25 | + |
| 26 | +/** |
| 27 | + * @brief Prints the header for the flat placement file. This includes helpful |
| 28 | + * information on how to read the file and when it was generated. |
| 29 | + * |
| 30 | + * @param fp |
| 31 | + * File pointer to the file the cluster is printed to. |
| 32 | + */ |
| 33 | +static void print_flat_placement_file_header(FILE* fp) { |
| 34 | + fprintf(fp, "# Flat Placement File\n"); |
| 35 | + fprintf(fp, "# Auto-generated by VPR %s\n", |
| 36 | + vtr::VERSION); |
| 37 | + fprintf(fp, "# Created: %s\n", |
| 38 | + vtr::BUILD_TIMESTAMP); |
| 39 | + fprintf(fp, "#\n"); |
| 40 | + fprintf(fp, "# This file prints the following information for each atom in the netlist:\n"); |
| 41 | + fprintf(fp, "# <atom_name> <x> <y> <layer> <atom_sub_tile> <atom_site_idx> #<clb_blk_id> <atom_pb_type>\n"); |
| 42 | + fprintf(fp, "\n"); |
| 43 | +} |
21 | 44 |
|
22 | 45 | /**
|
23 | 46 | * @brief Prints flat placement file entries for the atoms in one placed
|
@@ -73,6 +96,9 @@ void write_flat_placement(const char* flat_place_file_path,
|
73 | 96 | // Create a file in write mode for the flat placement.
|
74 | 97 | FILE* fp = fopen(flat_place_file_path, "w");
|
75 | 98 |
|
| 99 | + // Add a header to the flat placement file. |
| 100 | + print_flat_placement_file_header(fp); |
| 101 | + |
76 | 102 | // For each cluster, write out the atoms in the cluster at this cluster's
|
77 | 103 | // location.
|
78 | 104 | for (ClusterBlockId iblk : cluster_netlist.blocks()) {
|
@@ -174,3 +200,118 @@ bool load_flat_placement(t_vpr_setup& vpr_setup, const t_arch& arch) {
|
174 | 200 | return false;
|
175 | 201 | }
|
176 | 202 |
|
| 203 | +void log_flat_placement_reconstruction_info( |
| 204 | + const FlatPlacementInfo& flat_placement_info, |
| 205 | + const vtr::vector_map<ClusterBlockId, t_block_loc>& block_locs, |
| 206 | + const vtr::vector<ClusterBlockId, std::unordered_set<AtomBlockId>>& atoms_lookup, |
| 207 | + const AtomLookup& cluster_of_atom_lookup, |
| 208 | + const AtomNetlist& atom_netlist, |
| 209 | + const ClusteredNetlist& clustered_netlist) { |
| 210 | + // Go through each cluster and see how many clusters have atoms that |
| 211 | + // do not belong (cluster is imperfect). |
| 212 | + unsigned num_imperfect_clusters = 0; |
| 213 | + for (ClusterBlockId clb_blk_id : clustered_netlist.blocks()) { |
| 214 | + // Get the centroid of the cluster |
| 215 | + const auto& clb_atoms = atoms_lookup[clb_blk_id]; |
| 216 | + float centroid_x = 0.f; |
| 217 | + float centroid_y = 0.f; |
| 218 | + float centroid_layer = 0.f; |
| 219 | + float centroid_sub_tile = 0.f; |
| 220 | + for (AtomBlockId atom_blk_id : clb_atoms) { |
| 221 | + // TODO: Currently only handle the case when all of the position |
| 222 | + // data is provided. This can be extended, |
| 223 | + VTR_ASSERT(flat_placement_info.blk_x_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); |
| 224 | + VTR_ASSERT(flat_placement_info.blk_y_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); |
| 225 | + VTR_ASSERT(flat_placement_info.blk_layer[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); |
| 226 | + VTR_ASSERT(flat_placement_info.blk_sub_tile[atom_blk_id] != FlatPlacementInfo::UNDEFINED_SUB_TILE); |
| 227 | + |
| 228 | + centroid_x += flat_placement_info.blk_x_pos[atom_blk_id]; |
| 229 | + centroid_y += flat_placement_info.blk_y_pos[atom_blk_id]; |
| 230 | + centroid_layer += flat_placement_info.blk_layer[atom_blk_id]; |
| 231 | + centroid_sub_tile += flat_placement_info.blk_sub_tile[atom_blk_id]; |
| 232 | + } |
| 233 | + centroid_x /= static_cast<float>(clb_atoms.size()); |
| 234 | + centroid_y /= static_cast<float>(clb_atoms.size()); |
| 235 | + centroid_layer /= static_cast<float>(clb_atoms.size()); |
| 236 | + centroid_sub_tile /= static_cast<float>(clb_atoms.size()); |
| 237 | + // Check if every atom in the cluster is within 0.5 units of the |
| 238 | + // centroid. |
| 239 | + for (AtomBlockId atom_blk_id : clb_atoms) { |
| 240 | + // If the atom's flat placement more than half a block in any |
| 241 | + // direction from the flat placement centroid, then it does not |
| 242 | + // want to be in this cluster. |
| 243 | + // FIXME: This should take into account large blocks somehow, just |
| 244 | + // being 0.5 tiles away may not be sufficient. |
| 245 | + if (std::abs(centroid_x - flat_placement_info.blk_x_pos[atom_blk_id]) > 0.5f || |
| 246 | + std::abs(centroid_y - flat_placement_info.blk_y_pos[atom_blk_id]) > 0.5f || |
| 247 | + std::abs(centroid_layer - flat_placement_info.blk_layer[atom_blk_id]) > 0.5f || |
| 248 | + std::abs(centroid_sub_tile - flat_placement_info.blk_sub_tile[atom_blk_id]) > 0.5f) { |
| 249 | + num_imperfect_clusters++; |
| 250 | + break; |
| 251 | + } |
| 252 | + } |
| 253 | + } |
| 254 | + // Go through each atom and compute how much it has displaced and count |
| 255 | + // how many have been displaced beyond some threshold. |
| 256 | + constexpr float disp_threashold = 0.5f; |
| 257 | + float total_disp = 0; |
| 258 | + unsigned num_atoms_missplaced = 0; |
| 259 | + for (AtomBlockId atom_blk_id : atom_netlist.blocks()) { |
| 260 | + // TODO: Currently only handle the case when all of the position |
| 261 | + // data is provided. This can be extended, |
| 262 | + VTR_ASSERT(flat_placement_info.blk_x_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); |
| 263 | + VTR_ASSERT(flat_placement_info.blk_y_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); |
| 264 | + VTR_ASSERT(flat_placement_info.blk_layer[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); |
| 265 | + VTR_ASSERT(flat_placement_info.blk_sub_tile[atom_blk_id] != FlatPlacementInfo::UNDEFINED_SUB_TILE); |
| 266 | + |
| 267 | + // Get the (x, y, layer) position of the block. |
| 268 | + int blk_x = flat_placement_info.blk_x_pos[atom_blk_id]; |
| 269 | + int blk_y = flat_placement_info.blk_y_pos[atom_blk_id]; |
| 270 | + int blk_layer = flat_placement_info.blk_layer[atom_blk_id]; |
| 271 | + |
| 272 | + // Get the (x, y, layer) position of the cluster that contains this block. |
| 273 | + ClusterBlockId atom_clb_id = cluster_of_atom_lookup.atom_clb(atom_blk_id); |
| 274 | + const t_block_loc& clb_loc = block_locs[atom_clb_id]; |
| 275 | + |
| 276 | + // Compute the distance between these two positions. |
| 277 | + // FIXME: This will overreport large blocks. This should really be |
| 278 | + // the distance outside of the tile you want to be placed in. |
| 279 | + float dx = blk_x - clb_loc.loc.x; |
| 280 | + float dy = blk_y - clb_loc.loc.y; |
| 281 | + float dlayer = blk_layer - clb_loc.loc.layer; |
| 282 | + float dist = std::sqrt((dx * dx) + (dy * dy) + (dlayer * dlayer)); |
| 283 | + |
| 284 | + // Accumulate into the total displacement. |
| 285 | + total_disp += dist; |
| 286 | + |
| 287 | + // Check if this block has been displaced beyond the threshold. |
| 288 | + if (dist >= disp_threashold) { |
| 289 | + num_atoms_missplaced++; |
| 290 | + } |
| 291 | + |
| 292 | + // TODO: Make this debug option of higher verbosity. Helpful for |
| 293 | + // debugging flat placement reconstruction. |
| 294 | + /* |
| 295 | + VTR_LOG("%s %d %d %d %d\n", |
| 296 | + g_vpr_ctx.atom().nlist.block_name(atom_blk_id).c_str(), |
| 297 | + clb_loc.loc.x, |
| 298 | + clb_loc.loc.y, |
| 299 | + clb_loc.loc.layer, |
| 300 | + clb_loc.loc.sub_tile); |
| 301 | + */ |
| 302 | + } |
| 303 | + |
| 304 | + // Log the flat placement reconstruction info. |
| 305 | + size_t num_atoms = atom_netlist.blocks().size(); |
| 306 | + size_t num_clusters = clustered_netlist.blocks().size(); |
| 307 | + VTR_LOG("Flat Placement Reconstruction Info:\n"); |
| 308 | + VTR_LOG("\tPercent of clusters with reconstruction errors: %f\n", |
| 309 | + static_cast<float>(num_imperfect_clusters) / static_cast<float>(num_clusters)); |
| 310 | + VTR_LOG("\tTotal displacement of initial placement from flat placement: %f\n", |
| 311 | + total_disp); |
| 312 | + VTR_LOG("\tAverage atom displacement of initial placement from flat placement: %f\n", |
| 313 | + total_disp / static_cast<float>(num_atoms)); |
| 314 | + VTR_LOG("\tPercent of atoms misplaced from the flat placement: %f\n", |
| 315 | + static_cast<float>(num_atoms_missplaced) / static_cast<float>(num_atoms)); |
| 316 | +} |
| 317 | + |
0 commit comments