* ./katabatic :

- Change: Uses a map instead of a sorted vector in the layer assignment
        steps. It was used to order GCells by density, and causing terrific
        slowdown on big examples. Namely the eFPGA 16x16 took 1h20, now it's
        down to  21 seconds...
          Devellop a new object <DyKeyQueue> to handle map with elements
        whose key *can* change. Next step is to normalize the key caching
        mechanism and to templatize.
    - Change: In LayerAssign, account the number of globals AutoSegments
        moved up.
This commit is contained in:
Jean-Paul Chaput 2010-03-23 09:25:15 +00:00
parent f56b102584
commit 15a61c5f96
4 changed files with 180 additions and 12 deletions

View File

@ -80,6 +80,18 @@ namespace Katabatic {
}
// -------------------------------------------------------------------
// Class : "Kite::GCell::CompareByKey".
//
// lhs < rhs --> true
bool GCell::CompareByKey::operator() ( const GCell* lhs, const GCell* rhs )
{
return lhs->getKey() < rhs->getKey();
}
// -------------------------------------------------------------------
// Class : "Katabatic::GCell".
@ -107,6 +119,7 @@ namespace Katabatic {
, _routedSegmentCount(0)
, _saturated (false)
, _invalid (true)
, _key (0.0,_index)
{
for ( size_t i=0 ; i<_depth ; i++ ) {
_blockages [i] = 0.0;
@ -719,7 +732,7 @@ namespace Katabatic {
}
bool GCell::stepDesaturate ( unsigned int depth, set<Net*>& globalNets )
bool GCell::stepDesaturate ( unsigned int depth, set<Net*>& globalNets, AutoSegment*& moved )
{
#if defined(CHECK_DETERMINISM)
cerr << "Order: stepDesaturate [" << getIndex() << "] depth:" << depth << endl;
@ -761,6 +774,7 @@ namespace Katabatic {
#endif
//cerr << "Move up " << (*isegment) << endl;
(*isegment)->changeDepth ( depth+2, false, false );
moved = (*isegment);
updateDensity ();
@ -976,6 +990,73 @@ namespace Katabatic {
}
// -------------------------------------------------------------------
// Class : "Kite::DyKeyQueue".
DyKeyQueue::DyKeyQueue ( unsigned int depth )
: _depth (depth)
, _map ()
, _requests()
{ }
DyKeyQueue::DyKeyQueue ( unsigned int depth, const vector<GCell*>& gcells )
: _depth (depth)
, _map ()
, _requests()
{
for ( size_t i=0 ; i<gcells.size() ; i++ )
_requests.insert ( gcells[i] );
}
DyKeyQueue::~DyKeyQueue ()
{
if ( not _requests.empty() ) {
cerr << Warning("~DyKeyQueue(): Still contains %d requests (and %d elements)."
,_requests.size(),_map.size()) << endl;
}
}
const std::set<GCell*,GCell::CompareByKey>& DyKeyQueue::getGCells () const
{ return _map; }
void DyKeyQueue::invalidate ( GCell* gcell )
{ push ( gcell ); }
void DyKeyQueue::push ( GCell* gcell )
{ _requests.insert ( gcell ); }
void DyKeyQueue::revalidate ()
{
std::set<GCell*,GCell::CompareByKey>::iterator iinserted;
std::set<GCell*>::iterator igcell = _requests.begin();
for ( ; igcell != _requests.end() ; ++igcell ) {
iinserted = _map.find(*igcell);
if ( iinserted != _map.end() ) {
_map.erase ( iinserted );
}
(*igcell)->updateKey (_depth);
_map.insert ( *igcell );
}
_requests.clear ();
}
GCell* DyKeyQueue::pop ()
{
if ( _map.empty() ) return NULL;
std::set<GCell*,GCell::CompareByKey>::iterator igcell = _map.begin();
GCell* gcell = *igcell;
_map.erase ( igcell );
}
// -------------------------------------------------------------------
// Utilities.

View File

@ -88,7 +88,10 @@ namespace Katabatic {
}
void KatabaticEngine::_desaturate ( unsigned int depth, set<Net*>& globalNets )
void KatabaticEngine::_desaturate ( unsigned int depth
, set<Net*>& globalNets
, unsigned long& total
, unsigned long& globals )
{
if ( depth+2 >= Session::getRoutingGauge()->getDepth() ) {
cerr << Warning("Katabatic::_desaturate(): %s, no remaining upper layers."
@ -100,16 +103,43 @@ namespace Katabatic {
cmess1 << " o Desaturate layer "
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl;
vector<GCell*> gcells = *(_gcellGrid->getGCellVector());
//vector<GCell*> gcells = *(_gcellGrid->getGCellVector());
DyKeyQueue queue ( depth, *(_gcellGrid->getGCellVector()) );
AutoSegment* segment = NULL;
vector<GCell*> invalidateds;
bool optimized = true;
while ( optimized ) {
optimized = false;
sort ( gcells.begin(), gcells.end(), GCell::CompareByDensity(depth) );
for ( size_t i=0 ; i<gcells.size() ; i++ ) {
if ( !gcells[i]->isSaturated ( depth ) ) break;
//sort ( gcells.begin(), gcells.end(), GCell::CompareByDensity(depth) );
queue.revalidate ();
std::set<GCell*,GCell::CompareByKey>::const_iterator igcell = queue.getGCells().begin();
size_t i = 0;
for ( ; igcell!=queue.getGCells().end() ; ++igcell, ++i ) {
if ( not (*igcell)->isSaturated ( depth ) ) {
ltrace(190) << "STOP desaturated: @" << i << " " << *igcell << endl;
for ( ; igcell!=queue.getGCells().end() ; ++igcell ) {
if ( (*igcell)->isSaturated ( depth ) ) {
cerr << "[ERROR] Still saturated: @" << i << " " << *igcell << endl;
break;
}
}
break;
}
ltrace(190) << "step desaturate @: " << i << " " << *igcell << endl;
optimized = (*igcell)->stepDesaturate ( depth, globalNets, segment );
if ( segment ) {
++total; ++globals;
segment->getGCells ( invalidateds );
for ( size_t j=0 ; j<invalidateds.size() ; j++ ) {
queue.invalidate ( invalidateds[j] );
}
}
optimized = gcells[i]->stepDesaturate ( depth, globalNets );
if ( optimized ) break;
}
}
@ -246,8 +276,8 @@ namespace Katabatic {
Session::revalidate ();
for ( int i=0 ; i < 3 ; i++ ) {
_desaturate ( 1, globalNets );
_desaturate ( 2, globalNets );
_desaturate ( 1, globalNets, total, global );
_desaturate ( 2, globalNets, total, global );
globalNets.clear ();

View File

@ -79,6 +79,21 @@ namespace Katabatic {
private:
size_t _depth;
};
class CompareByKey {
public:
bool operator() ( const GCell* lhs, const GCell* rhs );
};
class Key {
private:
float _density;
unsigned int _index;
public:
inline Key ( float, unsigned int );
inline float getDensity () const;
inline unsigned int getIndex () const;
inline void update ( GCell*, unsigned int );
friend bool operator< ( const Key&, const Key& );
};
public:
// Static Utilities.
@ -130,6 +145,7 @@ namespace Katabatic {
AutoSegments getVStopSegments ();
inline AutoSegments getStartSegments ( unsigned int direction );
inline AutoSegments getStopSegments ( unsigned int direction );
inline const Key& getKey () const;
size_t checkDensity () const;
bool checkEdgeSaturation ( float threshold ) const;
// Modifiers.
@ -144,8 +160,9 @@ namespace Katabatic {
void removeContact ( AutoContact* );
void updateContacts ();
size_t updateDensity ();
inline void updateKey ( unsigned int depth );
void desaturate ( unsigned int depth, set<Net*>& );
bool stepDesaturate ( unsigned int depth, set<Net*>& );
bool stepDesaturate ( unsigned int depth, set<Net*>&, AutoSegment*& moved );
inline void invalidate ();
// Inspector Management.
Record* _getRecord () const;
@ -175,6 +192,7 @@ namespace Katabatic {
unsigned int _routedSegmentCount;
bool _saturated;
bool _invalid;
Key _key;
protected:
// Constructors & Destructors.
@ -197,7 +215,7 @@ namespace Katabatic {
};
// Inline Functions.
// GCell Inline Functions.
inline bool GCell::isSaturated () const { return _saturated; }
inline bool GCell::isValid () const { return !_invalid; }
inline GCellGrid* GCell::getGCellGrid () const { return _gcellGrid; }
@ -215,6 +233,8 @@ namespace Katabatic {
inline unsigned int GCell::getRoutedCount () const { return _routedSegmentCount; }
inline string GCell::_getTypeName () const { return _TName("GCell"); }
inline void GCell::invalidate () { _invalid = true; }
inline const GCell::Key& GCell::getKey () const { return _key; }
inline void GCell::updateKey ( unsigned int depth ) { _key.update(this,depth); }
inline AutoSegments GCell::getStartSegments ( unsigned int direction )
{ return (direction&Constant::Horizontal) ? getHStartSegments() : getVStartSegments(); }
@ -238,6 +258,43 @@ namespace Katabatic {
{ invalidate(); _contacts.push_back(contact); }
// GCell::Key Inline Functions.
inline GCell::Key::Key ( float density, unsigned int index ) : _density(density), _index(index) {}
inline float GCell::Key::getDensity () const { return _density; }
inline unsigned int GCell::Key::getIndex () const { return _index; }
inline void GCell::Key::update ( GCell* gcell, unsigned int depth )
{ _density=gcell->getDensity(depth); _index=gcell->getIndex(); }
inline bool operator< ( const GCell::Key& lhs, const GCell::Key& rhs )
{
float difference = Hurricane::roundfp ( lhs._density - rhs._density );
if ( difference != 0.0 ) return (difference > 0.0);
return ( lhs._index < rhs._index );
}
// -------------------------------------------------------------------
// Class : "DyKeyQueue".
class DyKeyQueue {
public:
DyKeyQueue ( unsigned int depth );
DyKeyQueue ( unsigned int depth, const std::vector<GCell*>& );
~DyKeyQueue ();
const std::set<GCell*,GCell::CompareByKey>& getGCells () const;
GCell* pop ();
void push ( GCell* );
void invalidate ( GCell* );
void revalidate ();
private:
unsigned int _depth;
std::set<GCell*,GCell::CompareByKey> _map;
std::set<GCell*> _requests;
};
// -------------------------------------------------------------------
// Utilities.

View File

@ -163,7 +163,7 @@ namespace Katabatic {
void _loadNetGlobalRouting ( Net* );
void _alignate ( Net* );
void _canonize ( Net* );
void _desaturate ( unsigned int depth, set<Net*>& );
void _desaturate ( unsigned int depth, set<Net*>&, unsigned long& total, unsigned long& globals );
void _layerAssignByLength ( unsigned long& total, unsigned long& global, set<Net*>& );
void _layerAssignByLength ( Net* , unsigned long& total, unsigned long& global, set<Net*>& );
void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set<Net*>& );