Skip to content

Commit 776026f

Browse files
authored
Merge pull request #1529 from Bill-hbrhbr/RefactorPlaceCpp
Refactor place.cpp Part I
2 parents 7ae49bf + 2f1b25d commit 776026f

12 files changed

+847
-600
lines changed

vpr/src/place/place.cpp

Lines changed: 58 additions & 532 deletions
Large diffs are not rendered by default.

vpr/src/place/place_delay_model.cpp

Lines changed: 98 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/**
2+
* @file place_delay_model.cpp
3+
* @brief This file implements all the class methods and individual
4+
* routines related to the placer delay model.
5+
*/
6+
17
#include <queue>
28
#include "place_delay_model.h"
39
#include "globals.h"
@@ -10,6 +16,8 @@
1016
#include "vtr_math.h"
1117
#include "vpr_error.h"
1218

19+
#include "placer_globals.h"
20+
1321
#ifdef VTR_ENABLE_CAPNPROTO
1422
# include "capnp/serialize.h"
1523
# include "place_delay_model.capnp.h"
@@ -18,10 +26,7 @@
1826
# include "serdes_utils.h"
1927
#endif /* VTR_ENABLE_CAPNPROTO */
2028

21-
/*
22-
* DeltaDelayModel
23-
*/
24-
29+
///@brief DeltaDelayModel methods.
2530
float DeltaDelayModel::delay(int from_x, int from_y, int /*from_pin*/, int to_x, int to_y, int /*to_pin*/) const {
2631
int delta_x = std::abs(from_x - to_x);
2732
int delta_y = std::abs(from_y - to_y);
@@ -46,9 +51,11 @@ void DeltaDelayModel::dump_echo(std::string filepath) const {
4651
vtr::fclose(f);
4752
}
4853

49-
/*
50-
* OverrideDelayModel
51-
*/
54+
const DeltaDelayModel* OverrideDelayModel::base_delay_model() const {
55+
return base_delay_model_.get();
56+
}
57+
58+
///@brief OverrideDelayModel methods.
5259
float OverrideDelayModel::delay(int from_x, int from_y, int from_pin, int to_x, int to_y, int to_pin) const {
5360
//First check to if there is an override delay value
5461
auto& device_ctx = g_vpr_ctx.device();
@@ -136,18 +143,14 @@ float OverrideDelayModel::get_delay_override(int from_type, int from_class, int
136143
return iter->second;
137144
}
138145

139-
const DeltaDelayModel* OverrideDelayModel::base_delay_model() const {
140-
return base_delay_model_.get();
141-
}
142-
143146
void OverrideDelayModel::set_base_delay_model(std::unique_ptr<DeltaDelayModel> base_delay_model_obj) {
144147
base_delay_model_ = std::move(base_delay_model_obj);
145148
}
146149

147-
// When writing capnp targetted serialization, always allow compilation when
148-
// VTR_ENABLE_CAPNPROTO=OFF. Generally this means throwing an exception
149-
// instead.
150-
//
150+
/**
151+
* When writing capnp targetted serialization, always allow compilation when
152+
* VTR_ENABLE_CAPNPROTO=OFF. Generally this means throwing an exception instead.
153+
*/
151154
#ifndef VTR_ENABLE_CAPNPROTO
152155

153156
# define DISABLE_ERROR \
@@ -300,3 +303,83 @@ void OverrideDelayModel::write(const std::string& file) const {
300303
}
301304

302305
#endif
306+
307+
///@brief Initialize the placer delay model.
308+
std::unique_ptr<PlaceDelayModel> alloc_lookups_and_delay_model(t_chan_width_dist chan_width_dist,
309+
const t_placer_opts& placer_opts,
310+
const t_router_opts& router_opts,
311+
t_det_routing_arch* det_routing_arch,
312+
std::vector<t_segment_inf>& segment_inf,
313+
const t_direct_inf* directs,
314+
const int num_directs) {
315+
return compute_place_delay_model(placer_opts, router_opts, det_routing_arch, segment_inf,
316+
chan_width_dist, directs, num_directs);
317+
}
318+
319+
/**
320+
* @brief Returns the delay of one point to point connection.
321+
*
322+
* Only estimate delay for signals routed through the inter-block routing network.
323+
* TODO: Do how should we compute the delay for globals. "Global signals are assumed to have zero delay."
324+
*/
325+
float comp_td_single_connection_delay(const PlaceDelayModel* delay_model, ClusterNetId net_id, int ipin) {
326+
auto& cluster_ctx = g_vpr_ctx.clustering();
327+
auto& place_ctx = g_vpr_ctx.placement();
328+
329+
float delay_source_to_sink = 0.;
330+
331+
if (!cluster_ctx.clb_nlist.net_is_ignored(net_id)) {
332+
ClusterPinId source_pin = cluster_ctx.clb_nlist.net_driver(net_id);
333+
ClusterPinId sink_pin = cluster_ctx.clb_nlist.net_pin(net_id, ipin);
334+
335+
ClusterBlockId source_block = cluster_ctx.clb_nlist.pin_block(source_pin);
336+
ClusterBlockId sink_block = cluster_ctx.clb_nlist.pin_block(sink_pin);
337+
338+
int source_block_ipin = cluster_ctx.clb_nlist.pin_logical_index(source_pin);
339+
int sink_block_ipin = cluster_ctx.clb_nlist.pin_logical_index(sink_pin);
340+
341+
int source_x = place_ctx.block_locs[source_block].loc.x;
342+
int source_y = place_ctx.block_locs[source_block].loc.y;
343+
int sink_x = place_ctx.block_locs[sink_block].loc.x;
344+
int sink_y = place_ctx.block_locs[sink_block].loc.y;
345+
346+
/**
347+
* This heuristic only considers delta_x and delta_y, a much better
348+
* heuristic would be to to create a more comprehensive lookup table.
349+
*
350+
* In particular this approach does not accurately capture the effect
351+
* of fast carry-chain connections.
352+
*/
353+
delay_source_to_sink = delay_model->delay(source_x,
354+
source_y,
355+
source_block_ipin,
356+
sink_x,
357+
sink_y,
358+
sink_block_ipin);
359+
if (delay_source_to_sink < 0) {
360+
VPR_ERROR(VPR_ERROR_PLACE,
361+
"in comp_td_single_connection_delay: Bad delay_source_to_sink value %g from %s (at %d,%d) to %s (at %d,%d)\n"
362+
"in comp_td_single_connection_delay: Delay is less than 0\n",
363+
block_type_pin_index_to_name(physical_tile_type(source_block), source_block_ipin).c_str(),
364+
source_x, source_y,
365+
block_type_pin_index_to_name(physical_tile_type(sink_block), sink_block_ipin).c_str(),
366+
sink_x, sink_y,
367+
delay_source_to_sink);
368+
}
369+
}
370+
371+
return (delay_source_to_sink);
372+
}
373+
374+
///@brief Recompute all point to point delays, updating `connection_delay` matrix.
375+
void comp_td_connection_delays(const PlaceDelayModel* delay_model) {
376+
const auto& cluster_ctx = g_vpr_ctx.clustering();
377+
auto& p_timing_ctx = g_placer_ctx.mutable_timing();
378+
auto& connection_delay = p_timing_ctx.connection_delay;
379+
380+
for (auto net_id : cluster_ctx.clb_nlist.nets()) {
381+
for (size_t ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net_id).size(); ++ipin) {
382+
connection_delay[net_id][ipin] = comp_td_single_connection_delay(delay_model, net_id, ipin);
383+
}
384+
}
385+
}

vpr/src/place/place_delay_model.h

Lines changed: 83 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
#ifndef PLACE_DELAY_MODEL_H
2-
#define PLACE_DELAY_MODEL_H
1+
/**
2+
* @file place_delay_model.h
3+
* @brief This file contains all the class and function declarations related to
4+
* the placer delay model. For implementations, see place_delay_model.cpp.
5+
*/
36

7+
#pragma once
48
#include "vtr_ndmatrix.h"
59
#include "vtr_flat_map.h"
610
#include "vpr_types.h"
@@ -20,38 +24,63 @@
2024
# define ALWAYS_INLINE inline
2125
#endif
2226

23-
//Abstract interface to a placement delay model
27+
///@brief Forward declarations.
28+
class PlaceDelayModel;
29+
30+
///@brief Initialize the placer delay model.
31+
std::unique_ptr<PlaceDelayModel> alloc_lookups_and_delay_model(t_chan_width_dist chan_width_dist,
32+
const t_placer_opts& place_opts,
33+
const t_router_opts& router_opts,
34+
t_det_routing_arch* det_routing_arch,
35+
std::vector<t_segment_inf>& segment_inf,
36+
const t_direct_inf* directs,
37+
const int num_directs);
38+
39+
///@brief Returns the delay of one point to point connection.
40+
float comp_td_single_connection_delay(const PlaceDelayModel* delay_model, ClusterNetId net_id, int ipin);
41+
42+
///@brief Recompute all point to point delays, updating `connection_delay` matrix.
43+
void comp_td_connection_delays(const PlaceDelayModel* delay_model);
44+
45+
///@brief Abstract interface to a placement delay model.
2446
class PlaceDelayModel {
2547
public:
2648
virtual ~PlaceDelayModel() = default;
2749

28-
// Computes place delay model.
50+
///@brief Computes place delay model.
2951
virtual void compute(
3052
RouterDelayProfiler& route_profiler,
3153
const t_placer_opts& placer_opts,
3254
const t_router_opts& router_opts,
3355
int longest_length)
3456
= 0;
3557

36-
//Returns the delay estimate between the specified block pins
37-
//
38-
// Either compute or read methods must be invoked before invoking
39-
// delay.
58+
/**
59+
* @brief Returns the delay estimate between the specified block pins.
60+
*
61+
* Either compute or read methods must be invoked before invoking delay.
62+
*/
4063
virtual float delay(int from_x, int from_y, int from_pin, int to_x, int to_y, int to_pin) const = 0;
4164

42-
//Dumps the delay model to an echo file
65+
///@brief Dumps the delay model to an echo file.
4366
virtual void dump_echo(std::string filename) const = 0;
4467

45-
// Write place delay model to specified file.
46-
// May be unimplemented, in which case method should throw an exception.
68+
/**
69+
* @brief Write place delay model to specified file.
70+
*
71+
* May be unimplemented, in which case method should throw an exception.
72+
*/
4773
virtual void write(const std::string& file) const = 0;
4874

49-
// Read place delay model from specified file.
50-
// May be unimplemented, in which case method should throw an exception.
75+
/**
76+
* @brief Read place delay model from specified file.
77+
*
78+
* May be unimplemented, in which case method should throw an exception.
79+
*/
5180
virtual void read(const std::string& file) = 0;
5281
};
5382

54-
//A simple delay model based on the distance (delta) between block locations
83+
///@brief A simple delay model based on the distance (delta) between block locations.
5584
class DeltaDelayModel : public PlaceDelayModel {
5685
public:
5786
DeltaDelayModel() {}
@@ -101,6 +130,21 @@ class OverrideDelayModel : public PlaceDelayModel {
101130
void compute_override_delay_model(RouterDelayProfiler& router,
102131
const t_router_opts& router_opts);
103132

133+
/**
134+
* @brief Structure that allows delays to be queried from the delay model.
135+
*
136+
* Delay is calculated given the origin physical tile, the origin
137+
* pin, the destination physical tile, and the destination pin.
138+
* This structure encapsulates all these information.
139+
*
140+
* @param from_type, to_type
141+
* Physical tile index (for easy array access)
142+
* @param from_class, to_class
143+
* The class that the pins belongs to.
144+
* @param to_x, to_y
145+
* The horizontal and vertical displacement
146+
* between two physical tiles.
147+
*/
104148
struct t_override {
105149
short from_type;
106150
short to_type;
@@ -109,10 +153,19 @@ class OverrideDelayModel : public PlaceDelayModel {
109153
short delta_x;
110154
short delta_y;
111155

112-
//A combination of ALWAYS_INLINE attribute and std::lexicographical_compare
113-
//is required for operator< to be inlined by compiler.
114-
//Proper inlining of the function reduces place time by around 5%.
115-
//For more information: https://github.com/verilog-to-routing/vtr-verilog-to-routing/issues/1225
156+
/**
157+
* @brief Comparison operator designed for performance.
158+
*
159+
* Operator< is important since t_override serves as the key into the
160+
* map structure delay_overrides_. A default comparison operator would
161+
* not be inlined by the compiler.
162+
*
163+
* A combination of ALWAYS_INLINE attribute and std::lexicographical_compare
164+
* is required for operator< to be inlined by compiler. Proper inlining of
165+
* the function reduces place time by around 5%.
166+
*
167+
* For more information: https://github.com/verilog-to-routing/vtr-verilog-to-routing/issues/1225
168+
*/
116169
friend ALWAYS_INLINE bool operator<(const t_override& lhs, const t_override& rhs) {
117170
const short* left = reinterpret_cast<const short*>(&lhs);
118171
const short* right = reinterpret_cast<const short*>(&rhs);
@@ -121,10 +174,20 @@ class OverrideDelayModel : public PlaceDelayModel {
121174
}
122175
};
123176

177+
/**
178+
* @brief Map data structure that returns delay values according to
179+
* specific delay model queries.
180+
*
181+
* Delay model queries are provided by the t_override structure, which
182+
* encapsulates the information regarding the origin and the destination.
183+
*/
124184
vtr::flat_map2<t_override, float> delay_overrides_;
125185

126-
//operator< treats memory layout of t_override as an array of short
127-
//this requires all members of t_override are shorts and there is no padding between members of t_override
186+
/**
187+
* operator< treats memory layout of t_override as an array of short.
188+
* This requires all members of t_override are shorts and there is no
189+
* padding between members of t_override.
190+
*/
128191
static_assert(sizeof(t_override) == sizeof(t_override::from_type) + sizeof(t_override::to_type) + sizeof(t_override::from_class) + sizeof(t_override::to_class) + sizeof(t_override::delta_x) + sizeof(t_override::delta_y), "Expect t_override to have a memory layout equivalent to an array of short (no padding)");
129192
static_assert(sizeof(t_override::from_type) == sizeof(short), "Expect all t_override data members to be shorts");
130193
static_assert(sizeof(t_override::to_type) == sizeof(short), "Expect all t_override data members to be shorts");
@@ -133,5 +196,3 @@ class OverrideDelayModel : public PlaceDelayModel {
133196
static_assert(sizeof(t_override::delta_x) == sizeof(short), "Expect all t_override data members to be shorts");
134197
static_assert(sizeof(t_override::delta_y) == sizeof(short), "Expect all t_override data members to be shorts");
135198
};
136-
137-
#endif

0 commit comments

Comments
 (0)