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:
parent
05ec238080
commit
3b343f08cf
|
@ -72,15 +72,17 @@
|
|||
#
|
||||
# Adds -Wall to the C/C++ flags.
|
||||
#
|
||||
#set(DEBUG_FLAGS "-g -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC")
|
||||
set(DEBUG_FLAGS "-g")
|
||||
if(CYGWIN)
|
||||
set(CXX_STANDARD "gnu++0x")
|
||||
else()
|
||||
set(CXX_STANDARD "c++11")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall -g" 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_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall -g" 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_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_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)
|
||||
|
||||
|
||||
#
|
||||
|
|
|
@ -108,7 +108,7 @@ def guessOs ():
|
|||
print " (using: \"%s\")" % osType
|
||||
|
||||
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)
|
||||
|
||||
|
|
|
@ -20,5 +20,5 @@ parametersTable = \
|
|||
, ('chip.pad.pvsseck' , TypeString, 'pvsseck_px')
|
||||
, ('clockTree.minimumSide' , TypeInt , 300)
|
||||
, ('clockTree.buffer' , TypeString, 'buf_x2')
|
||||
, ('clockTree.placerEngine' , TypeString, 'Mauka')
|
||||
, ('clockTree.placerEngine' , TypeString, 'Etesian')
|
||||
)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
parametersTable = \
|
||||
( ('nimbus.aspectRatio' , TypePercentage, 100 , { 'min':10, 'max':1000 } )
|
||||
, ("nimbus.pinsPlacement", TypeBool , False )
|
||||
, ("nimbus.spaceMargin" , TypePercentage, 40 )
|
||||
, ("nimbus.spaceMargin" , TypePercentage, 5 )
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -126,8 +126,6 @@ namespace CRL {
|
|||
, _parentLibrary(NULL)
|
||||
, _routingGauges()
|
||||
{
|
||||
//cerr << "AllianceFramework::AllianceFramework()" << endl;
|
||||
|
||||
DataBase* db = DataBase::getDB ();
|
||||
if ( not db )
|
||||
db = DataBase::create ();
|
||||
|
|
|
@ -262,6 +262,8 @@ namespace CRL {
|
|||
// AllianceFramework::get();
|
||||
// cerr << "AllianceFramework has been allocated." << endl;
|
||||
|
||||
// cerr << "std::string typeid name:" << typeid(string).name() << endl;
|
||||
|
||||
// Check for duplicated type_info initialization.
|
||||
const boptions::variable_value& value = arguments["coriolis_top"];
|
||||
if ( value.value().type() != typeid(string) ) {
|
||||
|
|
|
@ -98,4 +98,8 @@ namespace CRL {
|
|||
|
||||
} // namespace CRL.
|
||||
|
||||
|
||||
INSPECTOR_P_SUPPORT(CRL::CellGauge);
|
||||
|
||||
|
||||
#endif // CRL_CELL_GAUGE_H
|
||||
|
|
|
@ -21,8 +21,11 @@
|
|||
|
||||
link_directories ( ${CRLCORE_BINARY_DIR}/src/ccore )
|
||||
|
||||
# add_executable ( cyclop ${cpps} )
|
||||
add_executable ( cyclop ${cpps} ${mocCpps} )
|
||||
if(NOT WITH_QT5)
|
||||
list ( APPEND cpps ${mocCpps} )
|
||||
endif()
|
||||
|
||||
add_executable ( cyclop ${cpps} )
|
||||
target_link_libraries ( cyclop crlcore
|
||||
${HURRICANE_PYTHON_LIBRARIES}
|
||||
${HURRICANE_GRAPHICAL_LIBRARIES}
|
||||
|
|
|
@ -113,7 +113,7 @@ def ScriptMain ( **kw ):
|
|||
etesian.destroy()
|
||||
|
||||
ht.connectLeaf()
|
||||
ht.prune()
|
||||
#ht.prune()
|
||||
ht.route()
|
||||
ht.save( cell )
|
||||
|
||||
|
|
|
@ -311,6 +311,7 @@ namespace Etesian {
|
|||
bool yspinSet = false;
|
||||
size_t yspinSlice0 = 0;
|
||||
SliceHoles sliceHoles ( this );
|
||||
Box toCellAb = getCell()->getAbutmentBox();
|
||||
|
||||
forEach ( Occurrence, ioccurrence, getCell()->getLeafInstanceOccurrences() )
|
||||
{
|
||||
|
@ -328,6 +329,12 @@ namespace Etesian {
|
|||
(*ioccurrence).getPath().getTransformation().applyOn( instanceTransf );
|
||||
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) {
|
||||
yspinSet = true;
|
||||
|
||||
|
|
|
@ -14,13 +14,15 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#if HAVE_COLOQUINTE
|
||||
#include "Coloquinte/circuit.hxx"
|
||||
#include "Coloquinte/legalizer.hxx"
|
||||
#include "coloquinte/circuit.hxx"
|
||||
#include "coloquinte/legalizer.hxx"
|
||||
#endif
|
||||
#include "vlsisapd/configuration/Configuration.h"
|
||||
#include "vlsisapd/utilities/Dots.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/Bug.h"
|
||||
|
@ -50,13 +52,14 @@ namespace {
|
|||
|
||||
using namespace std;
|
||||
using namespace Hurricane;
|
||||
using coloquinte::int_t;
|
||||
using coloquinte::float_t;
|
||||
using coloquinte::point;
|
||||
|
||||
|
||||
|
||||
#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 )
|
||||
|
@ -130,42 +133,53 @@ namespace {
|
|||
{
|
||||
Cell* masterCell = rp->getOccurrence().getMasterCell();
|
||||
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) {
|
||||
offset.setX( component->getCenter().getX() - offset.getX() );
|
||||
offset.setY( component->getCenter().getY() - offset.getY() );
|
||||
offset.setX( component->getCenter().getX() - masterBox.getXMin() );
|
||||
offset.setY( component->getCenter().getY() - masterBox.getYMin() );
|
||||
}
|
||||
else { // Why?
|
||||
offset = masterBox.getCenter();
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
Transformation toTransformation ( point<float_t> position
|
||||
, point<float_t> orientation
|
||||
Transformation toTransformation ( point<int_t> position
|
||||
, point<bool> orientation
|
||||
, Cell* model
|
||||
, DbU::Unit pitch
|
||||
)
|
||||
{
|
||||
DbU::Unit tx = position.x_ * 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;
|
||||
|
||||
if ( (orientation.x_ >= 0) and (orientation.y_ >= 0) ) {
|
||||
tx += - center.getX();
|
||||
ty += - center.getY();
|
||||
} else if ( (orientation.x_ < 0) and (orientation.y_ >= 0) ) {
|
||||
tx += center.getX();
|
||||
ty += - center.getY();
|
||||
// TODO offsets
|
||||
if ( orientation.x_ and orientation.y_ ) {
|
||||
//tx += - center.getX();
|
||||
//ty += - center.getY();
|
||||
} else if ( not orientation.x_ and orientation.y_) {
|
||||
//tx += center.getX();
|
||||
tx += cellBox.getWidth();
|
||||
//ty += - center.getY();
|
||||
orient = Transformation::Orientation::MX;
|
||||
} else if ( (orientation.x_ >= 0) and (orientation.y_ < 0) ) {
|
||||
tx += - center.getX();
|
||||
ty += center.getY();
|
||||
} else if ( orientation.x_ and not orientation.y_) {
|
||||
//tx += - center.getX();
|
||||
//ty += center.getY();
|
||||
ty += cellBox.getHeight();
|
||||
orient = Transformation::Orientation::MY;
|
||||
} else if ( (orientation.x_ < 0) and (orientation.y_ < 0) ) {
|
||||
tx += center.getX();
|
||||
ty += center.getY();
|
||||
} else if ( not orientation.x_ and not orientation.y_) {
|
||||
//tx += center.getX();
|
||||
//ty += center.getY();
|
||||
tx += cellBox.getWidth();
|
||||
ty += cellBox.getHeight();
|
||||
orient = Transformation::Orientation::R2;
|
||||
}
|
||||
|
||||
|
@ -230,15 +244,7 @@ namespace Etesian {
|
|||
using coloquinte::temporary_net;
|
||||
using coloquinte::temporary_pin;
|
||||
using coloquinte::netlist;
|
||||
using coloquinte::gp::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;
|
||||
using coloquinte::placement_t;
|
||||
|
||||
const char* missingEtesian =
|
||||
"%s :\n\n"
|
||||
|
@ -272,7 +278,8 @@ namespace Etesian {
|
|||
, _idsToInsts ()
|
||||
, _cellWidget (NULL)
|
||||
, _feedCells (this)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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 ()
|
||||
{
|
||||
//cerr << "EtesianEngine::resetPlacement()" << endl;
|
||||
|
@ -412,8 +475,8 @@ namespace Etesian {
|
|||
size_t instancesNb = getCell()->getLeafInstanceOccurrences().getSize();
|
||||
vector<Transformation> idsToTransf ( instancesNb );
|
||||
vector<temporary_cell> instances ( instancesNb );
|
||||
vector< point<float_t> > positions ( instancesNb );
|
||||
vector< point<float_t> > orientations( instancesNb, point<float_t>(1.0,1.0) );
|
||||
vector< point<int_t> > positions ( instancesNb );
|
||||
vector< point<bool> > orientations( instancesNb, point<bool>(true, true) );
|
||||
|
||||
cmess1 << " - Converting " << instancesNb << " instances" << endl;
|
||||
cout.flush();
|
||||
|
@ -454,15 +517,17 @@ namespace Etesian {
|
|||
(*ioccurrence).getPath().getTransformation().applyOn( instanceTransf );
|
||||
instanceTransf.applyOn( instanceAb );
|
||||
|
||||
double xsize = instanceAb.getWidth () / pitch;
|
||||
double ysize = instanceAb.getHeight() / pitch;
|
||||
double xpos = instanceAb.getCenter().getX() / pitch;
|
||||
double ypos = instanceAb.getCenter().getY() / pitch;
|
||||
// Upper rounded
|
||||
int_t xsize = (instanceAb.getWidth () + pitch -1) / pitch;
|
||||
int_t ysize = (instanceAb.getHeight() + pitch -1) / 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].list_index = instanceId;
|
||||
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() ) {
|
||||
instances[instanceId].attributes = coloquinte::XMovable
|
||||
|
@ -502,19 +567,20 @@ namespace Etesian {
|
|||
|
||||
dots.dot();
|
||||
|
||||
nets[netId] = temporary_net( netId, 1.0 );
|
||||
nets[netId] = temporary_net( netId, 1000 );
|
||||
|
||||
forEach ( RoutingPad*, irp, (*inet)->getRoutingPads() ) {
|
||||
string insName = extractInstanceName( *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 );
|
||||
if (iid == _cellsToIds.end() ) {
|
||||
cerr << Error( "Unable to lookup instance <%s>.", insName.c_str() ) << endl;
|
||||
} 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().getYMax() / pitch)
|
||||
);
|
||||
_circuit = netlist( instances, nets, pins );
|
||||
_circuit = netlist( instances, nets, pins );
|
||||
_circuit.selfcheck();
|
||||
_placementLB.positions_ = positions;
|
||||
_placementLB.orientations_ = orientations;
|
||||
_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
|
||||
}
|
||||
|
@ -539,9 +606,14 @@ namespace Etesian {
|
|||
void EtesianEngine::place ( unsigned int flags )
|
||||
{
|
||||
#if HAVE_COLOQUINTE
|
||||
using namespace coloquinte::gp;
|
||||
using namespace coloquinte::dp;
|
||||
|
||||
if (flags & SlowMotion) getConfiguration()-> setFlags( SlowMotion );
|
||||
else getConfiguration()->unsetFlags( SlowMotion );
|
||||
|
||||
if (getCell()->getAbutmentBox().isEmpty()) setDefaultAb();
|
||||
|
||||
toColoquinte();
|
||||
|
||||
cmess1 << " o Running Coloquinte." << endl;
|
||||
|
@ -561,7 +633,7 @@ namespace Etesian {
|
|||
first_legalizer.selfcheck();
|
||||
|
||||
cmess1 << " o Simple legalization." << endl;
|
||||
get_result( _circuit, _placementUB, first_legalizer);
|
||||
get_rough_legalization( _circuit, _placementUB, first_legalizer);
|
||||
|
||||
timeDelta = time(NULL) - startTime;
|
||||
cmess2 << " - Elapsed time:" << timeDelta
|
||||
|
@ -573,7 +645,6 @@ namespace Etesian {
|
|||
_placementLB = _placementUB;
|
||||
_placementLB.selfcheck();
|
||||
|
||||
zero_orientations( _circuit, _placementLB );
|
||||
_updatePlacement( _placementUB );
|
||||
|
||||
// cerr << _idsToInsts[1266]
|
||||
|
@ -583,30 +654,21 @@ namespace Etesian {
|
|||
|
||||
// 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;
|
||||
auto solv = get_star_linear_system( _circuit, _placementLB, 1.0, 0, 10000);
|
||||
get_result( _circuit, _placementLB, solv, 200 );
|
||||
auto solv = get_star_linear_system( _circuit, _placementLB, 1.0, 0, 10000)
|
||||
+ get_pulling_forces( _circuit, _placementUB, 1000000.0);
|
||||
solve_linear_system( _circuit, _placementLB, solv, 200 );
|
||||
_progressReport2( startTime, " [--]" );
|
||||
|
||||
for ( int i=0; i<10; ++i ) {
|
||||
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;
|
||||
float_t pulling_force = 0.01;
|
||||
|
||||
cmess2 << " o Simple legalization." << endl;
|
||||
for ( int i=0; i<50; ++i, pulling_force += 0.03 ) {
|
||||
// Create a legalizer and bipartition it until we have sufficient precision
|
||||
// (~2 to 10 standard cell widths).
|
||||
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.y_bipartition();
|
||||
legalizer.redo_line_partitions();
|
||||
|
@ -615,13 +677,10 @@ namespace Etesian {
|
|||
legalizer.redo_diagonal_bipartitions();
|
||||
legalizer.selfcheck();
|
||||
}
|
||||
if (i < 10) {
|
||||
spread_orientations( _circuit, _placementLB );
|
||||
}
|
||||
// Keep the orientation between LB and UB
|
||||
_placementUB = _placementLB;
|
||||
|
||||
get_result( _circuit, _placementUB, legalizer );
|
||||
get_rough_legalization( _circuit, _placementUB, legalizer );
|
||||
label.str("");
|
||||
label << " [" << setw(2) << setfill('0') << i << "] Bipart.";
|
||||
_progressReport1( startTime, label.str() );
|
||||
|
@ -638,21 +697,20 @@ namespace Etesian {
|
|||
// and the pulling forces (threshold distance)
|
||||
auto solv = get_HPWLF_linear_system ( _circuit, _placementLB, 0.01, 2, 100000 )
|
||||
+ 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." );
|
||||
_updatePlacement( _placementLB );
|
||||
|
||||
// Optimize orientation sometimes
|
||||
// if (i>=10 and i%5 == 0) {
|
||||
// optimize_exact_orientations( _circuit, _placementLB );
|
||||
// std::cout << "Oriented" << std::endl;
|
||||
// //output_progressReport(circuit, LB_pl);
|
||||
// _updatePlacement( _placementLB );
|
||||
// }
|
||||
if (i%5 == 0) {
|
||||
optimize_exact_orientations( _circuit, _placementLB );
|
||||
_progressReport2( startTime, " Orient." );
|
||||
_updatePlacement( _placementLB );
|
||||
}
|
||||
}
|
||||
|
||||
cmess1 << " o Detailed Placement." << endl;
|
||||
index_t legalizeIterations = 10;
|
||||
index_t legalizeIterations = 3;
|
||||
for ( index_t i=0; i<legalizeIterations; ++i ){
|
||||
ostringstream label;
|
||||
label.str("");
|
||||
|
@ -662,22 +720,22 @@ namespace Etesian {
|
|||
_progressReport1( startTime, label.str()+" Oriented ......." );
|
||||
_updatePlacement( _placementUB );
|
||||
|
||||
auto legalizer = legalize( _circuit, _placementLB, _surface, sliceHeight );
|
||||
auto legalizer = legalize( _circuit, _placementUB, _surface, sliceHeight );
|
||||
coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
|
||||
_progressReport1( startTime, " Legalized ......" );
|
||||
_updatePlacement( _placementUB );
|
||||
|
||||
swaps_global( _circuit, legalizer, 3, 4 );
|
||||
swaps_global_HPWL( _circuit, legalizer, 3, 4 );
|
||||
coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
|
||||
_progressReport1( startTime, " Global Swaps ..." );
|
||||
_updatePlacement( _placementUB );
|
||||
|
||||
OSRP_convex( _circuit, legalizer );
|
||||
OSRP_convex_HPWL( _circuit, legalizer );
|
||||
coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
|
||||
_progressReport1( startTime, " Row Optimization" );
|
||||
_updatePlacement( _placementUB );
|
||||
|
||||
swaps_row( _circuit, legalizer, 4 );
|
||||
swaps_row_HPWL( _circuit, legalizer, 4 );
|
||||
coloquinte::dp::get_result( _circuit, legalizer, _placementUB );
|
||||
_progressReport1( startTime, " Local Swaps ...." );
|
||||
|
||||
|
@ -690,7 +748,6 @@ namespace Etesian {
|
|||
_updatePlacement( _placementUB, (i==legalizeIterations-1) ? ForceUpdate : 0 );
|
||||
}
|
||||
|
||||
|
||||
cmess1 << " o Adding feed cells." << endl;
|
||||
addFeeds();
|
||||
|
||||
|
@ -723,11 +780,11 @@ namespace Etesian {
|
|||
elapsed << " dTime:" << setw(5) << (time(NULL) - startTime) << "s ";
|
||||
|
||||
cmess2 << label << elapsed.str()
|
||||
<< " HPWL:" << get_HPWL_wirelength ( _circuit, _placementUB )
|
||||
<< " RMST:" << get_RSMT_wirelength ( _circuit, _placementUB )
|
||||
<< " HPWL:" << coloquinte::gp::get_HPWL_wirelength ( _circuit, _placementUB )
|
||||
<< " RMST:" << coloquinte::gp::get_RSMT_wirelength ( _circuit, _placementUB )
|
||||
<< "\n" << indent
|
||||
<< " Linear Disrupt.:" << get_mean_linear_disruption ( _circuit, _placementLB, _placementUB )
|
||||
<< " Quad Disrupt.:" << get_mean_quadratic_disruption( _circuit, _placementLB, _placementUB )
|
||||
<< " Linear Disrupt.:" << coloquinte::gp::get_mean_linear_disruption ( _circuit, _placementLB, _placementUB )
|
||||
<< " Quad Disrupt.:" << coloquinte::gp::get_mean_quadratic_disruption( _circuit, _placementLB, _placementUB )
|
||||
<< endl;
|
||||
#endif
|
||||
}
|
||||
|
@ -747,14 +804,14 @@ namespace Etesian {
|
|||
elapsed << " dTime:" << setw(5) << (time(NULL) - startTime) << "s ";
|
||||
|
||||
cmess2 << label << elapsed.str()
|
||||
<< " HPWL:" << get_HPWL_wirelength( _circuit, _placementLB )
|
||||
<< " RMST:" << get_RSMT_wirelength( _circuit, _placementLB )
|
||||
<< " HPWL:" << coloquinte::gp::get_HPWL_wirelength( _circuit, _placementLB )
|
||||
<< " RMST:" << coloquinte::gp::get_RSMT_wirelength( _circuit, _placementLB )
|
||||
<< endl;
|
||||
#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 ((not isSlowMotion()) and not (flags & ForceUpdate)) return;
|
||||
|
@ -775,14 +832,16 @@ namespace Etesian {
|
|||
if (iid == _cellsToIds.end() ) {
|
||||
cerr << Error( "Unable to lookup instance <%s>.", instanceName.c_str() ) << endl;
|
||||
} 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_) ) {
|
||||
cerr << Error( "Instance <%s> is not placed yet (position == NaN)."
|
||||
, instanceName.c_str() ) << endl;
|
||||
instance->setPlacementStatus( Instance::PlacementStatus::UNPLACED );
|
||||
continue;
|
||||
}
|
||||
*/
|
||||
|
||||
Transformation trans = toTransformation( position
|
||||
, placement.orientations_[(*iid).second]
|
||||
|
|
|
@ -88,6 +88,8 @@ extern "C" {
|
|||
PyModule_AddObject( module, "GraphicEtesianEngine", (PyObject*)&PyTypeGraphicEtesianEngine );
|
||||
|
||||
PyEtesianEngine_postModuleInit();
|
||||
|
||||
//cerr << "std::string typeid name:" << typeid(string).name() << endl;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace Etesian {
|
|||
using std::hex;
|
||||
using std::ostringstream;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::trace_on;
|
||||
using Hurricane::in_trace;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
#include "Coloquinte/circuit.hxx"
|
||||
#include "coloquinte/circuit.hxx"
|
||||
|
||||
#include "hurricane/Timer.h"
|
||||
#include "hurricane/Name.h"
|
||||
|
@ -74,6 +74,7 @@ namespace Etesian {
|
|||
void startMeasures ();
|
||||
void stopMeasures ();
|
||||
void printMeasures ( std::string ) const;
|
||||
void setDefaultAb ();
|
||||
void resetPlacement ();
|
||||
void toColoquinte ();
|
||||
void place ( unsigned int flags=SlowMotion );
|
||||
|
@ -92,8 +93,8 @@ namespace Etesian {
|
|||
Timer _timer;
|
||||
coloquinte::box<coloquinte::int_t> _surface;
|
||||
coloquinte::netlist _circuit;
|
||||
coloquinte::gp::placement_t _placementLB;
|
||||
coloquinte::gp::placement_t _placementUB;
|
||||
coloquinte::placement_t _placementLB;
|
||||
coloquinte::placement_t _placementUB;
|
||||
std::unordered_map<string,unsigned int> _cellsToIds;
|
||||
std::vector<Instance*> _idsToInsts;
|
||||
Hurricane::CellWidget* _cellWidget;
|
||||
|
@ -109,7 +110,7 @@ namespace Etesian {
|
|||
EtesianEngine ( const EtesianEngine& );
|
||||
EtesianEngine& operator= ( const EtesianEngine& );
|
||||
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 _progressReport2 ( time_t startTime, string label ) const;
|
||||
};
|
||||
|
|
|
@ -142,6 +142,10 @@ void Plug::setNet(Net* net)
|
|||
if (!getBodyHook()->getSlaveHooks().isEmpty())
|
||||
throw Error("Can't change net of plug: not empty slave hooks");
|
||||
|
||||
if (net == NULL) {
|
||||
cerr << "About to disconnect " << this << endl;
|
||||
}
|
||||
|
||||
_setNet(net);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -515,6 +515,7 @@ extern "C" {
|
|||
// Module Initialization : "initHurricane ()"
|
||||
|
||||
DL_EXPORT(void) initHurricane () {
|
||||
//trace_on();
|
||||
trace << "initHurricane()" << endl;
|
||||
|
||||
PyDebugSession_LinkPyType ();
|
||||
|
|
|
@ -640,7 +640,8 @@ extern "C" {
|
|||
static void PY_FUNC_NAME ( PY_SELF_TYPE *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 ) { \
|
||||
trace << "C++ object := " << hex \
|
||||
|
@ -897,6 +898,7 @@ extern "C" {
|
|||
\
|
||||
extern void Py##TYPE##Vector_LinkPyType();
|
||||
|
||||
|
||||
#define IteratorValNextMethod(TYPE) \
|
||||
static PyObject* Py##TYPE##IteratorNext(Py##TYPE##VectorIterator* pyIterator) \
|
||||
{ \
|
||||
|
@ -992,6 +994,8 @@ extern "C" {
|
|||
if (pyObject == NULL) { return NULL; } \
|
||||
\
|
||||
pyObject->ACCESS_OBJECT = object; \
|
||||
trace << "Py" #SELF_TYPE "_Link(" << hex << pyObject << ") " \
|
||||
<< hex << (void*)object << ":" << object << endl; \
|
||||
HCATCH \
|
||||
\
|
||||
return ( (PyObject*)pyObject ); \
|
||||
|
@ -1006,25 +1010,27 @@ extern "C" {
|
|||
static PyObject* PY_FUNC_NAME ( PY_SELF_TYPE *self ) \
|
||||
{ \
|
||||
HTRY \
|
||||
if ( self->ACCESS_OBJECT == NULL ) { \
|
||||
if (self->ACCESS_OBJECT == NULL) { \
|
||||
ostringstream message; \
|
||||
message << "applying a Delete to a Python object with no HURRICANE object attached"; \
|
||||
PyErr_SetString ( ProxyError, message.str().c_str() ); \
|
||||
return ( NULL ); \
|
||||
message << "applying a destroy() to a Python object with no Hurricane object attached"; \
|
||||
PyErr_SetString( ProxyError, message.str().c_str() ); \
|
||||
return NULL; \
|
||||
} \
|
||||
ProxyProperty* proxy = static_cast<ProxyProperty*> \
|
||||
( self->ACCESS_OBJECT->getProperty ( ProxyProperty::getPropertyName() ) ); \
|
||||
( self->ACCESS_OBJECT->getProperty( ProxyProperty::getPropertyName() ) ); \
|
||||
if (proxy == NULL) { \
|
||||
ostringstream message; \
|
||||
message << "Trying to Delete a Hurricane object of with no Proxy attached "; \
|
||||
PyErr_SetString ( ProxyError, message.str().c_str() ); \
|
||||
return ( NULL ); \
|
||||
message << "Trying to destroy() a Hurricane object of with no Proxy attached "; \
|
||||
PyErr_SetString( ProxyError, message.str().c_str() ); \
|
||||
return NULL; \
|
||||
} \
|
||||
self->ACCESS_OBJECT->destroy(); \
|
||||
self->ACCESS_OBJECT = NULL; \
|
||||
HCATCH \
|
||||
Py_RETURN_NONE; \
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Attribute Macro For BDo Link/Creation.
|
||||
|
||||
|
@ -1050,6 +1056,8 @@ extern "C" {
|
|||
pyObject = (Py##SELF_TYPE*)proxy->getShadow (); \
|
||||
Py_INCREF ( ACCESS_CLASS(pyObject) ); \
|
||||
} \
|
||||
trace << "PyDbo" #SELF_TYPE "_Link(" << hex << pyObject << ") " \
|
||||
<< hex << (void*)object << ":" << object << endl; \
|
||||
HCATCH \
|
||||
\
|
||||
return ( (PyObject*)pyObject ); \
|
||||
|
@ -1062,7 +1070,7 @@ extern "C" {
|
|||
static void Py##SELF_TYPE##_DeAlloc ( Py##SELF_TYPE *self ) \
|
||||
{ \
|
||||
trace << "PyDbObject_DeAlloc(" << hex << self << ") " \
|
||||
<< self->ACCESS_OBJECT << endl; \
|
||||
<< hex << (void*)(self->ACCESS_OBJECT) << ":" << self->ACCESS_OBJECT << endl; \
|
||||
\
|
||||
if ( self->ACCESS_OBJECT != NULL ) { \
|
||||
ProxyProperty* proxy = static_cast<ProxyProperty*> \
|
||||
|
@ -1087,7 +1095,8 @@ extern "C" {
|
|||
static void Py##SELF_TYPE##_DeAlloc ( Py##SELF_TYPE *self ) \
|
||||
{ \
|
||||
trace << "PythonOnlyObject_DeAlloc(" << hex << self << ") " \
|
||||
<< self->ACCESS_OBJECT << endl; \
|
||||
<< hex << (void*)(self->ACCESS_OBJECT) \
|
||||
<< ":" << self->ACCESS_OBJECT << endl; \
|
||||
PyObject_DEL ( self ); \
|
||||
}
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ QBrush* getBrush ( const string& pattern, int red, int green, int blue )
|
|||
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) );
|
||||
if (bits != NULL) delete bits;
|
||||
//if (bits != NULL) delete bits;
|
||||
|
||||
return brush;
|
||||
}
|
||||
|
|
|
@ -325,7 +325,7 @@ namespace Katabatic {
|
|||
private:
|
||||
unsigned int _depth;
|
||||
std::set<GCell*,GCell::CompareByKey> _set;
|
||||
std::set<GCell*> _requests;
|
||||
GCell::SetIndex _requests;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -134,8 +134,8 @@ SubRow* Row::getSubRowBetween(DbU::Unit x1, DbU::Unit x2)
|
|||
if (_subRowVector.size() == 1)
|
||||
return _subRowVector[0];
|
||||
|
||||
SubRowXMax::iterator rinf = _subRowXMax.upper_bound(x1);
|
||||
SubRowXMax::iterator rsup = _subRowXMinInv.upper_bound(x2);
|
||||
SubRowXMax::iterator rinf = _subRowXMax.upper_bound(x1);
|
||||
SubRowXMinInv::iterator rsup = _subRowXMinInv.upper_bound(x2);
|
||||
|
||||
|
||||
unsigned randidx = rinf->second +
|
||||
|
|
|
@ -579,8 +579,8 @@ Bin* Surface::getBinInSurface(Bin* srcbin, double dist)
|
|||
if (upperY > getYMax())
|
||||
upperY = getYMax();
|
||||
|
||||
RowYMax::iterator rinf = _rowYMax.upper_bound(lowerY);
|
||||
RowYMax::iterator rsup = _rowYMinInv.upper_bound(upperY);
|
||||
RowYMax::iterator rinf = _rowYMax.upper_bound(lowerY);
|
||||
RowYMinInv::iterator rsup = _rowYMinInv.upper_bound(upperY);
|
||||
|
||||
|
||||
unsigned randidx = rinf->second +
|
||||
|
|
Loading…
Reference in New Issue