Anabatic transient commit 5.

* Bug: In Anabatic:
    - In Dijkstra/Vertex, use the new Observer for fast access from the GCells.
    - In Dijktra::propagate() loop detection.
    - In Dijkstra, reset the "_from" of vertexes between two propagates on
      the same Net (otherwise: loops...).
    - In Matrix, there must be two different way of calculating an index from
      a position. One for the min, which is rounded to superior. And one for
      the max which is rounded to inferior.
    - In Matrix::updateArea(), checks for invalid indexes.
This commit is contained in:
Jean-Paul Chaput 2016-06-03 17:29:22 +02:00
parent 747027f23a
commit aa20813342
9 changed files with 201 additions and 80 deletions

View File

@ -54,11 +54,21 @@ namespace Anabatic {
string s = "<Vertex " + getString(_id)
+ " connexId:" + getString(_connexId)
+ " d:" + ((_distance == unreached) ? "unreached" : getString(_distance) )
+ " stamp:" + (hasValidStamp() ? "valid" : "outdated")
+ " from:" + ((_from) ? "set" : "NULL")
+ ">";
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* vertex = gcell->getObserver<Vertex>(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>();
Vertex* vneighbor = gneighbor->getObserver<Vertex>(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()
) <<endl;
break;
}
_sources.insert( current );
current->setDistance( 0.0 );
current->setConnexId( _connectedsId );
current = current->getPredecessor();
Vertex* predecessor = current->getPredecessor();
current->setFrom( NULL );
current = predecessor;
}
cdebug.tabw(111,-1);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -16,6 +16,7 @@
#include <sstream>
#include <iostream>
#include <iomanip>
#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;
}
}

View File

@ -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<GCell*>& 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<GCell*>& 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); }

View File

@ -19,6 +19,7 @@
#include <set>
#include <iomanip>
#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<Vertex> _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<Vertex>( this );
//gcell->setLookup<Vertex>( 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<Vertex>() : NULL; }
{ return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->getObserver<Vertex>(GCell::Observable::Vertex) : NULL; }
inline bool Vertex::CompareById::operator() ( const Vertex* lhs, const Vertex* rhs )
{ return lhs->getId() < rhs->getId(); }
typedef set<Vertex*,Vertex::CompareById> VertexSet;

View File

@ -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;
}

View File

@ -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<typename Type>
inline void setLookup ( Type* decorator );
template<typename Type>
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<typename OwnerT>
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<Edge*> _westEdges;
@ -132,7 +147,6 @@ namespace Anabatic {
DbU::Unit _xmin;
DbU::Unit _ymin;
vector<Contact*> _contacts;
void* _lookup;
};
@ -172,11 +186,17 @@ namespace Anabatic {
return Interval( getXMin(), getXMax() );
}
template<typename Type>
inline void GCell::setLookup ( Type* decorator ) { _lookup=reinterpret_cast<void*>(decorator); }
inline void GCell::setObserver ( size_t slot, BaseObserver* observer )
{ _observable.setObserver( slot, observer ); }
template<typename Type>
inline Type* GCell::lookup () const { return reinterpret_cast<Type*>( _lookup ); }
template<typename OwnerT>
inline OwnerT* GCell::getObserver ( size_t slot )
{ return _observable.getObserver<OwnerT>(slot); }
inline void GCell::notify ( unsigned int flags )
{ _observable.notify( flags ); }
inline GCell::Observable::Observable () : StaticObservable<1>() { }
// -------------------------------------------------------------------

View File

@ -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; }