diff --git a/foehn/CMakeLists.txt b/foehn/CMakeLists.txt new file mode 100644 index 00000000..09beea02 --- /dev/null +++ b/foehn/CMakeLists.txt @@ -0,0 +1,33 @@ +# -*- explicit-buffer-name: "CMakeLists.txt" -*- + + set(CMAKE_LEGACY_CYGWIN_WIN32 0) + project(FOEHN) + + option(BUILD_DOC "Build the documentation (doxygen)" OFF) + option(CHECK_DATABASE "Run database in full check mode (very slow)" OFF) + option(USE_LIBBFD "Link with BFD libraries to print stack traces" OFF) + + cmake_minimum_required(VERSION 2.8.9) + + set(ignoreVariables "${BUILD_DOC} ${CMAKE_INSTALL_DIR}") + + list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/") + find_package(Bootstrap REQUIRED) + setup_project_paths(CORIOLIS) + + set_cmake_policies() + setup_boost(program_options) + setup_qt() + + find_package(Libexecinfo REQUIRED) + find_package(Python 3 REQUIRED COMPONENTS Interpreter Development) + find_package(PythonSitePackages REQUIRED) + find_package(LEFDEF REQUIRED) + find_package(FLUTE REQUIRED) + find_package(HURRICANE REQUIRED) + find_package(CORIOLIS REQUIRED) + find_package(Doxygen) + + add_subdirectory(src) + add_subdirectory(cmake_modules) + #add_subdirectory(doc) diff --git a/foehn/cmake_modules/CMakeLists.txt b/foehn/cmake_modules/CMakeLists.txt new file mode 100644 index 00000000..c00c46f8 --- /dev/null +++ b/foehn/cmake_modules/CMakeLists.txt @@ -0,0 +1 @@ +install ( FILES FindFOEHN.cmake DESTINATION share/cmake/Modules ) diff --git a/foehn/cmake_modules/FindFOEHN.cmake b/foehn/cmake_modules/FindFOEHN.cmake new file mode 100644 index 00000000..a7141b0d --- /dev/null +++ b/foehn/cmake_modules/FindFOEHN.cmake @@ -0,0 +1,37 @@ +# - Find the Katabatic includes and libraries. +# The following variables are set if Coriolis is found. If FOEHN is not +# found, FOEHN_FOUND is set to false. +# FOEHN_FOUND - True when the Coriolis include directory is found. +# FOEHN_INCLUDE_DIR - the path to where the Coriolis include files are. +# FOEHN_LIBRARIES - The path to where the Coriolis library files are. + + +SET(FOEHN_INCLUDE_PATH_DESCRIPTION "directory containing the Katabatic include files. E.g /usr/local/include/coriolis2 or /asim/coriolis/include/coriolis2") + +SET(FOEHN_DIR_MESSAGE "Set the FOEHN_INCLUDE_DIR cmake cache entry to the ${FOEHN_INCLUDE_PATH_DESCRIPTION}") + +# don't even bother under WIN32 +IF(UNIX) + # + # Look for an installation. + # + FIND_PATH(FOEHN_INCLUDE_PATH NAMES anabatic/FoehnEngine.h PATHS + # Look in other places. + ${CORIOLIS_DIR_SEARCH} + PATH_SUFFIXES include/coriolis2 + # Help the user find it if we cannot. + DOC "The ${FOEHN_INCLUDE_PATH_DESCRIPTION}" + ) + + FIND_LIBRARY(FOEHN_LIBRARY_PATH + NAMES anabatic + PATHS ${CORIOLIS_DIR_SEARCH} + PATH_SUFFIXES lib64 lib + # Help the user find it if we cannot. + DOC "The ${FOEHN_INCLUDE_PATH_DESCRIPTION}" + ) + + SET_LIBRARIES_PATH(FOEHN FOEHN) + HURRICANE_CHECK_LIBRARIES(FOEHN) + +ENDIF(UNIX) diff --git a/foehn/src/CMakeLists.txt b/foehn/src/CMakeLists.txt new file mode 100644 index 00000000..2284640c --- /dev/null +++ b/foehn/src/CMakeLists.txt @@ -0,0 +1,64 @@ +# -*- explicit-buffer-name: "CMakeLists.txt" -*- + + include_directories( ${FOEHN_SOURCE_DIR}/src + ${CORIOLIS_INCLUDE_DIR} + ${ETESIAN_INCLUDE_DIR} + ${HURRICANE_INCLUDE_DIR} + ${CONFIGURATION_INCLUDE_DIR} + ${FLUTE_INCLUDE_DIR} + ${Boost_INCLUDE_DIRS} + ${QtX_INCLUDE_DIRS} + ${Python_INCLUDE_DIRS} + ) + set( includes foehn/DagProperty.h + foehn/Dag.h + foehn/Configuration.h + foehn/FoehnEngine.h + ) + set( pyIncludes foehn/PyDagExtension.h + foehn/PyDag.h + foehn/PyFoehnEngine.h ) + set( cpps DagProperty.cpp + Dag.cpp + Configuration.cpp + FoehnEngine.cpp + ) + set( pyCpps PyDagExtension.cpp + PyDag.cpp + PyFoehnEngine.cpp + PyFoehn.cpp + ) + + set( depLibs ${CORIOLIS_PYTHON_LIBRARIES} + ${CORIOLIS_LIBRARIES} + ${HURRICANE_PYTHON_LIBRARIES} + ${HURRICANE_GRAPHICAL_LIBRARIES} + ${HURRICANE_LIBRARIES} + ${CONFIGURATION_LIBRARY} + ${CIF_LIBRARY} + ${AGDS_LIBRARY} + ${COLOQUINTE_LIBRARIES} + ${FLUTE_LIBRARIES} + ${LEFDEF_LIBRARIES} + ${OA_LIBRARIES} + ${QtX_LIBRARIES} + ${Boost_LIBRARIES} + ${LIBXML2_LIBRARIES} + ${Python_LIBRARIES} -lutil + ) + + add_library( foehn ${cpps} ) + set_target_properties( foehn PROPERTIES VERSION 1.0 SOVERSION 1 ) + target_link_libraries( foehn ${depLibs} ) + + add_python_module( "${pyCpps}" + "${pyIncludes}" + "pyfoehn;1.0;1" + Foehn + "foehn;${depLibs}" + include/coriolis2/foehn + ) + + install( TARGETS foehn DESTINATION lib${LIB_SUFFIX} ) + install( FILES ${includes} DESTINATION include/coriolis2/foehn ) + diff --git a/foehn/src/Configuration.cpp b/foehn/src/Configuration.cpp new file mode 100644 index 00000000..46237d1d --- /dev/null +++ b/foehn/src/Configuration.cpp @@ -0,0 +1,175 @@ +// -*- mode: C++; explicit-buffer-name: "Configuration.cpp" -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2018, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | A n a b a t i c - Global Routing Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Configuration.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include +#include "hurricane/configuration/Configuration.h" +#include "hurricane/Warning.h" +#include "hurricane/Error.h" +#include "hurricane/Cell.h" +#include "crlcore/Utilities.h" +#include "foehn/Configuration.h" + + +namespace Foehn { + + using std::cout; + using std::cerr; + using std::endl; + using std::string; + using std::setprecision; + using std::ostringstream; + using std::vector; + using Hurricane::tab; + using Hurricane::Warning; + using Hurricane::Error; + + +// ------------------------------------------------------------------- +// Class : "Foehn::Configuration". + + + Configuration::Configuration () + : _dffPattern ( Cfg::getParamString("foehn.dffPattern", "^sff.*")->asString() ) + , _ignoredNetPattern ( Cfg::getParamString("foehn.ignoredNetPattern", "^ck.*")->asString() ) + , _ignoredMasterNetPattern( Cfg::getParamString("foehn.ignoredMasterNetPattern", "^$")->asString() ) + , _dffRe (new regex_t) + , _ignoredNetRe (new regex_t) + , _ignoredMasterNetRe(new regex_t) + { + setDffRe ( _dffPattern ); + setIgnoredNetRe ( _ignoredNetPattern ); + setIgnoredMasterNetRe( _ignoredMasterNetPattern ); + } + + + Configuration::Configuration ( const Configuration& other ) + : _dffPattern (other._dffPattern) + , _ignoredNetPattern (other._ignoredNetPattern) + , _ignoredMasterNetPattern(other._ignoredMasterNetPattern) + , _dffRe (new regex_t) + , _ignoredNetRe (new regex_t) + , _ignoredMasterNetRe(new regex_t) + { + setDffRe ( _dffPattern ); + setIgnoredNetRe ( _ignoredNetPattern ); + setIgnoredMasterNetRe( _ignoredMasterNetPattern ); + } + + + Configuration::~Configuration () + { + regfree( _dffRe ); + regfree( _ignoredNetRe ); + regfree( _ignoredMasterNetRe ); + } + + + Configuration* Configuration::clone () const + { return new Configuration(*this); } + + + void Configuration::_setRegex ( regex_t*& regex, string pattern, string attr ) + { + char regexError[1024]; + int regexCode; + + if ((regexCode = regcomp(regex,pattern.c_str(),REG_EXTENDED|REG_NOSUB))) { + regerror( regexCode, regex, regexError, 1024 ); + throw Error ( "Foehn::Configuration::_setRegex(): Invalid regular expresssion for \"%s\"\n" + " (pattern=\"%s\" : %s)" + , attr, pattern, regexError ); + } + } + + + void Configuration::setDffRe ( string pattern ) + { + _dffPattern = pattern; + _setRegex( _dffRe , _dffPattern , "_dffPattern" ); + } + + + void Configuration::setIgnoredNetRe ( string pattern ) + { + _ignoredNetPattern = pattern; + _setRegex( _ignoredNetRe , _ignoredNetPattern , "_ignoredNetPattern" ); + } + + + void Configuration::setIgnoredMasterNetRe ( string pattern ) + { + _ignoredMasterNetPattern = pattern; + _setRegex( _ignoredMasterNetRe , _ignoredMasterNetPattern , "_ignoredNetPattern" ); + } + + + bool Configuration::isDff ( string name ) const + { + if (not _dffRe) return false; + return regexec( _dffRe, name.c_str(), 0, NULL, 0 ) == 0; + } + + + bool Configuration::isIgnoredNet ( string name ) const + { + if (not _ignoredNetRe) return false; + return regexec( _ignoredNetRe, name.c_str(), 0, NULL, 0 ) == 0; + } + + + bool Configuration::isIgnoredMasterNet ( string name ) const + { + if (not _ignoredMasterNetRe) return false; + return regexec( _ignoredMasterNetRe, name.c_str(), 0, NULL, 0 ) == 0; + } + + + void Configuration::print ( const Cell* cell ) const + { + if (not cmess1.enabled()) return; + + cout << " o Configuration of ToolEngine for Cell <" << cell->getName() << ">" << endl; + cout << Dots::asString(" - DFF pattern" , _dffPattern ) << endl; + cout << Dots::asString(" - Ignored nets pattern" , _ignoredNetPattern ) << endl; + cout << Dots::asString(" - Ignored master nets pattern", _ignoredMasterNetPattern) << endl; + } + + + string Configuration::_getTypeName () const + { return "Foehn::Configuration"; } + + + string Configuration::_getString () const + { + ostringstream os; + os << "<" << _getTypeName() << ">"; + return os.str(); + } + + + Record* Configuration::_getRecord () const + { + Record* record = new Record ( _getString() ); + record->add( getSlot( "_dffPattern" , _dffPattern )); + record->add( getSlot( "_ignoredNetPattern" , _ignoredNetPattern )); + record->add( getSlot( "_ignoredMasterNetPattern", _ignoredMasterNetPattern )); + return record; + } + + +} // Foehn namespace. diff --git a/foehn/src/Dag.cpp b/foehn/src/Dag.cpp new file mode 100644 index 00000000..b2ffbb1c --- /dev/null +++ b/foehn/src/Dag.cpp @@ -0,0 +1,256 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Universié 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Dag.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include "hurricane/Bug.h" +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/Breakpoint.h" +#include "hurricane/DataBase.h" +#include "hurricane/RegularLayer.h" +#include "hurricane/Horizontal.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Vertical.h" +#include "hurricane/Cell.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/DebugSession.h" +#include "hurricane/UpdateSession.h" +#include "crlcore/RoutingGauge.h" +#include "crlcore/Measures.h" +#include "crlcore/Histogram.h" +#include "foehn/FoehnEngine.h" +#include "foehn/DagProperty.h" +#include "foehn/Dag.h" + + +namespace Foehn { + + using std::cerr; + using std::cout; + using std::endl; + using std::ostringstream; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Breakpoint; + using Hurricane::DebugSession; + using Hurricane::UpdateSession; + using Hurricane::Plug; + using CRL::addMeasure; + using CRL::getMeasure; + using CRL::Histogram; + + +// ------------------------------------------------------------------- +// Class : "Foehn::Dag". + + + Dag::Dag ( FoehnEngine* foehn, string label ) + : _foehn (foehn) + , _configuration(foehn->getConfiguration()) + , _label (label) + , _dorder () + , _inputs () + , _reacheds () + { } + + + Dag::~Dag () + { + for ( Entity* entity : _dorder ) { + DagProperty* property = DagExtension::get( entity ); + if (property) property->decref(); + } + } + + + Cell* Dag::getCell () const + { return _foehn->getCell(); } + + + void Dag::addDStart ( Instance* instance ) + { + DagProperty* prop = DagExtension::get( instance ); + if (not prop) { + prop = DagProperty::create( instance ); + } + prop->setMinDepth( 0 ); + prop->setMaxDepth( 0 ); + //addToDOrder( instance ); + _reacheds.push_back( instance ); + } + + + void Dag::addDStart ( Net* net ) + { + cdebug_log(130,0) << "FoehnEngine::addDStart() " << net << endl; + DagProperty* prop = DagExtension::get( net ); + if (not prop) { + prop = DagProperty::create( net ); + } + prop->setMinDepth( 0 ); + prop->setMaxDepth( 0 ); + _inputs.push_back( net ); + } + + + void Dag::addToDOrder ( Instance* instance ) + { + cdebug_log(130,1) << "FoehnEngine::addToDOrder() " << instance << endl; + _dorder.push_back( instance ); + + Net* driver = nullptr; + DagProperty* driverProp = nullptr; + DagProperty* instProp = DagExtension::get( instance ); + if (not instProp) + instProp = DagProperty::create( instance ); + + for ( Plug* plug : instance->getPlugs() ) { + if (not plug->getNet()) continue; + if (plug->getMasterNet()->getDirection() & Net::Direction::DirOut) { + driver = plug->getNet(); + driverProp = DagExtension::get( driver ); + if (not driverProp) { + driverProp = DagProperty::create( driver ); + } + } + } + + if (not driver) { + cerr << Warning( "FoehnEngine::addToDOrder(): No driver found on %s." + , getString(instance).c_str() ) << endl; + cdebug_tabw(130,-1); + return; + } + cdebug_log(130,0) << "driver " << driver << endl; + driverProp->setMinDepth( instProp->getMinDepth() ); + driverProp->setDriver ( instance ); + _dorder.push_back( driver ); + cdebug_tabw(130,-1); + } + + + void Dag::_dpropagateOn ( Net* net ) + { + DagProperty* netProp = DagExtension::get( net ); + cdebug_log(130,1) << "_dpropagateOn() @" << netProp->getMinDepth() << " " << net << endl; + for ( Plug* plug : net->getPlugs() ) { + if (plug->getMasterNet()->getDirection() & Net::Direction::DirOut) continue; + if (plug->getInstance()) { + _dpropagateOn( plug->getInstance() ); + } + } + cdebug_tabw(130,-1); + } + + + void Dag::_dpropagateOn ( Instance* instance ) + { + if (isDff(instance->getMasterCell()->getName())) return; + + cdebug_log(130,1) << "_dpropagateOn() " << instance << endl; + DagProperty* prop = DagExtension::get( instance ); + if (prop) { + cdebug_log(130,0) << "Skip, already reached " << endl; + cdebug_tabw(130,-1); + return; + } + + int32_t depth = 0; + for ( Plug* plug : instance->getPlugs() ) { + if (isIgnoredPlug(plug)) continue; + if (plug->getMasterNet()->getDirection() & Net::Direction::DirIn) { + DagProperty* netProp = DagExtension::get( plug->getNet() ); + if (not netProp) { + cdebug_log(130,0) << "Reject: not reached " << plug->getNet() << endl; + cdebug_tabw(130,-1); + return; + } + depth = std::max( depth, netProp->getMinDepth() ); + } + } + + if (not prop) + prop = DagProperty::create( instance ); + prop->setMinDepth( depth+1 ); + cdebug_log(130,0) << "Reached @" << (depth+1) << endl; + //addToDOrder( instance ); + _reacheds.push_back( instance ); + cdebug_tabw(130,-1); + } + + + void Dag::dpropagate () + { + //DebugSession::open( 130, 141 ); + cdebug_log(130,1) << "Dag::dpropagate()" << endl; + while ( not _reacheds.empty() or not _inputs.empty() ) { + size_t istart = _dorder.size(); + for ( Net* net : _inputs ) + _dorder.push_back( net ); + _inputs.clear(); + for ( Instance* instance : _reacheds ) + addToDOrder( instance ); + _reacheds.clear(); + cdebug_log(130,0) << "_dorder.size()=" << _dorder.size() << " istart=" << istart << endl; + for ( ; istart<_dorder.size() ; ++istart ) { + cdebug_log(130,0) << istart << " " << _dorder[istart] << endl; + Net* net = dynamic_cast( _dorder[istart] ); + if (not net) continue; + _dpropagateOn( net ); + } + } + cdebug_tabw(130,-1); + //DebugSession::close(); + } + + + void Dag::resetDepths () + { + for ( Entity* entity : _dorder ) { + DagProperty* property = DagExtension::get( entity ); + property->setMinDepth( -1 ); + property->setMaxDepth( -1 ); + } + } + + + string Dag::_getTypeName () const + { return "Dag"; } + + + string Dag::_getString () const + { + ostringstream os; + os << "<" << _getTypeName() << " \"" << _label << "\" " << getCell()->getName() << ">"; + return os.str(); + } + + + Record* Dag::_getRecord () const + { + Record* record = new Record( _getString() ); + record->add( getSlot( "_foehn" , &_foehn )); + record->add( getSlot( "_configuration", &_configuration )); + record->add( getSlot( "_label" , &_label )); + record->add( getSlot( "_dorder" , &_dorder )); + record->add( getSlot( "_inputs" , &_inputs )); + return record; + } + + +} // Foehn namespace. diff --git a/foehn/src/DagProperty.cpp b/foehn/src/DagProperty.cpp new file mode 100644 index 00000000..375c0ef4 --- /dev/null +++ b/foehn/src/DagProperty.cpp @@ -0,0 +1,123 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./DagProperty.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/Net.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "foehn/DagProperty.h" + + +namespace Foehn { + + using namespace std; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Property; + + +// ------------------------------------------------------------------- +// Class : "DagProperty" + + Name DagProperty::_name = "Foehn::DagProperty"; + + + DagProperty* DagProperty::create ( DBo* owner ) + { + DagProperty *property = new DagProperty(); + + property->_postCreate (); + owner->put( property ); + return property; + } + + + void DagProperty::_preDestroy () + { + Super::_preDestroy(); + } + + + bool DagProperty::isNetOwned () const + { return (dynamic_cast( getOwner() ) != nullptr); } + + + bool DagProperty::isInstanceOwned () const + { return (dynamic_cast( getOwner() ) != nullptr); } + + + void DagProperty::onReleasedBy ( DBo* owner ) + { PrivateProperty::onReleasedBy( owner ); } + + + Name DagProperty::getPropertyName () + { return _name; } + + + Name DagProperty::getName () const + { return getPropertyName(); } + + + string DagProperty::_getTypeName () const + { return "Foehn::DagProperty"; } + + + string DagProperty::_getString () const + { + string s = PrivateProperty::_getString (); + s.insert ( s.length() - 1 , " " + getString(getOwner()) ); + + return s; + } + + + Record* DagProperty::_getRecord () const + { + Record* record = PrivateProperty::_getRecord(); + if ( record ) { + record->add( getSlot( "_name" , _name ) ); + record->add( getSlot( "_flags" , _flags ) ); + record->add( getSlot( "_minDepth", _minDepth ) ); + record->add( getSlot( "_maxDepth", _maxDepth ) ); + } + return record; + } + + +// ------------------------------------------------------------------- +// Class : "DagExtension" + + + DagProperty* DagExtension::get ( const DBo* dbo ) + { + Property* property = dbo->getProperty( DagProperty::getPropertyName() ); + if (property) + return dynamic_cast( property ); + return NULL; + } + + + DagProperty* DagExtension::create ( DBo* dbo ) + { + DagProperty* property = get( dbo ); + if (not property) + property = DagProperty::create( dbo ); + return property; + } + + +} // Foehn namespace. diff --git a/foehn/src/FoehnEngine.cpp b/foehn/src/FoehnEngine.cpp new file mode 100644 index 00000000..7c9907eb --- /dev/null +++ b/foehn/src/FoehnEngine.cpp @@ -0,0 +1,155 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Universié 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./FoehnEngine.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include "hurricane/Bug.h" +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/Breakpoint.h" +#include "hurricane/DataBase.h" +#include "hurricane/RegularLayer.h" +#include "hurricane/Horizontal.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Vertical.h" +#include "hurricane/Cell.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/DebugSession.h" +#include "hurricane/UpdateSession.h" +#include "crlcore/RoutingGauge.h" +#include "crlcore/Measures.h" +#include "crlcore/Histogram.h" +#include "foehn/DagProperty.h" +#include "foehn/FoehnEngine.h" + + +namespace Foehn { + + using std::cerr; + using std::cout; + using std::endl; + using std::ostringstream; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::Breakpoint; + using Hurricane::DebugSession; + using Hurricane::UpdateSession; + using Hurricane::Plug; + using CRL::addMeasure; + using CRL::getMeasure; + using CRL::Histogram; + + +// ------------------------------------------------------------------- +// Class : "Foehn::FoehnEngine". + + Name FoehnEngine::_toolName = "Foehn"; + + + FoehnEngine* FoehnEngine::get ( const Cell* cell ) + { return static_cast(ToolEngine::get(cell,staticGetName())); } + + + const Name& FoehnEngine::staticGetName () + { return _toolName; } + + + const Name& FoehnEngine::getName () const + { return _toolName; } + + + FoehnEngine::FoehnEngine ( Cell* cell ) + : Super (cell) + , _viewer (nullptr) + , _configuration() + { } + + + void FoehnEngine::_postCreate () + { + Super::_postCreate(); + } + + + FoehnEngine* FoehnEngine::create ( Cell* cell ) + { + if (not cell) throw Error( "FoehnEngine::create(): NULL cell argument." ); + + FoehnEngine* engine = new FoehnEngine ( cell ); + engine->_postCreate(); + return engine; + } + + + FoehnEngine::~FoehnEngine () + { } + + + void FoehnEngine::_preDestroy () + { + clear(); + Super::_preDestroy(); + } + + + Dag* FoehnEngine::newDag ( string label ) + { + Dag* dag = new Dag ( this, label ); + _dags.push_back( dag ); + return dag; + } + + + Dag* FoehnEngine::getDag ( string label ) const + { + for ( Dag* dag : _dags ) { + if (dag->getLabel() == label) return dag; + } + return NULL; + } + + + void FoehnEngine::clear () + { + for ( Dag* dag : _dags ) delete dag; + _dags.clear(); + } + + + string FoehnEngine::_getTypeName () const + { return getString(_toolName); } + + + string FoehnEngine::_getString () const + { + ostringstream os; + os << "<" << _toolName << " " << _cell->getName() << ">"; + return os.str(); + } + + + Record* FoehnEngine::_getRecord () const + { + Record* record = Super::_getRecord(); + record->add( getSlot( "_toolName" , &_toolName )); + record->add( getSlot( "_configuration", &_configuration )); + record->add( getSlot( "_dags" , &_dags )); + return record; + } + + +} // Foehn namespace. diff --git a/foehn/src/PyDag.cpp b/foehn/src/PyDag.cpp new file mode 100644 index 00000000..5e7a7cd0 --- /dev/null +++ b/foehn/src/PyDag.cpp @@ -0,0 +1,227 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./PyDag.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/isobar/PyEntity.h" +#include "hurricane/isobar/PyNet.h" +#include "hurricane/isobar/PyCell.h" +#include "hurricane/isobar/PyInstance.h" +#include "hurricane/viewer/ExceptionWidget.h" +#include "hurricane/Cell.h" +#include "crlcore/Utilities.h" +#include "foehn/PyDag.h" +#include "foehn/FoehnEngine.h" +#include + + +#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(Dag,dag,function) + + +namespace Foehn { + + using std::cerr; + using std::endl; + using std::hex; + using std::ostringstream; + using Hurricane::tab; + using Hurricane::Exception; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::ExceptionWidget; + using Isobar::__cs; + using Isobar::Converter; + using Isobar::ProxyProperty; + using Isobar::ProxyError; + using Isobar::ConstructorError; + using Isobar::HurricaneError; + using Isobar::HurricaneWarning; + using Isobar::getPyHash; + using Isobar::ParseOneArg; + using Isobar::ParseTwoArg; + using Isobar::PyEntity; + using Isobar::PyEntityVector; + using Isobar::PyTypeEntityVector; + using Isobar::PyEntityVectorIterator; + using Isobar::PyNet; + using Isobar::PyCell; + using Isobar::PyInstance; + using Isobar::PyCell_Link; + using Isobar::PyTypeNet; + using Isobar::PyTypeInstance; + + +extern "C" { + +#if defined(__PYTHON_MODULE__) + + +// +=================================================================+ +// | "PyDag" Python Module Code Part | +// +=================================================================+ + + + static PyObject* PyDag_setDffRe ( PyDag* self, PyObject* args ) + { + cdebug_log(40,0) << "PyDag_setDffRe ()" << endl; + HTRY + METHOD_HEAD( "Dag.setDffRe()" ) + char* dffRe = NULL; + if (not PyArg_ParseTuple(args, "s:Dag.setDffRe", &dffRe)) { + PyErr_SetString( ConstructorError, "Dag.setDffRe(): Invalid number of parameters." ); + return NULL; + } + dag->setDffRe( dffRe ); + HCATCH + Py_RETURN_NONE; + } + + + static PyObject* PyDag_setIgnoredNetRe ( PyDag* self, PyObject* args ) + { + cdebug_log(40,0) << "PyDag_setIgnoredNetRe ()" << endl; + HTRY + METHOD_HEAD( "Dag.setIgnoredNetRe()" ) + char* re = NULL; + if (not PyArg_ParseTuple(args, "s:Dag.setIgnoredNetRe", &re)) { + PyErr_SetString( ConstructorError, "Dag.setIgnoredNetRe(): Invalid number of parameters." ); + return NULL; + } + dag->setIgnoredNetRe( re ); + HCATCH + Py_RETURN_NONE; + } + + + static PyObject* PyDag_setIgnoredMasterNetRe ( PyDag* self, PyObject* args ) + { + cdebug_log(40,0) << "PyDag_setIgnoredMasterNetRe ()" << endl; + HTRY + METHOD_HEAD( "Dag.setIgnoredMasterNetRe()" ) + char* re = NULL; + if (not PyArg_ParseTuple(args, "s:Dag.setIgnoredMasterNetRe", &re)) { + PyErr_SetString( ConstructorError, "Dag.setIgnoredMasterNetRe(): Invalid number of parameters." ); + return NULL; + } + dag->setIgnoredMasterNetRe( re ); + HCATCH + Py_RETURN_NONE; + } + + + PyObject* PyDag_dpropagate ( PyDag* self ) + { + cdebug_log(40,0) << "PyDag_dpropagate()" << endl; + HTRY + METHOD_HEAD("Dag.dpropagate()") + if (dag->getFoehn()->getViewer()) { + if (ExceptionWidget::catchAllWrapper( std::bind(&Dag::dpropagate,dag) )) { + PyErr_SetString( HurricaneError, "Dag::dpropagate() has thrown an exception (C++)." ); + return NULL; + } + } else { + dag->dpropagate(); + } + HCATCH + Py_RETURN_NONE; + } + + + PyObject* PyDag_resetDepths ( PyDag* self ) + { + cdebug_log(40,0) << "PyDag_resetDepths()" << endl; + HTRY + METHOD_HEAD("Dag.resetDepths()") + if (dag->getFoehn()->getViewer()) { + if (ExceptionWidget::catchAllWrapper( std::bind(&Dag::resetDepths,dag) )) { + PyErr_SetString( HurricaneError, "Dag::resetDepths() has thrown an exception (C++)." ); + return NULL; + } + } else { + dag->resetDepths(); + } + HCATCH + Py_RETURN_NONE; + } + + + static PyObject* PyDag_addDStart ( PyDag* self, PyObject* args ) + { + cdebug_log(40,0) << "PyDag_addDStart ()" << endl; + HTRY + METHOD_HEAD( "Dag.addDStart()" ) + PyObject* pyDBo = NULL; + if (not PyArg_ParseTuple(args, "O:Dag.addDStart", &pyDBo)) { + PyErr_SetString( ConstructorError, "Dag.addDStart(): Invalid number of parameters." ); + return NULL; + } + if (IsPyInstance(pyDBo)) dag->addDStart( PYINSTANCE_O(pyDBo) ); + else if (IsPyNet (pyDBo)) dag->addDStart( PYNET_O (pyDBo) ); + else { + PyErr_SetString( ConstructorError, "Dag.addDStart(): First parameter is *not* an Instance." ); + return NULL; + } + HCATCH + Py_RETURN_NONE; + } + + + // Standart Accessors (Attributes). + accessorVectorFromVoid(getDOrder,PyDag,Dag,Entity) + + + PyMethodDef PyDag_Methods[] = + { { "setDffRe" , (PyCFunction)PyDag_setDffRe , METH_VARARGS + , "Set the pattern to match the memory elements (D Flip-Flop)." } + , { "setIgnoredNetRe" , (PyCFunction)PyDag_setIgnoredNetRe , METH_VARARGS + , "Set the pattern for ignored nets in propagation." } + , { "setIgnoredMasterNetRe" , (PyCFunction)PyDag_setIgnoredMasterNetRe , METH_VARARGS + , "Set the pattern for ignored *master* net in propagation." } + , { "addDStart" , (PyCFunction)PyDag_addDStart , METH_VARARGS + , "Add a starting instance for the direct propagation." } + , { "dpropagate" , (PyCFunction)PyDag_dpropagate , METH_NOARGS + , "Compute the Instance & Net direct ordering." } + , { "resetDepths" , (PyCFunction)PyDag_resetDepths , METH_NOARGS + , "Reset depths." } + , { "getDOrder" , (PyCFunction)PyDag_getDOrder , METH_NOARGS + , "Return the direct ordering of Instances & Nets." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + PythonOnlyDeleteMethod(Dag) + PyTypeObjectLinkPyType(Dag) + + + +#else // End of Python Module Code Part. + + +// +=================================================================+ +// | "PyDag" Shared Library Code Part | +// +=================================================================+ + + + // Link/Creation Method. + PyTypeObjectDefinitions(Dag) + LinkCreateMethod(Dag) + + +#endif // Shared Library Code Part. + +} // extern "C". + +} // Foehn namespace. + diff --git a/foehn/src/PyDagExtension.cpp b/foehn/src/PyDagExtension.cpp new file mode 100644 index 00000000..93741bb6 --- /dev/null +++ b/foehn/src/PyDagExtension.cpp @@ -0,0 +1,279 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./PyDagExtension.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/isobar/PyEntity.h" +#include "hurricane/isobar/PyInstance.h" +#include "foehn/PyDagExtension.h" +#include "foehn/DagProperty.h" + + +namespace Foehn { + + using namespace Hurricane; + using Isobar::ConstructorError; + using Isobar::HurricaneError; + using Isobar::HurricaneWarning; + using Isobar::PyInstance_Link; + using Isobar::PyTypeInstance; + using Isobar::PyInstance; + + extern "C" { + + +#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(DagExtension,property,function) + + +// +=================================================================+ +// | "PyDagExtension" Python Module Code Part | +// +=================================================================+ + +#if defined(__PYTHON_MODULE__) + +#define ExtensionGetBoolFunction(FUNC_NAME,SELF_TYPE) \ + static PyObject* Py##SELF_TYPE##_##FUNC_NAME ( PyObject*, PyObject* args ) \ + { \ + cdebug_log(20,0) << "Py"#FUNC_NAME"()" << endl; \ + bool flag = false; \ + HTRY \ + PyObject* pyDBo; \ + if (not PyArg_ParseTuple(args,"O:"#SELF_TYPE"."#FUNC_NAME"()", &pyDBo)) { \ + PyErr_SetString( ConstructorError, #SELF_TYPE"."#FUNC_NAME": Takes exactly one arguments." ); \ + return NULL; \ + } \ + Entity* entity = Isobar::EntityCast( pyDBo ); \ + if (not entity) { \ + PyErr_SetString( ConstructorError, #SELF_TYPE"."#FUNC_NAME": Argument is not an Entity." ); \ + return NULL; \ + } \ + flag = SELF_TYPE::FUNC_NAME( entity ); \ + HCATCH \ + if (flag) Py_RETURN_TRUE; \ + Py_RETURN_FALSE; \ + } + + +#define ExtensionGetInt32Function(FUNC_NAME,SELF_TYPE) \ + static PyObject* Py##SELF_TYPE##_##FUNC_NAME ( PyObject*, PyObject* args ) \ + { \ + cdebug_log(20,0) << "Py"#FUNC_NAME"()" << endl; \ + int32_t value = 0; \ + HTRY \ + PyObject* pyDBo; \ + if (not PyArg_ParseTuple(args,"O:"#SELF_TYPE"."#FUNC_NAME"()", &pyDBo)) { \ + PyErr_SetString( ConstructorError, #SELF_TYPE"."#FUNC_NAME": Takes exactly one arguments." ); \ + return NULL; \ + } \ + Entity* entity = Isobar::EntityCast( pyDBo ); \ + if (not entity) { \ + PyErr_SetString( ConstructorError, #SELF_TYPE"."#FUNC_NAME": Argument is not an Entity." ); \ + return NULL; \ + } \ + value = SELF_TYPE::FUNC_NAME( entity ); \ + HCATCH \ + return Py_BuildValue( "i", value ); \ + } + + +#define ExtensionGetUInt64Function(FUNC_NAME,SELF_TYPE) \ + static PyObject* Py##SELF_TYPE##_##FUNC_NAME ( PyObject*, PyObject* args ) \ + { \ + cdebug_log(20,0) << "Py"#FUNC_NAME"()" << endl; \ + uint64_t value = 0; \ + HTRY \ + PyObject* pyDBo; \ + if (not PyArg_ParseTuple(args,"O:"#SELF_TYPE"."#FUNC_NAME"()", &pyDBo)) { \ + PyErr_SetString( ConstructorError, #SELF_TYPE"."#FUNC_NAME": Takes exactly one arguments." ); \ + return NULL; \ + } \ + Entity* entity = Isobar::EntityCast( pyDBo ); \ + if (not entity) { \ + PyErr_SetString( ConstructorError, #SELF_TYPE"."#FUNC_NAME": Argument is not an Entity." ); \ + return NULL; \ + } \ + value = SELF_TYPE::FUNC_NAME( entity ); \ + HCATCH \ + return Py_BuildValue( "k", value ); \ + } + + +#define ExtensionSetInt32Function(FUNC_NAME,SELF_TYPE) \ + static PyObject* Py##SELF_TYPE##_##FUNC_NAME ( PyObject*, PyObject* args ) \ + { \ + cdebug_log(20,0) << "Py"#FUNC_NAME"()" << endl; \ + HTRY \ + PyObject* pyDBo = NULL; \ + long value = 0; \ + if (not PyArg_ParseTuple(args,"OL:"#SELF_TYPE"."#FUNC_NAME"()", &pyDBo, &value)) { \ + PyErr_SetString( ConstructorError, #SELF_TYPE"."#FUNC_NAME": Takes exactly two arguments." ); \ + return NULL; \ + } \ + Entity* entity = Isobar::EntityCast( pyDBo ); \ + if (not entity) { \ + PyErr_SetString( ConstructorError, #SELF_TYPE"."#FUNC_NAME": First argument is not an Entity." ); \ + return NULL; \ + } \ + SELF_TYPE::FUNC_NAME( entity, value ); \ + HCATCH \ + Py_RETURN_NONE; \ + } + + +#define ExtensionSetUInt64Function(FUNC_NAME,SELF_TYPE) \ + static PyObject* Py##SELF_TYPE##_##FUNC_NAME ( PyObject*, PyObject* args ) \ + { \ + cdebug_log(20,0) << "Py"#FUNC_NAME"()" << endl; \ + HTRY \ + PyObject* pyDBo = NULL; \ + unsigned long value = 0; \ + if (not PyArg_ParseTuple(args,"Ok:"#SELF_TYPE"."#FUNC_NAME"()", &pyDBo, &value)) { \ + PyErr_SetString( ConstructorError, #SELF_TYPE"."#FUNC_NAME": Takes exactly two arguments." ); \ + return NULL; \ + } \ + Entity* entity = Isobar::EntityCast( pyDBo ); \ + if (not entity) { \ + PyErr_SetString( ConstructorError, #SELF_TYPE"."#FUNC_NAME": First argument is not an Entity." ); \ + return NULL; \ + } \ + SELF_TYPE::FUNC_NAME( entity, value ); \ + HCATCH \ + Py_RETURN_NONE; \ + } + + + static void PyDagExtension_DeAlloc ( PyDagExtension* self ) + { + cdebug_log(20,0) << "PyDagExtension_DeAlloc(" << hex << self << ")" << endl; + } + + + ExtensionGetBoolFunction (isPresent ,DagExtension) + ExtensionGetBoolFunction (isNetOwned ,DagExtension) + ExtensionGetBoolFunction (isInstanceOwned,DagExtension) + ExtensionGetUInt64Function(getFlags ,DagExtension) + ExtensionSetUInt64Function(setFlags ,DagExtension) + ExtensionSetUInt64Function(resetFlags ,DagExtension) + ExtensionGetInt32Function (getMinDepth ,DagExtension) + ExtensionGetInt32Function (getMaxDepth ,DagExtension) + ExtensionSetInt32Function (setMinDepth ,DagExtension) + ExtensionSetInt32Function (setMaxDepth ,DagExtension) + + + static PyObject* PyDagExtension_getDriver ( PyObject*, PyObject* args ) + { + cdebug_log(20,0) << "PyDagExtension_getDriver()" << endl; + Instance* driver = nullptr; + HTRY + PyObject* pyDBo = NULL; + if (not PyArg_ParseTuple(args,"O:DagExtension.getDriver()", &pyDBo)) { + PyErr_SetString( ConstructorError, "DagExtension.getDriver(): Takes exactly one arguments." ); + return NULL; + } + Entity* entity = Isobar::EntityCast( pyDBo ); + if (not entity) { + PyErr_SetString( ConstructorError, "DagExtension.getDriver(): Argument is not an Entity." ); + return NULL; + } + driver = DagExtension::getDriver( entity ); + HCATCH + return PyInstance_Link( driver ); + } + + + static PyObject* PyDagExtension_setDriver ( PyObject*, PyObject* args ) + { + cdebug_log(20,0) << "PyDagExtension_setDriver()" << endl; + HTRY + PyObject* pyDBo = nullptr; + PyObject* pyDriver = nullptr; + if (not PyArg_ParseTuple(args,"OO:DagExtension.setDriver()", &pyDBo, &pyDriver)) { + PyErr_SetString( ConstructorError, "DagExtension.setDriver(): Takes exactly two arguments." ); + return NULL; + } + Entity* entity = Isobar::EntityCast( pyDBo ); + if (not entity) { + PyErr_SetString( ConstructorError, "DagExtension.setDriver: First argument is not an Entity." ); + return NULL; + } + if (not IsPyInstance(pyDriver)) { + PyErr_SetString( ConstructorError, "DagExtension.setDriver: Second argument is not an Instance." ); + return NULL; + } + DagExtension::setDriver( entity, PYINSTANCE_O(pyDriver) ); + HCATCH + Py_RETURN_NONE; + } + + + PyMethodDef PyDagExtension_Methods[] = + { { "isPresent" , (PyCFunction)PyDagExtension_isPresent , METH_VARARGS|METH_CLASS + , "Tells if a DBo has a DagProperty." } + , { "isNetOwned" , (PyCFunction)PyDagExtension_isNetOwned , METH_VARARGS|METH_CLASS + , "Tells if the DagProperty is owned by a Net." } + , { "isInstanceOwned" , (PyCFunction)PyDagExtension_isInstanceOwned , METH_VARARGS|METH_CLASS + , "Tells if the DagProperty is owned by an Instance." } + , { "getFlags" , (PyCFunction)PyDagExtension_getFlags , METH_VARARGS|METH_CLASS + , "Returns the flags of the DAG associated property." } + , { "getDriver" , (PyCFunction)PyDagExtension_getDriver , METH_VARARGS|METH_CLASS + , "Returns the driver (Instance) from the DAG property of a Net." } + , { "setFlags" , (PyCFunction)PyDagExtension_setFlags , METH_VARARGS|METH_CLASS + , "Set flags of the DAG associated property." } + , { "resetFlags" , (PyCFunction)PyDagExtension_resetFlags , METH_VARARGS|METH_CLASS + , "Reset flags of the DAG associated property." } + , { "getMinDepth" , (PyCFunction)PyDagExtension_getMinDepth , METH_VARARGS|METH_CLASS + , "Returns the minimum depth of the object in the DAG." } + , { "getMaxDepth" , (PyCFunction)PyDagExtension_getMaxDepth , METH_VARARGS|METH_CLASS + , "Returns the maximum depth of the object in the DAG." } + , { "setMinDepth" , (PyCFunction)PyDagExtension_setMinDepth , METH_VARARGS|METH_CLASS + , "Sets the minimum depth of the object in the DAG." } + , { "setMaxDepth" , (PyCFunction)PyDagExtension_setMaxDepth , METH_VARARGS|METH_CLASS + , "Sets the maximum depth of the object in the DAG." } + , { "setDriver" , (PyCFunction)PyDagExtension_setDriver , METH_VARARGS|METH_CLASS + , "Sets the driver (Instance) on the DAG property of a Net." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + PyTypeObjectLinkPyTypeWithoutObject(DagExtension,DagExtension) + + +#else // End of Python Module Code Part. + + +// +=================================================================+ +// | "PyDagExtension" Shared Library Code Part | +// +=================================================================+ + + + PyTypeObjectDefinitions(DagExtension) + + + extern void PyDagExtension_postModuleInit () + { + PyObject* constant; + + LoadObjectConstant(PyTypeDagExtension.tp_dict,DagExtension::Ignore ,"Ignore" ); + LoadObjectConstant(PyTypeDagExtension.tp_dict,DagExtension::Reached,"Reached"); + } + + + +# endif // End of Shared Library Code Part. + + +} // End of extern "C". + +} // Foehn namespace. + diff --git a/foehn/src/PyFoehn.cpp b/foehn/src/PyFoehn.cpp new file mode 100644 index 00000000..9dd31b24 --- /dev/null +++ b/foehn/src/PyFoehn.cpp @@ -0,0 +1,121 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./PyFoehn.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/isobar/PyHurricane.h" +#include "hurricane/isobar/PyCell.h" +#include "foehn/PyFoehnEngine.h" +//#include "foehn/PyGraphicFoehnEngine.h" +#include "foehn/PyDagExtension.h" +#include "foehn/PyDag.h" + + +namespace Foehn { + + using std::cerr; + using std::endl; + using Hurricane::tab; + using Isobar::getPyHash; + using Isobar::__cs; + using CRL::PyTypeToolEngine; +//using CRL::PyTypeGraphicTool; + + +#if !defined(__PYTHON_MODULE__) + +// +=================================================================+ +// | "PyFoehn" Shared Library Code Part | +// +=================================================================+ + + +# else // End of PyHurricane Shared Library Code Part. + + +// +=================================================================+ +// | "PyFoehn" Python Module Code Part | +// +=================================================================+ + + +extern "C" { + + + static PyMethodDef PyFoehn_Methods[] = + { {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + static PyModuleDef PyFoehn_ModuleDef = + { PyModuleDef_HEAD_INIT + , .m_name = "Foehn" + , .m_doc = "A DAG Toolbox." + , .m_size = -1 + , .m_methods = PyFoehn_Methods + }; + + + + + // --------------------------------------------------------------- + // Module Initialization : "PyInit_Foehn()" + + PyMODINIT_FUNC PyInit_Foehn ( void ) + { + cdebug_log(40,0) << "PyInit_Foehn()" << endl; + + // PyFoehnFlags_LinkPyType(); + PyFoehnEngine_LinkPyType(); + // PyGraphicFoehnEngine_LinkPyType(); + PyDagExtension_LinkPyType(); + PyDag_LinkPyType(); + + // PYTYPE_READY ( FoehnFlags ); + PYTYPE_READY_SUB( FoehnEngine , ToolEngine ); + // PYTYPE_READY_SUB( GraphicFoehnEngine, GraphicTool ); + PYTYPE_READY ( DagExtension ); + PYTYPE_READY ( Dag ); + + + PyObject* module = PyModule_Create( &PyFoehn_ModuleDef ); + if (module == NULL) { + cerr << "[ERROR]\n" + << " Failed to initialize Foehn module." << endl; + return NULL; + } + + Py_INCREF( &PyTypeFoehnEngine ); + PyModule_AddObject( module, "FoehnEngine", (PyObject*)&PyTypeFoehnEngine ); + // Py_INCREF( &PyTypeGraphicFoehnEngine ); + // PyModule_AddObject( module, "GraphicFoehnEngine", (PyObject*)&PyTypeGraphicFoehnEngine ); + // Py_INCREF( &PyTypeFoehnFlags ); + // PyModule_AddObject( module, "Flags", (PyObject*)&PyTypeFoehnFlags ); + Py_INCREF( &PyTypeDagExtension ); + PyModule_AddObject( module, "DagExtension", (PyObject*)&PyTypeDagExtension ); + Py_INCREF( &PyTypeDag ); + PyModule_AddObject( module, "Dag", (PyObject*)&PyTypeDag ); + + PyFoehnEngine_postModuleInit(); + PyDagExtension_postModuleInit(); + return module; + } + + +} // extern "C". + + +#endif // Python Module Code Part. + + +} // Foehn namespace. diff --git a/foehn/src/PyFoehnEngine.cpp b/foehn/src/PyFoehnEngine.cpp new file mode 100644 index 00000000..c56f3be2 --- /dev/null +++ b/foehn/src/PyFoehnEngine.cpp @@ -0,0 +1,229 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./PyFoehnEngine.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/isobar/PyEntity.h" +#include "hurricane/isobar/PyNet.h" +#include "hurricane/isobar/PyCell.h" +#include "hurricane/isobar/PyInstance.h" +#include "hurricane/viewer/PyCellViewer.h" +#include "hurricane/viewer/ExceptionWidget.h" +#include "hurricane/Cell.h" +#include "crlcore/Utilities.h" +#include "foehn/PyFoehnEngine.h" +#include "foehn/PyDag.h" +#include + +# undef ACCESS_OBJECT +# undef ACCESS_CLASS +# define ACCESS_OBJECT _baseObject._object +# define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject) +#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(FoehnEngine,foehn,function) + + +namespace Foehn { + + using std::cerr; + using std::endl; + using std::hex; + using std::ostringstream; + using Hurricane::tab; + using Hurricane::Exception; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Warning; + using Hurricane::ExceptionWidget; + using Isobar::__cs; + using Isobar::Converter; + using Isobar::ProxyProperty; + using Isobar::ProxyError; + using Isobar::ConstructorError; + using Isobar::HurricaneError; + using Isobar::HurricaneWarning; + using Isobar::getPyHash; + using Isobar::ParseOneArg; + using Isobar::ParseTwoArg; + using Isobar::PyEntity; + using Isobar::PyEntityVector; + using Isobar::PyTypeEntityVector; + using Isobar::PyEntityVectorIterator; + using Isobar::PyNet; + using Isobar::PyCell; + using Isobar::PyInstance; + using Isobar::PyCell_Link; + using Isobar::PyCellViewer; + using Isobar::PyTypeNet; + using Isobar::PyTypeInstance; + using Isobar::PyTypeCellViewer; + using CRL::PyToolEngine; + + +extern "C" { + +#if defined(__PYTHON_MODULE__) + + +#define DirectVoidToolMethod(SELF_TYPE, SELF_OBJECT, FUNC_NAME) \ + static PyObject* Py##SELF_TYPE##_##FUNC_NAME(Py##SELF_TYPE* self) \ + { \ + cdebug_log(40,0) << "Py" #SELF_TYPE "_" #FUNC_NAME "()" << endl; \ + HTRY \ + METHOD_HEAD(#SELF_TYPE "." #FUNC_NAME "()") \ + if (SELF_OBJECT->getViewer()) { \ + if (ExceptionWidget::catchAllWrapper( std::bind(&FoehnEngine::FUNC_NAME,SELF_OBJECT) )) { \ + PyErr_SetString( HurricaneError, #FUNC_NAME "() has thrown an exception (C++)." ); \ + return NULL; \ + } \ + } else { \ + SELF_OBJECT->FUNC_NAME(); \ + } \ + HCATCH \ + Py_RETURN_NONE; \ + } + + +// +=================================================================+ +// | "PyFoehnEngine" Python Module Code Part | +// +=================================================================+ + + + static PyObject* PyFoehnEngine_get ( PyObject*, PyObject* args ) + { + cdebug_log(40,0) << "PyFoehnEngine_get()" << endl; + FoehnEngine* foehn = NULL; + HTRY + PyObject* arg0; + if (not ParseOneArg("Foehn.get", args, CELL_ARG, &arg0)) return NULL; + foehn = FoehnEngine::get( PYCELL_O(arg0) ); + HCATCH + return PyFoehnEngine_Link( foehn ); + } + + + static PyObject* PyFoehnEngine_create ( PyObject*, PyObject* args ) + { + cdebug_log(40,0) << "PyFoehnEngine_create()" << endl; + FoehnEngine* foehn = NULL; + HTRY + PyObject* arg0; + if (not ParseOneArg("Foehn.get", args, CELL_ARG, &arg0)) return NULL; + + Cell* cell = PYCELL_O( arg0 ); + foehn = FoehnEngine::get( cell ); + if (foehn == NULL) { + foehn = FoehnEngine::create( cell ); + if (cmess1.enabled()) { + //foehn->getFoehnConfiguration()->print(cell); + } + } else + cerr << Warning( "%s already has a Foehn engine.", getString(cell).c_str() ) << endl; + HCATCH + return PyFoehnEngine_Link( foehn ); + } + + + static PyObject* PyFoehnEngine_getDag ( PyFoehnEngine* self, PyObject* args ) + { + cdebug_log(40,0) << "PyFoehnEngine_getDag ()" << endl; + Dag* dag = NULL; + HTRY + METHOD_HEAD( "FoehnEngine.getDag()" ) + char* label = NULL; + if (not PyArg_ParseTuple(args, "s:FoehnEngine.getDag", &label)) { + PyErr_SetString( ConstructorError, "FoehnEngine.getDag(): Invalid number of parameters." ); + return NULL; + } + dag = foehn->getDag( label ); + HCATCH + return PyDag_Link( dag ); + } + + + static PyObject* PyFoehnEngine_newDag ( PyFoehnEngine* self, PyObject* args ) + { + cdebug_log(40,0) << "PyFoehnEngine_newDag ()" << endl; + Dag* dag = NULL; + HTRY + METHOD_HEAD( "FoehnEngine.newDag()" ) + char* label = NULL; + if (not PyArg_ParseTuple(args, "s:FoehnEngine.newDag", &label)) { + PyErr_SetString( ConstructorError, "FoehnEngine.newDag(): Invalid number of parameters." ); + return NULL; + } + dag = foehn->newDag( label ); + HCATCH + return PyDag_Link( dag ); + } + + + // Standart Accessors (Attributes). + DirectVoidToolMethod (FoehnEngine,foehn,clear) + + // Standart Destroy (Attribute). + DBoDestroyAttribute(PyFoehnEngine_destroy,PyFoehnEngine) + + + PyMethodDef PyFoehnEngine_Methods[] = + { { "get" , (PyCFunction)PyFoehnEngine_get , METH_VARARGS|METH_STATIC + , "Returns the Foehn engine attached to the Cell, None if there isnt't." } + , { "create" , (PyCFunction)PyFoehnEngine_create , METH_VARARGS|METH_STATIC + , "Create a Foehn engine on this cell." } + , { "getDag" , (PyCFunction)PyFoehnEngine_getDag , METH_VARARGS + , "Get a DAG of the given label." } + , { "newDag" , (PyCFunction)PyFoehnEngine_newDag , METH_VARARGS + , "Create a new dag named label." } + , { "clear" , (PyCFunction)PyFoehnEngine_clear , METH_NOARGS + , "Clear the previous order computed. The tool remains ready for another one." } + , { "destroy" , (PyCFunction)PyFoehnEngine_destroy , METH_NOARGS + , "Destroy the associated hurricane object. The python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + DBoDeleteMethod(FoehnEngine) + PyTypeObjectLinkPyType(FoehnEngine) + + +#else // End of Python Module Code Part. + + +// +=================================================================+ +// | "PyFoehnEngine" Shared Library Code Part | +// +=================================================================+ + + + // Link/Creation Method. + PyTypeInheritedObjectDefinitions(FoehnEngine,PyToolEngine) + DBoLinkCreateMethod(FoehnEngine) + + + extern void PyFoehnEngine_postModuleInit () + { + // PyFoehnFlags_postModuleInit(); + + // PyDict_SetItemString( PyTypeFoehnEngine.tp_dict, "Flags", (PyObject*)&PyTypeFoehnFlags ); + + // PyObject* constant = NULL; + // LoadObjectConstant( PyTypeFoehnEngine.tp_dict, FoehnEngine::GlobalRoutingSuccess , "GlobalRoutingSuccess" ) + // LoadObjectConstant( PyTypeFoehnEngine.tp_dict, FoehnEngine::DetailedRoutingSuccess, "DetailedRoutingSuccess" ) + } + + +#endif // Shared Library Code Part. + +} // extern "C". + +} // Foehn namespace. + diff --git a/foehn/src/foehn/Configuration.h b/foehn/src/foehn/Configuration.h new file mode 100644 index 00000000..5d707eab --- /dev/null +++ b/foehn/src/foehn/Configuration.h @@ -0,0 +1,69 @@ +// -*- mode: C++; explicit-buffer-name: "Configuration.h" -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./foehn/Configuration.h" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include +#include +#include +namespace Hurricane { + class Cell; +} + + +namespace Foehn { + + using Hurricane::Record; + using Hurricane::Cell; + + +// ------------------------------------------------------------------- +// Class : "Foehn::Configuration". + + class Configuration { + public: + // Constructor & Destructor. + Configuration (); + Configuration ( const Configuration& ); + ~Configuration (); + Configuration* clone () const; + // Methods. + bool isDff ( std::string ) const; + bool isIgnoredNet ( std::string ) const; + bool isIgnoredMasterNet ( std::string ) const; + void setDffRe ( std::string ); + void setIgnoredNetRe ( std::string ); + void setIgnoredMasterNetRe ( std::string ); + void _setRegex ( regex_t*& , std::string pattern, std::string attr ); + void print ( const Cell* ) const; + Record* _getRecord () const; + std::string _getString () const; + std::string _getTypeName () const; + private: + Configuration& operator= ( const Configuration& ) = delete; + private: + std::string _dffPattern; + std::string _ignoredNetPattern; + std::string _ignoredMasterNetPattern; + regex_t* _dffRe; + regex_t* _ignoredNetRe; + regex_t* _ignoredMasterNetRe; + }; + + +} // Foehn namespace. + + +INSPECTOR_P_SUPPORT(Foehn::Configuration); diff --git a/foehn/src/foehn/Dag.h b/foehn/src/foehn/Dag.h new file mode 100644 index 00000000..4d1e4984 --- /dev/null +++ b/foehn/src/foehn/Dag.h @@ -0,0 +1,114 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Universié 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./foehn/Dag.h" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include +#include +namespace Hurricane { + class Instance; +} +#include "hurricane/Plug.h" +#include "foehn/Configuration.h" + + +namespace Foehn { + + using std::string; + using std::vector; + using Hurricane::Name; + using Hurricane::Record; + using Hurricane::DBo; + using Hurricane::Entity; + using Hurricane::Net; + using Hurricane::Cell; + using Hurricane::Instance; + using Hurricane::Plug; + class FoehnEngine; + + +// ------------------------------------------------------------------- +// Class : "Foehn::Dag". + + + class Dag { + public: + Dag ( FoehnEngine*, std::string label ); + Dag ( const Dag& ) = delete; + ~Dag (); + Dag& operator= ( const Dag& ) = delete; + FoehnEngine* getFoehn (); + inline Configuration& getConfiguration (); + inline std::string getLabel () const; + Cell* getCell () const; + inline bool isDff ( std::string ) const; + inline bool isDff ( Name ) const; + inline bool isIgnoredNet ( std::string ) const; + inline bool isIgnoredNet ( Name ) const; + inline bool isIgnoredMasterNet ( std::string ) const; + inline bool isIgnoredMasterNet ( Name ) const; + inline bool isIgnoredPlug ( const Plug* ) const; + inline void setDffRe ( std::string ); + inline void setIgnoredNetRe ( std::string ); + inline void setIgnoredMasterNetRe ( std::string ); + void addDStart ( Instance* ); + void addDStart ( Net* ); + void addToDOrder ( Instance* ); + void dpropagate (); + void resetDepths (); + void _dpropagateOn ( Net* ); + void _dpropagateOn ( Instance* ); + inline const std::vector& getDOrder () const; + // Inspector support. + Record* _getRecord () const; + string _getString () const; + string _getTypeName () const; + private: + FoehnEngine* _foehn; + Configuration _configuration; + std::string _label; + std::vector _dorder; + std::vector _inputs; + std::vector _reacheds; + }; + + + inline FoehnEngine* Dag::getFoehn () { return _foehn; } + inline Configuration& Dag::getConfiguration () { return _configuration; } + inline std::string Dag::getLabel () const { return _label; } + inline bool Dag::isDff ( std::string name ) const { return _configuration.isDff(name); } + inline bool Dag::isDff ( Name name ) const { return _configuration.isDff(getString(name)); } + inline bool Dag::isIgnoredNet ( std::string name ) const { return _configuration.isIgnoredNet(name); } + inline bool Dag::isIgnoredNet ( Name name ) const { return _configuration.isIgnoredNet(getString(name)); } + inline bool Dag::isIgnoredMasterNet ( std::string name ) const { return _configuration.isIgnoredMasterNet(name); } + inline bool Dag::isIgnoredMasterNet ( Name name ) const { return _configuration.isIgnoredMasterNet(getString(name)); } + inline void Dag::setDffRe ( std::string name ) { _configuration.setDffRe(name); } + inline void Dag::setIgnoredNetRe ( std::string name ) { _configuration.setIgnoredNetRe(name); } + inline void Dag::setIgnoredMasterNetRe ( std::string name ) { _configuration.setIgnoredMasterNetRe(name); } + inline const std::vector& Dag::getDOrder () const { return _dorder; } + + inline bool Dag::isIgnoredPlug ( const Plug* plug ) const + { + if (not plug->getNet()) return true; + if (isIgnoredNet(plug->getNet()->getName())) return true; + if (isIgnoredMasterNet(plug->getMasterNet()->getName())) return true; + return false; + } + + +} // Foehn namespace. + + +INSPECTOR_P_SUPPORT(Foehn::Dag); diff --git a/foehn/src/foehn/DagProperty.h b/foehn/src/foehn/DagProperty.h new file mode 100644 index 00000000..6a0d0972 --- /dev/null +++ b/foehn/src/foehn/DagProperty.h @@ -0,0 +1,224 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./foehn/DagProperty.h" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include +#include "hurricane/Name.h" +#include "hurricane/Property.h" +#include "hurricane/Slot.h" +namespace Hurricane { + class Net; + class Instance; +} + + +namespace Foehn { + + using Hurricane::Record; + using Hurricane::Name; + using Hurricane::DBo; + using Hurricane::Net; + using Hurricane::Instance; + + +// ------------------------------------------------------------------- +// Class : "Foehn::NetDatas". + + class DagProperty : public Hurricane::PrivateProperty { + public: + typedef Hurricane::PrivateProperty Super; + static Name _name; + public: + static DagProperty* create ( DBo* ); + static Name getPropertyName (); + virtual Name getName () const; + bool isNetOwned () const; + bool isInstanceOwned () const; + inline uint64_t getFlags () const; + inline int32_t getMinDepth () const; + inline int32_t getMaxDepth () const; + inline Instance* getDriver () const; + inline void setMinDepth ( int32_t ); + inline void setMaxDepth ( int32_t ); + inline void setFlags ( uint64_t ); + inline void resetFlags ( uint64_t ); + inline void setDriver ( Instance* ); + inline void incref (); + inline void decref (); + virtual void onReleasedBy ( DBo* owner ); + virtual std::string _getTypeName () const; + virtual std::string _getString () const; + virtual Record* _getRecord () const; + protected: + virtual void _preDestroy (); + protected: + uint64_t _flags; + int32_t _minDepth; + int32_t _maxDepth; + uint16_t _refcount; + Instance* _driver; + protected: + inline DagProperty (); + }; + + + inline DagProperty::DagProperty () + : PrivateProperty() + , _flags () + , _minDepth(-1) + , _maxDepth(-1) + , _refcount(1) + , _driver (nullptr) + { } + + + inline int32_t DagProperty::getMinDepth () const { return _minDepth; } + inline int32_t DagProperty::getMaxDepth () const { return _maxDepth; } + inline void DagProperty::setMinDepth ( int32_t depth ) { _minDepth = depth; } + inline void DagProperty::setMaxDepth ( int32_t depth ) { _minDepth = depth; } + inline uint64_t DagProperty::getFlags () const { return _flags; } + inline void DagProperty::setFlags ( uint64_t flags ) { _flags |= flags; } + inline void DagProperty::resetFlags ( uint64_t flags ) { _flags &= ~flags; } + inline Instance* DagProperty::getDriver () const { return _driver; } + inline void DagProperty::setDriver ( Instance* driver ) { _driver = driver; } + inline void DagProperty::incref () { ++_refcount; } + inline void DagProperty::decref () { --_refcount; if (_refcount == 0) destroy(); } + + +// ------------------------------------------------------------------- +// Class : "Foehn::DagExtension". + + class DagExtension { + public: + static const uint64_t Ignore = (1<<0); + static const uint64_t Reached = (1<<1); + public: + static DagProperty* get ( const DBo* ); + static DagProperty* create ( DBo* ); + static inline bool isPresent ( const DBo* ); + static inline bool isNetOwned ( const DBo* ); + static inline bool isInstanceOwned ( const DBo* ); + static inline uint64_t getFlags ( const DBo* ); + static inline int32_t getMinDepth ( const DBo* ); + static inline int32_t getMaxDepth ( const DBo* ); + static inline Instance* getDriver ( const DBo* ); + static inline void setFlags ( const DBo*, uint64_t ); + static inline void resetFlags ( const DBo*, uint64_t ); + static inline void setMinDepth ( const DBo*, int32_t ); + static inline void setMaxDepth ( const DBo*, int32_t ); + static inline void setDriver ( const DBo*, Instance* ); + }; + + + inline bool DagExtension::isPresent ( const DBo* dbo ) + { + DagProperty* property = get( dbo ); + return (property != nullptr); + } + + + inline bool DagExtension::isNetOwned ( const DBo* dbo ) + { + DagProperty* property = get( dbo ); + if (not property) return false; + return property->isNetOwned(); + } + + + inline bool DagExtension::isInstanceOwned ( const DBo* dbo ) + { + DagProperty* property = get( dbo ); + if (not property) return false; + return property->isInstanceOwned(); + } + + + inline uint64_t DagExtension::getFlags ( const DBo* dbo ) + { + DagProperty* property = get( dbo ); + if (not property) return 0; + return property->getFlags(); + } + + + inline int32_t DagExtension::getMinDepth ( const DBo* dbo ) + { + DagProperty* property = get( dbo ); + if (not property) return -1; + return property->getMinDepth(); + } + + + inline int32_t DagExtension::getMaxDepth ( const DBo* dbo ) + { + DagProperty* property = get( dbo ); + if (not property) return -1; + return property->getMaxDepth(); + } + + + inline Instance* DagExtension::getDriver ( const DBo* dbo ) + { + DagProperty* property = get( dbo ); + if (not property) return nullptr; + return property->getDriver(); + } + + + inline void DagExtension::setFlags ( const DBo* dbo, uint64_t flags ) + { + DagProperty* property = get( dbo ); + if (not property) return; + property->setFlags( flags ); + } + + + inline void DagExtension::resetFlags ( const DBo* dbo, uint64_t flags ) + { + DagProperty* property = get( dbo ); + if (not property) return; + property->resetFlags( flags ); + } + + + inline void DagExtension::setMinDepth ( const DBo* dbo, int32_t depth ) + { + DagProperty* property = get( dbo ); + if (not property) return; + property->setMinDepth( depth ); + } + + + inline void DagExtension::setMaxDepth ( const DBo* dbo, int32_t depth ) + { + DagProperty* property = get( dbo ); + if (not property) return; + property->setMaxDepth( depth ); + } + + + inline void DagExtension::setDriver ( const DBo* dbo, Instance* instance ) + { + DagProperty* property = get( dbo ); + if (not property) return; + property->setDriver( instance ); + } + + +} // Foehn Namespace. + + +INSPECTOR_P_SUPPORT(Foehn::DagProperty); diff --git a/foehn/src/foehn/FoehnEngine.h b/foehn/src/foehn/FoehnEngine.h new file mode 100644 index 00000000..57576581 --- /dev/null +++ b/foehn/src/foehn/FoehnEngine.h @@ -0,0 +1,92 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Universié 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./foehn/FoehnEngine.h" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include +#include +namespace Hurricane { + class Instance; + class CellViewer; +} +#include "hurricane/Plug.h" +#include "crlcore/ToolEngine.h" +#include "foehn/Configuration.h" +#include "foehn/Dag.h" + + +namespace Foehn { + + using std::string; + using std::vector; + using Hurricane::Name; + using Hurricane::Record; + using Hurricane::DBo; + using Hurricane::Entity; + using Hurricane::Net; + using Hurricane::Cell; + using Hurricane::Instance; + using Hurricane::Plug; + using Hurricane::CellViewer; + using CRL::ToolEngine; + + +// ------------------------------------------------------------------- +// Class : "Foehn::FoehnEngine". + + + class FoehnEngine : public ToolEngine { + public: + typedef ToolEngine Super; + public: + static FoehnEngine* create ( Cell* ); + static FoehnEngine* get ( const Cell* ); + static const Name& staticGetName (); + virtual const Name& getName () const; + inline Configuration& getConfiguration (); + Dag* getDag ( std::string label ) const; + Dag* newDag ( std::string label ); + void clear (); + inline CellViewer* getViewer () const; + inline void setViewer ( CellViewer* ); + // Inspector support. + virtual Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const; + protected: + FoehnEngine ( Cell* ); + virtual ~ FoehnEngine (); + virtual void _postCreate (); + virtual void _preDestroy (); + private: + FoehnEngine ( const FoehnEngine& ) = delete; + FoehnEngine& operator= ( const FoehnEngine& ) = delete; + private: + static Name _toolName; + CellViewer* _viewer; + Configuration _configuration; + std::vector _dags; + }; + + + inline Configuration& FoehnEngine::getConfiguration () { return _configuration; } + inline CellViewer* FoehnEngine::getViewer () const { return _viewer; } + inline void FoehnEngine::setViewer ( CellViewer* viewer ) { _viewer = viewer; } + + +} // Foehn namespace. + + +INSPECTOR_P_SUPPORT(Foehn::FoehnEngine); diff --git a/foehn/src/foehn/PyDag.h b/foehn/src/foehn/PyDag.h new file mode 100644 index 00000000..3fe4753d --- /dev/null +++ b/foehn/src/foehn/PyDag.h @@ -0,0 +1,53 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./foehn/PyDag.cpp" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include "hurricane/isobar/PyHurricane.h" +#include "foehn/Dag.h" + + +namespace Foehn { + + extern "C" { + + +// ------------------------------------------------------------------- +// Python Object : "PyDag". + + typedef struct { + PyObject_HEAD + Dag* _object; + } PyDag; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyFoehn.ccp". + + extern PyTypeObject PyTypeDag; + extern PyMethodDef PyDag_Methods[]; + + extern PyObject* PyDag_Link ( Foehn::Dag* ); + extern void PyDag_LinkPyType (); + + +#define IsPyDag(v) ( (v)->ob_type == &PyTypeDag ) +#define PYDAG(v) ( (PyDag*)(v) ) +#define PYDAG_O(v) ( PYDAG(v)->_object ) + + +} // extern "C". + +} // Foehn namespace. diff --git a/foehn/src/foehn/PyDagExtension.h b/foehn/src/foehn/PyDagExtension.h new file mode 100644 index 00000000..327de7ce --- /dev/null +++ b/foehn/src/foehn/PyDagExtension.h @@ -0,0 +1,43 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./foehn/PyDagExtension.h" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include "hurricane/isobar/PyHurricane.h" + + +namespace Foehn { + + extern "C" { + + + typedef struct { + PyObject_HEAD + } PyDagExtension; + + + extern PyTypeObject PyTypeDagExtension; + extern PyMethodDef PyDagExtension_Methods[]; + extern void PyDagExtension_LinkPyType (); + extern void PyDagExtension_postModuleInit (); + + +#define IsPyDagExtension(v) ( (v)->ob_type == &PyTypeDagExtension ) +#define PYDAGEXTENSION(v) ( (PyDagExtension*)(v) ) + + + } // extern "C". + +} // Foehn namespace. diff --git a/foehn/src/foehn/PyFoehnEngine.h b/foehn/src/foehn/PyFoehnEngine.h new file mode 100644 index 00000000..37ca3d7d --- /dev/null +++ b/foehn/src/foehn/PyFoehnEngine.h @@ -0,0 +1,54 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | F o e h n - DAG Toolbox | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./foehn/PyFoehnEngine.cpp" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include "hurricane/isobar/PyHurricane.h" +#include "crlcore/PyToolEngine.h" +#include "foehn/FoehnEngine.h" + + +namespace Foehn { + + extern "C" { + + +// ------------------------------------------------------------------- +// Python Object : "PyFoehnEngine". + + typedef struct { + CRL::PyToolEngine _baseObject; + } PyFoehnEngine; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyFoehn.ccp". + + extern PyTypeObject PyTypeFoehnEngine; + extern PyMethodDef PyFoehnEngine_Methods[]; + + extern PyObject* PyFoehnEngine_Link ( Foehn::FoehnEngine* ); + extern void PyFoehnEngine_LinkPyType (); + extern void PyFoehnEngine_postModuleInit (); + + +#define IsPyFoehnEngine(v) ( (v)->ob_type == &PyTypeFoehnEngine ) +#define PYFOEHNENGINE(v) ( (PyFoehnEngine*)(v) ) +#define PYFOEHNENGINE_O(v) ( PYFOEHNENGINE(v)->_baseObject._object ) + + +} // extern "C". + +} // Foehn namespace.