From 15a61c5f966b4aea383be1b32dcb2e6be6409f7b Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 23 Mar 2010 09:25:15 +0000 Subject: [PATCH] * ./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 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. --- katabatic/src/GCell.cpp | 83 ++++++++++++++++++++++- katabatic/src/LayerAssign.cpp | 46 ++++++++++--- katabatic/src/katabatic/GCell.h | 61 ++++++++++++++++- katabatic/src/katabatic/KatabaticEngine.h | 2 +- 4 files changed, 180 insertions(+), 12 deletions(-) diff --git a/katabatic/src/GCell.cpp b/katabatic/src/GCell.cpp index c974afed..27894994 100644 --- a/katabatic/src/GCell.cpp +++ b/katabatic/src/GCell.cpp @@ -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& globalNets ) + bool GCell::stepDesaturate ( unsigned int depth, set& 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& gcells ) + : _depth (depth) + , _map () + , _requests() + { + for ( size_t i=0 ; i& 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::iterator iinserted; + std::set::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::iterator igcell = _map.begin(); + GCell* gcell = *igcell; + _map.erase ( igcell ); + } + + // ------------------------------------------------------------------- // Utilities. diff --git a/katabatic/src/LayerAssign.cpp b/katabatic/src/LayerAssign.cpp index c499a145..4dbf3eb6 100644 --- a/katabatic/src/LayerAssign.cpp +++ b/katabatic/src/LayerAssign.cpp @@ -88,7 +88,10 @@ namespace Katabatic { } - void KatabaticEngine::_desaturate ( unsigned int depth, set& globalNets ) + void KatabaticEngine::_desaturate ( unsigned int depth + , set& 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 gcells = *(_gcellGrid->getGCellVector()); + //vector gcells = *(_gcellGrid->getGCellVector()); + DyKeyQueue queue ( depth, *(_gcellGrid->getGCellVector()) ); + AutoSegment* segment = NULL; + vector invalidateds; bool optimized = true; while ( optimized ) { optimized = false; - sort ( gcells.begin(), gcells.end(), GCell::CompareByDensity(depth) ); - for ( size_t i=0 ; iisSaturated ( depth ) ) break; + //sort ( gcells.begin(), gcells.end(), GCell::CompareByDensity(depth) ); + queue.revalidate (); + + std::set::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 ; jstepDesaturate ( 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 (); diff --git a/katabatic/src/katabatic/GCell.h b/katabatic/src/katabatic/GCell.h index d87012e8..959049bd 100644 --- a/katabatic/src/katabatic/GCell.h +++ b/katabatic/src/katabatic/GCell.h @@ -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& ); - bool stepDesaturate ( unsigned int depth, set& ); + bool stepDesaturate ( unsigned int depth, set&, 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& ); + ~DyKeyQueue (); + const std::set& getGCells () const; + GCell* pop (); + void push ( GCell* ); + void invalidate ( GCell* ); + void revalidate (); + private: + unsigned int _depth; + std::set _map; + std::set _requests; + }; + + // ------------------------------------------------------------------- // Utilities. diff --git a/katabatic/src/katabatic/KatabaticEngine.h b/katabatic/src/katabatic/KatabaticEngine.h index 055debef..c3a14ab8 100644 --- a/katabatic/src/katabatic/KatabaticEngine.h +++ b/katabatic/src/katabatic/KatabaticEngine.h @@ -163,7 +163,7 @@ namespace Katabatic { void _loadNetGlobalRouting ( Net* ); void _alignate ( Net* ); void _canonize ( Net* ); - void _desaturate ( unsigned int depth, set& ); + void _desaturate ( unsigned int depth, set&, unsigned long& total, unsigned long& globals ); void _layerAssignByLength ( unsigned long& total, unsigned long& global, set& ); void _layerAssignByLength ( Net* , unsigned long& total, unsigned long& global, set& ); void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set& );