More configuration parameters for P&R Conductor, for experimenting.
* Change: In Hurricane::Viewer::ExceptionWidget & CRL/python/helpers/io.py, downscale icons for non-HiDPI screen. * Change: In CRL/etc/common/display.py, change the display threshold of METAL1 layer so it do not appear at high scaling. * New: In Etesian, activate the "setFixedAbHeight()" feature and export it to Python. Allows to increase the space margin at constant height. To be used by the P&R conductor. * Change: In Unicorn/cgt.py, when running a script, insert the current working directory at head of the sys.path, not at the end. So installed modules do not shadow local one. * New: In Anabatic::Edge, new accessor "getRawcapacity()" to know the full capacity of the edge, that is, the real maximum number of tracks that can go through the associated side. * Change: In Katana/BloatProfile/Slice::tagsOverloaded(), bloating policy change, now bloat all the instances under the GCell, not only the first one. * Change: In KatanaEngine::runGlobalRouter(), restore the search halo growth policy to expanding of 3 GCells every 3 iterations. New metrics displayed, the edge wire length length overload. * Change: In cumulus/plugins/ConductorPlugin.py, now accepts the following configuration parameters: - "anabatic.globalIterationsEstimate", maximum number of global iterations during the bloating computation passes. - "conductor.useFixedAbHeight", tells wether the additionnal blank space must be added so the aspect ratio is kept or the height is kept (and the block become wider). Disable the display of "rubber" to unclutter a little the view.
This commit is contained in:
parent
9812f2fc3a
commit
e711ce8dd2
|
@ -60,6 +60,7 @@ namespace Anabatic {
|
|||
inline bool isHorizontal () const;
|
||||
inline bool hasNet ( const Net* ) const;
|
||||
inline unsigned int getCapacity () const;
|
||||
inline unsigned int getRawCapacity () const;
|
||||
inline unsigned int getReservedCapacity () const;
|
||||
inline unsigned int getCapacity ( size_t depth ) const;
|
||||
inline unsigned int getRealOccupancy () const;
|
||||
|
@ -137,6 +138,7 @@ namespace Anabatic {
|
|||
inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); }
|
||||
inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); }
|
||||
inline unsigned int Edge::getCapacity ( size_t depth ) const { return (_capacities) ? _capacities->getCapacity(depth) : 0; }
|
||||
inline unsigned int Edge::getRawCapacity () const { return (_capacities) ? _capacities->getCapacity() : 0; }
|
||||
inline unsigned int Edge::getReservedCapacity () const { return _reservedCapacity; }
|
||||
inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; }
|
||||
inline float Edge::getEstimateOccupancy () const { return _estimateOccupancy; }
|
||||
|
|
|
@ -229,7 +229,7 @@ def createStyles ( scale=1.0 ):
|
|||
style.addDrawingStyle( group='Active Layers', name='poly2' , color=toRGB('Orange' ), pattern=toHexa('poids2.8' ), border=1, threshold=0.00*scale )
|
||||
|
||||
# Routing Layers.
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal1' , color=toRGB('Blue' ), pattern=toHexa('slash.8' ), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal1' , color=toRGB('Blue' ), pattern=toHexa('slash.8' ), border=1, threshold=0.80*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal2' , color=toRGB('Aqua' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metcap' , color=toRGB('DarkTurquoise'), pattern=toHexa('poids2.8' ), border=2, threshold=0.00*scale )
|
||||
style.addDrawingStyle( group='Routing Layers', name='metal3' , color=toRGB('LightPink' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
|
||||
|
|
|
@ -121,8 +121,10 @@ class ErrorWidget ( QDialog ):
|
|||
vLayout.addStretch( 1 )
|
||||
vLayout.addLayout ( buttonLayout )
|
||||
|
||||
pixmapWidth = 150
|
||||
if not Viewer.Graphics.isHighDpi(): pixmapWidth = 70
|
||||
pixmap = QPixmap( ':/images/angry-birds-red.png' )
|
||||
pixmap = pixmap.scaledToWidth( 150 )
|
||||
pixmap = pixmap.scaledToWidth( pixmapWidth )
|
||||
icon = QLabel()
|
||||
icon.setPixmap( pixmap )
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ try:
|
|||
import math
|
||||
import Cfg
|
||||
import Hurricane
|
||||
from Hurricane import DbU
|
||||
from Hurricane import Breakpoint
|
||||
from Hurricane import UpdateSession
|
||||
import Viewer
|
||||
|
@ -66,10 +67,25 @@ def ScriptMain ( **kw ):
|
|||
stopLevel = Cfg.getParamInt('conductor.stopLevel').asInt()
|
||||
Breakpoint.setStopLevel( stopLevel )
|
||||
|
||||
Cfg.Configuration.pushDefaultPriority( Cfg.Parameter.Priority.Interactive )
|
||||
|
||||
grIterations = 10
|
||||
if Cfg.hasParameter('anabatic.globalIterations'):
|
||||
grIterations = Cfg.getParamInt('anabatic.globalIterations').asInt()
|
||||
|
||||
grIterationsEstimate = 7
|
||||
if Cfg.hasParameter('anabatic.globalIterationsEstimate'):
|
||||
grIterationsEstimate = Cfg.getParamInt('anabatic.globalIterationsEstimate').asInt()
|
||||
Cfg.getParamInt('anabatic.globalIterations').setInt( grIterationsEstimate )
|
||||
|
||||
maxPlaceIterations = 2
|
||||
if Cfg.hasParameter('conductor.maxPlaceIterations'):
|
||||
maxPlaceIterations = Cfg.getParamInt('conductor.maxPlaceIterations').asInt()
|
||||
|
||||
useFixedAbHeight = False
|
||||
if Cfg.hasParameter('conductor.useFixedAbHeight'):
|
||||
useFixedAbHeight = Cfg.getParamBool('conductor.useFixedAbHeight').asBool()
|
||||
|
||||
cell = None
|
||||
if kw.has_key('cell') and kw['cell']:
|
||||
cell = kw['cell']
|
||||
|
@ -78,6 +94,7 @@ def ScriptMain ( **kw ):
|
|||
if kw.has_key('editor') and kw['editor']:
|
||||
editor = kw['editor']
|
||||
print ' o Editor found, running in graphic mode.'
|
||||
editor.setLayerVisible( 'rubber', False )
|
||||
if cell == None: cell = editor.getCell()
|
||||
|
||||
if cell == None:
|
||||
|
@ -102,7 +119,11 @@ def ScriptMain ( **kw ):
|
|||
etesian = Etesian.EtesianEngine.create( cell )
|
||||
etesian.setPassNumber( iteration )
|
||||
if editor: etesian.setViewer( editor )
|
||||
if iteration: etesian.resetPlacement()
|
||||
if iteration:
|
||||
if useFixedAbHeight and iteration == 1:
|
||||
etesian.setFixedAbHeight( cell.getAbutmentBox().getHeight() )
|
||||
print 'etesian.setFixedAbHeight():', DbU.getValueString(cell.getAbutmentBox().getHeight())
|
||||
etesian.resetPlacement()
|
||||
etesian.place()
|
||||
etesian.destroy()
|
||||
etesian = None
|
||||
|
@ -110,6 +131,9 @@ def ScriptMain ( **kw ):
|
|||
editor.refresh()
|
||||
editor.fit()
|
||||
|
||||
if iteration+1 == maxPlaceIterations:
|
||||
Cfg.getParamInt('anabatic.globalIterations').setInt( grIterations )
|
||||
|
||||
katana = Katana.KatanaEngine.create( cell )
|
||||
katana.setPassNumber( iteration )
|
||||
if editor: katana.setViewer( editor )
|
||||
|
@ -120,6 +144,8 @@ def ScriptMain ( **kw ):
|
|||
)
|
||||
#| Katana.Flags.ShowFailedNets
|
||||
Breakpoint.stop( 1, 'After routing iteration %d' % iteration )
|
||||
if editor:
|
||||
editor.setShowSelection( False )
|
||||
|
||||
if katana.isGlobalRoutingSuccess(): break
|
||||
iteration += 1
|
||||
|
@ -138,6 +164,8 @@ def ScriptMain ( **kw ):
|
|||
|
||||
#plugins.RSavePlugin.ScriptMain( **kw )
|
||||
|
||||
Cfg.Configuration.popDefaultPriority()
|
||||
|
||||
except Exception, e:
|
||||
catch( e )
|
||||
|
||||
|
|
|
@ -394,7 +394,7 @@ namespace Etesian {
|
|||
double gcellLength = cellLength*(1.0+spaceMargin) / DbU::toLambda( getSliceHeight() );
|
||||
|
||||
double rows = 0.0;
|
||||
setFixedAbHeight( 0 );
|
||||
//setFixedAbHeight( 0 );
|
||||
if (getFixedAbHeight()) rows = getFixedAbHeight() / getSliceHeight();
|
||||
else rows = std::ceil( sqrt( gcellLength/aspectRatio ) );
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ extern "C" {
|
|||
|
||||
DirectVoidMethod(EtesianEngine,etesian,setDefaultAb)
|
||||
DirectVoidMethod(EtesianEngine,etesian,resetPlacement)
|
||||
DirectSetLongAttribute(PyEtesianEngine_setFixedAbHeight,setFixedAbHeight,PyEtesianEngine,EtesianEngine)
|
||||
|
||||
|
||||
static PyObject* PyEtesianEngine_get ( PyObject*, PyObject* args )
|
||||
|
@ -208,6 +209,8 @@ extern "C" {
|
|||
, "Set the sub-block (Instance) to place." }
|
||||
, { "setDefaultAb" , (PyCFunction)PyEtesianEngine_setDefaultAb , METH_NOARGS
|
||||
, "Compute and set the abutment box using the aspect ratio and the space margin." }
|
||||
, { "setFixedAbHeight" , (PyCFunction)PyEtesianEngine_setFixedAbHeight , METH_VARARGS
|
||||
, "Use this height when computing the size of the default abutment box (disable aspect ratio)." }
|
||||
, { "resetPlacement" , (PyCFunction)PyEtesianEngine_resetPlacement , METH_NOARGS
|
||||
, "Compute and set the abutment box using the aspect ratio and the space margin." }
|
||||
, { "place" , (PyCFunction)PyEtesianEngine_place , METH_NOARGS
|
||||
|
|
|
@ -137,7 +137,7 @@ namespace Hurricane {
|
|||
|
||||
QLabel* leftMargin = new QLabel ();
|
||||
leftMargin->setSizePolicy ( QSizePolicy::Preferred, QSizePolicy::MinimumExpanding );
|
||||
leftMargin->setPixmap ( QPixmap(":/images/angry-birds-bomb.png").scaledToWidth(200) );
|
||||
leftMargin->setPixmap ( QPixmap(":/images/angry-birds-bomb.png").scaledToWidth( Graphics::isHighDpi() ? 200 : 80 ) );
|
||||
leftMargin->setStyleSheet ( "QLabel { background-color: #FF9999;"
|
||||
" padding: 5px }" );
|
||||
|
||||
|
|
|
@ -108,9 +108,9 @@ extern "C" {
|
|||
Py_INCREF ( &PyTypeHApplication );
|
||||
PyModule_AddObject ( module, "HApplication", (PyObject*)&PyTypeHApplication );
|
||||
Py_INCREF ( &PyTypeGraphics );
|
||||
PyModule_AddObject ( module, "Graphics", (PyObject*)&PyTypeGraphics );
|
||||
PyModule_AddObject ( module, "Graphics" , (PyObject*)&PyTypeGraphics );
|
||||
Py_INCREF ( &PyTypeCellViewer );
|
||||
PyModule_AddObject ( module, "CellViewer", (PyObject*)&PyTypeCellViewer );
|
||||
PyModule_AddObject ( module, "CellViewer" , (PyObject*)&PyTypeCellViewer );
|
||||
|
||||
PyDisplayStyle_postModuleInit();
|
||||
PyCellViewer_postModuleInit();
|
||||
|
|
|
@ -52,6 +52,8 @@ namespace {
|
|||
using Anabatic::Edge;
|
||||
using namespace Katana;
|
||||
|
||||
class Slices;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "FlatInstance".
|
||||
|
@ -116,19 +118,21 @@ namespace {
|
|||
|
||||
class Slice {
|
||||
public:
|
||||
inline Slice ( GCell* );
|
||||
inline Slice ( Slices*, GCell* );
|
||||
inline DbU::Unit getY () const;
|
||||
inline void add ( Occurrence );
|
||||
inline void sort ();
|
||||
void tagOverloadeds ( size_t& count, size_t& newCount );
|
||||
private:
|
||||
Slices* _owner;
|
||||
GCell* _left;
|
||||
vector<FlatInstance> _instances;
|
||||
};
|
||||
|
||||
|
||||
inline Slice::Slice ( GCell* left )
|
||||
: _left (left)
|
||||
inline Slice::Slice ( Slices* owner, GCell* left )
|
||||
: _owner (owner)
|
||||
, _left (left)
|
||||
, _instances()
|
||||
{ }
|
||||
|
||||
|
@ -138,78 +142,17 @@ namespace {
|
|||
inline void Slice::sort () { std::sort( _instances.begin(), _instances.end() ); }
|
||||
|
||||
|
||||
void Slice::tagOverloadeds ( size_t& count, size_t& newCount )
|
||||
{
|
||||
GCell* gcell = _left;
|
||||
Edge* eastEdge = _left->getEastEdge();
|
||||
Edge* northEdge = _left->getNorthEdge();
|
||||
bool bloated = false;
|
||||
|
||||
//cerr << "+ Slice @" << DbU::getValueString(getY()) << endl;
|
||||
|
||||
for ( FlatInstance& fi : _instances ) {
|
||||
//cerr << "| @" << DbU::getValueString(fi.getX()) << " " << fi.getOccurrence() << endl;
|
||||
|
||||
if (fi.getX() >= gcell->getXMax()) {
|
||||
for ( gcell = gcell->getEast() ; gcell and (fi.getX() > gcell->getXMax())
|
||||
; gcell = gcell->getEast() ) {
|
||||
//cerr << "| Skip " << gcell << endl;
|
||||
}
|
||||
//cerr << "| Advance to " << gcell << endl;
|
||||
if (not gcell) break;
|
||||
|
||||
bloated = false;
|
||||
eastEdge = gcell->getEastEdge();
|
||||
northEdge = gcell->getNorthEdge();
|
||||
}
|
||||
|
||||
unsigned int overload = 0;
|
||||
|
||||
if (eastEdge) {
|
||||
if (eastEdge->getRealOccupancy() > eastEdge->getCapacity()) {
|
||||
overload = eastEdge->getRealOccupancy() - eastEdge->getCapacity();
|
||||
}
|
||||
// else if (eastEdge->getHistoricCost() > 3.0) {
|
||||
// overload = 4;
|
||||
// }
|
||||
}
|
||||
|
||||
if (northEdge) {
|
||||
if (northEdge->getRealOccupancy() > northEdge->getCapacity()) {
|
||||
overload = std::max( overload, northEdge->getRealOccupancy() - northEdge->getCapacity() );
|
||||
}
|
||||
// else if (northEdge->getHistoricCost() > 3.0) {
|
||||
// overload = 4;
|
||||
// }
|
||||
}
|
||||
|
||||
if (overload and not bloated) {
|
||||
bloated = true;
|
||||
BloatState* state = BloatExtension::get( fi.getOccurrence() );
|
||||
if (not state) {
|
||||
state = BloatExtension::create( fi.getOccurrence(), overload );
|
||||
//cerr << "> Bloat: " << fi.getOccurrence() << endl;
|
||||
//cerr << "> Under:" << gcell << endl;
|
||||
++newCount;
|
||||
} else {
|
||||
state->setTracksCount( state->getTracksCount() + overload );
|
||||
}
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Slices".
|
||||
|
||||
class Slices {
|
||||
public:
|
||||
Slices ( KatanaEngine* );
|
||||
~Slices ();
|
||||
inline void add ( Occurrence );
|
||||
inline void sort ();
|
||||
inline void tagOverloadeds ();
|
||||
Slices ( KatanaEngine* );
|
||||
~Slices ();
|
||||
inline KatanaEngine* getKatana () const;
|
||||
inline void add ( Occurrence );
|
||||
inline void sort ();
|
||||
inline void tagOverloadeds ();
|
||||
private:
|
||||
KatanaEngine* _katana;
|
||||
Box _cellAb;
|
||||
|
@ -250,7 +193,7 @@ namespace {
|
|||
, getString(left).c_str()
|
||||
);
|
||||
|
||||
_slices.push_back( new Slice( left ) );
|
||||
_slices.push_back( new Slice( this, left ) );
|
||||
left = left->getNorth();
|
||||
}
|
||||
}
|
||||
|
@ -260,6 +203,10 @@ namespace {
|
|||
{ for ( Slice* slice : _slices ) delete slice; }
|
||||
|
||||
|
||||
inline KatanaEngine* Slices::getKatana () const
|
||||
{ return _katana; }
|
||||
|
||||
|
||||
inline void Slices::sort ()
|
||||
{ for ( Slice* slice : _slices ) slice->sort(); }
|
||||
|
||||
|
@ -293,6 +240,118 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
void Slice::tagOverloadeds ( size_t& count, size_t& newCount )
|
||||
{
|
||||
GCell* gcell = _left;
|
||||
size_t iLeft = 0;
|
||||
size_t iRight = 0;
|
||||
|
||||
while ( gcell ) {
|
||||
//cerr << "> Under:" << gcell << endl;
|
||||
|
||||
uint32_t overload = 0;
|
||||
for ( Edge* edge : gcell->getEdges( Flags::NorthSide|Flags::EastSide ) ) {
|
||||
if (edge->getRealOccupancy() > edge->getCapacity()) {
|
||||
overload = std::max( overload, edge->getRealOccupancy() - edge->getCapacity() );
|
||||
|
||||
// if (edge->getRealOccupancy() > edge->getRawCapacity()) {
|
||||
// overload += 4;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
iLeft = iRight;
|
||||
while ( iRight < _instances.size() ) {
|
||||
if (_instances[iRight].getX() >= gcell->getXMax()) break;
|
||||
++iRight;
|
||||
}
|
||||
|
||||
if (iLeft >= _instances.size()) break;
|
||||
|
||||
if (overload) {
|
||||
overload += 4;
|
||||
|
||||
for ( size_t i=iLeft ; i<iRight ; ++i ) {
|
||||
BloatState* state = BloatExtension::get( _instances[i].getOccurrence() );
|
||||
if (not state) {
|
||||
if (_owner->getKatana()->getPassNumber() > 0) continue;
|
||||
|
||||
state = BloatExtension::create( _instances[i].getOccurrence(), overload );
|
||||
++newCount;
|
||||
|
||||
//cerr << "| Bloat: " << overload << " " << _instances[i].getOccurrence() << endl;
|
||||
} else {
|
||||
state->setTracksCount( state->getTracksCount() + overload );
|
||||
}
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
gcell = gcell->getEast();
|
||||
}
|
||||
|
||||
|
||||
// GCell* gcell = _left;
|
||||
// Edge* eastEdge = _left->getEastEdge();
|
||||
// Edge* northEdge = _left->getNorthEdge();
|
||||
// bool bloated = false;
|
||||
|
||||
// //cerr << "+ Slice @" << DbU::getValueString(getY()) << endl;
|
||||
|
||||
// for ( FlatInstance& fi : _instances ) {
|
||||
// //cerr << "| @" << DbU::getValueString(fi.getX()) << " " << fi.getOccurrence() << endl;
|
||||
|
||||
// if (fi.getX() >= gcell->getXMax()) {
|
||||
// for ( gcell = gcell->getEast() ; gcell and (fi.getX() > gcell->getXMax())
|
||||
// ; gcell = gcell->getEast() ) {
|
||||
// //cerr << "| Skip " << gcell << endl;
|
||||
// }
|
||||
// //cerr << "| Advance to " << gcell << endl;
|
||||
// if (not gcell) break;
|
||||
|
||||
// bloated = false;
|
||||
// eastEdge = gcell->getEastEdge();
|
||||
// northEdge = gcell->getNorthEdge();
|
||||
// }
|
||||
|
||||
// unsigned int overload = 0;
|
||||
|
||||
// if (eastEdge) {
|
||||
// if (eastEdge->getRealOccupancy() > eastEdge->getCapacity()) {
|
||||
// overload = eastEdge->getRealOccupancy() - eastEdge->getCapacity();
|
||||
// }
|
||||
// // else if (eastEdge->getHistoricCost() > 3.0) {
|
||||
// // overload = 4;
|
||||
// // }
|
||||
// }
|
||||
|
||||
// if (northEdge) {
|
||||
// if (northEdge->getRealOccupancy() > northEdge->getCapacity()) {
|
||||
// overload = std::max( overload, northEdge->getRealOccupancy() - northEdge->getCapacity() );
|
||||
// }
|
||||
// // else if (northEdge->getHistoricCost() > 3.0) {
|
||||
// // overload = 4;
|
||||
// // }
|
||||
// }
|
||||
|
||||
// if (overload and not bloated) {
|
||||
// bloated = true;
|
||||
// overload += 8;
|
||||
|
||||
// BloatState* state = BloatExtension::get( fi.getOccurrence() );
|
||||
// if (not state) {
|
||||
// state = BloatExtension::create( fi.getOccurrence(), overload );
|
||||
// //cerr << "> Bloat: " << fi.getOccurrence() << endl;
|
||||
// //cerr << "> Under:" << gcell << endl;
|
||||
// ++newCount;
|
||||
// } else {
|
||||
// state->setTracksCount( state->getTracksCount() + overload );
|
||||
// }
|
||||
// ++count;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
|
|
|
@ -493,6 +493,9 @@ namespace Katana {
|
|||
if (getState() >= EngineState::EngineGlobalLoaded)
|
||||
throw Error ("KatanaEngine::runGlobalRouter(): Global routing already done or loaded.");
|
||||
|
||||
if (flags & Flags::ShowBloatedInstances) selectBloatedInstances( this );
|
||||
Breakpoint::stop( 1, "Bloated cells from previous placement iteration." );
|
||||
|
||||
startMeasures();
|
||||
cmess1 << " o Running global routing." << endl;
|
||||
|
||||
|
@ -580,12 +583,14 @@ namespace Katana {
|
|||
edgeOverflowWL = 0;
|
||||
netCount = 0;
|
||||
if (iteration < globalIterations - 1) {
|
||||
for ( Edge* edge : ovEdges ) {
|
||||
edgeOverflowWL += edge->getRealOccupancy() - edge->getCapacity();
|
||||
}
|
||||
|
||||
size_t iEdge = 0;
|
||||
while ( iEdge < ovEdges.size() ) {
|
||||
Edge* edge = ovEdges[iEdge];
|
||||
|
||||
edgeOverflowWL += edge->getRealOccupancy() - edge->getCapacity();
|
||||
netCount += edge->ripup();
|
||||
Edge* edge = ovEdges[iEdge];
|
||||
netCount += edge->ripup();
|
||||
|
||||
if (iEdge >= ovEdges.size()) break;
|
||||
if (ovEdges[iEdge] == edge) {
|
||||
|
@ -597,16 +602,15 @@ namespace Katana {
|
|||
}
|
||||
}
|
||||
|
||||
//dijkstra->setSearchAreaHalo( (getSearchHalo() + 3*(iteration/3)) * Session::getSliceHeight() );
|
||||
dijkstra->setSearchAreaHalo( 3 * Session::getSliceHeight() );
|
||||
dijkstra->setSearchAreaHalo( (getSearchHalo() + 3*(iteration/3)) * Session::getSliceHeight() );
|
||||
}
|
||||
|
||||
cmess2 << " ovE:" << setw(4) << overflow << " " << setw(5) << edgeOverflowWL;
|
||||
cmess2 << " ovE:" << setw(4) << overflow << " ovWL:" << setw(5) << edgeOverflowWL;
|
||||
|
||||
cmess2 << " ripup:" << setw(4) << netCount << right;
|
||||
suspendMeasures();
|
||||
cmess2 << " " << setw(6) << Timer::getStringMemory(getTimer().getIncrease())
|
||||
<< " " << setw(5) << Timer::getStringTime (getTimer().getCombTime()) << endl;
|
||||
cmess2 << " " << setw(7) << Timer::getStringMemory(getTimer().getIncrease())
|
||||
<< " " << setw(6) << Timer::getStringTime (getTimer().getCombTime()) << endl;
|
||||
resumeMeasures();
|
||||
|
||||
++iteration;
|
||||
|
|
|
@ -68,7 +68,7 @@ def runScript ( scriptPath, editor ):
|
|||
try:
|
||||
kw = { }
|
||||
if editor: kw[ 'editor' ] = editor
|
||||
sys.path.append(os.path.dirname(scriptPath))
|
||||
sys.path.insert( 0, os.path.dirname(scriptPath) )
|
||||
|
||||
module = __import__( os.path.basename(scriptPath), globals(), locals() )
|
||||
if not module.__dict__.has_key('ScriptMain'):
|
||||
|
|
Loading…
Reference in New Issue