|
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" |
21 | 24 |
|
22 | 25 | /**
|
23 | 26 | * @brief Prints flat placement file entries for the atoms in one placed
|
@@ -174,3 +177,114 @@ bool load_flat_placement(t_vpr_setup& vpr_setup, const t_arch& arch) {
|
174 | 177 | return false;
|
175 | 178 | }
|
176 | 179 |
|
| 180 | +void log_flat_placement_reconstruction_info( |
| 181 | + const FlatPlacementInfo& flat_placement_info, |
| 182 | + const vtr::vector_map<ClusterBlockId, t_block_loc>& block_locs, |
| 183 | + const vtr::vector<ClusterBlockId, std::unordered_set<AtomBlockId>>& atoms_lookup, |
| 184 | + const AtomLookup& lookup, |
| 185 | + const AtomNetlist& atom_netlist, |
| 186 | + const ClusteredNetlist& clustered_netlist) { |
| 187 | + // Go through each cluster and see how many clusters have atoms that |
| 188 | + // do not belong (cluster is imperfect). |
| 189 | + unsigned num_imperfect_clusters = 0; |
| 190 | + for (ClusterBlockId clb_blk_id : clustered_netlist.blocks()) { |
| 191 | + // Get the centroid of the cluster |
| 192 | + const auto& clb_atoms = atoms_lookup[clb_blk_id]; |
| 193 | + float centroid_x = 0.f; |
| 194 | + float centroid_y = 0.f; |
| 195 | + float centroid_layer = 0.f; |
| 196 | + float centroid_sub_tile = 0.f; |
| 197 | + for (AtomBlockId atom_blk_id : clb_atoms) { |
| 198 | + // TODO: Currently only handle the case when all of the position |
| 199 | + // data is provided. This can be extended, |
| 200 | + VTR_ASSERT(flat_placement_info.blk_x_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); |
| 201 | + VTR_ASSERT(flat_placement_info.blk_y_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); |
| 202 | + VTR_ASSERT(flat_placement_info.blk_layer[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); |
| 203 | + VTR_ASSERT(flat_placement_info.blk_sub_tile[atom_blk_id] != FlatPlacementInfo::UNDEFINED_SUB_TILE); |
| 204 | + |
| 205 | + centroid_x += flat_placement_info.blk_x_pos[atom_blk_id]; |
| 206 | + centroid_y += flat_placement_info.blk_y_pos[atom_blk_id]; |
| 207 | + centroid_layer += flat_placement_info.blk_layer[atom_blk_id]; |
| 208 | + centroid_sub_tile += flat_placement_info.blk_sub_tile[atom_blk_id]; |
| 209 | + } |
| 210 | + centroid_x /= static_cast<float>(clb_atoms.size()); |
| 211 | + centroid_y /= static_cast<float>(clb_atoms.size()); |
| 212 | + centroid_layer /= static_cast<float>(clb_atoms.size()); |
| 213 | + centroid_sub_tile /= static_cast<float>(clb_atoms.size()); |
| 214 | + // Check if every atom in the cluster is within 0.5 units of the |
| 215 | + // centroid. |
| 216 | + for (AtomBlockId atom_blk_id : clb_atoms) { |
| 217 | + // If the atom's flat placement more than half a block in any |
| 218 | + // direction from the flat placement centroid, then it does not |
| 219 | + // want to be in this cluster. |
| 220 | + if (std::abs(centroid_x - flat_placement_info.blk_x_pos[atom_blk_id]) > 0.5f || |
| 221 | + std::abs(centroid_y - flat_placement_info.blk_y_pos[atom_blk_id]) > 0.5f || |
| 222 | + std::abs(centroid_layer - flat_placement_info.blk_layer[atom_blk_id]) > 0.5f || |
| 223 | + std::abs(centroid_sub_tile - flat_placement_info.blk_sub_tile[atom_blk_id]) > 0.5f) { |
| 224 | + num_imperfect_clusters++; |
| 225 | + break; |
| 226 | + } |
| 227 | + } |
| 228 | + } |
| 229 | + // Go through each atom and compute how much it has displaced and count |
| 230 | + // how many have been displaced beyond some threshold. |
| 231 | + constexpr float disp_threashold = 0.5f; |
| 232 | + float total_disp = 0; |
| 233 | + unsigned num_atoms_missplaced = 0; |
| 234 | + for (AtomBlockId atom_blk_id : atom_netlist.blocks()) { |
| 235 | + // TODO: Currently only handle the case when all of the position |
| 236 | + // data is provided. This can be extended, |
| 237 | + VTR_ASSERT(flat_placement_info.blk_x_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); |
| 238 | + VTR_ASSERT(flat_placement_info.blk_y_pos[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); |
| 239 | + VTR_ASSERT(flat_placement_info.blk_layer[atom_blk_id] != FlatPlacementInfo::UNDEFINED_POS); |
| 240 | + VTR_ASSERT(flat_placement_info.blk_sub_tile[atom_blk_id] != FlatPlacementInfo::UNDEFINED_SUB_TILE); |
| 241 | + |
| 242 | + // Get the (x, y, layer) position of the block. |
| 243 | + int blk_x = flat_placement_info.blk_x_pos[atom_blk_id]; |
| 244 | + int blk_y = flat_placement_info.blk_y_pos[atom_blk_id]; |
| 245 | + int blk_layer = flat_placement_info.blk_layer[atom_blk_id]; |
| 246 | + |
| 247 | + // Get the (x, y, layer) position of the cluster that contains this block. |
| 248 | + ClusterBlockId atom_clb_id = lookup.atom_clb(atom_blk_id); |
| 249 | + const t_block_loc& clb_loc = block_locs[atom_clb_id]; |
| 250 | + |
| 251 | + // Compute the distance between these two positions. |
| 252 | + float dx = blk_x - clb_loc.loc.x; |
| 253 | + float dy = blk_y - clb_loc.loc.y; |
| 254 | + float dlayer = blk_layer - clb_loc.loc.layer; |
| 255 | + float dist = std::sqrt((dx * dx) + (dy * dy) + (dlayer * dlayer)); |
| 256 | + |
| 257 | + // Accumulate into the total displacement. |
| 258 | + total_disp += dist; |
| 259 | + |
| 260 | + // Check if this block has been displaced beyond the threshold. |
| 261 | + if (dist >= disp_threashold) { |
| 262 | + num_atoms_missplaced++; |
| 263 | + } |
| 264 | + |
| 265 | + // TODO: Make this debug option of higher verbosity. Helpful for |
| 266 | + // debugging flat placement reconstruction. |
| 267 | + /* |
| 268 | + VTR_LOG("%s %d %d %d %d\n", |
| 269 | + g_vpr_ctx.atom().nlist.block_name(atom_blk_id).c_str(), |
| 270 | + clb_loc.loc.x, |
| 271 | + clb_loc.loc.y, |
| 272 | + clb_loc.loc.layer, |
| 273 | + clb_loc.loc.sub_tile); |
| 274 | + */ |
| 275 | + } |
| 276 | + |
| 277 | + // Log the flat placement reconstruction info. |
| 278 | + size_t num_atoms = atom_netlist.blocks().size(); |
| 279 | + size_t num_clusters = clustered_netlist.blocks().size(); |
| 280 | + VTR_LOG("Flat Placement Reconstruction Info:\n"); |
| 281 | + VTR_LOG("\tPercent of clusters with reconstruction errors: %f\n", |
| 282 | + static_cast<float>(num_imperfect_clusters) / static_cast<float>(num_clusters)); |
| 283 | + VTR_LOG("\tTotal displacement of initial placement from flat placement: %f\n", |
| 284 | + total_disp); |
| 285 | + VTR_LOG("\tAverage atom displacement of initial placement from flat placement: %f\n", |
| 286 | + total_disp / static_cast<float>(num_atoms)); |
| 287 | + VTR_LOG("\tPercent of atoms misplaced from the flat placement: %f\n", |
| 288 | + static_cast<float>(num_atoms_missplaced) / static_cast<float>(num_atoms)); |
| 289 | +} |
| 290 | + |
0 commit comments