Skip to content

Commit 4aa2cfb

Browse files
[AP] Testing Infrastructure
Added changes required to test the AP Flow on the MCNC and VTR benchmarks. This creates fixed device sizes for each benchmark which can be used to fairly compare the AP Flow to the default VTR flow. Added the currently passing MCNC and VTR benchmarks to the strong tests to lock in the AP flow. It is a bit unstable right now until the full legalizer is put in. May need to disable a few of the tests.
1 parent 2586a98 commit 4aa2cfb

22 files changed

+6553
-3
lines changed

vpr/src/analytical_place/full_legalizer.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "logic_types.h"
2727
#include "pack.h"
2828
#include "physical_types.h"
29+
#include "place_and_route.h"
2930
#include "place_constraints.h"
3031
#include "place_macro.h"
3132
#include "verify_clustering.h"
@@ -103,9 +104,6 @@ class APClusterPlacer {
103104
g_vpr_ctx.mutable_placement().cube_bb = false;
104105
g_vpr_ctx.mutable_placement().compressed_block_grids = create_compressed_block_grids();
105106

106-
// Initialize the macros
107-
blk_loc_registry.mutable_place_macros().alloc_and_load_placement_macros(directs);
108-
109107
// TODO: The next few steps will be basically a direct copy of the initial
110108
// placement code since it does everything we need! It would be nice
111109
// to share the code.
@@ -133,6 +131,13 @@ class APClusterPlacer {
133131
const ClusteringContext& cluster_ctx = g_vpr_ctx.clustering();
134132
const auto& block_locs = g_vpr_ctx.placement().block_locs();
135133
auto& blk_loc_registry = g_vpr_ctx.mutable_placement().mutable_blk_loc_registry();
134+
// If this block has already been placed, just return true.
135+
// TODO: This should be investigated further. What I think is happening
136+
// is that a macro is being placed which contains another cluster.
137+
// This must be a carry chain. May need to rewrite the algorithm
138+
// below to use macros instead of clusters.
139+
if (is_block_placed(clb_blk_id, block_locs))
140+
return true;
136141
VTR_ASSERT(!is_block_placed(clb_blk_id, block_locs) && "Block already placed. Is this intentional?");
137142
t_pl_macro pl_macro = get_macro(clb_blk_id);
138143
t_pl_loc to_loc;
@@ -170,6 +175,10 @@ class APClusterPlacer {
170175
bool exhaustively_place_cluster(ClusterBlockId clb_blk_id) {
171176
const auto& block_locs = g_vpr_ctx.placement().block_locs();
172177
auto& blk_loc_registry = g_vpr_ctx.mutable_placement().mutable_blk_loc_registry();
178+
// If this block has already been placed, just return true.
179+
// TODO: See similar comment above.
180+
if (is_block_placed(clb_blk_id, block_locs))
181+
return true;
173182
VTR_ASSERT(!is_block_placed(clb_blk_id, block_locs) && "Block already placed. Is this intentional?");
174183
t_pl_macro pl_macro = get_macro(clb_blk_id);
175184
const PartitionRegion& pr = is_cluster_constrained(clb_blk_id) ? g_vpr_ctx.floorplanning().cluster_constraints[clb_blk_id] : get_device_partition_region();
@@ -346,6 +355,10 @@ void FullLegalizer::place_clusters(const ClusteredNetlist& clb_nlist,
346355
for (APBlockId ap_blk_id : ap_netlist_.blocks()) {
347356
const t_pack_molecule* blk_mol = ap_netlist_.block_molecule(ap_blk_id);
348357
for (AtomBlockId atom_blk_id : blk_mol->atom_block_ids) {
358+
// See issue #2791, some of the atom_block_ids may be invalid. They
359+
// can safely be ignored.
360+
if (!atom_blk_id.is_valid())
361+
continue;
349362
// Ensure that this block is not in any other AP block. That would
350363
// be weird.
351364
VTR_ASSERT(!atom_to_ap_block[atom_blk_id].is_valid());
@@ -429,5 +442,10 @@ void FullLegalizer::legalize(const PartialPlacement& p_placement) {
429442
"Aborting program.\n",
430443
num_placement_errors);
431444
}
445+
446+
// TODO: This was taken from vpr_api. Not sure why it is needed. Should be
447+
// made part of the placement and verify placement should check for
448+
// it.
449+
post_place_sync();
432450
}
433451

vpr/src/analytical_place/partial_legalizer.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ static inline PrimitiveVector get_primitive_mass(APBlockId blk_id,
7676
PrimitiveVector mass;
7777
const t_pack_molecule* mol = netlist.block_molecule(blk_id);
7878
for (AtomBlockId atom_blk_id : mol->atom_block_ids) {
79+
// See issue #2791, some of the atom_block_ids may be invalid. They can
80+
// safely be ignored.
81+
if (!atom_blk_id.is_valid())
82+
continue;
7983
const t_model* model = g_vpr_ctx.atom().nlist.block_model(atom_blk_id);
8084
VTR_ASSERT_DEBUG(model->index >= 0);
8185
mass.add_val_to_dim(get_model_mass(model), model->index);
@@ -354,6 +358,8 @@ void FlowBasedLegalizer::compute_neighbors_of_bin(LegalizerBinId src_bin_id, siz
354358
// Create visited flags for each bin. Set the source to visited.
355359
vtr::vector_map<LegalizerBinId, bool> bin_visited(bins_.size(), false);
356360
bin_visited[src_bin_id] = true;
361+
// Create a distance count for each bin from the src.
362+
vtr::vector_map<LegalizerBinId, unsigned> bin_distance(bins_.size(), 0);
357363
// Flags to check if a specific model has been found in the given direction.
358364
// In this case, direction is the direction of the largest component of the
359365
// manhattan distance between the source bin and the target bin.
@@ -401,6 +407,11 @@ void FlowBasedLegalizer::compute_neighbors_of_bin(LegalizerBinId src_bin_id, siz
401407
// Pop the bin from the queue.
402408
LegalizerBinId bin_id = q.front();
403409
q.pop();
410+
// If the distance of this block from the source is too large, do not
411+
// explore.
412+
unsigned curr_bin_dist = bin_distance[bin_id];
413+
if (curr_bin_dist > max_bin_neighbor_dist_)
414+
continue;
404415
// Get the direct neighbors of the bin (neighbors that are directly
405416
// touching).
406417
auto direct_neighbors = get_direct_neighbors_of_bin(bin_id, bins_, tile_bin_);
@@ -431,6 +442,8 @@ void FlowBasedLegalizer::compute_neighbors_of_bin(LegalizerBinId src_bin_id, siz
431442
}
432443
// Mark this bin as visited and push it onto the queue.
433444
bin_visited[dir_neighbor_bin_id] = true;
445+
// Update the distance.
446+
bin_distance[dir_neighbor_bin_id] = curr_bin_dist + 1;
434447
// FIXME: This may be inneficient since it will do an entire BFS of
435448
// the grid if a neighbor of a given type does not exist in
436449
// a specific direction. Should add a check to see if it is
@@ -506,6 +519,7 @@ FlowBasedLegalizer::FlowBasedLegalizer(const APNetlist& netlist)
506519
tile_bin_[x][y] = new_bin_id;
507520
}
508521
}
522+
509523
// Get the number of models in the device.
510524
size_t num_models = get_num_models();
511525
// Connect the bins.
@@ -524,10 +538,14 @@ FlowBasedLegalizer::FlowBasedLegalizer(const APNetlist& netlist)
524538
compute_neighbors_of_bin(tile_bin_[x][y], num_models);
525539
}
526540
}
541+
527542
// Pre-compute the masses of the APBlocks
543+
VTR_LOGV(log_verbosity_ >= 10, "Pre-computing the block masses...\n");
528544
for (APBlockId blk_id : netlist.blocks()) {
529545
block_masses_.insert(blk_id, get_primitive_mass(blk_id, netlist));
530546
}
547+
VTR_LOGV(log_verbosity_ >= 10, "Finished pre-computing the block masses.\n");
548+
531549
// Initialize the block_bins.
532550
block_bins_.resize(netlist.blocks().size(), LegalizerBinId::INVALID());
533551
}

vpr/src/analytical_place/partial_legalizer.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,18 @@ class FlowBasedLegalizer : public PartialLegalizer {
196196
/// enough space to flow blocks.
197197
static constexpr size_t max_num_iterations_ = 100;
198198

199+
/// @brief The maximum number of hops away a neighbor of a bin can be. Where
200+
/// a hop is the minimum number of bins you need to pass through to
201+
/// get to this neighbor (manhattan distance in bins-space).
202+
///
203+
/// This is used to speed up the computation of the neighbors of bins since
204+
/// it reduces the amount of the graph that needs to be explored.
205+
///
206+
/// TODO: This may need to be made per primitive type since some types may
207+
/// need to explore more of the architecture than others to find
208+
/// sufficient neighbors.
209+
static constexpr unsigned max_bin_neighbor_dist_ = 4;
210+
199211
/// @brief A vector of all the bins in the legalizer.
200212
vtr::vector_map<LegalizerBinId, LegalizerBin> bins_;
201213

vtr_flow/arch/timing/k6_frac_N10_40nm.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,27 @@
6666
<!--Fill with 'clb'-->
6767
<fill type="clb" priority="10"/>
6868
</auto_layout>
69+
<fixed_layout name="mcnc_small" width="11" height="11">
70+
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
71+
<perimeter type="io" priority="100"/>
72+
<corners type="EMPTY" priority="101"/>
73+
<!--Fill with 'clb'-->
74+
<fill type="clb" priority="10"/>
75+
</fixed_layout>
76+
<fixed_layout name="mcnc_medium" width="16" height="16">
77+
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
78+
<perimeter type="io" priority="100"/>
79+
<corners type="EMPTY" priority="101"/>
80+
<!--Fill with 'clb'-->
81+
<fill type="clb" priority="10"/>
82+
</fixed_layout>
83+
<fixed_layout name="mcnc_large" width="22" height="22">
84+
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
85+
<perimeter type="io" priority="100"/>
86+
<corners type="EMPTY" priority="101"/>
87+
<!--Fill with 'clb'-->
88+
<fill type="clb" priority="10"/>
89+
</fixed_layout>
6990
</layout>
7091
<device>
7192
<!-- VB & JL: Using Ian Kuon's transistor sizing and drive strength data for routing, at 40 nm. Ian used BPTM

vtr_flow/arch/timing/k6_frac_N10_frac_chain_mem32K_40nm.xml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,71 @@
237237
<col type="memory" startx="2" starty="1" repeatx="8" priority="20"/>
238238
<col type="EMPTY" startx="2" repeatx="8" starty="1" priority="19"/>
239239
</auto_layout>
240+
<fixed_layout name="vtr_extra_small" width="20" height="20">
241+
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
242+
<perimeter type="io" priority="100"/>
243+
<corners type="EMPTY" priority="101"/>
244+
<!--Fill with 'clb'-->
245+
<fill type="clb" priority="10"/>
246+
<!--Column of 'mult_36' with 'EMPTY' blocks wherever a 'mult_36' does not fit. Vertical offset by 1 for perimeter.-->
247+
<col type="mult_36" startx="6" starty="1" repeatx="8" priority="20"/>
248+
<col type="EMPTY" startx="6" repeatx="8" starty="1" priority="19"/>
249+
<!--Column of 'memory' with 'EMPTY' blocks wherever a 'memory' does not fit. Vertical offset by 1 for perimeter.-->
250+
<col type="memory" startx="2" starty="1" repeatx="8" priority="20"/>
251+
<col type="EMPTY" startx="2" repeatx="8" starty="1" priority="19"/>
252+
</fixed_layout>
253+
<fixed_layout name="vtr_small" width="30" height="30">
254+
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
255+
<perimeter type="io" priority="100"/>
256+
<corners type="EMPTY" priority="101"/>
257+
<!--Fill with 'clb'-->
258+
<fill type="clb" priority="10"/>
259+
<!--Column of 'mult_36' with 'EMPTY' blocks wherever a 'mult_36' does not fit. Vertical offset by 1 for perimeter.-->
260+
<col type="mult_36" startx="6" starty="1" repeatx="8" priority="20"/>
261+
<col type="EMPTY" startx="6" repeatx="8" starty="1" priority="19"/>
262+
<!--Column of 'memory' with 'EMPTY' blocks wherever a 'memory' does not fit. Vertical offset by 1 for perimeter.-->
263+
<col type="memory" startx="2" starty="1" repeatx="8" priority="20"/>
264+
<col type="EMPTY" startx="2" repeatx="8" starty="1" priority="19"/>
265+
</fixed_layout>
266+
<fixed_layout name="vtr_medium" width="42" height="42">
267+
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
268+
<perimeter type="io" priority="100"/>
269+
<corners type="EMPTY" priority="101"/>
270+
<!--Fill with 'clb'-->
271+
<fill type="clb" priority="10"/>
272+
<!--Column of 'mult_36' with 'EMPTY' blocks wherever a 'mult_36' does not fit. Vertical offset by 1 for perimeter.-->
273+
<col type="mult_36" startx="6" starty="1" repeatx="8" priority="20"/>
274+
<col type="EMPTY" startx="6" repeatx="8" starty="1" priority="19"/>
275+
<!--Column of 'memory' with 'EMPTY' blocks wherever a 'memory' does not fit. Vertical offset by 1 for perimeter.-->
276+
<col type="memory" startx="2" starty="1" repeatx="8" priority="20"/>
277+
<col type="EMPTY" startx="2" repeatx="8" starty="1" priority="19"/>
278+
</fixed_layout>
279+
<fixed_layout name="vtr_large" width="65" height="65">
280+
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
281+
<perimeter type="io" priority="100"/>
282+
<corners type="EMPTY" priority="101"/>
283+
<!--Fill with 'clb'-->
284+
<fill type="clb" priority="10"/>
285+
<!--Column of 'mult_36' with 'EMPTY' blocks wherever a 'mult_36' does not fit. Vertical offset by 1 for perimeter.-->
286+
<col type="mult_36" startx="6" starty="1" repeatx="8" priority="20"/>
287+
<col type="EMPTY" startx="6" repeatx="8" starty="1" priority="19"/>
288+
<!--Column of 'memory' with 'EMPTY' blocks wherever a 'memory' does not fit. Vertical offset by 1 for perimeter.-->
289+
<col type="memory" startx="2" starty="1" repeatx="8" priority="20"/>
290+
<col type="EMPTY" startx="2" repeatx="8" starty="1" priority="19"/>
291+
</fixed_layout>
292+
<fixed_layout name="vtr_extra_large" width="105" height="105">
293+
<!--Perimeter of 'io' blocks with 'EMPTY' blocks at corners-->
294+
<perimeter type="io" priority="100"/>
295+
<corners type="EMPTY" priority="101"/>
296+
<!--Fill with 'clb'-->
297+
<fill type="clb" priority="10"/>
298+
<!--Column of 'mult_36' with 'EMPTY' blocks wherever a 'mult_36' does not fit. Vertical offset by 1 for perimeter.-->
299+
<col type="mult_36" startx="6" starty="1" repeatx="8" priority="20"/>
300+
<col type="EMPTY" startx="6" repeatx="8" starty="1" priority="19"/>
301+
<!--Column of 'memory' with 'EMPTY' blocks wherever a 'memory' does not fit. Vertical offset by 1 for perimeter.-->
302+
<col type="memory" startx="2" starty="1" repeatx="8" priority="20"/>
303+
<col type="EMPTY" startx="2" repeatx="8" starty="1" priority="19"/>
304+
</fixed_layout>
240305
</layout>
241306
<device>
242307
<!-- VB & JL: Using Ian Kuon's transistor sizing and drive strength data for routing, at 40 nm. Ian used BPTM
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
%include "common/pass_requirements.vpr_status.txt"
2+
%include "timing/pass_requirements.vpr_ap.txt"
3+
%include "timing/pass_requirements.vpr_route_fixed_chan_width.txt"
4+
5+
%include "common/pass_requirements.vtr_benchmarks.txt"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
vpr_status;output.txt;vpr_status=(.*)
2+
total_wirelength;vpr.out;\s*Total wirelength: (\d+)
3+
# Final critical path delay (least slack): 6.34202 ns, Fmax: 157.678 MHz
4+
crit_path_delay;vpr.out;Critical path: (.*) ns
5+
ap_runtime;vpr.out;Analytical Placement took (.*) seconds
6+
pack_runtime;vpr.out;Packing took (.*) seconds
7+
# TODO: Figure out how to match Placement and not Analytical Placement better.
8+
place_runtime;vpr.out;^(?!.*\bAnalytical\b).*Placement took (.*) seconds
9+
route_runtime;vpr.out;Routing took (.*) seconds
10+
total_runtime;vpr.out;The entire flow of VPR took (.*) seconds
11+
num_clb;vpr.out;Netlist clb blocks:\s*(\d+)
12+

vtr_flow/scripts/python_libs/vtr/task.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ def parse_circuit_constraint_list(
325325
"arch",
326326
"device",
327327
"constraints",
328+
"route_chan_width",
328329
]
329330
)
330331

@@ -792,6 +793,10 @@ def apply_cmd_line_circuit_constraints(cmd, circuit, config):
792793
circuit_vpr_constraints = config.circuit_constraints[circuit]["constraints"]
793794
if circuit_vpr_constraints is not None:
794795
cmd += ["--read_vpr_constraints", circuit_vpr_constraints]
796+
# Check if the circuit has constrained route channel width.
797+
constrained_route_w = config.circuit_constraints[circuit]["route_chan_width"]
798+
if constrained_route_w is not None:
799+
cmd += ["--route_chan_width", constrained_route_w]
795800

796801
def resolve_vtr_source_file(config, filename, base_dir=""):
797802
"""
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#
2+
############################################
3+
# Configuration file for running experiments
4+
##############################################
5+
6+
# Path to directory of circuits to use
7+
circuits_dir=benchmarks/blif/wiremap6
8+
9+
# Path to directory of architectures to use
10+
archs_dir=arch/timing
11+
12+
# Add architectures to list to sweep
13+
arch_list_add=k6_frac_N10_40nm.xml
14+
15+
# Add circuits to list to sweep
16+
circuit_list_add=apex4.pre-vpr.blif
17+
circuit_list_add=des.pre-vpr.blif
18+
circuit_list_add=ex1010.pre-vpr.blif
19+
circuit_list_add=seq.pre-vpr.blif
20+
21+
# Constrain the circuits to their devices
22+
circuit_constraint_list_add=(apex4.pre-vpr.blif, device=mcnc_medium)
23+
circuit_constraint_list_add=(seq.pre-vpr.blif, device=mcnc_medium)
24+
circuit_constraint_list_add=(des.pre-vpr.blif, device=mcnc_large)
25+
circuit_constraint_list_add=(ex1010.pre-vpr.blif, device=mcnc_large)
26+
27+
# Constrain the IOs
28+
circuit_constraint_list_add=(apex4.pre-vpr.blif, constraints=../../../../constraints/apex4_io_constraint.xml)
29+
circuit_constraint_list_add=(seq.pre-vpr.blif, constraints=../../../../constraints/seq_io_constraint.xml)
30+
circuit_constraint_list_add=(des.pre-vpr.blif, constraints=../../../../constraints/des_io_constraint.xml)
31+
circuit_constraint_list_add=(ex1010.pre-vpr.blif, constraints=../../../../constraints/ex1010_io_constraint.xml)
32+
33+
# Constrain the circuits to their channel widths
34+
# 1.3 * minW
35+
circuit_constraint_list_add=(apex4.pre-vpr.blif, route_chan_width=78)
36+
circuit_constraint_list_add=(seq.pre-vpr.blif, route_chan_width=78)
37+
circuit_constraint_list_add=(des.pre-vpr.blif, route_chan_width=44)
38+
circuit_constraint_list_add=(ex1010.pre-vpr.blif, route_chan_width=112)
39+
40+
# Parse info and how to parse
41+
parse_file=vpr_fixed_chan_width.txt
42+
43+
# How to parse QoR info
44+
qor_parse_file=qor_ap_fixed_chan_width.txt
45+
46+
# Pass requirements
47+
pass_requirements_file=pass_requirements_ap_fixed_chan_width.txt
48+
49+
# Pass the script params while writing the vpr constraints.
50+
script_params=-starting_stage vpr -track_memory_usage --analytical_place --route
51+

0 commit comments

Comments
 (0)