Correcting non-deterministic behavior in Anabatic/Katana (again).

This non-deterministic behavior was showing only in the ARMv2a benchmark
around event 180k...
* Bug: In Anabatic::Session::_netInvalidateds & _netRevalidateds, the
    set<> was still sorted on pointers. As contacts & segments can be
    created to maintain connexity after a layer change, we got a
    discrepency in objects Ids that may generate a change in ordering
    later.
* Bug: In Katana::Session::_doRemovalEvents(), the set of Tracks that
    got elements deleted was still using pointers. Now we use a TrackSet
    sorted on (direction,depth,axis). This should not have created
    a change in the results, as destructions do not change Ids, but it
    genereate extra differences in traces.
This commit is contained in:
Jean-Paul Chaput 2019-08-20 16:30:03 +02:00
parent 014dbe1bcc
commit 1124e92ac2
15 changed files with 244 additions and 243 deletions

View File

@ -718,7 +718,7 @@ namespace Anabatic {
if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth); if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth);
else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth); else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth);
else cap = getViaToSameCap (depth); else cap = getViaToSameCap (depth);
cdebug_log(159,0) << "getExtensionCap(): flags:" << getFlags() cdebug_log(145,0) << "getExtensionCap(): flags:" << getFlags()
<< " VIA cap:" << DbU::getValueString(cap) << " VIA cap:" << DbU::getValueString(cap)
<< " " << (getFlags() & SegSourceBottom) << " " << (getFlags() & SegSourceBottom)
<< endl; << endl;

View File

