Skip to content

Commit ab25381

Browse files
Merge pull request #2934 from AlexandreSinger/feature-appack
[APPack] Updated How APPack Adheres to Given Placement
2 parents 3a19e8d + 47fca21 commit ab25381

27 files changed

+450
-213
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: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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) + std::abs(loc_a.y - loc_b.y) + std::abs(loc_a.layer - loc_b.layer);
20+
}

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/appack_context.h

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/**
2+
* @file
3+
* @author Alex Siner
4+
* @date March 2025
5+
* @brief Declaration of the APPack Context object which stores all the
6+
* information used to configure APPack in the packer.
7+
*/
8+
9+
#pragma once
10+
11+
#include <algorithm>
12+
#include <limits>
13+
#include "device_grid.h"
14+
#include "flat_placement_types.h"
15+
#include "vpr_context.h"
16+
17+
/**
18+
* @brief Configuration options for APPack.
19+
*
20+
* APPack is an upgrade to the AAPack algorithm which uses an atom-level placement
21+
* to inform the packer into creating better clusters. These options configure
22+
* how APPack interprets the flat placement information.
23+
*/
24+
struct t_appack_options {
25+
// Constructor for the appack options.
26+
t_appack_options(const FlatPlacementInfo& flat_placement_info,
27+
const DeviceGrid& device_grid) {
28+
// If the flat placement info is valid, we want to use APPack.
29+
// TODO: Should probably check that all the information is valid here.
30+
use_appack = flat_placement_info.valid;
31+
32+
// Set the max candidate distance as being some fraction of the longest
33+
// distance on the device (from the bottom corner to the top corner).
34+
// We also use an offset for the minimum this distance can be to prevent
35+
// small devices from finding candidates.
36+
float max_candidate_distance_scale = 0.5f;
37+
float max_candidate_distance_offset = 20.f;
38+
// Longest L1 distance on the device.
39+
float longest_distance = device_grid.width() + device_grid.height();
40+
max_candidate_distance = std::max(max_candidate_distance_scale * longest_distance,
41+
max_candidate_distance_offset);
42+
}
43+
44+
// Whether to use APPack or not.
45+
// This is initialized in the constructor based on if the flat placement
46+
// info is valid or not.
47+
bool use_appack = false;
48+
49+
// =========== Cluster location ======================================== //
50+
// What is the location of the cluster being created relative to the
51+
// molecules being packed into it.
52+
enum class e_cl_loc_ty {
53+
CENTROID, /**< The location of the cluster is the centroid of the molecules which have been packed into it. */
54+
SEED /**< The location of the cluster is the location of the first molecule packed into it. */
55+
};
56+
e_cl_loc_ty cluster_location_ty = e_cl_loc_ty::CENTROID;
57+
58+
// =========== Candidate gain attenuation ============================== //
59+
// These terms are used to update the gain of a given candidate based on
60+
// its distance (d) relative to the location of the cluster being constructed.
61+
// gain_new = attenuation * gain_original
62+
// We use the following gain attenuation function:
63+
// attenuation = { 1 - (quad_fac * d)^2 if d < dist_th
64+
// { 1 / sqrt(d - sqrt_offset) if d >= dist_th
65+
// Distance threshold which decides when to use quadratic decay or inverted
66+
// sqrt decay. If the distance is less than this threshold, quadratic decay
67+
// is used. Inverted sqrt is used otherwise.
68+
float dist_th = 1.0f;
69+
// Horizontal offset to the inverted sqrt decay.
70+
float sqrt_offset = -2.9f;
71+
// Scaling factor for the quadratic decay term.
72+
float quad_fac = 0.7f;
73+
74+
// =========== Candidate selection distance ============================ //
75+
// When selecting candidates, what distance from the cluster will we
76+
// consider? Any candidate beyond this distance will not be proposed.
77+
// This is set in the constructor.
78+
// TODO: It may be a good idea to have max different distances for different
79+
// types of molecules / clusters. For example, CLBs vs DSPs
80+
float max_candidate_distance = std::numeric_limits<float>::max();
81+
82+
// TODO: Investigate adding flat placement info to unrelated clustering.
83+
84+
// TODO: Investigate adding flat placement info to seed selection.
85+
};
86+
87+
/**
88+
* @brief State relating to APPack.
89+
*
90+
* This class is intended to contain information on using flat placement
91+
* information in packing.
92+
*/
93+
struct APPackContext : public Context {
94+
/**
95+
* @brief Constructor for the APPack context.
96+
*/
97+
APPackContext(const FlatPlacementInfo& fplace_info, const DeviceGrid& device_grid)
98+
: appack_options(fplace_info, device_grid)
99+
, flat_placement_info(fplace_info) {}
100+
101+
/**
102+
* @brief Options used to configure APPack.
103+
*/
104+
t_appack_options appack_options;
105+
106+
/**
107+
* @brief The flat placement information passed into APPack.
108+
*/
109+
const FlatPlacementInfo& flat_placement_info;
110+
};

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)