Bug in Python proxy deallocation. Update to latest Coloquinte.

* Bug: In Bootstrap, in coriolisEnv.py, check if devtoolset-2 is already
    active before launching it as a sub-shell.
* Bug: In Isobar, In PyHurricane.h, DBoDestroyAttribute() set the proxy
    pointer toward the C++ object to NULL. So when the Python object is
    deleted no double-deletion occurs on the C++ object.
      Add some more trace information in Python link/dealloc.
* Change: In CRL Core, in cyclop, make CMakeLists.txt automatically
    choose the right rule for linking the binary wether we use Qt 4 or
    Qt 5. Very irksome problem.
* New: In EtesianEngine::addFeed(), do not take into account instances
    that are not placed entirely inside the top cell abutment box (was
    causing a core dump).
* Bug: In Katabatic, in GCellQueue, correct a mismatch between a GCell
    set and the iterators used upon it.
* Bug: In Mauka, in Row & Surface correct a mismatch between a container
    and it's iterator.
* New: In Etesian, updated to work with the latest Coloquinte, patch
    contributed by G. Gouvine.
      Added EtesianEngine::setDefaultAb() to compute an abutment box if
    the Cell is completly unplaced.
* New: In cumulus, in ClockTree, now the placer can be configured to be
    either Mauka (slow simulated annealing) or Etesian (fast analytic).
    New setting 'clockTree.placerEngine' in plugin settings.
This commit is contained in:
Jean-Paul Chaput 2015-02-13 23:38:55 +01:00
parent 05ec238080
commit 3b343f08cf
21 changed files with 212 additions and 119 deletions

View File

@ -72,15 +72,17 @@
# #
# Adds -Wall to the C/C++ flags. # Adds -Wall to the C/C++ flags.
# #
#set(DEBUG_FLAGS "-g -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC")
set(DEBUG_FLAGS "-g")
if(CYGWIN) if(CYGWIN)
set(CXX_STANDARD "gnu++0x") set(CXX_STANDARD "gnu++0x")
else() else()
set(CXX_STANDARD "c++11") set(CXX_STANDARD "c++11")
endif() endif()
set(CMAKE_C_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall -g" CACHE STRING "C Compiler Debug options." FORCE) set(CMAKE_C_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE)
set(CMAKE_C_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -O2 -DNDEBUG" CACHE STRING "C Compiler Release options." FORCE) set(CMAKE_C_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -O2 -DNDEBUG" CACHE STRING "C Compiler Release options." FORCE)
set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall -g" CACHE STRING "C++ Compiler Debug options." FORCE) set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE)
set(CMAKE_CXX_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -O2 -DNDEBUG" CACHE STRING "C++ Compiler Release options." FORCE) set(CMAKE_CXX_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -O2 -DNDEBUG" CACHE STRING "C++ Compiler Release options." FORCE)
# #

View File

@ -108,7 +108,7 @@ def guessOs ():
print " (using: \"%s\")" % osType print " (using: \"%s\")" % osType
ldLibraryPath = os.getenv('LD_LIBRARY_PATH') ldLibraryPath = os.getenv('LD_LIBRARY_PATH')
if 'devtoolset' in ldLibraryPath: useDevtoolset2 = False if not ldLibraryPath or 'devtoolset' in ldLibraryPath: useDevtoolset2 = False
return (osType,libDir,useDevtoolset2) return (osType,libDir,useDevtoolset2)

View File

@ -20,5 +20,5 @@ parametersTable = \
, ('chip.pad.pvsseck' , TypeString, 'pvsseck_px') , ('chip.pad.pvsseck' , TypeString, 'pvsseck_px')
, ('clockTree.minimumSide' , TypeInt , 300) , ('clockTree.minimumSide' , TypeInt , 300)
, ('clockTree.buffer' , TypeString, 'buf_x2') , ('clockTree.buffer' , TypeString, 'buf_x2')
, ('clockTree.placerEngine' , TypeString, 'Mauka') , ('clockTree.placerEngine' , TypeString, 'Etesian')
) )

View File

@ -4,7 +4,7 @@
parametersTable = \ parametersTable = \
( ('nimbus.aspectRatio' , TypePercentage, 100 , { 'min':10, 'max':1000 } ) ( ('nimbus.aspectRatio' , TypePercentage, 100 , { 'min':10, 'max':1000 } )
, ("nimbus.pinsPlacement", TypeBool , False ) , ("nimbus.pinsPlacement", TypeBool , False )
, ("nimbus.spaceMargin" , TypePercentage, 40 ) , ("nimbus.spaceMargin" , TypePercentage, 5 )
) )

View File

