Anabatic transient commit 4.

* Bug: In Anabatic:
    - In Edge, materialize was done before the Edge get it's final position.
      Must be invalidated afterwards for the UpdateSession to put him in
      the correct QuadTree.
    - Functional (debugged) Dijkstra skeleton.
This commit is contained in:
Jean-Paul Chaput 2016-05-30 18:52:38 +02:00
parent 1f4d6b7e83
commit fac3474d55
8 changed files with 225 additions and 79 deletions

View File

@ -49,6 +49,16 @@ namespace Anabatic {
{ return _stamp == getAnabatic()->getStamp(); }
string Vertex::_getString () const
{
string s = "<Vertex " + getString(_id)
+ " connexId:" + getString(_connexId)
+ " d:" + ((_distance == unreached) ? "unreached" : getString(_distance) )
+ ">";
return s;
}
// -------------------------------------------------------------------
// Class : "Anabatic::Dijkstra".
@ -79,12 +89,17 @@ namespace Anabatic {
void Dijkstra::load ( Net* net )
{
_net = net;
cdebug.log(111,1) << "Dijkstra::load() " << _net << endl;
UpdateSession::open();
_sources.clear();
_targets.clear();
_searchArea.makeEmpty();
_stamp = _anabatic->incStamp();
for ( Component* component : net->getRoutingPads() ) {
for ( Component* component : _net->getRoutingPads() ) {
RoutingPad* rp = dynamic_cast<RoutingPad*>( component );
if (rp) {
Box rpBb = rp->getBoundingBox();
@ -94,8 +109,8 @@ namespace Anabatic {
if (not gcell) {
cerr << Error( "Dijkstra::load(): %s of %s is not under any GCell.\n"
" It will be ignored ans the routing will be incomplete."
, getString(rp ).c_str()
, getString(net).c_str()
, getString(rp ).c_str()
, getString(_net).c_str()
) << endl;
continue;
}
@ -104,22 +119,27 @@ namespace Anabatic {
Vertex* vertex = gcell->lookup<Vertex>();
if (vertex->getConnexId() < 0) {
cdebug.log(111) << "Add Vertex: " << vertex << endl;
vertex->setStamp ( _stamp );
vertex->setConnexId( _targets.size() );
vertex->getGContact( _net );
Contact* gcontact = vertex->getGContact( _net );
rp->getBodyHook()->detach();
rp->getBodyHook()->attach( gcontact->getBodyHook() );
_targets.insert( vertex );
}
}
}
UpdateSession::close();
cdebug.tabw(111,-1);
}
void Dijkstra::selectFirstSource ()
{
if (_targets.empty()) {
cerr << Error( "Dijkstra::selectFirstSource(): %s has no vertexes to route, ignored.\n"
cerr << Error( "Dijkstra::selectFirstSource(): %s has no vertexes to route, ignored."
, getString(_net).c_str()
) << endl;
return;
@ -137,75 +157,126 @@ namespace Anabatic {
}
}
_targets.erase( firstSource );
_targets.erase ( firstSource );
_sources.insert( firstSource );
cdebug.log(111) << "Dijkstra::selectFirstSource() " << *_sources.begin() << endl;
}
void Dijkstra::propagate ()
bool Dijkstra::propagate ()
{
cdebug.log(111,1) << "Dijkstra::propagate() " << _net << endl;
while ( not _queue.empty() ) {
_queue.dump();
Vertex* current = _queue.top();
_queue.pop();
cdebug.log(111) << "Pop: (size:" << _queue.size() << ") " << current << endl;
if ((current->getConnexId() == _connectedsId) or (current->getConnexId() < 0)) {
for ( Edge* edge : current->getGCell()->getEdges() ) {
if (edge == current->getFrom()) continue;
GCell* gneighbor = edge->getOpposite(current->getGCell());
Vertex* vneighbor = gneighbor->lookup<Vertex>();
cdebug.log(111) << "Neighbor: " << vneighbor << endl;
if (vneighbor->getConnexId() == _connectedsId) continue;
float distance = current->getDistance() + edge->getDistance();
if (distance < current->getDistance()) {
if (distance < vneighbor->getDistance()) {
if (vneighbor->getDistance() != Vertex::unreached) _queue.erase( vneighbor );
else vneighbor->setStamp( _stamp );
vneighbor->setDistance( distance );
vneighbor->setFrom ( edge );
_queue.push( vneighbor );
cdebug.log(111) << "Push: (size:" << _queue.size() << ") " << vneighbor << endl;
}
}
continue;
}
// We did reach another target (different <connexId>).
// Tag back the path.
cdebug.log(111) << "Trace back" << endl;
_targets.erase( current );
while ( current ) {
cdebug.log(111) << "| " << current << endl;
_sources.insert( current );
current->setDistance( 0.0 );
current->setConnexId( _connectedsId );
current = current->getPredecessor();
}
break;
cdebug.tabw(111,-1);
return true;
}
cerr << Error( "Dijkstra::propagate(): %s has unreachable targets."
, getString(_net).c_str()
) << endl;
cdebug.tabw(111,-1);
return false;
}
void Dijkstra::run ()
{
if (_sources.empty()) return;
cdebug.log(111,1) << "Dijkstra::run() on " << _net << endl;
selectFirstSource();
if (_sources.empty()) {
cdebug.log(111) << "No source to start, not routed." << endl;
cdebug.tabw(111,-1);
return;
}
UpdateSession::open();
Vertex* source = *_sources.begin();
_queue.clear();
_queue.push( *_sources.begin() );
_connectedsId = (*_sources.begin())->getConnexId();
_queue.push( source );
_connectedsId = source->getConnexId();
source->setDistance( 0.0 );
while ( not _targets.empty() ) propagate();
cdebug.log(111) << "Push source: (size:" << _queue.size() << ") "
<< source
<< " _connectedsId:" << _connectedsId << endl;
while ( not _targets.empty() and propagate() );
toWires();
_queue.clear();
UpdateSession::close();
cdebug.tabw(111,-1);
}
void Dijkstra::toWires ()
{
cdebug.log(111,1) << "Dijkstra::toWires() " << _net << endl;
for ( Vertex* vertex : _sources ) {
Edge* from = vertex->getFrom();
if (not from) continue;
cdebug.log(111) << "| " << vertex << endl;
from->incRealOccupancy( 1 );
Vertex* source = vertex;
Vertex* target = source->getPredecessor();
@ -214,7 +285,7 @@ namespace Anabatic {
std::swap( source, target );
Contact* sourceContact = source->getGContact( _net );
Contact* targetContact = source->getGContact( _net );
Contact* targetContact = target->getGContact( _net );
if (from->isHorizontal()) {
Horizontal::create( sourceContact
@ -232,6 +303,8 @@ namespace Anabatic {
);
}
}
cdebug.tabw(111,-1);
}

View File

@ -190,6 +190,7 @@ namespace Anabatic {
_axis = side.getCenter();
_capacity = getAnabatic()->getCapacity( side, _flags );
Super::invalidate( false );
_flags.reset( Flags::Invalidated );
cdebug.log(110) << "Edge::_revalidate() " << this << endl;
}

View File

@ -32,66 +32,87 @@ namespace Anabatic {
, _flags(Flags::EastSide)
, _iedge(0)
{
cdebug.log(110) << "GCell_Edges::Locator::Locator() " << isValid() << endl;
if (_gcell->getEastEdges().empty()) progress();
}
EdgesHL* GCell_Edges::Locator::getClone () const
{ return new Locator (*this); }
{
cdebug.log(110) << "GCell_Edges::Locator::getClone()" << endl;
return new Locator (*this);
}
Edge* GCell_Edges::Locator::getElement () const
{
if (_flags & Flags::EastSide ) return _gcell->getEastEdges ()[_iedge];
if (_flags & Flags::NorthSide) return _gcell->getNorthEdges()[_iedge];
if (_flags & Flags::WestSide ) return _gcell->getWestEdges ()[_iedge];
if (_flags & Flags::SouthSide) return _gcell->getSouthEdges()[_iedge];
if (_flags.contains(Flags::EastSide )) return _gcell->getEastEdges ()[_iedge];
if (_flags.contains(Flags::NorthSide)) return _gcell->getNorthEdges()[_iedge];
if (_flags.contains(Flags::WestSide )) return _gcell->getWestEdges ()[_iedge];
if (_flags.contains(Flags::SouthSide)) return _gcell->getSouthEdges()[_iedge];
return NULL;
}
bool GCell_Edges::Locator::isValid () const
{ return not _flags; }
{ return _flags; }
void GCell_Edges::Locator::progress ()
{
cdebug.log(110) << "GCell_Edges::Locator::progress()" << 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 & Flags::EastSide) {
if (_flags.contains(Flags::EastSide)) {
if (_iedge < _gcell->getEastEdges().size()) break;
cdebug.log(110) << "Switching to North side." << endl;
_flags = Flags::NorthSide;
_iedge = 0;
cdebug.log(110) << this << endl;
continue;
}
if (_flags & Flags::NorthSide) {
if (_flags.contains(Flags::NorthSide)) {
if (_iedge < _gcell->getNorthEdges().size()) break;
cdebug.log(110) << "Switching to West side." << endl;
_flags = Flags::WestSide;
_iedge = 0;
cdebug.log(110) << this << endl;
continue;
}
if (_flags & Flags::WestSide) {
if (_flags.contains(Flags::WestSide)) {
if (_iedge < _gcell->getWestEdges().size()) break;
cdebug.log(110) << "Switching to South side." << endl;
_flags = Flags::SouthSide;
_iedge = 0;
continue;
}
if (_flags & Flags::SouthSide) {
if (_flags.contains(Flags::SouthSide)) {
if (_iedge < _gcell->getSouthEdges().size()) break;
cdebug.log(110) << "All edges done." << endl;
_flags = 0;
_iedge = 0;
break;;
}
}
cdebug.log(110) << "GCell_Edges::Locator::progress() [to] " << _flags << " iedge:" << _iedge << endl;
}
string GCell_Edges::Locator::_getString () const
{
string s = "<GCell_Edges::Locator";
if (_flags & Flags::EastSide ) s += "East[" + getString(_iedge) + "]";
if (_flags & Flags::NorthSide) s += "North[" + getString(_iedge) + "]";
if (_flags & Flags::WestSide ) s += "West[" + getString(_iedge) + "]";
if (_flags & Flags::SouthSide) s += "South[" + getString(_iedge) + "]";
if (_flags == 0) s += "invalid";
if (_flags.contains(Flags::EastSide )) s += " East[" + getString(_iedge) + "]";
if (_flags.contains(Flags::NorthSide)) s += " North[" + getString(_iedge) + "]";
if (_flags.contains(Flags::WestSide )) s += " West[" + getString(_iedge) + "]";
if (_flags.contains(Flags::SouthSide)) s += " South[" + getString(_iedge) + "]";
if (_flags == 0) s += " invalid";
s += ">";
return s;
}

View File

@ -16,6 +16,7 @@
#include <iostream>
#include "hurricane/Contact.h"
#include "hurricane/UpdateSession.h"
#include "anabatic/GCell.h"
#include "anabatic/AnabaticEngine.h"
@ -25,6 +26,7 @@ namespace Anabatic {
using std::cerr;
using std::endl;
using Hurricane::Error;
using Hurricane::UpdateSession;
Name GCell::_extensionName = "Anabatic::GCell";
@ -208,7 +210,6 @@ namespace Anabatic {
const GCell* current = this;
while ( current ) {
cerr << "current:" << current << endl;
if (not current->isFlat() and current->getBoundingBox().contains(x,y)) break;
if (x >= current->getXMax()) { current = current->getEast (); continue; }
@ -378,6 +379,8 @@ namespace Anabatic {
return false;
}
UpdateSession::open();
GCell* row = this;
GCell* column = NULL;
DbU::Unit ycut = vspan.getVMin()+side;
@ -395,6 +398,8 @@ namespace Anabatic {
column = column->vcut( xcut );
}
UpdateSession::close();
return true;
}
@ -511,18 +516,24 @@ namespace Anabatic {
Contact* GCell::getGContact ( Net* net )
{
for ( Contact* contact : _contacts ) {
if (contact->getNet() == net) return contact;
if (contact->getNet() == net) {
cdebug.log(111) << "GCell::getGContact(): " << contact << endl;
return contact;
}
}
Point center = getBoundingBox().getCenter();
return Contact::create( net
, _anabatic->getConfiguration()->getGContactLayer()
, center.getX()
, center.getY()
, DbU::fromLambda(2.0)
, DbU::fromLambda(2.0)
);
Point center = getBoundingBox().getCenter();
Contact* contact = Contact::create( net
, _anabatic->getConfiguration()->getGContactLayer()
, center.getX()
, center.getY()
, DbU::fromLambda(2.0)
, DbU::fromLambda(2.0)
);
cdebug.log(111) << "GCell::getGContact(): " << contact << endl;
return contact;
}

View File

@ -23,6 +23,7 @@
#include <hurricane/Error.h>
#include <hurricane/Breakpoint.h>
#include <hurricane/DebugSession.h>
#include <hurricane/UpdateSession.h>
#include <hurricane/Go.h>
#include <hurricane/Net.h>
#include <hurricane/Cell.h>
@ -46,6 +47,7 @@ namespace Anabatic {
using Hurricane::Exception;
using Hurricane::Breakpoint;
using Hurricane::DebugSession;
using Hurricane::UpdateSession;
using Hurricane::Point;
using Hurricane::Entity;
using Hurricane::Net;
@ -75,6 +77,8 @@ namespace Anabatic {
void anabaticTest_2 ( AnabaticEngine* engine )
{
UpdateSession::open();
GCell* row0 = engine->getSouthWestGCell();
DbU::Unit xcorner = engine->getCell()->getAbutmentBox().getXMin();
DbU::Unit ycorner = engine->getCell()->getAbutmentBox().getYMin();
@ -106,6 +110,8 @@ namespace Anabatic {
cdebug.log(119,1) << "row1+1: " << row1 << endl;
cdebug.tabw(119,-1);
UpdateSession::close();
}
@ -132,13 +138,17 @@ namespace Anabatic {
engine->getSouthWestGCell()->doGrid();
Net* net = cell->getNet( "ialu.inv_x2_3_sig" );
if (net) {
Dijkstra* dijkstra = new Dijkstra ( engine );
vector<Net*> nets;
nets.push_back( cell->getNet( "ialu.inv_x2_3_sig" ) );
nets.push_back( cell->getNet( "iram.na3_x1_13_sig" ) );
nets.push_back( cell->getNet( "iram.ram_idx_7(1)" ) );
Dijkstra* dijkstra = new Dijkstra ( engine );
for ( Net* net : nets ) {
dijkstra->load( net );
dijkstra->run();
delete dijkstra;
}
delete dijkstra;
}

View File

@ -18,6 +18,7 @@
#define ANABATIC_DIJKSTRA_H
#include <set>
#include <iomanip>
namespace Hurricane {
class Net;
}
@ -27,6 +28,7 @@ namespace Hurricane {
namespace Anabatic {
using std::set;
using std::multiset;
using Hurricane::Net;
class AnabaticEngine;
@ -41,29 +43,31 @@ namespace Anabatic {
inline bool operator() ( const Vertex* lhs, const Vertex* rhs );
};
public:
static float unreached;
public:
inline Vertex ( GCell* );
inline Vertex ( size_t id );
inline ~Vertex ();
inline unsigned int getId () const;
inline GCell* getGCell () const;
inline AnabaticEngine* getAnabatic () const;
inline Contact* getGContact ( Net* );
bool hasValidStamp () const;
inline Point getCenter () const;
inline float getDistance () const;
inline int getStamp () const;
inline int getConnexId () const;
inline Edge* getFrom () const;
inline Vertex* getPredecessor () const;
inline void setDistance ( float );
inline void setStamp ( int );
inline void setConnexId ( int );
inline void setFrom ( Edge* );
static float unreached;
public:
inline Vertex ( GCell* );
inline Vertex ( size_t id );
inline ~Vertex ();
inline unsigned int getId () const;
inline GCell* getGCell () const;
inline AnabaticEngine* getAnabatic () const;
inline Contact* getGContact ( Net* );
bool hasValidStamp () const;
inline Point getCenter () const;
inline float getDistance () const;
inline int getStamp () const;
inline int getConnexId () const;
inline Edge* getFrom () const;
inline Vertex* getPredecessor () const;
inline void setDistance ( float );
inline void setStamp ( int );
inline void setConnexId ( int );
inline void setFrom ( Edge* );
// Inspector support.
string _getString () const;
private:
Vertex ( const Vertex& );
Vertex& operator= ( const Vertex& );
Vertex ( const Vertex& );
Vertex& operator= ( const Vertex& );
private:
size_t _id;
GCell* _gcell;
@ -132,13 +136,14 @@ namespace Anabatic {
inline Vertex* top ();
inline void pop ();
inline void clear ();
inline void dump () const;
private:
class CompareByDistance {
public:
inline bool operator() ( const Vertex* lhs, const Vertex* rhs );
};
private:
set<Vertex*,CompareByDistance> _queue;
multiset<Vertex*,CompareByDistance> _queue;
};
@ -146,15 +151,26 @@ namespace Anabatic {
{ return lhs->getDistance() < rhs->getDistance(); }
inline PriorityQueue::PriorityQueue () : _queue() { }
inline PriorityQueue::~PriorityQueue () { }
inline bool PriorityQueue::empty () const { return _queue.empty(); }
inline size_t PriorityQueue::size () const { return _queue.size(); }
inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); }
inline void PriorityQueue::erase ( Vertex* v ) { _queue.erase(v); }
inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); }
inline void PriorityQueue::pop () { _queue.erase(_queue.begin()); }
inline void PriorityQueue::clear () { _queue.clear(); }
inline PriorityQueue::PriorityQueue () : _queue() { }
inline PriorityQueue::~PriorityQueue () { }
inline bool PriorityQueue::empty () const { return _queue.empty(); }
inline size_t PriorityQueue::size () const { return _queue.size(); }
inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); }
inline void PriorityQueue::erase ( Vertex* v ) { _queue.erase(v); }
inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); }
inline void PriorityQueue::pop () { _queue.erase(_queue.begin()); }
inline void PriorityQueue::clear () { _queue.clear(); }
inline void PriorityQueue::dump () const
{
if (cdebug.enabled(111)) {
cdebug.log(111,1) << "PriorityQueue::dump() size:" << size() << std::endl;
size_t order = 0;
for ( Vertex* v : _queue )
cdebug.log(111) << "[" << std::setw(3) << order++ << "] " << v << std::endl;
cdebug.tabw(111,-1);
}
}
// -------------------------------------------------------------------
@ -167,7 +183,7 @@ namespace Anabatic {
public:
void load ( Net* );
void run ();
void propagate ();
bool propagate ();
void selectFirstSource ();
void toWires ();
private:
@ -188,4 +204,8 @@ namespace Anabatic {
} // Anabatic namespace.
GETSTRING_POINTER_SUPPORT(Anabatic::Vertex);
IOSTREAM_POINTER_SUPPORT(Anabatic::Vertex);
#endif // ANABATIC_DIJKSTRA_H

View File

@ -63,6 +63,7 @@ namespace Anabatic {
inline DbU::Unit getAxis () const;
DbU::Unit getAxisMin () const;
Interval getSide () const;
inline void incRealOccupancy ( unsigned int );
inline const Flags& flags () const;
inline Flags& flags ();
inline void invalidate ();
@ -111,6 +112,7 @@ namespace Anabatic {
inline GCell* Edge::getSource () const { return _source; }
inline GCell* Edge::getTarget () const { return _target; }
inline DbU::Unit Edge::getAxis () const { return _axis; }
inline void Edge::incRealOccupancy ( unsigned int delta ) { _realOccupancy+=delta; }
inline const Flags& Edge::flags () const { return _flags; }
inline Flags& Edge::flags () { return _flags; }
inline void Edge::invalidate () { _flags |= Flags::Invalidated; }

View File

@ -88,7 +88,9 @@ namespace Anabatic {
, _gcell(locator._gcell)
, _flags(locator._flags)
, _iedge(locator._iedge)
{ }
{
cdebug.log(110) << "GCell_Edges::Locator::Locator(const Locator&)" << std::endl;
}
inline GCell_Edges::GCell_Edges ( const GCell* gcell )
@ -103,6 +105,12 @@ namespace Anabatic {
{ }
} // Anabatic namespace.
} // Anabatic namespace.
GETSTRING_POINTER_SUPPORT(Anabatic::GCell_Edges);
GETSTRING_POINTER_SUPPORT(Anabatic::GCell_Edges::Locator);
IOSTREAM_POINTER_SUPPORT(Anabatic::GCell_Edges);
IOSTREAM_POINTER_SUPPORT(Anabatic::GCell_Edges::Locator);
#endif // ANABATIC_EDGES_H