9
9
10
10
#include < algorithm>
11
11
#include < cmath>
12
+ #include < limits>
13
+ #include < vector>
12
14
#include " PreClusterTimingManager.h"
13
15
#include " atom_netlist.h"
14
16
#include " cluster_legalizer.h"
@@ -129,11 +131,12 @@ static inline float get_seed_gain(AtomBlockId blk_id,
129
131
* criticalities.
130
132
*/
131
133
static inline void print_seed_gains (const char * fname,
132
- const std::vector<AtomBlockId >& seed_atoms ,
133
- const vtr::vector<AtomBlockId , float >& atom_gain ,
134
+ const std::vector<PackMoleculeId >& seed_mols ,
135
+ const vtr::vector<PackMoleculeId , float >& molecule_gain ,
134
136
const vtr::vector<AtomBlockId, float >& atom_criticality,
135
137
const AtomNetlist& atom_netlist,
136
- const LogicalModels& models) {
138
+ const LogicalModels& models,
139
+ const Prepacker& prepacker) {
137
140
FILE* fp = vtr::fopen (fname, " w" );
138
141
139
142
// For pretty formatting determine the maximum name length
@@ -148,16 +151,18 @@ static inline void print_seed_gains(const char* fname,
148
151
149
152
fprintf (fp, " %-*s %-*s %8s %8s\n " , max_name_len, " atom_block_name" , max_type_len, " atom_block_type" , " gain" , " criticality" );
150
153
fprintf (fp, " \n " );
151
- for (auto blk_id : seed_atoms) {
152
- std::string name = atom_netlist.block_name (blk_id);
153
- fprintf (fp, " %-*s " , max_name_len, name.c_str ());
154
+ for (auto mol_id : seed_mols) {
155
+ for (AtomBlockId blk_id : prepacker.get_molecule (mol_id).atom_block_ids ) {
156
+ std::string name = atom_netlist.block_name (blk_id);
157
+ fprintf (fp, " %-*s " , max_name_len, name.c_str ());
154
158
155
- std::string model_name = models.model_name (atom_netlist.block_model (blk_id));
156
- fprintf (fp, " %-*s " , max_type_len, model_name.c_str ());
159
+ std::string model_name = models.model_name (atom_netlist.block_model (blk_id));
160
+ fprintf (fp, " %-*s " , max_type_len, model_name.c_str ());
157
161
158
- fprintf (fp, " %*f " , std::max ((int )strlen (" gain" ), 8 ), atom_gain[blk_id]);
159
- fprintf (fp, " %*f " , std::max ((int )strlen (" criticality" ), 8 ), atom_criticality[blk_id]);
160
- fprintf (fp, " \n " );
162
+ fprintf (fp, " %*f " , std::max ((int )strlen (" gain" ), 8 ), molecule_gain[mol_id]);
163
+ fprintf (fp, " %*f " , std::max ((int )strlen (" criticality" ), 8 ), atom_criticality[blk_id]);
164
+ fprintf (fp, " \n " );
165
+ }
161
166
}
162
167
163
168
fclose (fp);
@@ -169,7 +174,7 @@ GreedySeedSelector::GreedySeedSelector(const AtomNetlist& atom_netlist,
169
174
const t_molecule_stats& max_molecule_stats,
170
175
const LogicalModels& models,
171
176
const PreClusterTimingManager& pre_cluster_timing_manager)
172
- : seed_atoms_(atom_netlist.blocks ().begin(), atom_netlist.blocks ().end()) {
177
+ : seed_mols_(prepacker.molecules ().begin(), prepacker.molecules ().end()) {
173
178
// Seed atoms list is initialized with all atoms in the atom netlist.
174
179
175
180
// Pre-compute the criticality of each atom
@@ -186,17 +191,28 @@ GreedySeedSelector::GreedySeedSelector(const AtomNetlist& atom_netlist,
186
191
// Maintain a lookup table of the seed gain for each atom. This will be
187
192
// used to sort the seed atoms.
188
193
// Initially all gains are zero.
189
- vtr::vector<AtomBlockId, float > atom_gains (atom_netlist.blocks ().size (), 0 .f );
190
-
191
- // Get the seed gain of each atom.
192
- for (AtomBlockId blk_id : atom_netlist.blocks ()) {
193
- atom_gains[blk_id] = get_seed_gain (blk_id,
194
- atom_netlist,
195
- prepacker,
196
- models,
197
- seed_type,
198
- max_molecule_stats,
199
- atom_criticality);
194
+ vtr::vector<PackMoleculeId, float > molecule_gains (seed_mols_.size (), 0 .f );
195
+
196
+ // Get the seed gain of each molecule.
197
+ for (PackMoleculeId mol_id : seed_mols_) {
198
+ // Gain of each molecule is the maximum gain of its atoms
199
+ float mol_gain = std::numeric_limits<float >::lowest ();
200
+ const std::vector<AtomBlockId>& molecule_atoms = prepacker.get_molecule (mol_id).atom_block_ids ;
201
+ for (AtomBlockId blk_id : molecule_atoms) {
202
+ // If the molecule does not fit the entire pack pattern, it's possible to have invalid block ids in the molecule_atoms vector
203
+ if (blk_id == AtomBlockId::INVALID ()) {
204
+ continue ;
205
+ }
206
+ float atom_gain = get_seed_gain (blk_id,
207
+ atom_netlist,
208
+ prepacker,
209
+ models,
210
+ seed_type,
211
+ max_molecule_stats,
212
+ atom_criticality);
213
+ mol_gain = std::max (mol_gain, atom_gain);
214
+ }
215
+ molecule_gains[mol_id] = mol_gain;
200
216
}
201
217
202
218
// Sort seeds in descending order of seed gain (i.e. highest seed gain first)
@@ -207,15 +223,15 @@ GreedySeedSelector::GreedySeedSelector(const AtomNetlist& atom_netlist,
207
223
// std::sort which does not specify how equal values are handled). Using a stable
208
224
// sort ensures that regardless of the underlying sorting algorithm the same seed
209
225
// order is produced regardless of compiler.
210
- auto by_descending_gain = [&](const AtomBlockId lhs, const AtomBlockId rhs) {
211
- return atom_gains [lhs] > atom_gains [rhs];
226
+ auto by_descending_gain = [&](const PackMoleculeId lhs, const PackMoleculeId rhs) {
227
+ return molecule_gains [lhs] > molecule_gains [rhs];
212
228
};
213
- std::stable_sort (seed_atoms_ .begin (), seed_atoms_ .end (), by_descending_gain);
229
+ std::stable_sort (seed_mols_ .begin (), seed_mols_ .end (), by_descending_gain);
214
230
215
231
// Print the seed gains if requested.
216
232
if (getEchoEnabled () && isEchoFileEnabled (E_ECHO_CLUSTERING_BLOCK_CRITICALITIES)) {
217
233
print_seed_gains (getEchoFileName (E_ECHO_CLUSTERING_BLOCK_CRITICALITIES),
218
- seed_atoms_, atom_gains , atom_criticality, atom_netlist, models);
234
+ seed_mols_, molecule_gains , atom_criticality, atom_netlist, models, prepacker );
219
235
}
220
236
221
237
// Set the starting seed index (the index of the first molecule to propose).
@@ -224,25 +240,20 @@ GreedySeedSelector::GreedySeedSelector(const AtomNetlist& atom_netlist,
224
240
seed_index_ = 0 ;
225
241
}
226
242
227
- PackMoleculeId GreedySeedSelector::get_next_seed (const Prepacker& prepacker,
228
- const ClusterLegalizer& cluster_legalizer) {
229
- while (seed_index_ < seed_atoms_.size ()) {
243
+ PackMoleculeId GreedySeedSelector::get_next_seed (const ClusterLegalizer& cluster_legalizer) {
244
+ while (seed_index_ < seed_mols_.size ()) {
230
245
// Get the current seed atom at the seed index and increment the
231
246
// seed index.
232
247
// All previous seed indices have been either proposed already or
233
248
// are already clustered. This process assumes that once an atom
234
249
// is clustered it will never become unclustered.
235
- AtomBlockId seed_blk_id = seed_atoms_ [seed_index_++];
250
+ PackMoleculeId seed_molecule_id = seed_mols_ [seed_index_++];
236
251
237
252
// If this atom has been clustered, it cannot be proposed as a seed.
238
253
// Skip to the next seed.
239
- if (cluster_legalizer.is_atom_clustered (seed_blk_id))
254
+ if (cluster_legalizer.is_mol_clustered (seed_molecule_id)) {
240
255
continue ;
241
-
242
- // Get the molecule that contains this atom and return it as the
243
- // next seed.
244
- PackMoleculeId seed_molecule_id = prepacker.get_atom_molecule (seed_blk_id);
245
- VTR_ASSERT (!cluster_legalizer.is_mol_clustered (seed_molecule_id));
256
+ }
246
257
return seed_molecule_id;
247
258
}
248
259
0 commit comments