@ -126,8 +126,6 @@ namespace CRL {
, _parentLibrary(NULL) , _parentLibrary(NULL)
, _routingGauges() , _routingGauges()
{ {
//cerr << "AllianceFramework::AllianceFramework()" << endl;
DataBase* db = DataBase::getDB (); DataBase* db = DataBase::getDB ();
if ( not db ) if ( not db )
db = DataBase::create (); db = DataBase::create ();

View File

@ -262,6 +262,8 @@ namespace CRL {
// AllianceFramework::get(); // AllianceFramework::get();
// cerr << "AllianceFramework has been allocated." << endl; // cerr << "AllianceFramework has been allocated." << endl;
// cerr << "std::string typeid name:" << typeid(string).name() << endl;
// Check for duplicated type_info initialization. // Check for duplicated type_info initialization.
const boptions::variable_value& value = arguments["coriolis_top"]; const boptions::variable_value& value = arguments["coriolis_top"];
if ( value.value().type() != typeid(string) ) { if ( value.value().type() != typeid(string) ) {

View File

@ -98,4 +98,8 @@ namespace CRL {
} // namespace CRL. } // namespace CRL.
INSPECTOR_P_SUPPORT(CRL::CellGauge);
#endif // CRL_CELL_GAUGE_H #endif // CRL_CELL_GAUGE_H

View File

@ -21,8 +21,11 @@
link_directories ( ${CRLCORE_BINARY_DIR}/src/ccore ) link_directories ( ${CRLCORE_BINARY_DIR}/src/ccore )
# add_executable ( cyclop ${cpps} ) if(NOT WITH_QT5)
add_executable ( cyclop ${cpps} ${mocCpps} ) list ( APPEND cpps ${mocCpps} )
endif()
add_executable ( cyclop ${cpps} )
target_link_libraries ( cyclop crlcore target_link_libraries ( cyclop crlcore
${HURRICANE_PYTHON_LIBRARIES} ${HURRICANE_PYTHON_LIBRARIES}
${HURRICANE_GRAPHICAL_LIBRARIES} ${HURRICANE_GRAPHICAL_LIBRARIES}

View File

@ -113,7 +113,7 @@ def ScriptMain ( **kw ):
etesian.destroy() etesian.destroy()
ht.connectLeaf() ht.connectLeaf()
ht.prune() #ht.prune()
ht.route() ht.route()
ht.save( cell ) ht.save( cell )

View File

@ -311,6 +311,7 @@ namespace Etesian {
bool yspinSet = false; bool yspinSet = false;
size_t yspinSlice0 = 0; size_t yspinSlice0 = 0;
SliceHoles sliceHoles ( this ); SliceHoles sliceHoles ( this );
Box toCellAb = getCell()->getAbutmentBox();
forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() ) forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() )
{ {
@ -328,6 +329,12 @@ namespace Etesian {
(*ioccurrence).getPath().getTransformation().applyOn( instanceTransf ); (*ioccurrence).getPath().getTransformation().applyOn( instanceTransf );
instanceTransf.applyOn( instanceAb ); instanceTransf.applyOn( instanceAb );
if (not toCellAb.contains(instanceAb)) {
cerr << Warning( "Instance %s is not fully enclosed in the top cell."
, getString(instance->getName()).c_str() ) << endl;
continue;
}
if (not yspinSet) { if (not yspinSet) {
yspinSet = true; yspinSet = true;

View File

@ -14,13 +14,15 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>
#if HAVE_COLOQUINTE #if HAVE_COLOQUINTE
#include "Coloquinte/circuit.hxx" #include "coloquinte/circuit.hxx"
#include "Coloquinte/legalizer.hxx" #include "coloquinte/legalizer.hxx"
#endif #endif
#include "vlsisapd/configuration/Configuration.h"
#include "vlsisapd/utilities/Dots.h" #include "vlsisapd/utilities/Dots.h"
#include "hurricane/DebugSession.h" #include "hurricane/DebugSession.h"
#include "hurricane/Bug.h" #include "hurricane/Bug.h"
@ -50,13 +52,14 @@ namespace {
using namespace std; using namespace std;
using namespace Hurricane; using namespace Hurricane;
using coloquinte::int_t;
using coloquinte::float_t; using coloquinte::float_t;
using coloquinte::point; using coloquinte::point;
#if HAVE_COLOQUINTE #if HAVE_COLOQUINTE
inline bool isNan( const float_t& f ) { return (f != f); } //inline bool isNan( const float_t& f ) { return (f != f); }
string extractInstanceName ( const RoutingPad* rp ) string extractInstanceName ( const RoutingPad* rp )
@ -130,42 +133,53 @@ namespace {
{ {
Cell* masterCell = rp->getOccurrence().getMasterCell(); Cell* masterCell = rp->getOccurrence().getMasterCell();
Component* component = rp->_getEntityAsComponent(); Component* component = rp->_getEntityAsComponent();
// TODO: verify that it doesn't assume that the orientation is North
Box masterBox = masterCell->getAbutmentBox();
Point offset = masterCell->getAbutmentBox().getCenter(); Point offset;
if (component) { if (component) {
offset.setX( component->getCenter().getX() - offset.getX() ); offset.setX( component->getCenter().getX() - masterBox.getXMin() );
offset.setY( component->getCenter().getY() - offset.getY() ); offset.setY( component->getCenter().getY() - masterBox.getYMin() );
}
else { // Why?
offset = masterBox.getCenter();
} }
return offset; return offset;
} }
Transformation toTransformation ( point<float_t> position Transformation toTransformation ( point<int_t> position
, point<float_t> orientation , point<bool> orientation
, Cell* model , Cell* model
, DbU::Unit pitch , DbU::Unit pitch
) )
{ {
DbU::Unit tx = position.x_ * pitch; DbU::Unit tx = position.x_ * pitch;
DbU::Unit ty = position.y_ * pitch; DbU::Unit ty = position.y_ * pitch;
Point center = model->getAbutmentBox().getCenter(); //Point center = model->getAbutmentBox().getCenter();
Box cellBox = model->getAbutmentBox();
Transformation::Orientation orient = Transformation::Orientation::ID; Transformation::Orientation orient = Transformation::Orientation::ID;
if ( (orientation.x_ >= 0) and (orientation.y_ >= 0) ) { // TODO offsets
tx += - center.getX(); if ( orientation.x_ and orientation.y_ ) {
ty += - center.getY(); //tx += - center.getX();
} else if ( (orientation.x_ < 0) and (orientation.y_ >= 0) ) { //ty += - center.getY();
tx += center.getX(); } else if ( not orientation.x_ and orientation.y_) {
ty += - center.getY(); //tx += center.getX();
tx += cellBox.getWidth();
//ty += - center.getY();
orient = Transformation::Orientation::MX; orient = Transformation::Orientation::MX;
} else if ( (orientation.x_ >= 0) and (orientation.y_ < 0) ) { } else if ( orientation.x_ and not orientation.y_) {
tx += - center.getX(); //tx += - center.getX();
ty += center.getY(); //ty += center.getY();
ty += cellBox.getHeight();
orient = Transformation::Orientation::MY; orient = Transformation::Orientation::MY;
} else if ( (orientation.x_ < 0) and (orientation.y_ < 0) ) { } else if ( not orientation.x_ and not orientation.y_) {
tx += center.getX(); //tx += center.getX();
ty += center.getY(); //ty += center.getY();
tx += cellBox.getWidth();
ty += cellBox.getHeight();
orient = Transformation::Orientation::R2; orient = Transformation::Orientation::R2;
} }
@ -230,15 +244,7 @@ namespace Etesian {
using coloquinte::temporary_net; using coloquinte::temporary_net;
using coloquinte::temporary_pin; using coloquinte::temporary_pin;
using coloquinte::netlist; using coloquinte::netlist;
using coloquinte::gp::placement_t; using coloquinte::placement_t;
using coloquinte::gp::get_rough_legalizer;
using coloquinte::gp::get_star_linear_system;
using coloquinte::gp::get_result;
using coloquinte::dp::legalize;
using coloquinte::dp::swaps_global;
using coloquinte::dp::swaps_row;
using coloquinte::dp::OSRP_convex;
using coloquinte::dp::row_compatible_orientation;
const char* missingEtesian = const char* missingEtesian =
"%s :\n\n" "%s :\n\n"
@ -272,7 +278,8 @@ namespace Etesian {
, _idsToInsts () , _idsToInsts ()
, _cellWidget (NULL) , _cellWidget (NULL)
, _feedCells (this) , _feedCells (this)
{ } {
}
void EtesianEngine::_postCreate () void EtesianEngine::_postCreate ()
@ -350,6 +357,62 @@ namespace Etesian {
} }
void EtesianEngine::setDefaultAb ()
{
double spaceMargin = Cfg::getParamPercentage("nimbus.spaceMargin", 10.0)->asDouble();
double aspectRatio = Cfg::getParamPercentage("nimbus.aspectRatio",100.0)->asDouble();
size_t instanceNb = 0;
double cellLength = 0;
vector<Occurrence> feedOccurrences;
forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() )
{
Instance* instance = static_cast<Instance*>((*ioccurrence).getEntity());
Cell* masterCell = instance->getMasterCell();
string instanceName = (*ioccurrence).getCompactString();
if (CatalogExtension::isFeed(masterCell)) {
cerr << Warning( "Found a feedcell %s in an unplaced design, removing."
, instanceName.c_str()
) << endl;
feedOccurrences.push_back( *ioccurrence );
continue;
}
cellLength += DbU::toLambda( masterCell->getAbutmentBox().getWidth() );
instanceNb += 1;
}
double gcellLength = cellLength*(1.0+spaceMargin) / DbU::toLambda( getSliceHeight() );
double rows = sqrt( gcellLength/aspectRatio );
if (floor(rows) != rows) rows = floor(rows)+1.0;
else rows = floor(rows);
double columns = gcellLength / rows;
if (floor(columns) != columns) columns = floor(columns)+1.0;
else columns = floor(columns);
cmess1 << " o Creating abutment box (margin:" << (spaceMargin*100.0)
<< "% aspect ratio:" << (aspectRatio*100.0)
<< "% g-length:" << (cellLength/DbU::toLambda(getSliceHeight()))
<< ")" << endl;
cmess1 << " - GCell grid: [" << (int)columns << "x" << (int)rows << "]" << endl;
UpdateSession::open();
for ( auto ioccurrence : feedOccurrences ) {
static_cast<Instance*>(ioccurrence.getEntity())->destroy();
}
getCell()->setAbutmentBox( Box( DbU::fromLambda(0)
, DbU::fromLambda(0)
, columns*getSliceHeight()
, rows *getSliceHeight()
) );
UpdateSession::close();
if (_cellWidget) _cellWidget->fitToContents();
}
void EtesianEngine::resetPlacement () void EtesianEngine::resetPlacement ()
{ {
//cerr << "EtesianEngine::resetPlacement()" << endl; //cerr << "EtesianEngine::resetPlacement()" << endl;
@ -412,8 +475,8 @@ namespace Etesian {
size_t instancesNb = getCell()->getLeafInstanceOccurrences().getSize(); size_t instancesNb = getCell()->getLeafInstanceOccurrences().getSize();
vector<Transformation> idsToTransf ( instancesNb ); vector<Transformation> idsToTransf ( instancesNb );
vector<temporary_cell> instances ( instancesNb ); vector<temporary_cell> instances ( instancesNb );
vector< point<float_t> > positions ( instancesNb ); vector< point<int_t> > positions ( instancesNb );
vector< point<float_t> > orientations( instancesNb, point<float_t>(1.0,1.0) ); vector< point<bool> > orientations( instancesNb, point<bool>(true, true) );
cmess1 << " - Converting " << instancesNb << " instances" << endl; cmess1 << " - Converting " << instancesNb << " instances" << endl;
cout.flush(); cout.flush();
@ -454,15 +517,17 @@ namespace Etesian {
(*ioccurrence).getPath().getTransformation().applyOn( instanceTransf ); (*ioccurrence).getPath().getTransformation().applyOn( instanceTransf );
instanceTransf.applyOn( instanceAb ); instanceTransf.applyOn( instanceAb );
double xsize = instanceAb.getWidth () / pitch; // Upper rounded
double ysize = instanceAb.getHeight() / pitch; int_t xsize = (instanceAb.getWidth () + pitch -1) / pitch;
double xpos = instanceAb.getCenter().getX() / pitch; int_t ysize = (instanceAb.getHeight() + pitch -1) / pitch;
double ypos = instanceAb.getCenter().getY() / pitch; // Lower rounded
int_t xpos = instanceAb.getXMin() / pitch;
int_t ypos = instanceAb.getYMin() / pitch;
instances[instanceId].size = point<int_t>( xsize, ysize ); instances[instanceId].size = point<int_t>( xsize, ysize );
instances[instanceId].list_index = instanceId; instances[instanceId].list_index = instanceId;
instances[instanceId].area = static_cast<capacity_t>(xsize) * static_cast<capacity_t>(ysize); instances[instanceId].area = static_cast<capacity_t>(xsize) * static_cast<capacity_t>(ysize);
positions[instanceId] = point<float_t>( xpos, ypos ); positions[instanceId] = point<int_t>( xpos, ypos );
if ( not instance->isFixed() and instance->isTerminal() ) { if ( not instance->isFixed() and instance->isTerminal() ) {
instances[instanceId].attributes = coloquinte::XMovable instances[instanceId].attributes = coloquinte::XMovable
@ -502,19 +567,20 @@ namespace Etesian {
dots.dot(); dots.dot();
nets[netId] = temporary_net( netId, 1.0 ); nets[netId] = temporary_net( netId, 1000 );
forEach ( RoutingPad*, irp, (*inet)->getRoutingPads() ) { forEach ( RoutingPad*, irp, (*inet)->getRoutingPads() ) {
string insName = extractInstanceName( *irp ); string insName = extractInstanceName( *irp );
Point offset = extractRpOffset ( *irp ); Point offset = extractRpOffset ( *irp );
double xpin = offset.getX() / pitch;
double ypin = offset.getY() / pitch; int_t xpin = offset.getX() / pitch;
int_t ypin = offset.getY() / pitch;
auto iid = _cellsToIds.find( insName ); auto iid = _cellsToIds.find( insName );
if (iid == _cellsToIds.end() ) { if (iid == _cellsToIds.end() ) {
cerr << Error( "Unable to lookup instance <%s>.", insName.c_str() ) << endl; cerr << Error( "Unable to lookup instance <%s>.", insName.c_str() ) << endl;
} else { } else {
pins.push_back( temporary_pin( point<float_t>(xpin,ypin), (*iid).second, netId ) ); pins.push_back( temporary_pin( point<int_t>(xpin,ypin), (*iid).second, netId ) );
} }
} }
@ -527,11 +593,12 @@ namespace Etesian {
, (int_t)(getCell()->getAbutmentBox().getYMin() / pitch) , (int_t)(getCell()->getAbutmentBox().getYMin() / pitch)
, (int_t)(getCell()->getAbutmentBox().getYMax() / pitch) , (int_t)(getCell()->getAbutmentBox().getYMax() / pitch)
); );
_circuit = netlist( instances, nets, pins ); _circuit = netlist( instances, nets, pins );
_circuit.selfcheck();
_placementLB.positions_ = positions; _placementLB.positions_ = positions;
_placementLB.orientations_ = orientations; _placementLB.orientations_ = orientations;
_placementUB = _placementLB; _placementUB = _placementLB;
cerr << "Coloquinte cell height: " << _circuit.get_cell(0).size.y_ << endl; //cerr << "Coloquinte cell height: " << _circuit.get_cell(0).size.y_ << endl;
#endif // HAVE_COLOQUINTE #endif // HAVE_COLOQUINTE
} }
@ -539,9 +606,14 @@ namespace Etesian {
void EtesianEngine::place ( unsigned int flags ) void EtesianEngine::place ( unsigned int flags )
{ {
#if HAVE_COLOQUINTE #if HAVE_COLOQUINTE
using namespace coloquinte::gp;
using namespace coloquinte::dp;
if (flags & SlowMotion) getConfiguration()-> setFlags( SlowMotion ); if (flags & SlowMotion) getConfiguration()-> setFlags( SlowMotion );
else getConfiguration()->unsetFlags( SlowMotion ); else getConfiguration()->unsetFlags( SlowMotion );
if (getCell()->getAbutmentBox().isEmpty()) setDefaultAb();
toColoquinte(); toColoquinte();
cmess1 << " o Running Coloquinte." << endl; cmess1 << " o Running Coloquinte." << endl;
@ -561,7 +633,7 @@ namespace Etesian {
first_legalizer.selfcheck(); first_legalizer.selfcheck();
cmess1 << " o Simple legalization." << endl; cmess1 << " o Simple legalization." << endl;
get_result( _circuit, _placementUB, first_legalizer); get_rough_legalization( _circuit, _placementUB, first_legalizer);
timeDelta = time(NULL) - startTime; timeDelta = time(NULL) - startTime;
cmess2 << " - Elapsed time:" << timeDelta cmess2 << " - Elapsed time:" << timeDelta
@ -573,7 +645,6 @@ namespace Etesian {
_placementLB = _placementUB; _placementLB = _placementUB;
_placementLB.selfcheck(); _placementLB.selfcheck();
zero_orientations( _circuit, _placementLB );
_updatePlacement( _placementUB ); _updatePlacement( _placementUB );
// cerr << _idsToInsts[1266] // cerr << _idsToInsts[1266]
@ -583,30 +654,21 @@ namespace Etesian {
// Breakpoint::get()->stop( 0, "After " ); // Breakpoint::get()->stop( 0, "After " );
// Early topology-independent solution // Early topology-independent solution + negligible pulling forces to avoid dumb solutions
cmess1 << " o Star (*) Optimization." << endl; cmess1 << " o Star (*) Optimization." << endl;
auto solv = get_star_linear_system( _circuit, _placementLB, 1.0, 0, 10000); auto solv = get_star_linear_system( _circuit, _placementLB, 1.0, 0, 10000)
get_result( _circuit, _placementLB, solv, 200 ); + get_pulling_forces( _circuit, _placementUB, 1000000.0);
solve_linear_system( _circuit, _placementLB, solv, 200 );
_progressReport2( startTime, " [--]" ); _progressReport2( startTime, " [--]" );
for ( int i=0; i<10; ++i ) { float_t pulling_force = 0.01;
auto solv = get_HPWLF_linear_system( _circuit, _placementLB, 1.0, 2, 100000 );
get_result( _circuit, _placementLB, solv, 300 ); // number of iterations
label.str("");
label << " [" << setw(2) << setfill('0') << i << "]";
_progressReport2( startTime, label.str() );
_updatePlacement( _placementLB );
}
float_t pulling_force = 0.03;
cmess2 << " o Simple legalization." << endl; cmess2 << " o Simple legalization." << endl;
for ( int i=0; i<50; ++i, pulling_force += 0.03 ) { for ( int i=0; i<50; ++i, pulling_force += 0.03 ) {
// Create a legalizer and bipartition it until we have sufficient precision // Create a legalizer and bipartition it until we have sufficient precision
// (~2 to 10 standard cell widths). // (~2 to 10 standard cell widths).
auto legalizer = get_rough_legalizer( _circuit, _placementLB, _surface ); auto legalizer = get_rough_legalizer( _circuit, _placementLB, _surface );
for ( int quad_part=0 ; quad_part<8 ; quad_part++ ) { for ( int quad_part=0 ; _circuit.cell_cnt() > 10 * (1 << (quad_part*2)) ; ++quad_part ) { // Until there is about 10 standard cells per region
legalizer.x_bipartition(); legalizer.x_bipartition();
legalizer.y_bipartition(); legalizer.y_bipartition();
legalizer.redo_line_partitions(); legalizer.redo_line_partitions();
@ -615,13 +677,10 @@ namespace Etesian {
legalizer.redo_diagonal_bipartitions(); legalizer.redo_diagonal_bipartitions();
legalizer.selfcheck(); legalizer.selfcheck();
} }
if (i < 10) {
spread_orientations( _circuit, _placementLB );
}
// Keep the orientation between LB and UB // Keep the orientation between LB and UB
_placementUB = _placementLB; _placementUB = _placementLB;
get_result( _circuit, _placementUB, legalizer ); get_rough_legalization( _circuit, _placementUB, legalizer );
label.str(""); label.str("");
label << " [" << setw(2) << setfill('0') << i << "] Bipart."; label << " [" << setw(2) << setfill('0') << i << "] Bipart.";
_progressReport1( startTime, label.str() ); _progressReport1( startTime, label.str() );
@ -638,21 +697,20 @@ namespace Etesian {
// and the pulling forces (threshold distance) // and the pulling forces (threshold distance)
auto solv = get_HPWLF_linear_system ( _circuit, _placementLB, 0.01, 2, 100000 ) auto solv = get_HPWLF_linear_system ( _circuit, _placementLB, 0.01, 2, 100000 )
+ get_linear_pulling_forces( _circuit, _placementUB, _placementLB, pulling_force, 40.0 ); + get_linear_pulling_forces( _circuit, _placementUB, _placementLB, pulling_force, 40.0 );
get_result( _circuit, _placementLB, solv, 400 ); // number of iterations solve_linear_system( _circuit, _placementLB, solv, 400 ); // number of iterations
_progressReport2( startTime, " Linear." ); _progressReport2( startTime, " Linear." );
_updatePlacement( _placementLB ); _updatePlacement( _placementLB );
// Optimize orientation sometimes // Optimize orientation sometimes
// if (i>=10 and i%5 == 0) { if (i%5 == 0) {
// optimize_exact_orientations( _circuit, _placementLB ); optimize_exact_orientations( _circuit, _placementLB );
// std::cout << "Oriented" << std::endl; _progressReport2( startTime, " Orient." );
// //output_progressReport(circuit, LB_pl); _updatePlacement( _placementLB );
// _updatePlacement( _placementLB ); }
// }
} }
cmess1 << " o Detailed Placement." << endl; cmess1 << " o Detailed Placement." << endl;
index_t legalizeIterations = 10; index_t legalizeIterations = 3;
for ( index_t i=0; i<legalizeIterations; ++i ){ for ( index_t i=0; i<legalizeIterations; ++i ){
ostringstream label; ostringstream label;
label.str(""); label.str("");
@ -662,22 +720,22 @@ namespace Etesian {
_progressReport1( startTime, label.str()+" Oriented ......." ); _progressReport1( startTime, label.str()+" Oriented ......." );
_updatePlacement( _placementUB ); _updatePlacement( _placementUB );
auto legalizer = legalize( _circuit, _placementLB, _surface, sliceHeight ); auto legalizer = legalize( _circuit, _placementUB, _surface, sliceHeight );
coloquinte::dp::get_result( _circuit, legalizer, _placementUB ); coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
_progressReport1( startTime, " Legalized ......" ); _progressReport1( startTime, " Legalized ......" );
_updatePlacement( _placementUB ); _updatePlacement( _placementUB );
swaps_global( _circuit, legalizer, 3, 4 ); swaps_global_HPWL( _circuit, legalizer, 3, 4 );
coloquinte::dp::get_result( _circuit, legalizer, _placementUB ); coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
_progressReport1( startTime, " Global Swaps ..." ); _progressReport1( startTime, " Global Swaps ..." );
_updatePlacement( _placementUB ); _updatePlacement( _placementUB );
OSRP_convex( _circuit, legalizer ); OSRP_convex_HPWL( _circuit, legalizer );
coloquinte::dp::get_result( _circuit, legalizer, _placementUB ); coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
_progressReport1( startTime, " Row Optimization" ); _progressReport1( startTime, " Row Optimization" );
_updatePlacement( _placementUB ); _updatePlacement( _placementUB );
swaps_row( _circuit, legalizer, 4 ); swaps_row_HPWL( _circuit, legalizer, 4 );
coloquinte::dp::get_result( _circuit, legalizer, _placementUB ); coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
_progressReport1( startTime, " Local Swaps ...." ); _progressReport1( startTime, " Local Swaps ...." );
@ -690,7 +748,6 @@ namespace Etesian {
_updatePlacement( _placementUB, (i==legalizeIterations-1) ? ForceUpdate : 0 ); _updatePlacement( _placementUB, (i==legalizeIterations-1) ? ForceUpdate : 0 );
} }
cmess1 << " o Adding feed cells." << endl; cmess1 << " o Adding feed cells." << endl;
addFeeds(); addFeeds();
@ -723,11 +780,11 @@ namespace Etesian {
elapsed << " dTime:" << setw(5) << (time(NULL) - startTime) << "s "; elapsed << " dTime:" << setw(5) << (time(NULL) - startTime) << "s ";
cmess2 << label << elapsed.str() cmess2 << label << elapsed.str()
<< " HPWL:" << get_HPWL_wirelength ( _circuit, _placementUB ) << " HPWL:" << coloquinte::gp::get_HPWL_wirelength ( _circuit, _placementUB )
<< " RMST:" << get_RSMT_wirelength ( _circuit, _placementUB ) << " RMST:" << coloquinte::gp::get_RSMT_wirelength ( _circuit, _placementUB )
<< "\n" << indent << "\n" << indent
<< " Linear Disrupt.:" << get_mean_linear_disruption ( _circuit, _placementLB, _placementUB ) << " Linear Disrupt.:" << coloquinte::gp::get_mean_linear_disruption ( _circuit, _placementLB, _placementUB )
<< " Quad Disrupt.:" << get_mean_quadratic_disruption( _circuit, _placementLB, _placementUB ) << " Quad Disrupt.:" << coloquinte::gp::get_mean_quadratic_disruption( _circuit, _placementLB, _placementUB )
<< endl; << endl;
#endif #endif
} }
@ -747,14 +804,14 @@ namespace Etesian {
elapsed << " dTime:" << setw(5) << (time(NULL) - startTime) << "s "; elapsed << " dTime:" << setw(5) << (time(NULL) - startTime) << "s ";
cmess2 << label << elapsed.str() cmess2 << label << elapsed.str()
<< " HPWL:" << get_HPWL_wirelength( _circuit, _placementLB ) << " HPWL:" << coloquinte::gp::get_HPWL_wirelength( _circuit, _placementLB )
<< " RMST:" << get_RSMT_wirelength( _circuit, _placementLB ) << " RMST:" << coloquinte::gp::get_RSMT_wirelength( _circuit, _placementLB )
<< endl; << endl;
#endif #endif
} }
void EtesianEngine::_updatePlacement ( const coloquinte::gp::placement_t& placement, unsigned int flags ) void EtesianEngine::_updatePlacement ( const coloquinte::placement_t& placement, unsigned int flags )
{ {
#if HAVE_COLOQUINTE #if HAVE_COLOQUINTE
if ((not isSlowMotion()) and not (flags & ForceUpdate)) return; if ((not isSlowMotion()) and not (flags & ForceUpdate)) return;
@ -775,14 +832,16 @@ namespace Etesian {
if (iid == _cellsToIds.end() ) { if (iid == _cellsToIds.end() ) {
cerr << Error( "Unable to lookup instance <%s>.", instanceName.c_str() ) << endl; cerr << Error( "Unable to lookup instance <%s>.", instanceName.c_str() ) << endl;
} else { } else {
point<float_t> position = placement.positions_[(*iid).second]; point<int_t> position = placement.positions_[(*iid).second];
/*
if ( isNan(position.x_) or isNan(position.y_) ) { if ( isNan(position.x_) or isNan(position.y_) ) {
cerr << Error( "Instance <%s> is not placed yet (position == NaN)." cerr << Error( "Instance <%s> is not placed yet (position == NaN)."
, instanceName.c_str() ) << endl; , instanceName.c_str() ) << endl;
instance->setPlacementStatus( Instance::PlacementStatus::UNPLACED ); instance->setPlacementStatus( Instance::PlacementStatus::UNPLACED );
continue; continue;
} }
*/
Transformation trans = toTransformation( position Transformation trans = toTransformation( position
, placement.orientations_[(*iid).second] , placement.orientations_[(*iid).second]

View File

@ -88,6 +88,8 @@ extern "C" {
PyModule_AddObject( module, "GraphicEtesianEngine", (PyObject*)&PyTypeGraphicEtesianEngine ); PyModule_AddObject( module, "GraphicEtesianEngine", (PyObject*)&PyTypeGraphicEtesianEngine );
PyEtesianEngine_postModuleInit(); PyEtesianEngine_postModuleInit();
//cerr << "std::string typeid name:" << typeid(string).name() << endl;
} }

View File

@ -33,6 +33,7 @@ namespace Etesian {
using std::hex; using std::hex;
using std::ostringstream; using std::ostringstream;
using Hurricane::tab; using Hurricane::tab;
using Hurricane::trace_on;
using Hurricane::in_trace; using Hurricane::in_trace;
using Hurricane::Error; using Hurricane::Error;
using Hurricane::Warning; using Hurricane::Warning;

View File

@ -19,7 +19,7 @@
#include <iostream> #include <iostream>
#include <unordered_map> #include <unordered_map>
#include "Coloquinte/circuit.hxx" #include "coloquinte/circuit.hxx"
#include "hurricane/Timer.h" #include "hurricane/Timer.h"
#include "hurricane/Name.h" #include "hurricane/Name.h"
@ -74,6 +74,7 @@ namespace Etesian {
void startMeasures (); void startMeasures ();
void stopMeasures (); void stopMeasures ();
void printMeasures ( std::string ) const; void printMeasures ( std::string ) const;
void setDefaultAb ();
void resetPlacement (); void resetPlacement ();
void toColoquinte (); void toColoquinte ();
void place ( unsigned int flags=SlowMotion ); void place ( unsigned int flags=SlowMotion );
@ -92,8 +93,8 @@ namespace Etesian {
Timer _timer; Timer _timer;
coloquinte::box<coloquinte::int_t> _surface; coloquinte::box<coloquinte::int_t> _surface;
coloquinte::netlist _circuit; coloquinte::netlist _circuit;
coloquinte::gp::placement_t _placementLB; coloquinte::placement_t _placementLB;
coloquinte::gp::placement_t _placementUB; coloquinte::placement_t _placementUB;
std::unordered_map<string,unsigned int> _cellsToIds; std::unordered_map<string,unsigned int> _cellsToIds;
std::vector<Instance*> _idsToInsts; std::vector<Instance*> _idsToInsts;
Hurricane::CellWidget* _cellWidget; Hurricane::CellWidget* _cellWidget;
@ -109,7 +110,7 @@ namespace Etesian {
EtesianEngine ( const EtesianEngine& ); EtesianEngine ( const EtesianEngine& );
EtesianEngine& operator= ( const EtesianEngine& ); EtesianEngine& operator= ( const EtesianEngine& );
private: private:
void _updatePlacement ( const coloquinte::gp::placement_t&, unsigned int flags=0 ); void _updatePlacement ( const coloquinte::placement_t&, unsigned int flags=0 );
void _progressReport1 ( time_t startTime, string label ) const; void _progressReport1 ( time_t startTime, string label ) const;
void _progressReport2 ( time_t startTime, string label ) const; void _progressReport2 ( time_t startTime, string label ) const;
}; };

View File

@ -142,6 +142,10 @@ void Plug::setNet(Net* net)
if (!getBodyHook()->getSlaveHooks().isEmpty()) if (!getBodyHook()->getSlaveHooks().isEmpty())
throw Error("Can't change net of plug: not empty slave hooks"); throw Error("Can't change net of plug: not empty slave hooks");
if (net == NULL) {
cerr << "About to disconnect " << this << endl;
}
_setNet(net); _setNet(net);
} }
} }

View File

@ -515,6 +515,7 @@ extern "C" {
// Module Initialization : "initHurricane ()" // Module Initialization : "initHurricane ()"
DL_EXPORT(void) initHurricane () { DL_EXPORT(void) initHurricane () {
//trace_on();
trace << "initHurricane()" << endl; trace << "initHurricane()" << endl;
PyDebugSession_LinkPyType (); PyDebugSession_LinkPyType ();

View File

@ -640,7 +640,8 @@ extern "C" {
static void PY_FUNC_NAME ( PY_SELF_TYPE *self ) \ static void PY_FUNC_NAME ( PY_SELF_TYPE *self ) \
{ \ { \
trace << #PY_SELF_TYPE"_DeAlloc(" << hex << self << ") " \ trace << #PY_SELF_TYPE"_DeAlloc(" << hex << self << ") " \
<< self->ACCESS_OBJECT << endl; \ << hex << (void*)(self->ACCESS_OBJECT) \
<< ":" << self->ACCESS_OBJECT << endl; \
\ \
if ( self->ACCESS_OBJECT ) { \ if ( self->ACCESS_OBJECT ) { \
trace << "C++ object := " << hex \ trace << "C++ object := " << hex \
@ -897,6 +898,7 @@ extern "C" {
\ \
extern void Py##TYPE##Vector_LinkPyType(); extern void Py##TYPE##Vector_LinkPyType();
#define IteratorValNextMethod(TYPE) \ #define IteratorValNextMethod(TYPE) \
static PyObject* Py##TYPE##IteratorNext(Py##TYPE##VectorIterator* pyIterator) \ static PyObject* Py##TYPE##IteratorNext(Py##TYPE##VectorIterator* pyIterator) \
{ \ { \
@ -992,6 +994,8 @@ extern "C" {
if (pyObject == NULL) { return NULL; } \ if (pyObject == NULL) { return NULL; } \
\ \
pyObject->ACCESS_OBJECT = object; \ pyObject->ACCESS_OBJECT = object; \
trace << "Py" #SELF_TYPE "_Link(" << hex << pyObject << ") " \
<< hex << (void*)object << ":" << object << endl; \
HCATCH \ HCATCH \
\ \
return ( (PyObject*)pyObject ); \ return ( (PyObject*)pyObject ); \
@ -1006,25 +1010,27 @@ extern "C" {
static PyObject* PY_FUNC_NAME ( PY_SELF_TYPE *self ) \ static PyObject* PY_FUNC_NAME ( PY_SELF_TYPE *self ) \
{ \ { \
HTRY \ HTRY \
if ( self->ACCESS_OBJECT == NULL ) { \ if (self->ACCESS_OBJECT == NULL) { \
ostringstream message; \ ostringstream message; \
message << "applying a Delete to a Python object with no HURRICANE object attached"; \ message << "applying a destroy() to a Python object with no Hurricane object attached"; \
PyErr_SetString ( ProxyError, message.str().c_str() ); \ PyErr_SetString( ProxyError, message.str().c_str() ); \
return ( NULL ); \ return NULL; \
} \ } \
ProxyProperty* proxy = static_cast<ProxyProperty*> \ ProxyProperty* proxy = static_cast<ProxyProperty*> \
( self->ACCESS_OBJECT->getProperty ( ProxyProperty::getPropertyName() ) ); \ ( self->ACCESS_OBJECT->getProperty( ProxyProperty::getPropertyName() ) ); \
if (proxy == NULL) { \ if (proxy == NULL) { \
ostringstream message; \ ostringstream message; \
message << "Trying to Delete a Hurricane object of with no Proxy attached "; \ message << "Trying to destroy() a Hurricane object of with no Proxy attached "; \
PyErr_SetString ( ProxyError, message.str().c_str() ); \ PyErr_SetString( ProxyError, message.str().c_str() ); \
return ( NULL ); \ return NULL; \
} \ } \
self->ACCESS_OBJECT->destroy(); \ self->ACCESS_OBJECT->destroy(); \
self->ACCESS_OBJECT = NULL; \
HCATCH \ HCATCH \
Py_RETURN_NONE; \ Py_RETURN_NONE; \
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Attribute Macro For BDo Link/Creation. // Attribute Macro For BDo Link/Creation.
@ -1050,6 +1056,8 @@ extern "C" {
pyObject = (Py##SELF_TYPE*)proxy->getShadow (); \ pyObject = (Py##SELF_TYPE*)proxy->getShadow (); \
Py_INCREF ( ACCESS_CLASS(pyObject) ); \ Py_INCREF ( ACCESS_CLASS(pyObject) ); \
} \ } \
trace << "PyDbo" #SELF_TYPE "_Link(" << hex << pyObject << ") " \
<< hex << (void*)object << ":" << object << endl; \
HCATCH \ HCATCH \
\ \
return ( (PyObject*)pyObject ); \ return ( (PyObject*)pyObject ); \
@ -1062,7 +1070,7 @@ extern "C" {
static void Py##SELF_TYPE##_DeAlloc ( Py##SELF_TYPE *self ) \ static void Py##SELF_TYPE##_DeAlloc ( Py##SELF_TYPE *self ) \
{ \ { \
trace << "PyDbObject_DeAlloc(" << hex << self << ") " \ trace << "PyDbObject_DeAlloc(" << hex << self << ") " \
<< self->ACCESS_OBJECT << endl; \ << hex << (void*)(self->ACCESS_OBJECT) << ":" << self->ACCESS_OBJECT << endl; \
\ \
if ( self->ACCESS_OBJECT != NULL ) { \ if ( self->ACCESS_OBJECT != NULL ) { \
ProxyProperty* proxy = static_cast<ProxyProperty*> \ ProxyProperty* proxy = static_cast<ProxyProperty*> \
@ -1087,7 +1095,8 @@ extern "C" {
static void Py##SELF_TYPE##_DeAlloc ( Py##SELF_TYPE *self ) \ static void Py##SELF_TYPE##_DeAlloc ( Py##SELF_TYPE *self ) \
{ \ { \
trace << "PythonOnlyObject_DeAlloc(" << hex << self << ") " \ trace << "PythonOnlyObject_DeAlloc(" << hex << self << ") " \
<< self->ACCESS_OBJECT << endl; \ << hex << (void*)(self->ACCESS_OBJECT) \
<< ":" << self->ACCESS_OBJECT << endl; \
PyObject_DEL ( self ); \ PyObject_DEL ( self ); \
} }

View File

@ -90,7 +90,7 @@ QBrush* getBrush ( const string& pattern, int red, int green, int blue )
cerr << "[WARNING] Invalid bitmap pattern: \"0x" << pattern << "\"." << endl; cerr << "[WARNING] Invalid bitmap pattern: \"0x" << pattern << "\"." << endl;
QBrush* brush = new QBrush ( QColor(red,green,blue), QBitmap::fromData(QSize(size,size),bits,QImage::Format_Mono) ); QBrush* brush = new QBrush ( QColor(red,green,blue), QBitmap::fromData(QSize(size,size),bits,QImage::Format_Mono) );
if (bits != NULL) delete bits; //if (bits != NULL) delete bits;
return brush; return brush;
} }

View File

@ -325,7 +325,7 @@ namespace Katabatic {
private: private:
unsigned int _depth; unsigned int _depth;
std::set<GCell*,GCell::CompareByKey> _set; std::set<GCell*,GCell::CompareByKey> _set;
std::set<GCell*> _requests; GCell::SetIndex _requests;
}; };

View File

@ -134,8 +134,8 @@ SubRow* Row::getSubRowBetween(DbU::Unit x1, DbU::Unit x2)
if (_subRowVector.size() == 1) if (_subRowVector.size() == 1)
return _subRowVector[0]; return _subRowVector[0];
SubRowXMax::iterator rinf = _subRowXMax.upper_bound(x1); SubRowXMax::iterator rinf = _subRowXMax.upper_bound(x1);
SubRowXMax::iterator rsup = _subRowXMinInv.upper_bound(x2); SubRowXMinInv::iterator rsup = _subRowXMinInv.upper_bound(x2);
unsigned randidx = rinf->second + unsigned randidx = rinf->second +

View File

@ -579,8 +579,8 @@ Bin* Surface::getBinInSurface(Bin* srcbin, double dist)
if (upperY > getYMax()) if (upperY > getYMax())
upperY = getYMax(); upperY = getYMax();
RowYMax::iterator rinf = _rowYMax.upper_bound(lowerY); RowYMax::iterator rinf = _rowYMax.upper_bound(lowerY);
RowYMax::iterator rsup = _rowYMinInv.upper_bound(upperY); RowYMinInv::iterator rsup = _rowYMinInv.upper_bound(upperY);
unsigned randidx = rinf->second + unsigned randidx = rinf->second +