Skip to content

Commit ff26e38

Browse files
[APPack] Updated How APPack Adheres to Given Placement
The original implementation of APPack was focused on reconstructing a given flat placement. This can cause issues if the given flat placement disagrees with the decisions of the packer. Instead, updated APPack so that it treats the flat placement as a hint to help guide how it performs clustering. Added the following new features: - APPack computes the location of clusters based on the centroid of the molecules packed within. - APPack attenuates the gain terms of candidates based on their distance from the cluster. - APPack drops candidates which are too far from the cluster being created. Remove adding molecules near to the position of the cluster. This had similar affects to unrelated clustering and should be investigated separately later. With these changes to APPack, the AP flow now improves WL of circuits by 1-3% at the expense of up to 15% runtime compared to the default VPR flow.
1 parent ba2c1dd commit ff26e38

26 files changed

+402
-171
lines changed

vpr/src/analytical_place/detailed_placer.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77

88
#include "detailed_placer.h"
99
#include <memory>
10-
#include "FlatPlacementInfo.h"
1110
#include "PlacementDelayModelCreator.h"
1211
#include "ap_flow_enums.h"
1312
#include "atom_netlist.h"
1413
#include "clustered_netlist.h"
1514
#include "clustered_netlist_utils.h"
1615
#include "echo_files.h"
16+
#include "flat_placement_types.h"
1717
#include "globals.h"
1818
#include "physical_types.h"
1919
#include "place_and_route.h"
@@ -22,6 +22,7 @@
2222
#include "vpr_error.h"
2323
#include "vpr_types.h"
2424
#include "vpr_utils.h"
25+
#include "vtr_time.h"
2526

