Dijkstra and Net can manage different wire width.

in Dijkstra.cpp/.h, Edge.cpp/.h, GCell.cpp/.h:
*Change: GlobalRouting wires can have different wires' width. One Net's wires has one width only.

in NetRoutingProperty.cpp/.h, PyNetRoutingProperty.cpp/.h:
*New: A wire width parameter is added. It can be set through python script.
This commit is contained in:
EricLaoGitHub 2017-06-14 10:46:54 +02:00
parent 8a73b03fd8
commit e1724ca785
10 changed files with 154 additions and 27 deletions

View File

@ -231,7 +231,7 @@ namespace Anabatic {
}
bool Vertex::isRestricted ( const Vertex* v1, const Vertex* v2, DbU::Unit hpitch, DbU::Unit vpitch )
bool Vertex::isRestricted ( const Vertex* v1, const Vertex* v2, const Edge* e, DbU::Unit hpitch, DbU::Unit vpitch, Net* net )
{
bool restricted = true;
GCell* c1 = v1->getGCell();
@ -274,7 +274,12 @@ namespace Anabatic {
||(c2->getHeight() < vpitch)
||(restricted)
) return true;
else return false;
else {
if ((v2->getGCell()->isStrut())){
if (e->isMaxCapacity(net)) return true;
else return false;
} else return false;
}
}
}
@ -1160,8 +1165,8 @@ namespace Anabatic {
DbU::Unit Dijkstra::_distance ( const Vertex* current, const Vertex* vneighbour, const Edge* e )
{
if (Vertex::isRestricted(current, vneighbour)) return Vertex::unreachable;
else return current->getDistance() + e->getDistance();
if (Vertex::isRestricted(current, vneighbour, e)) return Vertex::unreachable;
else return current->getDistance() + e->getDistance();
}
@ -1526,7 +1531,7 @@ namespace Anabatic {
Vertex* current = _queue.top();
GCell* gcurrent = current->getGCell();
cdebug_log(111,1) << "Current:" << current << endl;
//cdebug_log(111,1) << "Current:" << current << endl;
_queue.pop();
if ( current->isAxisTarget() and needAxisTarget()) unsetFlags(Mode::AxisTarget);
@ -1534,6 +1539,7 @@ namespace Anabatic {
cdebug_log(111,1) << "Looking for neighbors:" << endl;
for ( Edge* edge : current->getGCell()->getEdges() ) {
cdebug_log(111,0) << "[Current]: " << current << endl;
cdebug_log(111,0) << "@ Edge " << edge << endl;
if (edge == current->getFrom()) {
@ -1565,7 +1571,7 @@ namespace Anabatic {
cdebug_tabw(111,1);
if (current->getFrom()) {
cdebug_log(111,0) << "| From: " << current->getFrom()->getOpposite(gcurrent) << endl;
current->getIntervFrom().print();
//current->getIntervFrom().print();
}
if (current->getFrom2()) {
cdebug_log(111,0) << "| From2: " << current->getFrom2()->getOpposite(gcurrent) << endl;
@ -1582,7 +1588,10 @@ namespace Anabatic {
bool isDistance2shorter = _isDistance2Shorter ( distance, current, vneighbor, edge ); // ANALOG
if ( (distance == vneighbor->getDistance())
and ( (not gcurrent->isMatrix()) and (not gneighbor->isMatrix()) ) ) {
and (not gcurrent->isMatrix() )
and (not gneighbor->isMatrix())
and (vneighbor->getFrom2() == NULL)
) {
_pushEqualDistance( distance, isDistance2shorter, current, vneighbor, edge ); // ANALOG
} else
if ( (distance < vneighbor->getDistance()) and (distance != Vertex::unreachable) ) {
@ -1602,7 +1611,9 @@ namespace Anabatic {
vneighbor->setBranchId( current->getBranchId() );
vneighbor->setDistance( distance );
cdebug_log(111,0) << "setFrom1: " << vneighbor << endl;
vneighbor->setFrom ( edge );
vneighbor->setFrom2( NULL );
_queue.push( vneighbor );
cdebug_log(111,0) << "Push: (size:" << _queue.size() << ") " << vneighbor << endl;
} else {
@ -1661,6 +1672,8 @@ namespace Anabatic {
while ( current ) {
cdebug_log(112,0) << endl;
cdebug_log(112,0) << "| " << current << " | " << endl;
if (current->getFrom()) cdebug_log(112,0) << " | From :" << current->getFrom()->getOpposite(current->getGCell()) << " | " << endl;
if (current->getFrom2()) cdebug_log(112,0) << " | From2:" << current->getFrom2()->getOpposite(current->getGCell()) << " | " << endl;
if (!current->getGCell()->isMatrix()){
//////////////////////////////////////////////////////////////////////////////////////////// ANALOG
@ -1773,7 +1786,7 @@ namespace Anabatic {
, targetContact
, _anabatic->getConfiguration()->getGHorizontalLayer()
, constraint.getCenter()
, DbU::fromLambda(2.0)
, state->getWPitch()*Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2"))//DbU::fromLambda(2.0)
);
for ( Edge* through : aligneds ) through->add( segment );
if (state){
@ -1787,7 +1800,7 @@ namespace Anabatic {
, targetContact
, _anabatic->getConfiguration()->getGVerticalLayer()
, constraint.getCenter()
, DbU::fromLambda(2.0)
, state->getWPitch()*Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL3"))//DbU::fromLambda(2.0)
);
for ( Edge* through : aligneds ) through->add( segment );
if (state){
@ -1995,7 +2008,7 @@ namespace Anabatic {
, targetSym
, _anabatic->getConfiguration()->getGHorizontalLayer()
, axis
, DbU::fromLambda(2.0)
, state->getWPitch()*Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2"))
);
cdebug_log(112,0) << "|| " << segment2 << endl;
} else if (v) {
@ -2034,7 +2047,7 @@ namespace Anabatic {
, targetSym
, _anabatic->getConfiguration()->getGVerticalLayer()
, axis
, DbU::fromLambda(2.0)
, state->getWPitch()*Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL3"))
);
cdebug_log(112,0) << "|| " << segment2 << endl;
}
@ -2115,15 +2128,15 @@ namespace Anabatic {
void Dijkstra::_pushEqualDistance ( DbU::Unit distance, bool isDistance2shorter, Vertex* current, Vertex* vneighbor, Edge* edge )
{
GCell* gneighbor = edge->getOpposite(current->getGCell());
cdebug_log(111,0) << "[case: Distance EQUAL + SameSide]" << endl;
cdebug_log(111,0) << "Previous getfrom:" << vneighbor->getFrom()->getOpposite( gneighbor ) << endl;
GCell* gnext = vneighbor->getGCell();
GCell* gprev = vneighbor->getFrom()->getOpposite(gnext);
Vertex* vprev = gprev->getObserver<Vertex>(GCell::Observable::Vertex);
if ((distance == vneighbor->getDistance()) and vneighbor->areSameSide(vprev, current)){
cdebug_log(111,0) << "[case: Distance EQUAL + SameSide]" << endl;
cdebug_log(111,0) << "Previous getfrom:" << vneighbor->getFrom()->getOpposite( gneighbor ) << endl;
cdebug_log(111,0) << "[case: Other GetFROM]" << endl;
cdebug_log(111,0) << "setFrom2: " << vneighbor << endl;
vneighbor->setFrom2 ( edge );
vneighbor->setFlags(Vertex::From2Mode);
//vneighbor->createIntervFrom2();
@ -2131,9 +2144,11 @@ namespace Anabatic {
vneighbor->unsetFlags(Vertex::From2Mode);
if (isDistance2shorter) {
vneighbor->setFlags(Vertex::UseFromFrom2);
cdebug_log(111,0) << "setFromFrom2: " << vneighbor << endl;
//cdebug_log(111,0) << "setFromFrom2: " << vneighbor << endl;
}
cdebug_log(111,0) << "Push BIS : " << vneighbor << endl;
cdebug_log(111,0) << "From1: " << vneighbor->getFrom()->getOpposite(vneighbor->getGCell()) << endl;
cdebug_log(111,0) << "From2: " << vneighbor->getFrom2()->getOpposite(vneighbor->getGCell()) << endl;
vneighbor->getIntervFrom().print();
vneighbor->getIntervFrom2().print();
}
@ -2143,12 +2158,12 @@ namespace Anabatic {
void Dijkstra::_updateGRAData ( Vertex* vneighbor, bool isDistance2shorter, Vertex* current )
{
vneighbor->unsetFlags(Vertex::UseFromFrom2);
cdebug_log(111,0) << "unsetFromFrom2: " << vneighbor << endl;
//cdebug_log(111,0) << "unsetFromFrom2: " << vneighbor << endl;
vneighbor->clearFrom2();
if (isDistance2shorter) {
vneighbor->setFlags(Vertex::UseFromFrom2);
cdebug_log(111,0) << "setFromFrom2: " << vneighbor << endl;
} else cdebug_log(111,0) << "DON'T setFromFrom2: " << vneighbor << endl;
//cdebug_log(111,0) << "setFromFrom2: " << vneighbor << endl;
}// else cdebug_log(111,0) << "setFrom1: " << vneighbor << endl;
vneighbor->setIntervals( current );
vneighbor->getIntervFrom().print();
@ -2204,7 +2219,7 @@ namespace Anabatic {
if (current->getConnexId() == _connectedsId) return true;
from = NULL;
if (useFrom2) {
cdebug_log(112,0) << "USE FROM2: " << current->getFrom2() << endl;
cdebug_log(112,0) << "USE FROM2: " << current->getFrom2()->getOpposite(current->getGCell()) << endl;
current->setFrom(current->getFrom2());
current->setIntervfrom(current->getPIMin2(), current->getPIMax2(), current->getPIAxis2());
current->clearFrom2();
@ -2226,6 +2241,7 @@ namespace Anabatic {
cdebug_log(112,0) << ", axis: " << DbU::getValueString(current->getPIAxis()) << endl;
current->getPredecessor()->setInterv(current->getPIMin(), current->getPIMax(), current->getPIAxis());
current->getIntervFrom().print();
//if (current->getPredecessor()->getGCell()->isStrut()) _updateRealOccupancy( current );
}
return false;
}
@ -2298,6 +2314,22 @@ namespace Anabatic {
}
void Dijkstra::_updateRealOccupancy ( Vertex* current )
{
cerr << "void Dijkstra::_updateRealOccupancy ( Vertex* current ): " << current << endl;
GCell* gcurrent = current->getGCell();
GCell* gnext = current->getPredecessor()->getGCell();
Edge* e = gcurrent->getEdgeTo(gnext);
NetRoutingState* state = NetRoutingExtension::get( _net );
cerr << "e: " << e << endl;
e->incRealOccupancy2(state->getWPitch());
cerr << "e: " << e << endl;
if (current->getGCell()->getWestEdge()) cerr << "W occupancy: " << current->getGCell()->getWestEdge()->getRealOccupancy() << "/" << current->getGCell()->getWestEdge()->getCapacity() << endl;
if (current->getGCell()->getEastEdge()) cerr << "E occupancy: " << current->getGCell()->getEastEdge()->getRealOccupancy() << "/" << current->getGCell()->getEastEdge()->getCapacity() << endl;
if (current->getGCell()->getNorthEdge()) cerr << "N occupancy: " << current->getGCell()->getNorthEdge()->getRealOccupancy() << "/" << current->getGCell()->getNorthEdge()->getCapacity() << endl;
if (current->getGCell()->getSouthEdge()) cerr << "S occupancy: " << current->getGCell()->getSouthEdge()->getRealOccupancy() << "/" << current->getGCell()->getSouthEdge()->getCapacity() << endl;
}
} // Anabatic namespace.

View File

@ -17,6 +17,8 @@
#include <iostream>
#include "hurricane/Error.h"
#include "hurricane/Segment.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "anabatic/Edge.h"
#include "anabatic/GCell.h"
#include "anabatic/AnabaticEngine.h"
@ -182,6 +184,10 @@ namespace Anabatic {
_realOccupancy = occupancy;
}
void Edge::incRealOccupancy2 ( int value )
{
_realOccupancy += value;
}
Segment* Edge::getSegment ( const Net* owner ) const
{
@ -195,7 +201,13 @@ namespace Anabatic {
void Edge::add ( Segment* segment )
{
_segments.push_back( segment );
incRealOccupancy( 1 ); // Need to take the wire width into account.
Horizontal* h = dynamic_cast<Horizontal*>(segment);
Vertical* v = dynamic_cast<Vertical*>(segment);
DbU::Unit pitch = 0;
if (h) pitch = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2"));
if (v) pitch = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL3"));
incRealOccupancy( segment->getWidth()/pitch ); // Need to take the wire width into account.
}
@ -300,6 +312,20 @@ namespace Anabatic {
}
bool Edge::isMaxCapacity ( Net* net ) const
{
if (net){
Hurricane::NetRoutingState* state = Hurricane::NetRoutingExtension::get( net );
//cerr << "bool Edge::isMaxCapacity ( Net* net ) const: " << net << endl;
//cerr << "WPitch: " << state->getWPitch() << endl;
return ( (_realOccupancy +state->getWPitch()) > _capacity ) ? true : false;
} else {
return ( _realOccupancy >= _capacity ) ? true : false;
}
}
void Edge::translate ( const DbU::Unit&, const DbU::Unit& )
{
cerr << Error( "Edge::translate(): On %s,\n"

View File

@ -1665,6 +1665,20 @@ namespace Anabatic {
return false;
}
void GCell::setEdgesOccupancy ( unsigned int width, unsigned int height )
{
getEastEdge()->setCapacity(width);
getWestEdge()->setCapacity(width);
getNorthEdge()->setCapacity(height);
getSouthEdge()->setCapacity(height);
getEastEdge()->setRealOccupancy(0);
getWestEdge()->setRealOccupancy(0);
getNorthEdge()->setRealOccupancy(0);
getSouthEdge()->setRealOccupancy(0);
}
string GCell::_getTypeName () const
{ return getString(_extensionName); }

View File

@ -244,7 +244,7 @@ namespace Anabatic {
bool hasRP ( Net* ) const;
bool hasVRP ( Net* ) const;
bool hasHRP ( Net* ) const;
static bool isRestricted ( const Vertex* v1, const Vertex* v2, DbU::Unit hpitch = 0, DbU::Unit vpitch = 0);
static bool isRestricted ( const Vertex* v1, const Vertex* v2, const Edge* e, DbU::Unit hpitch = 0, DbU::Unit vpitch = 0, Net* net = NULL);
bool areSameSide ( const Vertex*, const Vertex* ) const;
inline bool isFromFrom2 () const;
@ -518,6 +518,7 @@ namespace Anabatic {
void _updateGRAData ( Vertex*, bool, Vertex* );
void _initiateUpdateIntervals ( Vertex* );
bool _updateIntervals ( bool&, Vertex*, bool&, int&, Edge* );
void _updateRealOccupancy ( Vertex* );
private:
AnabaticEngine* _anabatic;

View File

@ -73,8 +73,11 @@ namespace Anabatic {
Interval getSide () const;
Segment* getSegment ( const Net* ) const;
inline const vector<Segment*>& getSegments () const;
inline void setCapacity ( int );
inline void incCapacity ( int );
inline void setRealOccupancy ( int );
void incRealOccupancy ( int );
void incRealOccupancy2 ( int );
inline void setHistoricCost ( float );
void add ( Segment* );
void remove ( Segment* );
@ -83,6 +86,8 @@ namespace Anabatic {
inline const Flags& flags () const;
inline Flags& flags ();
inline void revalidate () const;
bool isMaxCapacity ( Net* net = NULL ) const;
void _setSource ( GCell* );
void _setTarget ( GCell* );
private:
@ -133,13 +138,14 @@ namespace Anabatic {
inline GCell* Edge::getTarget () const { return _target; }
inline DbU::Unit Edge::getAxis () const { return _axis; }
inline const vector<Segment*>& Edge::getSegments () const { return _segments; }
inline void Edge::incCapacity ( int delta ) { _capacity = ((int)_capacity+delta > 0) ? _capacity+delta : 0; }
inline void Edge::incCapacity ( int delta ) { _capacity = ((int)_capacity+delta > 0) ? _capacity+delta : 0; }
inline void Edge::setCapacity ( int c ) { _capacity = ((int) c > 0) ? c : 0; }
inline void Edge::setRealOccupancy ( int c ) { _realOccupancy = ((int) c > 0) ? c : 0; }
inline void Edge::setHistoricCost ( float hcost ) { _historicCost = hcost; }
inline const Flags& Edge::flags () const { return _flags; }
inline Flags& Edge::flags () { return _flags; }
inline void Edge::revalidate () const { /*if (_flags&Flags::Invalidated)*/ const_cast<Edge*>(this)->_revalidate(); }
} // Anabatic namespace.

View File

@ -171,6 +171,12 @@ namespace Anabatic {
inline GCell* getEast () const;
inline GCell* getSouth () const;
inline GCell* getNorth () const;
inline Edge* getWestEdge () const;
inline Edge* getEastEdge () const;
inline Edge* getSouthEdge () const;
inline Edge* getNorthEdge () const;
GCell* getWest ( DbU::Unit y ) const;
GCell* getEast ( DbU::Unit y ) const;
GCell* getSouth ( DbU::Unit x ) const;
@ -237,6 +243,8 @@ namespace Anabatic {
bool stepNetDesaturate ( size_t depth
, set<Net*>& globalNets
, Set& invalidateds );
void setEdgesOccupancy (unsigned int, unsigned int);
// Misc. functions.
inline const Flags& flags () const;
inline Flags& flags ();
@ -323,6 +331,12 @@ namespace Anabatic {
inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); }
inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); }
inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); }
inline Edge* GCell::getWestEdge () const { return _westEdges.empty() ? NULL : _westEdges[0]; }
inline Edge* GCell::getEastEdge () const { return _eastEdges.empty() ? NULL : _eastEdges[0]; }
inline Edge* GCell::getSouthEdge () const { return _southEdges.empty() ? NULL : _southEdges[0]; }
inline Edge* GCell::getNorthEdge () const { return _northEdges.empty() ? NULL : _northEdges[0]; }
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; }
inline size_t GCell::getDepth () const { return _depth; }

View File

@ -135,6 +135,10 @@ namespace Hurricane {
w->endObject();
}
void NetRoutingState::setWPitch ( unsigned int w )
{
if (w != 0) _wPitch = w;
}
// -------------------------------------------------------------------
// Class : "JsonNetRoutingProperty"

View File

@ -72,6 +72,8 @@ namespace Hurricane {
inline void setFlags ( uint32_t mask );
inline void unsetFlags ( uint32_t mask );
inline bool isSelfSym () const;
void setWPitch ( uint32_t );
inline uint32_t getWPitch () const;
DbU::Unit getSymValue ( DbU::Unit ) const;
std::string _getString () const;
Record* _getRecord () const;
@ -84,10 +86,11 @@ namespace Hurricane {
Net* _symNet;
uint32_t _flags;
DbU::Unit _axis;
uint32_t _wPitch;
};
inline NetRoutingState::NetRoutingState ( Net* net, uint32_t flags ) : _net(net), _symNet(NULL), _flags(flags), _axis(0) { }
inline NetRoutingState::NetRoutingState ( Net* net, uint32_t flags ) : _net(net), _symNet(NULL), _flags(flags), _axis(0), _wPitch(1) { }
inline bool NetRoutingState::isExcluded () const { return _flags & Excluded; };
inline bool NetRoutingState::isFixed () const { return _flags & Fixed; };
@ -111,6 +114,7 @@ namespace Hurricane {
inline void NetRoutingState::setSymAxis ( DbU::Unit axis ) { _axis = axis; }
inline bool NetRoutingState::isSelfSym () const { return (_symNet == NULL) and (isSymmetric()); }
inline bool NetRoutingState::isSymSlave () const { return (_symNet != NULL) and (not isSymMaster()); }
inline uint32_t NetRoutingState::getWPitch () const { return _wPitch; }
// -------------------------------------------------------------------
@ -180,6 +184,10 @@ namespace Hurricane {
static inline void setSymAxis ( const Net*, DbU::Unit );
static inline void setFlags ( const Net*, uint32_t mask );
static inline void unsetFlags ( const Net*, uint32_t mask );
static inline uint32_t getWPitch ( const Net* );
static inline void setWPitch ( const Net*, uint32_t w );
static NetRoutingState* get ( const Net* );
static NetRoutingState* create ( Net*, uint32_t flags=0 );
private:
@ -307,6 +315,20 @@ namespace Hurricane {
}
inline uint32_t NetRoutingExtension::getWPitch ( const Net* net )
{
NetRoutingState* state = get( net );
return (state == NULL) ? 0 : state->getWPitch();
}
inline void NetRoutingExtension::setWPitch ( const Net* net, uint32_t w )
{
NetRoutingState* state = get( net );
if (state != NULL) state->setWPitch( w );
}
} // Hurricane namespace.

View File

@ -136,6 +136,8 @@ extern "C" {
ExtensionSetUIntFunction(setFlags ,NetRoutingExtension)
ExtensionSetUIntFunction(unsetFlags ,NetRoutingExtension)
ExtensionSetLongFunction(setSymAxis ,NetRoutingExtension)
ExtensionGetUIntFunction(getWPitch ,NetRoutingExtension)
ExtensionSetUIntFunction(setWPitch ,NetRoutingExtension)
static PyObject* PyNetRoutingExtension_getSymNet ( PyObject*, PyObject* args )
@ -214,6 +216,8 @@ extern "C" {
, "Returns the NetRoutingState, or None has not been created yet." }
, { "create" , (PyCFunction)PyNetRoutingExtension_create , METH_VARARGS|METH_CLASS
, "Returns the NetRoutingState, create it if needs be." }
, { "setWPitch" , (PyCFunction)PyNetRoutingExtension_setWPitch , METH_VARARGS|METH_CLASS , "To be documented." }
, { "getWPitch" , (PyCFunction)PyNetRoutingExtension_getWPitch , METH_NOARGS |METH_CLASS , "To be documented." }
, {NULL, NULL, 0, NULL} /* sentinel */
};

View File

@ -83,11 +83,13 @@ extern "C" {
DirectGetBoolAttribute(PyNetRoutingState_isAnalog ,isAnalog ,PyNetRoutingState,NetRoutingState)
DirectGetUIntAttribute(PyNetRoutingState_getFlags ,getFlags ,PyNetRoutingState,NetRoutingState)
DirectGetLongAttribute(PyNetRoutingState_getSymAxis ,getSymAxis ,PyNetRoutingState,NetRoutingState)
DirectGetUIntAttribute(PyNetRoutingState_getWPitch ,getWPitch ,PyNetRoutingState,NetRoutingState)
// Standart Mutators (Attributes).
DirectSetUInt32Attribute(PyNetRoutingState_setFlags ,setFlags ,PyNetRoutingState,NetRoutingState)
DirectSetUInt32Attribute(PyNetRoutingState_unsetFlags,unsetFlags,PyNetRoutingState,NetRoutingState)
DirectSetLongAttribute (PyNetRoutingState_setSymAxis,setSymAxis,PyNetRoutingState,NetRoutingState)
DirectSetUInt32Attribute(PyNetRoutingState_setWPitch ,setWPitch ,PyNetRoutingState,NetRoutingState)
PyMethodDef PyNetRoutingState_Methods[] =
@ -111,6 +113,8 @@ extern "C" {
, { "setSymAxis" , (PyCFunction)PyNetRoutingState_setSymAxis , METH_VARARGS , "To be documented." }
, { "getNet" , (PyCFunction)PyNetRoutingState_getNet , METH_VARARGS , "To be documented." }
, { "getSymNet" , (PyCFunction)PyNetRoutingState_getSymNet , METH_VARARGS , "To be documented." }
, { "getWPitch" , (PyCFunction)PyNetRoutingState_getWPitch , METH_NOARGS , "To be documented." }
, { "setWPitch" , (PyCFunction)PyNetRoutingState_setWPitch , METH_VARARGS , "To be documented." }
, {NULL, NULL, 0, NULL} /* sentinel */
};