16
16
#include < tuple>
17
17
#include < vector>
18
18
#include " atom_lookup.h"
19
+ #include " atom_netlist.h"
19
20
#include " cluster_placement.h"
20
21
#include " cluster_router.h"
21
22
#include " globals.h"
22
23
#include " logic_types.h"
24
+ #include " netlist_utils.h"
23
25
#include " noc_data_types.h"
24
26
#include " pack_types.h"
25
27
#include " partition.h"
@@ -514,15 +516,13 @@ try_place_atom_block_rec(const t_pb_graph_node* pb_graph_node,
514
516
// FIXME: UPDATE THIS!
515
517
VTR_ASSERT (!atom_ctx.lookup .pb_atom (pb)
516
518
&& atom_ctx.lookup .atom_pb (blk_id) == nullptr
517
- && (!atom_cluster.contains (blk_id) ||
518
- atom_cluster[blk_id] == LegalizationClusterId::INVALID ()));
519
+ && atom_cluster[blk_id] == LegalizationClusterId::INVALID ());
519
520
/* try pack to location */
520
521
VTR_ASSERT (pb->name == nullptr );
521
522
pb->name = vtr::strdup (atom_ctx.nlist .block_name (blk_id).c_str ());
522
523
523
524
// Update the atom netlist mappings
524
- // FIXME: This needs to be cleaned up!
525
- atom_cluster.insert (blk_id, cluster_id);
525
+ atom_cluster[blk_id] = cluster_id;
526
526
// NOTE: This pb is different from the pb of the cluster. It is the pb
527
527
// of the actual primitive. It may be an upwards battle to try and
528
528
// remove it!
@@ -679,10 +679,8 @@ static void compute_and_mark_lookahead_pins_used_for_pin(const t_pb_graph_pin* p
679
679
// pb_graph_pin driving net_id in the driver pb block
680
680
t_pb_graph_pin* output_pb_graph_pin = nullptr ;
681
681
// if the driver block is in the same clb as the input primitive block
682
- // FIXME: If atom_cluster was a vector, this can be made much cleaner!
683
- LegalizationClusterId driver_cluster_id = atom_cluster.contains (driver_blk_id) ? atom_cluster[driver_blk_id] : LegalizationClusterId::INVALID ();
684
- LegalizationClusterId prim_cluster_id = atom_cluster.contains (prim_blk_id) ? atom_cluster[prim_blk_id] : LegalizationClusterId::INVALID ();
685
- // if (atom_ctx.lookup.atom_clb(driver_blk_id) == atom_ctx.lookup.atom_clb(prim_blk_id)) {
682
+ LegalizationClusterId driver_cluster_id = atom_cluster[driver_blk_id];
683
+ LegalizationClusterId prim_cluster_id = atom_cluster[prim_blk_id];
686
684
if (driver_cluster_id == prim_cluster_id) {
687
685
// get pb_graph_pin driving the given net
688
686
output_pb_graph_pin = get_driver_pb_graph_pin (driver_pb, driver_pin_id);
@@ -753,9 +751,7 @@ static void compute_and_mark_lookahead_pins_used_for_pin(const t_pb_graph_pin* p
753
751
LegalizationClusterId driver_cluster = atom_cluster[driver_blk_id];
754
752
for (auto pin_id : atom_ctx.nlist .net_sinks (net_id)) {
755
753
auto sink_blk_id = atom_ctx.nlist .pin_block (pin_id);
756
- // FIXME: Can be made cleaner if atom_cluster was a vector
757
- if (!atom_cluster.contains (sink_blk_id) ||
758
- atom_cluster[sink_blk_id] != driver_cluster) {
754
+ if (atom_cluster[sink_blk_id] != driver_cluster) {
759
755
all_sinks_in_cur_cluster = false ;
760
756
break ;
761
757
}
@@ -1320,6 +1316,10 @@ e_block_pack_status ClusterLegalizer::try_pack_molecule(t_pack_molecule* molecul
1320
1316
cur_molecule->valid = false ;
1321
1317
1322
1318
commit_primitive (cluster_placement_stats_ptr, primitives_list[i]);
1319
+
1320
+ // FIXME: Does this need to go here? Shouldn't all atoms
1321
+ // be labeled?
1322
+ atom_cluster[atom_blk_id] = cluster_id;
1323
1323
}
1324
1324
1325
1325
// Update the lookahead pins used.
@@ -1399,13 +1399,14 @@ ClusterLegalizer::start_new_cluster(t_pack_molecule* molecule,
1399
1399
// TODO: Figure out why this uses FULL_EXTERNAL_PIN_UTIL
1400
1400
// Constant allowing all cluster pins to be used
1401
1401
const t_ext_pin_util FULL_EXTERNAL_PIN_UTIL (1 ., 1 .);
1402
- LegalizationClusterId new_cluster_id = LegalizationClusterId (legalization_clusters .size ());
1402
+ LegalizationClusterId new_cluster_id = LegalizationClusterId (legalization_cluster_ids .size ());
1403
1403
e_block_pack_status pack_status = try_pack_molecule (molecule,
1404
1404
new_cluster,
1405
1405
new_cluster_id,
1406
1406
FULL_EXTERNAL_PIN_UTIL);
1407
1407
1408
1408
if (pack_status == e_block_pack_status::BLK_PASSED) {
1409
+ legalization_cluster_ids.push_back (new_cluster_id);
1409
1410
legalization_clusters.push_back (std::move (new_cluster));
1410
1411
molecule_cluster[molecule] = new_cluster_id;
1411
1412
} else {
@@ -1467,6 +1468,8 @@ void ClusterLegalizer::destroy_cluster(LegalizationClusterId cluster_id) {
1467
1468
VTR_ASSERT_SAFE (molecule_cluster.find (mol) != molecule_cluster.end () &&
1468
1469
molecule_cluster[mol] == cluster_id);
1469
1470
molecule_cluster[mol] = LegalizationClusterId::INVALID ();
1471
+ // FIXME: Document this.
1472
+ mol->valid = true ;
1470
1473
// Revert the placement of all blocks in the molecule.
1471
1474
// TODO: remove_atom_from_target can also be used for a move function
1472
1475
// to remove a single molecule from a cluster. Truly just copy
@@ -1490,6 +1493,35 @@ void ClusterLegalizer::destroy_cluster(LegalizationClusterId cluster_id) {
1490
1493
free_router_data (cluster.router_data );
1491
1494
cluster.router_data = nullptr ;
1492
1495
cluster.pr = PartitionRegion ();
1496
+
1497
+ // Mark the cluster as invalid.
1498
+ legalization_cluster_ids[cluster_id] = LegalizationClusterId::INVALID ();
1499
+ }
1500
+
1501
+ void ClusterLegalizer::compress () {
1502
+ // Create a map from the old ids to the new (compressed) one.
1503
+ vtr::vector_map<LegalizationClusterId, LegalizationClusterId> cluster_id_map;
1504
+ cluster_id_map = compress_ids (legalization_cluster_ids);
1505
+ // Update all cluster values.
1506
+ legalization_cluster_ids = clean_and_reorder_ids (cluster_id_map);
1507
+ legalization_clusters = clean_and_reorder_values (legalization_clusters, cluster_id_map);
1508
+ // Update the reverse lookups.
1509
+ for (auto & it : molecule_cluster) {
1510
+ if (!it.second .is_valid ())
1511
+ continue ;
1512
+ molecule_cluster[it.first ] = cluster_id_map[it.second ];
1513
+ }
1514
+ for (size_t i = 0 ; i < atom_cluster.size (); i++) {
1515
+ AtomBlockId atom_blk_id = AtomBlockId (i);
1516
+ LegalizationClusterId old_cluster_id = atom_cluster[atom_blk_id];
1517
+ if (!old_cluster_id.is_valid ())
1518
+ continue ;
1519
+ atom_cluster[atom_blk_id] = cluster_id_map[old_cluster_id];
1520
+ }
1521
+ // Shrink everything to fit
1522
+ legalization_cluster_ids.shrink_to_fit ();
1523
+ legalization_clusters.shrink_to_fit ();
1524
+ atom_cluster.shrink_to_fit ();
1493
1525
}
1494
1526
1495
1527
bool ClusterLegalizer::check_cluster_legality (LegalizationClusterId cluster_id) {
@@ -1498,7 +1530,8 @@ bool ClusterLegalizer::check_cluster_legality(LegalizationClusterId cluster_id)
1498
1530
return try_intra_lb_route (cluster.router_data , log_verbosity, &mode_status);
1499
1531
}
1500
1532
1501
- void ClusterLegalizer::init (const Prepacker& prepacker,
1533
+ void ClusterLegalizer::init (const AtomNetlist& atom_netlist,
1534
+ const Prepacker& prepacker,
1502
1535
const std::vector<t_logical_block_type>& logical_block_types,
1503
1536
std::vector<t_lb_type_rr_node>* t_lb_type_rr_graphs,
1504
1537
size_t t_num_models,
@@ -1514,6 +1547,8 @@ void ClusterLegalizer::init(const Prepacker& prepacker,
1514
1547
// Verify that the inputs are valid.
1515
1548
VTR_ASSERT (t_lb_type_rr_graphs != nullptr );
1516
1549
1550
+ // Resize the atom_cluster lookup to make the accesses much cheaper.
1551
+ atom_cluster.resize (atom_netlist.blocks ().size (), LegalizationClusterId::INVALID ());
1517
1552
// Allocate the cluster_placement_stats
1518
1553
cluster_placement_stats = alloc_and_load_cluster_placement_stats ();
1519
1554
// Allocate the primitives_lists
0 commit comments