2627
std::unique_ptr<DetailedPlacer> make_detailed_placer(e_ap_detailed_placer detailed_placer_type,
2728
const BlkLocRegistry& curr_clustered_placement,
@@ -89,6 +90,9 @@ AnnealerDetailedPlacer::AnnealerDetailedPlacer(const BlkLocRegistry& curr_cluste
8990
}
9091

9192
void AnnealerDetailedPlacer::optimize_placement() {
93+
// Create a scoped timer for the detailed placer.
94+
vtr::ScopedStartFinishTimer full_legalizer_timer("AP Detailed Placer");
95+
9296
// Prevent the annealer from directly modifying the global legal placement.
9397
// It should only modify its own, local placement.
9498
g_vpr_ctx.mutable_placement().lock_loc_vars();

vpr/src/analytical_place/full_legalizer.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,23 @@
1616
#include <unordered_set>
1717
#include <vector>
1818

19-
#include "FlatPlacementInfo.h"
20-
#include "ap_flow_enums.h"
21-
#include "blk_loc_registry.h"
22-
#include "device_grid.h"
23-
#include "load_flat_place.h"
24-
#include "noc_place_utils.h"
25-
#include "partial_placement.h"
2619
#include "ShowSetup.h"
20+
#include "ap_flow_enums.h"
2721
#include "ap_netlist_fwd.h"
22+
#include "blk_loc_registry.h"
2823
#include "check_netlist.h"
2924
#include "cluster_legalizer.h"
3025
#include "cluster_util.h"
3126
#include "clustered_netlist.h"
27+
#include "device_grid.h"
28+
#include "flat_placement_types.h"
3229
#include "globals.h"
3330
#include "initial_placement.h"
31+
#include "load_flat_place.h"
3432
#include "logic_types.h"
33+
#include "noc_place_utils.h"
3534
#include "pack.h"
35+
#include "partial_placement.h"
3636
#include "physical_types.h"
3737
#include "place.h"
3838
#include "place_and_route.h"

vpr/src/analytical_place/global_placer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,24 @@ SimPLGlobalPlacer::SimPLGlobalPlacer(e_partial_legalizer partial_legalizer_type,
6969
// This can be a long method. Good to time this to see how long it takes to
7070
// construct the global placer.
7171
vtr::ScopedStartFinishTimer global_placer_building_timer("Constructing Global Placer");
72+
7273
// Build the solver.
74+
VTR_LOGV(log_verbosity_ >= 10, "\tBuilding the solver...\n");
7375
solver_ = make_analytical_solver(e_analytical_solver::QP_HYBRID,
7476
ap_netlist_);
77+
7578
// Build the density manager used by the partial legalizer.
79+
VTR_LOGV(log_verbosity_ >= 10, "\tBuilding the density manager...\n");
7680
density_manager_ = std::make_shared<FlatPlacementDensityManager>(ap_netlist_,
7781
prepacker,
7882
atom_netlist,
7983
device_grid,
8084
logical_block_types,
8185
physical_tile_types,
8286
log_verbosity_);
87+
8388
// Build the partial legalizer
89+
VTR_LOGV(log_verbosity_ >= 10, "\tBuilding the partial legalizer...\n");
8490
partial_legalizer_ = make_partial_legalizer(partial_legalizer_type,
8591
ap_netlist_,
8692
density_manager_,

vpr/src/base/FlatPlacementInfo.h renamed to vpr/src/base/flat_placement_types.h

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,54 @@
11
/**
22
* @file
33
* @author Alex Singer
4-
* @date January 2025
5-
* @brief Declaration of the FlatPlacementInfo object, which is used to store
6-
* flat placement information used by the packer.
4+
* @date March 2025
5+
* @brief Declaration of flat placement types used throughout VPR.
76
*/
87

98
#pragma once
109

1110
#include "atom_netlist.h"
11+
#include "vtr_assert.h"
1212
#include "vtr_vector.h"
1313

14+
/**
15+
* @brief A structure representing a flat placement location on the device.
16+
*
17+
* This is related to the t_pl_loc type; however this uses floating point
18+
* coordinates, allowing for blocks to be placed in illegal positions.
19+
*/
20+
struct t_flat_pl_loc {
21+
float x; /**< The x-coordinate of the location. */
22+
float y; /**< The y-coordinate of the location. */
23+
float layer; /**< The layer of the location. */
24+
25+
/**
26+
* @brief Adds the coordinates of another t_flat_pl_loc to this one.
27+
*
28+
* @param other The other t_flat_pl_loc whose coordinates are to be added.
29+
* @return A reference to this t_flat_pl_loc after addition.
30+
*/
31+
t_flat_pl_loc& operator+=(const t_flat_pl_loc& other) {
32+
x += other.x;
33+
y += other.y;
34+
layer += other.layer;
35+
return *this;
36+
}
37+
38+
/**
39+
* @brief Divides the coordinates of this t_flat_pl_loc by a divisor.
40+
*
41+
* @param divisor The value by which to divide the coordinates.
42+
* @return A reference to this t_flat_pl_loc after division.
43+
*/
44+
t_flat_pl_loc& operator/=(float divisor) {
45+
x /= divisor;
46+
y /= divisor;
47+
layer /= divisor;
48+
return *this;
49+
}
50+
};
51+
1452
/**
1553
* @brief Flat placement storage class.
1654
*
@@ -55,6 +93,15 @@ class FlatPlacementInfo {
5593
/// object, false otherwise.
5694
bool valid;
5795

96+
/**
97+
* @brief Get the flat placement location of the given atom block.
98+
*/
99+
inline t_flat_pl_loc get_pos(AtomBlockId blk_id) const {
100+
VTR_ASSERT_SAFE_MSG(blk_id.is_valid(), "Block ID is invalid");
101+
VTR_ASSERT_SAFE_MSG(valid, "FlatPlacementInfo not initialized");
102+
return {blk_x_pos[blk_id], blk_y_pos[blk_id], blk_layer[blk_id]};
103+
}
104+
58105
/**
59106
* @brief Default constructor of this class.
60107
*

vpr/src/base/flat_placement_utils.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @file
3+
* @author Alex Singer
4+
* @date March 2025
5+
* @brief Utility methods for working with flat placements.
6+
*/
7+
8+
#pragma once
9+
10+
#include <cstdlib>
11+
#include "flat_placement_types.h"
12+
13+
/**
14+
* @brief Returns the manhattan distance (L1 distance) between two flat
15+
* placement locations.
16+
*/
17+
inline float get_manhattan_distance(const t_flat_pl_loc& loc_a,
18+
const t_flat_pl_loc& loc_b) {
19+
return std::abs(loc_a.x - loc_b.x) +
20+
std::abs(loc_a.y - loc_b.y) +
21+
std::abs(loc_a.layer - loc_b.layer);
22+
}

vpr/src/base/load_flat_place.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include "atom_lookup.h"
1515
#include "atom_netlist.h"
1616
#include "clustered_netlist.h"
17-
#include "FlatPlacementInfo.h"
17+
#include "flat_placement_types.h"
1818
#include "globals.h"
1919
#include "vpr_context.h"
2020
#include "vpr_error.h"

vpr/src/base/place_and_route.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include <cmath>
55
#include <algorithm>
66

7-
#include "FlatPlacementInfo.h"
7+
#include "flat_placement_types.h"
88
#include "place_macro.h"
99
#include "vtr_assert.h"
1010
#include "vtr_log.h"

vpr/src/base/vpr_api.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include <memory>
1818
#include <vector>
1919

20-
#include "FlatPlacementInfo.h"
20+
#include "flat_placement_types.h"
2121
#include "cluster_util.h"
2222
#include "physical_types.h"
2323
#include "place_macro.h"

vpr/src/base/vpr_context.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include <vector>
66
#include <mutex>
77

8-
#include "FlatPlacementInfo.h"
8+
#include "flat_placement_types.h"
99
#include "physical_types.h"
1010
#include "place_macro.h"
1111
#include "user_place_constraints.h"

vpr/src/pack/cluster_legalizer.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,13 @@ class ClusterLegalizer {
445445
return cluster.pr;
446446
}
447447

448+
/// @brief Gets the molecules currently packed within the given cluster.
449+
inline const std::vector<PackMoleculeId>& get_cluster_molecules(LegalizationClusterId cluster_id) const {
450+
VTR_ASSERT_SAFE(cluster_id.is_valid() && (size_t)cluster_id < legalization_clusters_.size());
451+
const LegalizationCluster& cluster = legalization_clusters_[cluster_id];
452+
return cluster.molecules;
453+
}
454+
448455
/// @brief Gets the current number of molecules in the cluster.
449456
inline size_t get_num_molecules_in_cluster(LegalizationClusterId cluster_id) const {
450457
VTR_ASSERT_SAFE(cluster_id.is_valid() && (size_t)cluster_id < legalization_clusters_.size());

0 commit comments

Comments
 (0)