diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 4deb3ef3..32662c27 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -54,11 +54,21 @@ namespace Anabatic { string s = ""; return s; } + void Vertex::notify ( Vertex* vertex, unsigned int flags ) + { + //Vertex* vertex = getOwner(); + cdebug.log(111) << "Vertex::notify() " << vertex << endl; + // Take into account the GCell modification here. + } + + // ------------------------------------------------------------------- // Class : "Anabatic::Dijkstra". @@ -117,12 +127,13 @@ namespace Anabatic { _searchArea.merge( rpBb ); - Vertex* vertex = gcell->lookup(); + Vertex* vertex = gcell->getObserver(GCell::Observable::Vertex); if (vertex->getConnexId() < 0) { cdebug.log(111) << "Add Vertex: " << vertex << endl; vertex->setStamp ( _stamp ); vertex->setConnexId( _targets.size() ); + vertex->setFrom ( NULL ); Contact* gcontact = vertex->getGContact( _net ); rp->getBodyHook()->detach(); rp->getBodyHook()->attach( gcontact->getBodyHook() ); @@ -182,7 +193,7 @@ namespace Anabatic { if (edge == current->getFrom()) continue; GCell* gneighbor = edge->getOpposite(current->getGCell()); - Vertex* vneighbor = gneighbor->lookup(); + Vertex* vneighbor = gneighbor->getObserver(GCell::Observable::Vertex); cdebug.log(111) << "Neighbor: " << vneighbor << endl; @@ -212,10 +223,21 @@ namespace Anabatic { while ( current ) { cdebug.log(111) << "| " << current << endl; + if ( (current->getConnexId() == _connectedsId) and (current->getFrom()) ) { + cerr << Error( "Dijkstra::propagate(): There is a loop in the traceback path\n" + " while routing %s." + , getString(_net).c_str() + ) <setDistance( 0.0 ); current->setConnexId( _connectedsId ); - current = current->getPredecessor(); + + Vertex* predecessor = current->getPredecessor(); + current->setFrom( NULL ); + current = predecessor; } cdebug.tabw(111,-1); diff --git a/anabatic/src/Edges.cpp b/anabatic/src/Edges.cpp index 9c6c9164..d93aa483 100644 --- a/anabatic/src/Edges.cpp +++ b/anabatic/src/Edges.cpp @@ -32,14 +32,14 @@ namespace Anabatic { , _flags(Flags::EastSide) , _iedge(0) { - cdebug.log(110) << "GCell_Edges::Locator::Locator() " << isValid() << endl; + // cdebug.log(110) << "GCell_Edges::Locator::Locator() " << isValid() << endl; if (_gcell->getEastEdges().empty()) progress(); } EdgesHL* GCell_Edges::Locator::getClone () const { - cdebug.log(110) << "GCell_Edges::Locator::getClone()" << endl; + // cdebug.log(110) << "GCell_Edges::Locator::getClone()" << endl; return new Locator (*this); } @@ -60,48 +60,48 @@ namespace Anabatic { void GCell_Edges::Locator::progress () { - cdebug.log(110) << "GCell_Edges::Locator::progress() [from] " << _flags << " iedge:" << _iedge << endl; - cdebug.log(110) << " East:" << _gcell->getEastEdges().size() - << " North:" << _gcell->getNorthEdges().size() - << " West:" << _gcell->getWestEdges().size() - << " South:" << _gcell->getSouthEdges().size() << endl; - cdebug.log(110) << this << endl; + // cdebug.log(110) << "GCell_Edges::Locator::progress() [from] " << _flags << " iedge:" << _iedge << endl; + // cdebug.log(110) << " East:" << _gcell->getEastEdges().size() + // << " North:" << _gcell->getNorthEdges().size() + // << " West:" << _gcell->getWestEdges().size() + // << " South:" << _gcell->getSouthEdges().size() << endl; + // cdebug.log(110) << this << endl; ++_iedge; while (_flags) { if (_flags.contains(Flags::EastSide)) { if (_iedge < _gcell->getEastEdges().size()) break; - cdebug.log(110) << "Switching to North side." << endl; + // cdebug.log(110) << "Switching to North side." << endl; _flags = Flags::NorthSide; _iedge = 0; - cdebug.log(110) << this << endl; + // cdebug.log(110) << this << endl; continue; } if (_flags.contains(Flags::NorthSide)) { if (_iedge < _gcell->getNorthEdges().size()) break; - cdebug.log(110) << "Switching to West side." << endl; + // cdebug.log(110) << "Switching to West side." << endl; _flags = Flags::WestSide; _iedge = 0; - cdebug.log(110) << this << endl; + // cdebug.log(110) << this << endl; continue; } if (_flags.contains(Flags::WestSide)) { if (_iedge < _gcell->getWestEdges().size()) break; - cdebug.log(110) << "Switching to South side." << endl; + // cdebug.log(110) << "Switching to South side." << endl; _flags = Flags::SouthSide; _iedge = 0; continue; } if (_flags.contains(Flags::SouthSide)) { if (_iedge < _gcell->getSouthEdges().size()) break; - cdebug.log(110) << "All edges done." << endl; + // cdebug.log(110) << "All edges done." << endl; _flags = 0; _iedge = 0; break;; } } - cdebug.log(110) << "GCell_Edges::Locator::progress() [to] " << _flags << " iedge:" << _iedge << endl; + // cdebug.log(110) << "GCell_Edges::Locator::progress() [to] " << _flags << " iedge:" << _iedge << endl; } diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index 8589a01d..28c6f30e 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -34,6 +34,7 @@ namespace Anabatic { GCell::GCell ( AnabaticEngine* anabatic, DbU::Unit xmin, DbU::Unit ymin ) : Super(anabatic->getCell()) + , _observable() , _anabatic (anabatic) , _flags (Flags::NoFlags) , _westEdges () @@ -43,7 +44,6 @@ namespace Anabatic { , _xmin (xmin) , _ymin (ymin) , _contacts () - , _lookup (NULL) { } @@ -418,6 +418,7 @@ namespace Anabatic { cerr << Error( "GCell::_revalidate(): %s, Y Min is greater than Max.", getString(this).c_str() ); _anabatic->_updateLookup( this ); + _anabatic->getMatrix()->show(); cdebug.tabw(110,-1); } diff --git a/anabatic/src/Matrix.cpp b/anabatic/src/Matrix.cpp index a9dccdbc..cfcdd980 100644 --- a/anabatic/src/Matrix.cpp +++ b/anabatic/src/Matrix.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "hurricane/Cell.h" #include "anabatic/Matrix.h" #include "anabatic/GCell.h" @@ -26,6 +27,8 @@ namespace Anabatic { using std::cout; using std::cerr; using std::endl; + using std::setw; + using std::setfill; using std::ostringstream; using Hurricane::Error; @@ -46,8 +49,8 @@ namespace Anabatic { , _imax (0) , _jmax (0) { - _imax = _area.getWidth () / side; - _jmax = _area.getHeight() / side; + _imax = _area.getWidth () / side + ((_area.getWidth () % side) ? 1 : 0); + _jmax = _area.getHeight() / side + ((_area.getHeight() % side) ? 1 : 0); _gcells.resize( _imax*_jmax ); } @@ -60,25 +63,47 @@ namespace Anabatic { { _area = cell->getAbutmentBox(); _side = side; - _imax = _area.getWidth () / side; - _jmax = _area.getHeight() / side; + _imax = _area.getWidth () / side + ((_area.getWidth () % side) ? 1 : 0); + _jmax = _area.getHeight() / side + ((_area.getHeight() % side) ? 1 : 0); _gcells.resize( _imax*_jmax ); + + cdebug.log(110) << "Matrix::setCell(): " << this << endl; } GCell* Matrix::getUnder ( DbU::Unit x, DbU::Unit y ) const - { int index = xy2index(x,y); return (index < 0) ? NULL : _gcells[index]->getUnder(x,y); } + { + int index = xy2maxIndex(x,y); + cdebug.log(110) << "Matrix::getUnder() (" + << DbU::getValueString(x) << " " + << DbU::getValueString(y) << " " << index << endl; + return (index < 0) ? NULL : _gcells[index]->getUnder(x,y); + } void Matrix::updateLookup ( GCell* gcell ) { - //cdebug.log(110,1) << "Matrix::updateLookup(): " << gcell << endl; + cdebug.log(110,1) << "Matrix::updateLookup(): " << gcell << endl; - if (gcell->isFlat()) return; + if (gcell->isFlat()) { + cdebug.log(110) << " GCell is flat, no update." << endl; + cdebug.tabw(110,-1); + return; + } Box gcellBb = gcell->getBoundingBox(); Box updateArea = _area.getIntersection( gcellBb ); + cdebug.log(110) << "_side " << _side << endl; + cdebug.log(110) << "_area.getXMin() " << _area.getXMin() << endl; + cdebug.log(110) << "_area.getYMin() " << _area.getYMin() << endl; + cdebug.log(110) << "_area.getXMax() " << _area.getXMax() << endl; + cdebug.log(110) << "_area.getYMax() " << _area.getYMax() << endl; + cdebug.log(110) << "updateArea.getXMin() " << updateArea.getXMin() << endl; + cdebug.log(110) << "updateArea.getYMin() " << updateArea.getYMin() << endl; + cdebug.log(110) << "updateArea.getXMax() " << updateArea.getXMax() << endl; + cdebug.log(110) << "updateArea.getYMax() " << updateArea.getYMax() << endl; + if (updateArea.isEmpty()) { cerr << Error( "Matrix::updateLookup(): %s is not under area of %s." , getString(gcell).c_str() @@ -86,12 +111,20 @@ namespace Anabatic { ) << endl; } - Index indexMin = Index( this, updateArea.getXMin(), updateArea.getYMin() ); - Index indexMax = Index( this, updateArea.getXMax(), updateArea.getYMax() ); + Index indexMin = Index::asMin( this, updateArea.getXMin(), updateArea.getYMin() ); + Index indexMax = Index::asMax( this, updateArea.getXMax(), updateArea.getYMax() ); int xspan = indexMax.i() - indexMin.i(); - //cdebug.log(110) << "indexMin:" << indexMin << endl; - //cdebug.log(110) << "indexMax:" << indexMax << endl; + DbU::Unit dx = updateArea.getXMin() - _area.getXMin(); + DbU::Unit dy = updateArea.getYMin() - _area.getYMin(); + + cdebug.log(110) << "raw_i:" << (dx / _side + ((dx%_side) ? 1 : 0)) + << " raw_j:" << (dy / _side + ((dy%_side) ? 1 : 0)) << endl; + cdebug.log(110) << "indexMin:" << indexMin << endl; + cdebug.log(110) << "indexMax:" << indexMax << endl; + cdebug.log(110) << "xspan: " << xspan << endl; + + if (not indexMin.valid() or not indexMax.valid()) { cdebug.tabw(110,-1); return; } int index = indexMin.index(); while ( index <= indexMax.index() ) { @@ -101,7 +134,18 @@ namespace Anabatic { else index += _imax - xspan; } - //cdebug.tabw(110,-1); + cdebug.tabw(110,-1); + } + + + void Matrix::show () const + { + cdebug.log(111) << this << endl; + for ( size_t i=0 ; i<_gcells.size() ; ++i ) { + cdebug.log(111) << "[" << setw(3) << setfill('0') << i << setfill(' ') << "] (" + << setw(3) << index2i(i) << "," + << setw(3) << index2j(i) << ") " << _gcells[i] << endl; + } } diff --git a/anabatic/src/anabatic/AnabaticEngine.h b/anabatic/src/anabatic/AnabaticEngine.h index af3f2f42..8683d40e 100644 --- a/anabatic/src/anabatic/AnabaticEngine.h +++ b/anabatic/src/anabatic/AnabaticEngine.h @@ -56,6 +56,7 @@ namespace Anabatic { virtual Configuration* getConfiguration (); inline CellViewer* getViewer () const; inline void setViewer ( CellViewer* ); + inline const Matrix* getMatrix () const; inline const vector& getGCells () const; inline GCell* getSouthWestGCell () const; inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const; @@ -98,6 +99,7 @@ namespace Anabatic { inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; } inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } + inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; } inline const vector& AnabaticEngine::getGCells () const { return _gcells; } inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; } inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); } diff --git a/anabatic/src/anabatic/Dijkstra.h b/anabatic/src/anabatic/Dijkstra.h index 60404cbc..cba254c0 100644 --- a/anabatic/src/anabatic/Dijkstra.h +++ b/anabatic/src/anabatic/Dijkstra.h @@ -19,6 +19,7 @@ #include #include +#include "hurricane/Observer.h" namespace Hurricane { class Net; } @@ -29,6 +30,7 @@ namespace Anabatic { using std::set; using std::multiset; + using Hurricane::Observer; using Hurricane::Net; class AnabaticEngine; @@ -44,6 +46,8 @@ namespace Anabatic { }; public: static float unreached; + public: + static void notify ( Vertex*, unsigned flags ); public: inline Vertex ( GCell* ); inline Vertex ( size_t id ); @@ -69,29 +73,33 @@ namespace Anabatic { Vertex ( const Vertex& ); Vertex& operator= ( const Vertex& ); private: - size_t _id; - GCell* _gcell; - int _connexId; - int _stamp; - float _distance; - Edge* _from; + size_t _id; + GCell* _gcell; + Observer _observer; + int _connexId; + int _stamp; + float _distance; + Edge* _from; }; inline Vertex::Vertex ( GCell* gcell ) : _id (gcell->getId()) , _gcell (gcell) + , _observer(this) , _connexId(-1) , _stamp (-1) , _distance(unreached) , _from (NULL) { - gcell->setLookup( this ); + //gcell->setLookup( this ); + gcell->setObserver( GCell::Observable::Vertex, &_observer ); } inline Vertex::Vertex ( size_t id ) : _id (id) , _gcell (NULL) + , _observer((Vertex*)0x1) // To trick the NULL detection. , _connexId(-1) , _stamp (-1) , _distance(unreached) @@ -114,11 +122,12 @@ namespace Anabatic { inline void Vertex::setConnexId ( int id ) { _connexId=id; } inline Vertex* Vertex::getPredecessor () const - { return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->lookup() : NULL; } + { return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->getObserver(GCell::Observable::Vertex) : NULL; } inline bool Vertex::CompareById::operator() ( const Vertex* lhs, const Vertex* rhs ) { return lhs->getId() < rhs->getId(); } + typedef set VertexSet; diff --git a/anabatic/src/anabatic/Edges.h b/anabatic/src/anabatic/Edges.h index bca4b254..347d61c7 100644 --- a/anabatic/src/anabatic/Edges.h +++ b/anabatic/src/anabatic/Edges.h @@ -89,7 +89,7 @@ namespace Anabatic { , _flags(locator._flags) , _iedge(locator._iedge) { - cdebug.log(110) << "GCell_Edges::Locator::Locator(const Locator&)" << std::endl; + // cdebug.log(110) << "GCell_Edges::Locator::Locator(const Locator&)" << std::endl; } diff --git a/anabatic/src/anabatic/GCell.h b/anabatic/src/anabatic/GCell.h index e977723d..1c742fef 100644 --- a/anabatic/src/anabatic/GCell.h +++ b/anabatic/src/anabatic/GCell.h @@ -34,6 +34,8 @@ namespace Anabatic { using std::string; using std::vector; + using Hurricane::StaticObservable; + using Hurricane::BaseObserver; using Hurricane::Name; using Hurricane::Record; using Hurricane::DbU; @@ -54,6 +56,17 @@ namespace Anabatic { class GCell : public ExtensionGo { public: typedef ExtensionGo Super; + public: + class Observable : public StaticObservable<1> { + public: + enum Indexes { Vertex = 0 + }; + public: + inline Observable (); + private: + Observable ( const StaticObservable& ); + Observable& operator= ( const StaticObservable& ); + }; public: static Box getBorder ( const GCell*, const GCell* ); public: @@ -88,10 +101,6 @@ namespace Anabatic { GCell* vcut ( DbU::Unit x ); bool doGrid (); Contact* getGContact ( Net* ); - template - inline void setLookup ( Type* decorator ); - template - inline Type* lookup () const; // Misc. functions. inline const Flags& flags () const; inline Flags& flags (); @@ -102,27 +111,33 @@ namespace Anabatic { void _revalidate (); void _moveEdges ( GCell* dest, size_t ibegin, Flags flags ); public: + // Observers. + inline void setObserver ( size_t slot, BaseObserver* ); + template + inline OwnerT* getObserver ( size_t slot ); + inline void notify ( unsigned int flags ); // ExtensionGo support. - inline const Name& staticGetName (); - virtual const Name& getName () const; - virtual void translate ( const DbU::Unit&, const DbU::Unit& ); - virtual Box getBoundingBox () const; - public: - // Inspector support. - virtual string _getTypeName () const; - virtual string _getString () const; - virtual Record* _getRecord () const; - protected: - GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin ); - virtual ~GCell (); - GCell* _create ( DbU::Unit xmin, DbU::Unit ymin ); - virtual void _postCreate (); - virtual void _preDestroy (); - private: - GCell ( const GCell& ); - GCell& operator= ( const GCell& ); + inline const Name& staticGetName (); + virtual const Name& getName () const; + virtual void translate ( const DbU::Unit&, const DbU::Unit& ); + virtual Box getBoundingBox () const; + public: + // Inspector support. + virtual string _getTypeName () const; + virtual string _getString () const; + virtual Record* _getRecord () const; + protected: + GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin ); + virtual ~GCell (); + GCell* _create ( DbU::Unit xmin, DbU::Unit ymin ); + virtual void _postCreate (); + virtual void _preDestroy (); + private: + GCell ( const GCell& ); + GCell& operator= ( const GCell& ); private: static Name _extensionName; + Observable _observable; AnabaticEngine* _anabatic; Flags _flags; vector _westEdges; @@ -132,7 +147,6 @@ namespace Anabatic { DbU::Unit _xmin; DbU::Unit _ymin; vector _contacts; - void* _lookup; }; @@ -172,11 +186,17 @@ namespace Anabatic { return Interval( getXMin(), getXMax() ); } - template - inline void GCell::setLookup ( Type* decorator ) { _lookup=reinterpret_cast(decorator); } + inline void GCell::setObserver ( size_t slot, BaseObserver* observer ) + { _observable.setObserver( slot, observer ); } - template - inline Type* GCell::lookup () const { return reinterpret_cast( _lookup ); } + template + inline OwnerT* GCell::getObserver ( size_t slot ) + { return _observable.getObserver(slot); } + + inline void GCell::notify ( unsigned int flags ) + { _observable.notify( flags ); } + + inline GCell::Observable::Observable () : StaticObservable<1>() { } // ------------------------------------------------------------------- diff --git a/anabatic/src/anabatic/Matrix.h b/anabatic/src/anabatic/Matrix.h index b6357c27..cf603a4b 100644 --- a/anabatic/src/anabatic/Matrix.h +++ b/anabatic/src/anabatic/Matrix.h @@ -43,11 +43,14 @@ namespace Anabatic { class Matrix { public: class Index { + public: + static inline Matrix::Index asMin ( Matrix*, DbU::Unit x, DbU::Unit y ); + static inline Matrix::Index asMax ( Matrix*, DbU::Unit x, DbU::Unit y ); + static inline Matrix::Index asMin ( Matrix*, Point position ); + static inline Matrix::Index asMax ( Matrix*, Point position ); public: inline Index ( Matrix*, int index ); inline Index ( Matrix*, int i, int j ); - inline Index ( Matrix*, DbU::Unit x, DbU::Unit y ); - inline Index ( Matrix*, Point position ); inline Matrix* matrix () const; inline const int& index () const; inline int& index (); @@ -78,8 +81,10 @@ namespace Anabatic { inline int index2i ( const Index& ) const; inline int index2j ( const Index& ) const; inline int ij2index ( int i, int j ) const; - inline int xy2index ( DbU::Unit x, DbU::Unit y ) const; - inline int xy2index ( Point ) const; + inline int xy2minIndex ( DbU::Unit x, DbU::Unit y ) const; + inline int xy2minIndex ( Point ) const; + inline int xy2maxIndex ( DbU::Unit x, DbU::Unit y ) const; + inline int xy2maxIndex ( Point ) const; inline Index& west ( Index& ) const; inline Index& east ( Index& ) const; inline Index& south ( Index& ) const; @@ -88,6 +93,7 @@ namespace Anabatic { inline GCell* getUnder ( Point ) const; void setCell ( Cell*, DbU::Unit side ); void updateLookup ( GCell* ); + void show () const; // Inspector support. virtual Record* _getRecord () const; virtual string _getString () const; @@ -127,14 +133,29 @@ namespace Anabatic { { if ((i < 0) or (i >= _imax)) return -1; if ((j < 0) or (j >= _jmax)) return -1; - return j*_jmax + i; + return j*_imax + i; } - inline int Matrix::xy2index ( DbU::Unit x, DbU::Unit y ) const - { return ij2index( (x - _area.getXMin()) / _side, (y - _area.getYMin()) / _side ); } + inline int Matrix::xy2minIndex ( DbU::Unit x, DbU::Unit y ) const + { + DbU::Unit dx = x - _area.getXMin(); + DbU::Unit dy = y - _area.getYMin(); + return ij2index( dx / _side + ((dx%_side) ? 1 : 0) + , dy / _side + ((dy%_side) ? 1 : 0) ); + } - inline int Matrix::xy2index ( Point p ) const - { return xy2index( p.getX(), p.getY() ); } + inline int Matrix::xy2minIndex ( Point p ) const + { return xy2minIndex( p.getX(), p.getY() ); } + + inline int Matrix::xy2maxIndex ( DbU::Unit x, DbU::Unit y ) const + { + DbU::Unit dx = x - _area.getXMin(); + DbU::Unit dy = y - _area.getYMin(); + return ij2index( dx / _side, dy / _side ); + } + + inline int Matrix::xy2maxIndex ( Point p ) const + { return xy2maxIndex( p.getX(), p.getY() ); } inline Matrix::Index& Matrix::west ( Matrix::Index& index ) const { @@ -186,11 +207,13 @@ namespace Anabatic { // Matrix::Index inline functions. - inline Matrix::Index::Index ( Matrix* m, int index ) : _matrix(m), _index(index) { } - inline Matrix::Index::Index ( Matrix* m, int i, int j ) : _matrix(m), _index(m->ij2index(i,j)) { } - inline Matrix::Index::Index ( Matrix* m, DbU::Unit x, DbU::Unit y ) : _matrix(m), _index(m->xy2index(x,y)) { } - inline Matrix::Index::Index ( Matrix* m, Point position ) : _matrix(m), _index(m->xy2index(position)) { } + inline Matrix::Index::Index ( Matrix* m, int index ) : _matrix(m), _index(index) { } + inline Matrix::Index::Index ( Matrix* m, int i, int j ) : _matrix(m), _index(m->ij2index(i,j)) { } + inline Matrix::Index Matrix::Index::asMin ( Matrix* m, DbU::Unit x, DbU::Unit y ) { return Index( m, m->xy2minIndex(x,y) ); } + inline Matrix::Index Matrix::Index::asMin ( Matrix* m, Point position ) { return Index( m, m->xy2minIndex(position) ); } + inline Matrix::Index Matrix::Index::asMax ( Matrix* m, DbU::Unit x, DbU::Unit y ) { return Index( m, m->xy2maxIndex(x,y) ); } + inline Matrix::Index Matrix::Index::asMax ( Matrix* m, Point position ) { return Index( m, m->xy2maxIndex(position) ); } inline Matrix* Matrix::Index::matrix () const { return _matrix; } inline const int& Matrix::Index::index () const { return _index; } inline int& Matrix::Index::index () { return _index; }