Skip to content

Commit 0408e7d

Browse files
[Prepacker] Changed Internal Maps to VTR Vectors
For improved performance (and to simplify the interface further), changed the internal maps to VTR Vectors. Added asserts to ensure assumptions are maintained.
1 parent be17e82 commit 0408e7d

File tree

2 files changed

+38
-28
lines changed

2 files changed

+38
-28
lines changed

vpr/src/pack/prepack.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "vtr_assert.h"
3030
#include "vtr_range.h"
3131
#include "vtr_util.h"
32+
#include "vtr_vector.h"
3233

3334
/*****************************************/
3435
/*Local Function Declaration */
@@ -40,7 +41,7 @@ static void free_list_of_pack_patterns(std::vector<t_pack_patterns>& list_of_pac
4041
static void free_pack_pattern(t_pack_patterns* pack_pattern);
4142

4243
static t_pack_molecule* alloc_and_load_pack_molecules(t_pack_patterns* list_of_pack_patterns,
43-
std::unordered_map<AtomBlockId, t_pb_graph_node*>& expected_lowest_cost_pb_gnode,
44+
vtr::vector<AtomBlockId, t_pb_graph_node*>& expected_lowest_cost_pb_gnode,
4445
const int num_packing_patterns,
4546
std::multimap<AtomBlockId, t_pack_molecule*>& atom_molecules,
4647
const AtomNetlist& atom_nlist,
@@ -800,7 +801,7 @@ static void backward_expand_pack_pattern_from_edge(const t_pb_graph_edge* expans
800801
* ie. a single linear chain that can be split across multiple complex blocks
801802
*/
802803
static t_pack_molecule* alloc_and_load_pack_molecules(t_pack_patterns* list_of_pack_patterns,
803-
std::unordered_map<AtomBlockId, t_pb_graph_node*>& expected_lowest_cost_pb_gnode,
804+
vtr::vector<AtomBlockId, t_pb_graph_node*>& expected_lowest_cost_pb_gnode,
804805
const int num_packing_patterns,
805806
std::multimap<AtomBlockId, t_pack_molecule*>& atom_molecules,
806807
const AtomNetlist& atom_nlist,
@@ -1705,15 +1706,30 @@ static void free_pack_molecules(t_pack_molecule* list_of_pack_molecules) {
17051706

17061707
void Prepacker::init(const AtomNetlist& atom_nlist, const std::vector<t_logical_block_type>& logical_block_types) {
17071708
VTR_ASSERT(list_of_pack_molecules == nullptr && "Prepacker cannot be initialized twice.");
1709+
17081710
// Allocate the pack patterns from the logical block types.
17091711
list_of_pack_patterns = alloc_and_load_pack_patterns(logical_block_types);
17101712
// Use the pack patterns to allocate and load the pack molecules.
1713+
std::multimap<AtomBlockId, t_pack_molecule*> atom_molecules_multimap;
1714+
expected_lowest_cost_pb_gnode.resize(atom_nlist.blocks().size(), nullptr);
17111715
list_of_pack_molecules = alloc_and_load_pack_molecules(list_of_pack_patterns.data(),
17121716
expected_lowest_cost_pb_gnode,
17131717
list_of_pack_patterns.size(),
1714-
atom_molecules,
1718+
atom_molecules_multimap,
17151719
atom_nlist,
17161720
logical_block_types);
1721+
1722+
// The multimap is a legacy thing. Since blocks can be part of multiple pack
1723+
// patterns, during prepacking a block may be contained within multiple
1724+
// molecules. However, by the end of prepacking, molecules should be
1725+
// combined such that each block is contained in one and only one molecule.
1726+
atom_molecules.resize(atom_nlist.blocks().size(), nullptr);
1727+
for (AtomBlockId blk_id : atom_nlist.blocks()) {
1728+
// Every atom block should be packed into a single molecule (no more
1729+
// or less).
1730+
VTR_ASSERT(atom_molecules_multimap.count(blk_id) == 1);
1731+
atom_molecules[blk_id] = atom_molecules_multimap.find(blk_id)->second;
1732+
}
17171733
}
17181734

17191735
t_molecule_stats Prepacker::calc_max_molecule_stats(const AtomNetlist& atom_nlist) const {

vpr/src/pack/prepack.h

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,9 @@
1111
#define PREPACK_H
1212

1313
#include <algorithm>
14-
#include <map>
15-
#include <unordered_map>
1614
#include "vpr_types.h"
1715
#include "vtr_assert.h"
18-
#include "vtr_range.h"
16+
#include "vtr_vector.h"
1917

2018
class AtomNetlist;
2119
class AtomBlockId;
@@ -28,7 +26,7 @@ struct t_logical_block_type;
2826
* This class maintains the prepacking state, allowing the use of molecules
2927
* (prepacked atoms) while this object exists. After prepacking, every atom will
3028
* be part of a molecule (with a large number being part of single-atom
31-
* molecules.
29+
* molecules).
3230
*
3331
* Molecules currently come from pack patterns in the architecture file. For
3432
* example, a 3-bit carry chain in most architectures would turn into a molecule
@@ -50,7 +48,6 @@ struct t_logical_block_type;
5048
*
5149
*/
5250
class Prepacker {
53-
using atom_molecules_const_iterator = std::multimap<AtomBlockId, t_pack_molecule*>::const_iterator;
5451
public:
5552
// The constructor is default, the init method performs prepacking.
5653
Prepacker() = default;
@@ -72,18 +69,16 @@ class Prepacker {
7269
void init(const AtomNetlist& atom_nlist, const std::vector<t_logical_block_type> &logical_block_types);
7370

7471
/**
75-
* @brief Get the cluster molecules containing the given atom block.
72+
* @brief Get the cluster molecule containing the given atom block.
7673
*
77-
* @param blk_id The atom block to get the molecules of.
74+
* @param blk_id The atom block to get the molecule of.
7875
*/
7976
inline t_pack_molecule* get_atom_molecule(AtomBlockId blk_id) const {
80-
// Internally the prepacker maintains multiple molecules per atom, since
81-
// some atoms may be part of multiple pack patterns; however, the
82-
// prepacker should merge these eventually into one single molecule.
83-
// TODO: If this can be 100% verified, this should be turned into a
84-
// debug assert.
85-
VTR_ASSERT(atom_molecules.count(blk_id) == 1);
86-
return atom_molecules.find(blk_id)->second;
77+
// Safety debug to ensure the blk is valid and has a molecule entry.
78+
VTR_ASSERT_SAFE(blk_id.is_valid() && (size_t)blk_id < atom_molecules.size());
79+
// Safety debug to ensure the molecule is valid
80+
VTR_ASSERT_DEBUG(atom_molecules[blk_id] != nullptr);
81+
return atom_molecules[blk_id];
8782
}
8883

8984
/**
@@ -93,11 +88,11 @@ class Prepacker {
9388
* @param blk_id The atom block to get the pb graph node of.
9489
*/
9590
inline t_pb_graph_node* get_expected_lowest_cost_pb_gnode(AtomBlockId blk_id) const {
96-
auto iter = expected_lowest_cost_pb_gnode.find(blk_id);
97-
VTR_ASSERT(iter != expected_lowest_cost_pb_gnode.end());
98-
t_pb_graph_node* pb_gnode = iter->second;
99-
VTR_ASSERT(pb_gnode != nullptr);
100-
return pb_gnode;
91+
// Safety debug to ensure the blk is valid and has an entry.
92+
VTR_ASSERT_SAFE(blk_id.is_valid() && (size_t)blk_id < expected_lowest_cost_pb_gnode.size());
93+
// Ensure the entry is valid.
94+
VTR_ASSERT(expected_lowest_cost_pb_gnode[blk_id] != nullptr);
95+
return expected_lowest_cost_pb_gnode[blk_id];
10196
}
10297

10398
/**
@@ -186,14 +181,13 @@ class Prepacker {
186181
/**
187182
* @brief The molecules associated with each atom block.
188183
*
189-
* This map is loaded in the prepacking stage and freed at the very end of
190-
* vpr flow run. The pointers in this multimap is shared with
191-
* list_of_pack_molecules.
184+
* This vector is loaded in the init method and cleared in the reset method.
185+
* The pointers in this vector are shared with list_of_pack_molecules.
192186
*/
193-
std::multimap<AtomBlockId, t_pack_molecule*> atom_molecules;
187+
vtr::vector<AtomBlockId, t_pack_molecule*> atom_molecules;
194188

195-
/// @brief A map for the expected lowest cost physical block graph node.
196-
std::unordered_map<AtomBlockId, t_pb_graph_node*> expected_lowest_cost_pb_gnode;
189+
/// @brief A vector of the expected lowest cost physical block graph node.
190+
vtr::vector<AtomBlockId, t_pb_graph_node*> expected_lowest_cost_pb_gnode;
197191

198192
/// @brief A list of the pack patterns used for prepacking. I think the
199193
/// molecules keep pointers to this vector, so this needs to remain

0 commit comments

Comments
 (0)