@ -875,6 +875,8 @@ namespace Anabatic {
void AnabaticEngine::layerAssign ( uint32_t method ) void AnabaticEngine::layerAssign ( uint32_t method )
{ {
//DebugSession::open( 145, 150 );
cdebug_log(9000,0) << "Deter| Layer Assignment" << endl; cdebug_log(9000,0) << "Deter| Layer Assignment" << endl;
set<Net*> globalNets; set<Net*> globalNets;
@ -980,6 +982,8 @@ namespace Anabatic {
// cmess2 << " - Global segments : " << global << endl; // cmess2 << " - Global segments : " << global << endl;
// cmess2 << " - Ratio : " // cmess2 << " - Ratio : "
// << ((float)global/(float)total)*100.0 << "%." << endl; // << ((float)global/(float)total)*100.0 << "%." << endl;
//DebugSession::close();
} }

View File

@ -24,6 +24,7 @@
#include <boost/function.hpp> #include <boost/function.hpp>
#include "hurricane/Commons.h" #include "hurricane/Commons.h"
#include "hurricane/Box.h" #include "hurricane/Box.h"
#include "hurricane/DBo.h"
#include "crlcore/CellGauge.h" #include "crlcore/CellGauge.h"
#include "crlcore/RoutingGauge.h" #include "crlcore/RoutingGauge.h"
#include "anabatic/Constants.h" #include "anabatic/Constants.h"
@ -55,6 +56,7 @@ namespace Anabatic {
using Hurricane::DbU; using Hurricane::DbU;
using Hurricane::Point; using Hurricane::Point;
using Hurricane::Box; using Hurricane::Box;
using Hurricane::DBo;
using Hurricane::Net; using Hurricane::Net;
using Hurricane::Contact; using Hurricane::Contact;
using Hurricane::Segment; using Hurricane::Segment;
@ -131,7 +133,7 @@ namespace Anabatic {
static inline const vector<AutoSegment*>& getRevalidateds (); static inline const vector<AutoSegment*>& getRevalidateds ();
static inline const set<AutoSegment*>& getDestroyeds (); static inline const set<AutoSegment*>& getDestroyeds ();
static inline const vector<AutoSegment*>& getDoglegs (); static inline const vector<AutoSegment*>& getDoglegs ();
static inline const set<Net*>& getNetsModificateds (); static inline const set<Net*,DBo::CompareById>& getNetsModificateds ();
static void close (); static void close ();
static void setAnabaticFlags ( Flags ); static void setAnabaticFlags ( Flags );
static inline void dogleg ( AutoSegment* ); static inline void dogleg ( AutoSegment* );
@ -180,8 +182,8 @@ namespace Anabatic {
vector<AutoSegment*> _doglegs; vector<AutoSegment*> _doglegs;
vector<AutoSegment*> _segmentInvalidateds; vector<AutoSegment*> _segmentInvalidateds;
vector<AutoSegment*> _segmentRevalidateds; vector<AutoSegment*> _segmentRevalidateds;
set<Net*> _netInvalidateds; set<Net*,DBo::CompareById> _netInvalidateds;
set<Net*> _netRevalidateds; set<Net*,DBo::CompareById> _netRevalidateds;
set<AutoSegment*> _destroyedSegments; set<AutoSegment*> _destroyedSegments;
// Constructors. // Constructors.
@ -214,7 +216,7 @@ namespace Anabatic {
inline const vector<AutoSegment*>& Session::getRevalidateds () { return get("getRevalidateds()")->_segmentRevalidateds; } inline const vector<AutoSegment*>& Session::getRevalidateds () { return get("getRevalidateds()")->_segmentRevalidateds; }
inline const set<AutoSegment*>& Session::getDestroyeds () { return get("getDestroyeds()")->_destroyedSegments; } inline const set<AutoSegment*>& Session::getDestroyeds () { return get("getDestroyeds()")->_destroyedSegments; }
inline const vector<AutoSegment*>& Session::getDoglegs () { return get("getDoglegs()")->_doglegs; } inline const vector<AutoSegment*>& Session::getDoglegs () { return get("getDoglegs()")->_doglegs; }
inline const set<Net*>& Session::getNetsModificateds () { return get("getNetsModificateds()")->_netRevalidateds; } inline const set<Net*,DBo::CompareById>& Session::getNetsModificateds () { return get("getNetsModificateds()")->_netRevalidateds; }
inline void Session::doglegReset () { return get("doglegReset()")->_doglegReset (); } inline void Session::doglegReset () { return get("doglegReset()")->_doglegReset (); }
inline void Session::invalidate ( Net* net ) { return get("invalidate(Net*)")->_invalidate(net); } inline void Session::invalidate ( Net* net ) { return get("invalidate(Net*)")->_invalidate(net); }
inline void Session::invalidate ( AutoContact* autoContact ) { return get("invalidate(AutoContact*)")->_invalidate(autoContact); } inline void Session::invalidate ( AutoContact* autoContact ) { return get("invalidate(AutoContact*)")->_invalidate(autoContact); }

View File

@ -1035,37 +1035,6 @@ namespace Etesian {
} }
#if DISABLED
void EtesianEngine::place ( Instance* instance )
{
setBlock( instance );
if (getCell()->getAbutmentBox().isEmpty()) {
cmess2 << Error( "EtesianEngine::place(): Cell \"%s\" must have an abutment box."
, getString(getCell()->getName()).c_str()
) << std::endl;
return;
}
if (getBlockCell()->getAbutmentBox().isEmpty()) {
cmess2 << Error( "EtesianEngine::place(): Instance \"%s\" must have an abutment box."
, getString(instance->getName()).c_str()
) << std::endl;
return;
}
if(getBlockCell()->isPlaced()){
cmess2 << Error( "EtesianEngine::place(): The instance \"%s\" is already placed."
, getString(instance->getName()).c_str()
) << std::endl;
return;
}
getBlockCell()->uniquify();
getConfiguration()->print( getCell() );
findYSpin();
}
#endif
void EtesianEngine::_progressReport1 ( string label ) const void EtesianEngine::_progressReport1 ( string label ) const
{ {
size_t w = label.size(); size_t w = label.size();

View File

@ -211,10 +211,10 @@ namespace Katana {
{ {
cdebug_log(159,1) << "Katana::Session::_doRemovalEvents()" << endl; cdebug_log(159,1) << "Katana::Session::_doRemovalEvents()" << endl;
set<Track*> packTracks; TrackSet packTracks;
for ( size_t i=0 ; i<_removeEvents.size() ; ++i ) { for ( size_t i=0 ; i<_removeEvents.size() ; ++i ) {
cdebug_log(159,0) << "Event:" << _removeEvents[i]._segment << endl; cdebug_log(159,0) << "Remove event for:" << _removeEvents[i]._segment << endl;
if (not _removeEvents[i]._segment->getTrack()) continue; if (not _removeEvents[i]._segment->getTrack()) continue;
_removeEvents[i]._segment->detach( packTracks ); _removeEvents[i]._segment->detach( packTracks );
@ -222,7 +222,7 @@ namespace Katana {
} }
_removeEvents.clear(); _removeEvents.clear();
for ( set<Track*>::iterator it=packTracks.begin() ; it != packTracks.end() ; ++it ) for ( TrackSet::iterator it=packTracks.begin() ; it != packTracks.end() ; ++it )
(*it)->doRemoval(); (*it)->doRemoval();
cdebug_tabw(159,-1); cdebug_tabw(159,-1);
@ -453,7 +453,8 @@ namespace Katana {
return; return;
} }
if (forced) track->invalidate(); if (forced) track->invalidate();
_sortEvents.insert( track ); for ( Track* elem : _sortEvents ) if (elem == track) return;
_sortEvents.push_back( track );
} }

View File

@ -93,7 +93,7 @@ namespace Katana {
{ {
cdebug_log(155,1) << "Track::_preDestroy() - " << (void*)this << " " << this << endl; cdebug_log(155,1) << "Track::_preDestroy() - " << (void*)this << " " << this << endl;
set<Track*> dummy; TrackSet dummy;
for ( size_t i=0 ; i<_segments.size() ; i++ ) for ( size_t i=0 ; i<_segments.size() ; i++ )
if (_segments[i]) { if (_segments[i]) {
_segments[i]->detach( dummy ); _segments[i]->detach( dummy );
@ -520,7 +520,7 @@ namespace Katana {
bool holes = false; bool holes = false;
if (message) cerr << " o Checking Track - " << message << endl; if (message) cerr << " o Checking Track - " << message << endl;
cdebug_log(155,0) << (void*)this << ":" << this << endl; cdebug_log(155,0) << /*(void*)this << ":" <<*/ this << endl;
for ( size_t i=0 ; i<_segments.size() ; i++ ) { for ( size_t i=0 ; i<_segments.size() ; i++ ) {
if (_segments[i]) { if (_segments[i]) {

View File

@ -189,7 +189,7 @@ namespace Katana {
void TrackElement::swapTrack ( TrackElement* ) { } void TrackElement::swapTrack ( TrackElement* ) { }
void TrackElement::reschedule ( uint32_t ) { } void TrackElement::reschedule ( uint32_t ) { }
//void TrackElement::detach () { } //void TrackElement::detach () { }
void TrackElement::detach ( set<Track*>& ) { } //void TrackElement::detach ( TrackSet& ) { }
void TrackElement::revalidate () { } void TrackElement::revalidate () { }
void TrackElement::updatePPitch () { } void TrackElement::updatePPitch () { }
void TrackElement::updateTrackSpan () { } void TrackElement::updateTrackSpan () { }

View File

@ -237,6 +237,12 @@ namespace Katana {
{ } { }
void TrackFixedSegment::detach ( TrackSet& removeds )
{
// cerr << Error( "TrackFixedSegment::detach(): Must never be called on %s."
// , getString(this).c_str()) << endl;
}
string TrackFixedSegment::_getTypeName () const string TrackFixedSegment::_getTypeName () const
{ return "TrackFixedSegment"; } { return "TrackFixedSegment"; }

View File

@ -441,9 +441,9 @@ namespace Katana {
// } // }
void TrackSegment::detach ( set<Track*>& removeds ) void TrackSegment::detach ( TrackSet& removeds )
{ {
cdebug_log(159,1) << "TrackSegment::detach(set<Track*>&) - <id:" << getId() << "> trackSpan:" cdebug_log(159,1) << "TrackSegment::detach(TrackSet&) - <id:" << getId() << "> trackSpan:"
<< getTrackSpan() << endl; << getTrackSpan() << endl;
Track* wtrack = getTrack(); Track* wtrack = getTrack();

View File

@ -60,8 +60,8 @@ namespace Katana {
, _trackSpan (0) , _trackSpan (0)
, _trackCount(0) , _trackCount(0)
{ {
cdebug_log(159,1) << "CTOR TrackSegmentNonPref " << (void*)this << ":" << this << endl; cdebug_log(159,1) << "CTOR TrackSegmentNonPref " << /*(void*)this << ":" <<*/ this << endl;
cdebug_log(159,0) << " over " << (void*)segment << ":" << segment << endl; cdebug_log(159,0) << " over " << /*(void*)segment << ":" <<*/ segment << endl;
updateTrackSpan(); updateTrackSpan();
@ -94,7 +94,7 @@ namespace Katana {
void TrackSegmentNonPref::updateTrackSpan () void TrackSegmentNonPref::updateTrackSpan ()
{ {
DebugSession::open( getNet(), 150, 160 ); DebugSession::open( getNet(), 150, 160 );
cdebug_log(159,1) << "TrackSegmentNonPref::updateTrackspan() " << (void*)this << ":" << this << endl; cdebug_log(159,1) << "TrackSegmentNonPref::updateTrackspan() " << /*(void*)this << ":" <<*/ this << endl;
RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_base->getLayer()); RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_base->getLayer());
Interval newAxisSpan ( _base->getSourcePosition(), _base->getTargetPosition() ); Interval newAxisSpan ( _base->getSourcePosition(), _base->getTargetPosition() );

View File

@ -132,7 +132,7 @@ namespace Katana {
vector<Event> _insertEvents; vector<Event> _insertEvents;
vector<Event> _removeEvents; vector<Event> _removeEvents;
vector<Event> _lockEvents; vector<Event> _lockEvents;
set<Track*> _sortEvents; vector<Track*> _sortEvents;
protected: protected:
// Constructors & Destructors. // Constructors & Destructors.
Session ( KatanaEngine* ); Session ( KatanaEngine* );

View File

@ -87,7 +87,7 @@ namespace Katana {
TrackElement* getPrevious ( size_t& index, Net* ) const; TrackElement* getPrevious ( size_t& index, Net* ) const;
TrackElement* getNextFixed ( size_t& index ) const; TrackElement* getNextFixed ( size_t& index ) const;
size_t find ( const TrackElement* ) const; size_t find ( const TrackElement* ) const;
DbU::Unit getSourcePosition ( vector<TrackElement*>::iterator ) const; DbU::Unit getSourcePosition ( std::vector<TrackElement*>::iterator ) const;
DbU::Unit getMinimalPosition ( size_t index, uint32_t state ) const; DbU::Unit getMinimalPosition ( size_t index, uint32_t state ) const;
DbU::Unit getMaximalPosition ( size_t index, uint32_t state ) const; DbU::Unit getMaximalPosition ( size_t index, uint32_t state ) const;
Interval getFreeInterval ( DbU::Unit position, Net* net=NULL ) const; Interval getFreeInterval ( DbU::Unit position, Net* net=NULL ) const;
@ -120,8 +120,8 @@ namespace Katana {
DbU::Unit _axis; DbU::Unit _axis;
DbU::Unit _min; DbU::Unit _min;
DbU::Unit _max; DbU::Unit _max;
vector<TrackElement*> _segments; std::vector<TrackElement*> _segments;
vector<TrackMarker*> _markers; std::vector<TrackMarker*> _markers;
bool _localAssigned; bool _localAssigned;
bool _segmentsValid; bool _segmentsValid;
bool _markersValid; bool _markersValid;
@ -153,6 +153,11 @@ namespace Katana {
struct SegmentCompare { struct SegmentCompare {
inline bool operator() ( const TrackElement* lhs, const TrackElement* rhs ); inline bool operator() ( const TrackElement* lhs, const TrackElement* rhs );
}; };
public:
struct Compare {
inline bool operator() ( const Track* lhs, const Track* rhs ) const;
};
}; };
@ -210,6 +215,18 @@ namespace Katana {
} }
inline bool Track::Compare::operator() ( const Track* lhs, const Track* rhs ) const
{
if (lhs->isHorizontal() xor rhs->isHorizontal()) return lhs->isHorizontal();
if (lhs->getDepth () != rhs->getDepth ()) return lhs->getDepth() < rhs->getDepth();
return (lhs->getAxis() < rhs->getAxis());
}
class TrackSet : public std::set<Track*,Track::Compare> { };
} // Katana namespace. } // Katana namespace.

View File

@ -55,6 +55,7 @@ namespace Katana {
class Track; class Track;
class TrackCost; class TrackCost;
class TrackSegment; class TrackSegment;
class TrackSet;
typedef map<TrackElement*,TrackElement*> TrackElementPairing; typedef map<TrackElement*,TrackElement*> TrackElementPairing;
@ -174,7 +175,7 @@ namespace Katana {
virtual Interval getTargetConstraints () const; virtual Interval getTargetConstraints () const;
virtual DataNegociate* getDataNegociate ( Flags flags=Flags::DataSelf ) const; virtual DataNegociate* getDataNegociate ( Flags flags=Flags::DataSelf ) const;
inline TrackElement* getCanonical ( Interval& ); inline TrackElement* getCanonical ( Interval& );
virtual size_t getGCells ( vector<GCell*>& ) const; virtual size_t getGCells ( std::vector<GCell*>& ) const;
virtual TrackElement* getParent () const; virtual TrackElement* getParent () const;
virtual uint32_t getDoglegLevel () const; virtual uint32_t getDoglegLevel () const;
virtual TrackElement* getSourceDogleg (); virtual TrackElement* getSourceDogleg ();
@ -197,7 +198,7 @@ namespace Katana {
virtual void swapTrack ( TrackElement* ); virtual void swapTrack ( TrackElement* );
virtual void reschedule ( uint32_t level ); virtual void reschedule ( uint32_t level );
//virtual void detach (); //virtual void detach ();
virtual void detach ( std::set<Track*>& ); virtual void detach ( TrackSet& ) = 0;
virtual void invalidate (); virtual void invalidate ();
virtual void revalidate (); virtual void revalidate ();
virtual void updatePPitch (); virtual void updatePPitch ();

View File

@ -65,6 +65,7 @@ namespace Katana {
virtual void forcePriority ( float ); virtual void forcePriority ( float );
virtual void computePriority (); virtual void computePriority ();
virtual void computeAlignedPriority (); virtual void computeAlignedPriority ();
virtual void detach ( TrackSet& );
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
virtual string _getString () const; virtual string _getString () const;
virtual string _getTypeName () const; virtual string _getTypeName () const;

View File

@ -134,7 +134,7 @@ namespace Katana {
virtual void swapTrack ( TrackElement* ); virtual void swapTrack ( TrackElement* );
virtual void reschedule ( uint32_t level ); virtual void reschedule ( uint32_t level );
//virtual void detach (); //virtual void detach ();
virtual void detach ( std::set<Track*>& ); virtual void detach ( TrackSet& );
virtual void invalidate (); virtual void invalidate ();
virtual void revalidate (); virtual void revalidate ();
virtual void updatePPitch (); virtual void updatePPitch ();