--- a/src/internet/model/global-route-manager-impl.cc Fri Dec 06 19:42:02 2013 +0100
+++ b/src/internet/model/global-route-manager-impl.cc Fri Dec 06 14:57:33 2013 -0500
@@ -711,8 +711,9 @@
Ptr<GlobalRouter> rtr =
node->GetObject<GlobalRouter> ();
+ uint32_t systemId = MpiInterface::GetSystemId ();
// Ignore nodes that are not assigned to our systemId (distributed sim)
- if (node->GetSystemId () != MpiInterface::GetSystemId ())
+ if (node->GetSystemId () != systemId)
{
continue;
}
--- a/src/mpi/bindings/modulegen__gcc_ILP32.py Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/bindings/modulegen__gcc_ILP32.py Fri Dec 06 14:57:33 2013 -0500
@@ -40,20 +40,14 @@
module.add_class('Item', import_from_module='ns.network', outer_class=root_module['ns3::ByteTagList::Iterator'])
## callback.h (module 'core'): ns3::CallbackBase [class]
module.add_class('CallbackBase', import_from_module='ns.core')
- ## event-id.h (module 'core'): ns3::EventId [class]
- module.add_class('EventId', import_from_module='ns.core')
## hash.h (module 'core'): ns3::Hasher [class]
module.add_class('Hasher', import_from_module='ns.core')
- ## distributed-simulator-impl.h (module 'mpi'): ns3::LbtsMessage [class]
- module.add_class('LbtsMessage')
## mpi-interface.h (module 'mpi'): ns3::MpiInterface [class]
module.add_class('MpiInterface')
## object-base.h (module 'core'): ns3::ObjectBase [class]
module.add_class('ObjectBase', allow_subclassing=True, import_from_module='ns.core')
## object.h (module 'core'): ns3::ObjectDeleter [struct]
module.add_class('ObjectDeleter', import_from_module='ns.core')
- ## object-factory.h (module 'core'): ns3::ObjectFactory [class]
- module.add_class('ObjectFactory', import_from_module='ns.core')
## packet-metadata.h (module 'network'): ns3::PacketMetadata [class]
module.add_class('PacketMetadata', import_from_module='ns.network')
## packet-metadata.h (module 'network'): ns3::PacketMetadata::Item [struct]
@@ -72,8 +66,8 @@
module.add_class('TagData', import_from_module='ns.network', outer_class=root_module['ns3::PacketTagList'])
## packet-tag-list.h (module 'network'): ns3::PacketTagList::TagData::TagData_e [enumeration]
module.add_enum('TagData_e', ['MAX_SIZE'], outer_class=root_module['ns3::PacketTagList::TagData'], import_from_module='ns.network')
- ## mpi-interface.h (module 'mpi'): ns3::SentBuffer [class]
- module.add_class('SentBuffer')
+ ## parallel-communication-interface.h (module 'mpi'): ns3::ParallelCommunicationInterface [class]
+ module.add_class('ParallelCommunicationInterface', allow_subclassing=True)
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::Object, ns3::ObjectBase, ns3::ObjectDeleter> [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::Object', 'ns3::ObjectBase', 'ns3::ObjectDeleter'], parent=root_module['ns3::ObjectBase'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## tag.h (module 'network'): ns3::Tag [class]
@@ -100,12 +94,6 @@
module.add_class('Object', import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::Object, ns3::ObjectBase, ns3::ObjectDeleter >'])
## object.h (module 'core'): ns3::Object::AggregateIterator [class]
module.add_class('AggregateIterator', import_from_module='ns.core', outer_class=root_module['ns3::Object'])
- ## scheduler.h (module 'core'): ns3::Scheduler [class]
- module.add_class('Scheduler', import_from_module='ns.core', parent=root_module['ns3::Object'])
- ## scheduler.h (module 'core'): ns3::Scheduler::Event [struct]
- module.add_class('Event', import_from_module='ns.core', outer_class=root_module['ns3::Scheduler'])
- ## scheduler.h (module 'core'): ns3::Scheduler::EventKey [struct]
- module.add_class('EventKey', import_from_module='ns.core', outer_class=root_module['ns3::Scheduler'])
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::AttributeAccessor', 'ns3::empty', 'ns3::DefaultDeleter<ns3::AttributeAccessor>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> > [class]
@@ -114,8 +102,6 @@
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::AttributeValue', 'ns3::empty', 'ns3::DefaultDeleter<ns3::AttributeValue>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::CallbackImplBase, ns3::empty, ns3::DefaultDeleter<ns3::CallbackImplBase> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::CallbackImplBase', 'ns3::empty', 'ns3::DefaultDeleter<ns3::CallbackImplBase>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
- ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> > [class]
- module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::EventImpl', 'ns3::empty', 'ns3::DefaultDeleter<ns3::EventImpl>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::Hash::Implementation, ns3::empty, ns3::DefaultDeleter<ns3::Hash::Implementation> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::Hash::Implementation', 'ns3::empty', 'ns3::DefaultDeleter<ns3::Hash::Implementation>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::NixVector, ns3::empty, ns3::DefaultDeleter<ns3::NixVector> > [class]
@@ -124,12 +110,10 @@
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::Packet', 'ns3::empty', 'ns3::DefaultDeleter<ns3::Packet>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::TraceSourceAccessor, ns3::empty, ns3::DefaultDeleter<ns3::TraceSourceAccessor> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::TraceSourceAccessor', 'ns3::empty', 'ns3::DefaultDeleter<ns3::TraceSourceAccessor>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
- ## simulator-impl.h (module 'core'): ns3::SimulatorImpl [class]
- module.add_class('SimulatorImpl', import_from_module='ns.core', parent=root_module['ns3::Object'])
## nstime.h (module 'core'): ns3::Time [class]
module.add_class('Time', import_from_module='ns.core')
## nstime.h (module 'core'): ns3::Time::Unit [enumeration]
- module.add_enum('Unit', ['S', 'MS', 'US', 'NS', 'PS', 'FS', 'LAST'], outer_class=root_module['ns3::Time'], import_from_module='ns.core')
+ module.add_enum('Unit', ['Y', 'D', 'H', 'MIN', 'S', 'MS', 'US', 'NS', 'PS', 'FS', 'LAST'], outer_class=root_module['ns3::Time'], import_from_module='ns.core')
## nstime.h (module 'core'): ns3::Time [class]
root_module['ns3::Time'].implicitly_converts_to(root_module['ns3::int64x64_t'])
## trace-source-accessor.h (module 'core'): ns3::TraceSourceAccessor [class]
@@ -148,20 +132,12 @@
module.add_class('CallbackImplBase', import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::CallbackImplBase, ns3::empty, ns3::DefaultDeleter<ns3::CallbackImplBase> >'])
## callback.h (module 'core'): ns3::CallbackValue [class]
module.add_class('CallbackValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
- ## distributed-simulator-impl.h (module 'mpi'): ns3::DistributedSimulatorImpl [class]
- module.add_class('DistributedSimulatorImpl', parent=root_module['ns3::SimulatorImpl'])
## attribute.h (module 'core'): ns3::EmptyAttributeValue [class]
module.add_class('EmptyAttributeValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
- ## event-impl.h (module 'core'): ns3::EventImpl [class]
- module.add_class('EventImpl', import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> >'])
## mpi-receiver.h (module 'mpi'): ns3::MpiReceiver [class]
module.add_class('MpiReceiver', parent=root_module['ns3::Object'])
## nix-vector.h (module 'network'): ns3::NixVector [class]
module.add_class('NixVector', import_from_module='ns.network', parent=root_module['ns3::SimpleRefCount< ns3::NixVector, ns3::empty, ns3::DefaultDeleter<ns3::NixVector> >'])
- ## object-factory.h (module 'core'): ns3::ObjectFactoryChecker [class]
- module.add_class('ObjectFactoryChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
- ## object-factory.h (module 'core'): ns3::ObjectFactoryValue [class]
- module.add_class('ObjectFactoryValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
## packet.h (module 'network'): ns3::Packet [class]
module.add_class('Packet', import_from_module='ns.network', parent=root_module['ns3::SimpleRefCount< ns3::Packet, ns3::empty, ns3::DefaultDeleter<ns3::Packet> >'])
## nstime.h (module 'core'): ns3::TimeValue [class]
@@ -228,13 +204,10 @@
register_Ns3ByteTagListIterator_methods(root_module, root_module['ns3::ByteTagList::Iterator'])
register_Ns3ByteTagListIteratorItem_methods(root_module, root_module['ns3::ByteTagList::Iterator::Item'])
register_Ns3CallbackBase_methods(root_module, root_module['ns3::CallbackBase'])
- register_Ns3EventId_methods(root_module, root_module['ns3::EventId'])
register_Ns3Hasher_methods(root_module, root_module['ns3::Hasher'])
- register_Ns3LbtsMessage_methods(root_module, root_module['ns3::LbtsMessage'])
register_Ns3MpiInterface_methods(root_module, root_module['ns3::MpiInterface'])
register_Ns3ObjectBase_methods(root_module, root_module['ns3::ObjectBase'])
register_Ns3ObjectDeleter_methods(root_module, root_module['ns3::ObjectDeleter'])
- register_Ns3ObjectFactory_methods(root_module, root_module['ns3::ObjectFactory'])
register_Ns3PacketMetadata_methods(root_module, root_module['ns3::PacketMetadata'])
register_Ns3PacketMetadataItem_methods(root_module, root_module['ns3::PacketMetadata::Item'])
register_Ns3PacketMetadataItemIterator_methods(root_module, root_module['ns3::PacketMetadata::ItemIterator'])
@@ -242,7 +215,7 @@
register_Ns3PacketTagIteratorItem_methods(root_module, root_module['ns3::PacketTagIterator::Item'])
register_Ns3PacketTagList_methods(root_module, root_module['ns3::PacketTagList'])
register_Ns3PacketTagListTagData_methods(root_module, root_module['ns3::PacketTagList::TagData'])
- register_Ns3SentBuffer_methods(root_module, root_module['ns3::SentBuffer'])
+ register_Ns3ParallelCommunicationInterface_methods(root_module, root_module['ns3::ParallelCommunicationInterface'])
register_Ns3SimpleRefCount__Ns3Object_Ns3ObjectBase_Ns3ObjectDeleter_methods(root_module, root_module['ns3::SimpleRefCount< ns3::Object, ns3::ObjectBase, ns3::ObjectDeleter >'])
register_Ns3Tag_methods(root_module, root_module['ns3::Tag'])
register_Ns3TagBuffer_methods(root_module, root_module['ns3::TagBuffer'])
@@ -255,19 +228,14 @@
register_Ns3Header_methods(root_module, root_module['ns3::Header'])
register_Ns3Object_methods(root_module, root_module['ns3::Object'])
register_Ns3ObjectAggregateIterator_methods(root_module, root_module['ns3::Object::AggregateIterator'])
- register_Ns3Scheduler_methods(root_module, root_module['ns3::Scheduler'])
- register_Ns3SchedulerEvent_methods(root_module, root_module['ns3::Scheduler::Event'])
- register_Ns3SchedulerEventKey_methods(root_module, root_module['ns3::Scheduler::EventKey'])
register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >'])
register_Ns3SimpleRefCount__Ns3AttributeChecker_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeChecker__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
register_Ns3SimpleRefCount__Ns3AttributeValue_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeValue__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
register_Ns3SimpleRefCount__Ns3CallbackImplBase_Ns3Empty_Ns3DefaultDeleter__lt__ns3CallbackImplBase__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::CallbackImplBase, ns3::empty, ns3::DefaultDeleter<ns3::CallbackImplBase> >'])
- register_Ns3SimpleRefCount__Ns3EventImpl_Ns3Empty_Ns3DefaultDeleter__lt__ns3EventImpl__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> >'])
register_Ns3SimpleRefCount__Ns3HashImplementation_Ns3Empty_Ns3DefaultDeleter__lt__ns3HashImplementation__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::Hash::Implementation, ns3::empty, ns3::DefaultDeleter<ns3::Hash::Implementation> >'])
register_Ns3SimpleRefCount__Ns3NixVector_Ns3Empty_Ns3DefaultDeleter__lt__ns3NixVector__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::NixVector, ns3::empty, ns3::DefaultDeleter<ns3::NixVector> >'])
register_Ns3SimpleRefCount__Ns3Packet_Ns3Empty_Ns3DefaultDeleter__lt__ns3Packet__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::Packet, ns3::empty, ns3::DefaultDeleter<ns3::Packet> >'])
register_Ns3SimpleRefCount__Ns3TraceSourceAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3TraceSourceAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::TraceSourceAccessor, ns3::empty, ns3::DefaultDeleter<ns3::TraceSourceAccessor> >'])
- register_Ns3SimulatorImpl_methods(root_module, root_module['ns3::SimulatorImpl'])
register_Ns3Time_methods(root_module, root_module['ns3::Time'])
register_Ns3TraceSourceAccessor_methods(root_module, root_module['ns3::TraceSourceAccessor'])
register_Ns3Trailer_methods(root_module, root_module['ns3::Trailer'])
@@ -277,13 +245,9 @@
register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker'])
register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase'])
register_Ns3CallbackValue_methods(root_module, root_module['ns3::CallbackValue'])
- register_Ns3DistributedSimulatorImpl_methods(root_module, root_module['ns3::DistributedSimulatorImpl'])
register_Ns3EmptyAttributeValue_methods(root_module, root_module['ns3::EmptyAttributeValue'])
- register_Ns3EventImpl_methods(root_module, root_module['ns3::EventImpl'])
register_Ns3MpiReceiver_methods(root_module, root_module['ns3::MpiReceiver'])
register_Ns3NixVector_methods(root_module, root_module['ns3::NixVector'])
- register_Ns3ObjectFactoryChecker_methods(root_module, root_module['ns3::ObjectFactoryChecker'])
- register_Ns3ObjectFactoryValue_methods(root_module, root_module['ns3::ObjectFactoryValue'])
register_Ns3Packet_methods(root_module, root_module['ns3::Packet'])
register_Ns3TimeValue_methods(root_module, root_module['ns3::TimeValue'])
register_Ns3TypeIdChecker_methods(root_module, root_module['ns3::TypeIdChecker'])
@@ -703,51 +667,6 @@
is_static=True, visibility='protected')
return
-def register_Ns3EventId_methods(root_module, cls):
- cls.add_binary_comparison_operator('!=')
- cls.add_binary_comparison_operator('==')
- ## event-id.h (module 'core'): ns3::EventId::EventId(ns3::EventId const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::EventId const &', 'arg0')])
- ## event-id.h (module 'core'): ns3::EventId::EventId() [constructor]
- cls.add_constructor([])
- ## event-id.h (module 'core'): ns3::EventId::EventId(ns3::Ptr<ns3::EventImpl> const & impl, uint64_t ts, uint32_t context, uint32_t uid) [constructor]
- cls.add_constructor([param('ns3::Ptr< ns3::EventImpl > const &', 'impl'), param('uint64_t', 'ts'), param('uint32_t', 'context'), param('uint32_t', 'uid')])
- ## event-id.h (module 'core'): void ns3::EventId::Cancel() [member function]
- cls.add_method('Cancel',
- 'void',
- [])
- ## event-id.h (module 'core'): uint32_t ns3::EventId::GetContext() const [member function]
- cls.add_method('GetContext',
- 'uint32_t',
- [],
- is_const=True)
- ## event-id.h (module 'core'): uint64_t ns3::EventId::GetTs() const [member function]
- cls.add_method('GetTs',
- 'uint64_t',
- [],
- is_const=True)
- ## event-id.h (module 'core'): uint32_t ns3::EventId::GetUid() const [member function]
- cls.add_method('GetUid',
- 'uint32_t',
- [],
- is_const=True)
- ## event-id.h (module 'core'): bool ns3::EventId::IsExpired() const [member function]
- cls.add_method('IsExpired',
- 'bool',
- [],
- is_const=True)
- ## event-id.h (module 'core'): bool ns3::EventId::IsRunning() const [member function]
- cls.add_method('IsRunning',
- 'bool',
- [],
- is_const=True)
- ## event-id.h (module 'core'): ns3::EventImpl * ns3::EventId::PeekEventImpl() const [member function]
- cls.add_method('PeekEventImpl',
- 'ns3::EventImpl *',
- [],
- is_const=True)
- return
-
def register_Ns3Hasher_methods(root_module, cls):
## hash.h (module 'core'): ns3::Hasher::Hasher(ns3::Hasher const & arg0) [copy constructor]
cls.add_constructor([param('ns3::Hasher const &', 'arg0')])
@@ -777,35 +696,6 @@
[])
return
-def register_Ns3LbtsMessage_methods(root_module, cls):
- ## distributed-simulator-impl.h (module 'mpi'): ns3::LbtsMessage::LbtsMessage(ns3::LbtsMessage const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::LbtsMessage const &', 'arg0')])
- ## distributed-simulator-impl.h (module 'mpi'): ns3::LbtsMessage::LbtsMessage() [constructor]
- cls.add_constructor([])
- ## distributed-simulator-impl.h (module 'mpi'): ns3::LbtsMessage::LbtsMessage(uint32_t rxc, uint32_t txc, uint32_t id, bool isFinished, ns3::Time const & t) [constructor]
- cls.add_constructor([param('uint32_t', 'rxc'), param('uint32_t', 'txc'), param('uint32_t', 'id'), param('bool', 'isFinished'), param('ns3::Time const &', 't')])
- ## distributed-simulator-impl.h (module 'mpi'): uint32_t ns3::LbtsMessage::GetMyId() [member function]
- cls.add_method('GetMyId',
- 'uint32_t',
- [])
- ## distributed-simulator-impl.h (module 'mpi'): uint32_t ns3::LbtsMessage::GetRxCount() [member function]
- cls.add_method('GetRxCount',
- 'uint32_t',
- [])
- ## distributed-simulator-impl.h (module 'mpi'): ns3::Time ns3::LbtsMessage::GetSmallestTime() [member function]
- cls.add_method('GetSmallestTime',
- 'ns3::Time',
- [])
- ## distributed-simulator-impl.h (module 'mpi'): uint32_t ns3::LbtsMessage::GetTxCount() [member function]
- cls.add_method('GetTxCount',
- 'uint32_t',
- [])
- ## distributed-simulator-impl.h (module 'mpi'): bool ns3::LbtsMessage::IsFinished() [member function]
- cls.add_method('IsFinished',
- 'bool',
- [])
- return
-
def register_Ns3MpiInterface_methods(root_module, cls):
## mpi-interface.h (module 'mpi'): ns3::MpiInterface::MpiInterface() [constructor]
cls.add_constructor([])
@@ -826,11 +716,6 @@
'void',
[param('int *', 'pargc'), param('char * * *', 'pargv')],
is_static=True)
- ## mpi-interface.h (module 'mpi'): static uint32_t ns3::MpiInterface::GetRxCount() [member function]
- cls.add_method('GetRxCount',
- 'uint32_t',
- [],
- is_static=True)
## mpi-interface.h (module 'mpi'): static uint32_t ns3::MpiInterface::GetSize() [member function]
cls.add_method('GetSize',
'uint32_t',
@@ -841,31 +726,16 @@
'uint32_t',
[],
is_static=True)
- ## mpi-interface.h (module 'mpi'): static uint32_t ns3::MpiInterface::GetTxCount() [member function]
- cls.add_method('GetTxCount',
- 'uint32_t',
- [],
- is_static=True)
## mpi-interface.h (module 'mpi'): static bool ns3::MpiInterface::IsEnabled() [member function]
cls.add_method('IsEnabled',
'bool',
[],
is_static=True)
- ## mpi-interface.h (module 'mpi'): static void ns3::MpiInterface::ReceiveMessages() [member function]
- cls.add_method('ReceiveMessages',
- 'void',
- [],
- is_static=True)
## mpi-interface.h (module 'mpi'): static void ns3::MpiInterface::SendPacket(ns3::Ptr<ns3::Packet> p, ns3::Time const & rxTime, uint32_t node, uint32_t dev) [member function]
cls.add_method('SendPacket',
'void',
[param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Time const &', 'rxTime'), param('uint32_t', 'node'), param('uint32_t', 'dev')],
is_static=True)
- ## mpi-interface.h (module 'mpi'): static void ns3::MpiInterface::TestSendComplete() [member function]
- cls.add_method('TestSendComplete',
- 'void',
- [],
- is_static=True)
return
def register_Ns3ObjectBase_methods(root_module, cls):
@@ -941,42 +811,6 @@
is_static=True)
return
-def register_Ns3ObjectFactory_methods(root_module, cls):
- cls.add_output_stream_operator()
- ## object-factory.h (module 'core'): ns3::ObjectFactory::ObjectFactory(ns3::ObjectFactory const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::ObjectFactory const &', 'arg0')])
- ## object-factory.h (module 'core'): ns3::ObjectFactory::ObjectFactory() [constructor]
- cls.add_constructor([])
- ## object-factory.h (module 'core'): ns3::ObjectFactory::ObjectFactory(std::string typeId) [constructor]
- cls.add_constructor([param('std::string', 'typeId')])
- ## object-factory.h (module 'core'): ns3::Ptr<ns3::Object> ns3::ObjectFactory::Create() const [member function]
- cls.add_method('Create',
- 'ns3::Ptr< ns3::Object >',
- [],
- is_const=True)
- ## object-factory.h (module 'core'): ns3::TypeId ns3::ObjectFactory::GetTypeId() const [member function]
- cls.add_method('GetTypeId',
- 'ns3::TypeId',
- [],
- is_const=True)
- ## object-factory.h (module 'core'): void ns3::ObjectFactory::Set(std::string name, ns3::AttributeValue const & value) [member function]
- cls.add_method('Set',
- 'void',
- [param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')])
- ## object-factory.h (module 'core'): void ns3::ObjectFactory::SetTypeId(ns3::TypeId tid) [member function]
- cls.add_method('SetTypeId',
- 'void',
- [param('ns3::TypeId', 'tid')])
- ## object-factory.h (module 'core'): void ns3::ObjectFactory::SetTypeId(char const * tid) [member function]
- cls.add_method('SetTypeId',
- 'void',
- [param('char const *', 'tid')])
- ## object-factory.h (module 'core'): void ns3::ObjectFactory::SetTypeId(std::string tid) [member function]
- cls.add_method('SetTypeId',
- 'void',
- [param('std::string', 'tid')])
- return
-
def register_Ns3PacketMetadata_methods(root_module, cls):
## packet-metadata.h (module 'network'): ns3::PacketMetadata::PacketMetadata(uint64_t uid, uint32_t size) [constructor]
cls.add_constructor([param('uint64_t', 'uid'), param('uint32_t', 'size')])
@@ -1168,23 +1002,46 @@
cls.add_instance_attribute('tid', 'ns3::TypeId', is_const=False)
return
-def register_Ns3SentBuffer_methods(root_module, cls):
- ## mpi-interface.h (module 'mpi'): ns3::SentBuffer::SentBuffer(ns3::SentBuffer const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::SentBuffer const &', 'arg0')])
- ## mpi-interface.h (module 'mpi'): ns3::SentBuffer::SentBuffer() [constructor]
+def register_Ns3ParallelCommunicationInterface_methods(root_module, cls):
+ ## parallel-communication-interface.h (module 'mpi'): ns3::ParallelCommunicationInterface::ParallelCommunicationInterface() [constructor]
cls.add_constructor([])
- ## mpi-interface.h (module 'mpi'): uint8_t * ns3::SentBuffer::GetBuffer() [member function]
- cls.add_method('GetBuffer',
- 'uint8_t *',
- [])
- ## mpi-interface.h (module 'mpi'): MPI_Request * ns3::SentBuffer::GetRequest() [member function]
- cls.add_method('GetRequest',
- 'MPI_Request *',
- [])
- ## mpi-interface.h (module 'mpi'): void ns3::SentBuffer::SetBuffer(uint8_t * buffer) [member function]
- cls.add_method('SetBuffer',
+ ## parallel-communication-interface.h (module 'mpi'): ns3::ParallelCommunicationInterface::ParallelCommunicationInterface(ns3::ParallelCommunicationInterface const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::ParallelCommunicationInterface const &', 'arg0')])
+ ## parallel-communication-interface.h (module 'mpi'): void ns3::ParallelCommunicationInterface::Destroy() [member function]
+ cls.add_method('Destroy',
+ 'void',
+ [],
+ is_pure_virtual=True, is_virtual=True)
+ ## parallel-communication-interface.h (module 'mpi'): void ns3::ParallelCommunicationInterface::Disable() [member function]
+ cls.add_method('Disable',
+ 'void',
+ [],
+ is_pure_virtual=True, is_virtual=True)
+ ## parallel-communication-interface.h (module 'mpi'): void ns3::ParallelCommunicationInterface::Enable(int * pargc, char * * * pargv) [member function]
+ cls.add_method('Enable',
'void',
- [param('uint8_t *', 'buffer')])
+ [param('int *', 'pargc'), param('char * * *', 'pargv')],
+ is_pure_virtual=True, is_virtual=True)
+ ## parallel-communication-interface.h (module 'mpi'): uint32_t ns3::ParallelCommunicationInterface::GetSize() [member function]
+ cls.add_method('GetSize',
+ 'uint32_t',
+ [],
+ is_pure_virtual=True, is_virtual=True)
+ ## parallel-communication-interface.h (module 'mpi'): uint32_t ns3::ParallelCommunicationInterface::GetSystemId() [member function]
+ cls.add_method('GetSystemId',
+ 'uint32_t',
+ [],
+ is_pure_virtual=True, is_virtual=True)
+ ## parallel-communication-interface.h (module 'mpi'): bool ns3::ParallelCommunicationInterface::IsEnabled() [member function]
+ cls.add_method('IsEnabled',
+ 'bool',
+ [],
+ is_pure_virtual=True, is_virtual=True)
+ ## parallel-communication-interface.h (module 'mpi'): void ns3::ParallelCommunicationInterface::SendPacket(ns3::Ptr<ns3::Packet> p, ns3::Time const & rxTime, uint32_t node, uint32_t dev) [member function]
+ cls.add_method('SendPacket',
+ 'void',
+ [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Time const &', 'rxTime'), param('uint32_t', 'node'), param('uint32_t', 'dev')],
+ is_pure_virtual=True, is_virtual=True)
return
def register_Ns3SimpleRefCount__Ns3Object_Ns3ObjectBase_Ns3ObjectDeleter_methods(root_module, cls):
@@ -1718,71 +1575,6 @@
[])
return
-def register_Ns3Scheduler_methods(root_module, cls):
- ## scheduler.h (module 'core'): ns3::Scheduler::Scheduler() [constructor]
- cls.add_constructor([])
- ## scheduler.h (module 'core'): ns3::Scheduler::Scheduler(ns3::Scheduler const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::Scheduler const &', 'arg0')])
- ## scheduler.h (module 'core'): static ns3::TypeId ns3::Scheduler::GetTypeId() [member function]
- cls.add_method('GetTypeId',
- 'ns3::TypeId',
- [],
- is_static=True)
- ## scheduler.h (module 'core'): void ns3::Scheduler::Insert(ns3::Scheduler::Event const & ev) [member function]
- cls.add_method('Insert',
- 'void',
- [param('ns3::Scheduler::Event const &', 'ev')],
- is_pure_virtual=True, is_virtual=True)
- ## scheduler.h (module 'core'): bool ns3::Scheduler::IsEmpty() const [member function]
- cls.add_method('IsEmpty',
- 'bool',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## scheduler.h (module 'core'): ns3::Scheduler::Event ns3::Scheduler::PeekNext() const [member function]
- cls.add_method('PeekNext',
- 'ns3::Scheduler::Event',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## scheduler.h (module 'core'): void ns3::Scheduler::Remove(ns3::Scheduler::Event const & ev) [member function]
- cls.add_method('Remove',
- 'void',
- [param('ns3::Scheduler::Event const &', 'ev')],
- is_pure_virtual=True, is_virtual=True)
- ## scheduler.h (module 'core'): ns3::Scheduler::Event ns3::Scheduler::RemoveNext() [member function]
- cls.add_method('RemoveNext',
- 'ns3::Scheduler::Event',
- [],
- is_pure_virtual=True, is_virtual=True)
- return
-
-def register_Ns3SchedulerEvent_methods(root_module, cls):
- cls.add_binary_comparison_operator('<')
- ## scheduler.h (module 'core'): ns3::Scheduler::Event::Event() [constructor]
- cls.add_constructor([])
- ## scheduler.h (module 'core'): ns3::Scheduler::Event::Event(ns3::Scheduler::Event const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::Scheduler::Event const &', 'arg0')])
- ## scheduler.h (module 'core'): ns3::Scheduler::Event::impl [variable]
- cls.add_instance_attribute('impl', 'ns3::EventImpl *', is_const=False)
- ## scheduler.h (module 'core'): ns3::Scheduler::Event::key [variable]
- cls.add_instance_attribute('key', 'ns3::Scheduler::EventKey', is_const=False)
- return
-
-def register_Ns3SchedulerEventKey_methods(root_module, cls):
- cls.add_binary_comparison_operator('<')
- cls.add_binary_comparison_operator('>')
- cls.add_binary_comparison_operator('!=')
- ## scheduler.h (module 'core'): ns3::Scheduler::EventKey::EventKey() [constructor]
- cls.add_constructor([])
- ## scheduler.h (module 'core'): ns3::Scheduler::EventKey::EventKey(ns3::Scheduler::EventKey const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::Scheduler::EventKey const &', 'arg0')])
- ## scheduler.h (module 'core'): ns3::Scheduler::EventKey::m_context [variable]
- cls.add_instance_attribute('m_context', 'uint32_t', is_const=False)
- ## scheduler.h (module 'core'): ns3::Scheduler::EventKey::m_ts [variable]
- cls.add_instance_attribute('m_ts', 'uint64_t', is_const=False)
- ## scheduler.h (module 'core'): ns3::Scheduler::EventKey::m_uid [variable]
- cls.add_instance_attribute('m_uid', 'uint32_t', is_const=False)
- return
-
def register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, cls):
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >::SimpleRefCount() [constructor]
cls.add_constructor([])
@@ -1831,18 +1623,6 @@
is_static=True)
return
-def register_Ns3SimpleRefCount__Ns3EventImpl_Ns3Empty_Ns3DefaultDeleter__lt__ns3EventImpl__gt___methods(root_module, cls):
- ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> >::SimpleRefCount() [constructor]
- cls.add_constructor([])
- ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> >::SimpleRefCount(ns3::SimpleRefCount<ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> > const & o) [copy constructor]
- cls.add_constructor([param('ns3::SimpleRefCount< ns3::EventImpl, ns3::empty, ns3::DefaultDeleter< ns3::EventImpl > > const &', 'o')])
- ## simple-ref-count.h (module 'core'): static void ns3::SimpleRefCount<ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> >::Cleanup() [member function]
- cls.add_method('Cleanup',
- 'void',
- [],
- is_static=True)
- return
-
def register_Ns3SimpleRefCount__Ns3HashImplementation_Ns3Empty_Ns3DefaultDeleter__lt__ns3HashImplementation__gt___methods(root_module, cls):
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::Hash::Implementation, ns3::empty, ns3::DefaultDeleter<ns3::Hash::Implementation> >::SimpleRefCount() [constructor]
cls.add_constructor([])
@@ -1891,108 +1671,6 @@
is_static=True)
return
-def register_Ns3SimulatorImpl_methods(root_module, cls):
- ## simulator-impl.h (module 'core'): ns3::SimulatorImpl::SimulatorImpl() [constructor]
- cls.add_constructor([])
- ## simulator-impl.h (module 'core'): ns3::SimulatorImpl::SimulatorImpl(ns3::SimulatorImpl const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::SimulatorImpl const &', 'arg0')])
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::Cancel(ns3::EventId const & ev) [member function]
- cls.add_method('Cancel',
- 'void',
- [param('ns3::EventId const &', 'ev')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::Destroy() [member function]
- cls.add_method('Destroy',
- 'void',
- [],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): uint32_t ns3::SimulatorImpl::GetContext() const [member function]
- cls.add_method('GetContext',
- 'uint32_t',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): ns3::Time ns3::SimulatorImpl::GetDelayLeft(ns3::EventId const & id) const [member function]
- cls.add_method('GetDelayLeft',
- 'ns3::Time',
- [param('ns3::EventId const &', 'id')],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): ns3::Time ns3::SimulatorImpl::GetMaximumSimulationTime() const [member function]
- cls.add_method('GetMaximumSimulationTime',
- 'ns3::Time',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): uint32_t ns3::SimulatorImpl::GetSystemId() const [member function]
- cls.add_method('GetSystemId',
- 'uint32_t',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): static ns3::TypeId ns3::SimulatorImpl::GetTypeId() [member function]
- cls.add_method('GetTypeId',
- 'ns3::TypeId',
- [],
- is_static=True)
- ## simulator-impl.h (module 'core'): bool ns3::SimulatorImpl::IsExpired(ns3::EventId const & ev) const [member function]
- cls.add_method('IsExpired',
- 'bool',
- [param('ns3::EventId const &', 'ev')],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): bool ns3::SimulatorImpl::IsFinished() const [member function]
- cls.add_method('IsFinished',
- 'bool',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): ns3::Time ns3::SimulatorImpl::Now() const [member function]
- cls.add_method('Now',
- 'ns3::Time',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::Remove(ns3::EventId const & ev) [member function]
- cls.add_method('Remove',
- 'void',
- [param('ns3::EventId const &', 'ev')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::Run() [member function]
- cls.add_method('Run',
- 'void',
- [],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): ns3::EventId ns3::SimulatorImpl::Schedule(ns3::Time const & time, ns3::EventImpl * event) [member function]
- cls.add_method('Schedule',
- 'ns3::EventId',
- [param('ns3::Time const &', 'time'), param('ns3::EventImpl *', 'event')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): ns3::EventId ns3::SimulatorImpl::ScheduleDestroy(ns3::EventImpl * event) [member function]
- cls.add_method('ScheduleDestroy',
- 'ns3::EventId',
- [param('ns3::EventImpl *', 'event')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): ns3::EventId ns3::SimulatorImpl::ScheduleNow(ns3::EventImpl * event) [member function]
- cls.add_method('ScheduleNow',
- 'ns3::EventId',
- [param('ns3::EventImpl *', 'event')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::ScheduleWithContext(uint32_t context, ns3::Time const & time, ns3::EventImpl * event) [member function]
- cls.add_method('ScheduleWithContext',
- 'void',
- [param('uint32_t', 'context'), param('ns3::Time const &', 'time'), param('ns3::EventImpl *', 'event')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::SetScheduler(ns3::ObjectFactory schedulerFactory) [member function]
- cls.add_method('SetScheduler',
- 'void',
- [param('ns3::ObjectFactory', 'schedulerFactory')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::Stop() [member function]
- cls.add_method('Stop',
- 'void',
- [],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::Stop(ns3::Time const & time) [member function]
- cls.add_method('Stop',
- 'void',
- [param('ns3::Time const &', 'time')],
- is_pure_virtual=True, is_virtual=True)
- return
-
def register_Ns3Time_methods(root_module, cls):
cls.add_binary_numeric_operator('+', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right'))
cls.add_binary_numeric_operator('-', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right'))
@@ -2052,6 +1730,11 @@
'ns3::Time',
[param('uint64_t', 'value'), param('ns3::Time::Unit', 'timeUnit')],
is_static=True)
+ ## nstime.h (module 'core'): double ns3::Time::GetDays() const [member function]
+ cls.add_method('GetDays',
+ 'double',
+ [],
+ is_const=True)
## nstime.h (module 'core'): double ns3::Time::GetDouble() const [member function]
cls.add_method('GetDouble',
'double',
@@ -2062,6 +1745,11 @@
'int64_t',
[],
is_const=True)
+ ## nstime.h (module 'core'): double ns3::Time::GetHours() const [member function]
+ cls.add_method('GetHours',
+ 'double',
+ [],
+ is_const=True)
## nstime.h (module 'core'): int64_t ns3::Time::GetInteger() const [member function]
cls.add_method('GetInteger',
'int64_t',
@@ -2077,6 +1765,11 @@
'int64_t',
[],
is_const=True)
+ ## nstime.h (module 'core'): double ns3::Time::GetMinutes() const [member function]
+ cls.add_method('GetMinutes',
+ 'double',
+ [],
+ is_const=True)
## nstime.h (module 'core'): int64_t ns3::Time::GetNanoSeconds() const [member function]
cls.add_method('GetNanoSeconds',
'int64_t',
@@ -2102,6 +1795,11 @@
'int64_t',
[],
is_const=True)
+ ## nstime.h (module 'core'): double ns3::Time::GetYears() const [member function]
+ cls.add_method('GetYears',
+ 'double',
+ [],
+ is_const=True)
## nstime.h (module 'core'): bool ns3::Time::IsNegative() const [member function]
cls.add_method('IsNegative',
'bool',
@@ -2362,113 +2060,6 @@
[param('ns3::CallbackBase', 'base')])
return
-def register_Ns3DistributedSimulatorImpl_methods(root_module, cls):
- ## distributed-simulator-impl.h (module 'mpi'): ns3::DistributedSimulatorImpl::DistributedSimulatorImpl(ns3::DistributedSimulatorImpl const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::DistributedSimulatorImpl const &', 'arg0')])
- ## distributed-simulator-impl.h (module 'mpi'): ns3::DistributedSimulatorImpl::DistributedSimulatorImpl() [constructor]
- cls.add_constructor([])
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::Cancel(ns3::EventId const & ev) [member function]
- cls.add_method('Cancel',
- 'void',
- [param('ns3::EventId const &', 'ev')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::Destroy() [member function]
- cls.add_method('Destroy',
- 'void',
- [],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): uint32_t ns3::DistributedSimulatorImpl::GetContext() const [member function]
- cls.add_method('GetContext',
- 'uint32_t',
- [],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): ns3::Time ns3::DistributedSimulatorImpl::GetDelayLeft(ns3::EventId const & id) const [member function]
- cls.add_method('GetDelayLeft',
- 'ns3::Time',
- [param('ns3::EventId const &', 'id')],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): ns3::Time ns3::DistributedSimulatorImpl::GetMaximumSimulationTime() const [member function]
- cls.add_method('GetMaximumSimulationTime',
- 'ns3::Time',
- [],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): uint32_t ns3::DistributedSimulatorImpl::GetSystemId() const [member function]
- cls.add_method('GetSystemId',
- 'uint32_t',
- [],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): static ns3::TypeId ns3::DistributedSimulatorImpl::GetTypeId() [member function]
- cls.add_method('GetTypeId',
- 'ns3::TypeId',
- [],
- is_static=True)
- ## distributed-simulator-impl.h (module 'mpi'): bool ns3::DistributedSimulatorImpl::IsExpired(ns3::EventId const & ev) const [member function]
- cls.add_method('IsExpired',
- 'bool',
- [param('ns3::EventId const &', 'ev')],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): bool ns3::DistributedSimulatorImpl::IsFinished() const [member function]
- cls.add_method('IsFinished',
- 'bool',
- [],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): ns3::Time ns3::DistributedSimulatorImpl::Now() const [member function]
- cls.add_method('Now',
- 'ns3::Time',
- [],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::Remove(ns3::EventId const & ev) [member function]
- cls.add_method('Remove',
- 'void',
- [param('ns3::EventId const &', 'ev')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::Run() [member function]
- cls.add_method('Run',
- 'void',
- [],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): ns3::EventId ns3::DistributedSimulatorImpl::Schedule(ns3::Time const & time, ns3::EventImpl * event) [member function]
- cls.add_method('Schedule',
- 'ns3::EventId',
- [param('ns3::Time const &', 'time'), param('ns3::EventImpl *', 'event')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): ns3::EventId ns3::DistributedSimulatorImpl::ScheduleDestroy(ns3::EventImpl * event) [member function]
- cls.add_method('ScheduleDestroy',
- 'ns3::EventId',
- [param('ns3::EventImpl *', 'event')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): ns3::EventId ns3::DistributedSimulatorImpl::ScheduleNow(ns3::EventImpl * event) [member function]
- cls.add_method('ScheduleNow',
- 'ns3::EventId',
- [param('ns3::EventImpl *', 'event')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::ScheduleWithContext(uint32_t context, ns3::Time const & time, ns3::EventImpl * event) [member function]
- cls.add_method('ScheduleWithContext',
- 'void',
- [param('uint32_t', 'context'), param('ns3::Time const &', 'time'), param('ns3::EventImpl *', 'event')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::SetScheduler(ns3::ObjectFactory schedulerFactory) [member function]
- cls.add_method('SetScheduler',
- 'void',
- [param('ns3::ObjectFactory', 'schedulerFactory')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::Stop() [member function]
- cls.add_method('Stop',
- 'void',
- [],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::Stop(ns3::Time const & time) [member function]
- cls.add_method('Stop',
- 'void',
- [param('ns3::Time const &', 'time')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::DoDispose() [member function]
- cls.add_method('DoDispose',
- 'void',
- [],
- visibility='private', is_virtual=True)
- return
-
def register_Ns3EmptyAttributeValue_methods(root_module, cls):
## attribute.h (module 'core'): ns3::EmptyAttributeValue::EmptyAttributeValue(ns3::EmptyAttributeValue const & arg0) [copy constructor]
cls.add_constructor([param('ns3::EmptyAttributeValue const &', 'arg0')])
@@ -2491,30 +2082,6 @@
is_const=True, visibility='private', is_virtual=True)
return
-def register_Ns3EventImpl_methods(root_module, cls):
- ## event-impl.h (module 'core'): ns3::EventImpl::EventImpl(ns3::EventImpl const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::EventImpl const &', 'arg0')])
- ## event-impl.h (module 'core'): ns3::EventImpl::EventImpl() [constructor]
- cls.add_constructor([])
- ## event-impl.h (module 'core'): void ns3::EventImpl::Cancel() [member function]
- cls.add_method('Cancel',
- 'void',
- [])
- ## event-impl.h (module 'core'): void ns3::EventImpl::Invoke() [member function]
- cls.add_method('Invoke',
- 'void',
- [])
- ## event-impl.h (module 'core'): bool ns3::EventImpl::IsCancelled() [member function]
- cls.add_method('IsCancelled',
- 'bool',
- [])
- ## event-impl.h (module 'core'): void ns3::EventImpl::Notify() [member function]
- cls.add_method('Notify',
- 'void',
- [],
- is_pure_virtual=True, visibility='protected', is_virtual=True)
- return
-
def register_Ns3MpiReceiver_methods(root_module, cls):
## mpi-receiver.h (module 'mpi'): ns3::MpiReceiver::MpiReceiver() [constructor]
cls.add_constructor([])
@@ -2584,46 +2151,6 @@
is_const=True)
return
-def register_Ns3ObjectFactoryChecker_methods(root_module, cls):
- ## object-factory.h (module 'core'): ns3::ObjectFactoryChecker::ObjectFactoryChecker() [constructor]
- cls.add_constructor([])
- ## object-factory.h (module 'core'): ns3::ObjectFactoryChecker::ObjectFactoryChecker(ns3::ObjectFactoryChecker const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::ObjectFactoryChecker const &', 'arg0')])
- return
-
-def register_Ns3ObjectFactoryValue_methods(root_module, cls):
- ## object-factory.h (module 'core'): ns3::ObjectFactoryValue::ObjectFactoryValue() [constructor]
- cls.add_constructor([])
- ## object-factory.h (module 'core'): ns3::ObjectFactoryValue::ObjectFactoryValue(ns3::ObjectFactoryValue const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::ObjectFactoryValue const &', 'arg0')])
- ## object-factory.h (module 'core'): ns3::ObjectFactoryValue::ObjectFactoryValue(ns3::ObjectFactory const & value) [constructor]
- cls.add_constructor([param('ns3::ObjectFactory const &', 'value')])
- ## object-factory.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::ObjectFactoryValue::Copy() const [member function]
- cls.add_method('Copy',
- 'ns3::Ptr< ns3::AttributeValue >',
- [],
- is_const=True, is_virtual=True)
- ## object-factory.h (module 'core'): bool ns3::ObjectFactoryValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
- cls.add_method('DeserializeFromString',
- 'bool',
- [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
- is_virtual=True)
- ## object-factory.h (module 'core'): ns3::ObjectFactory ns3::ObjectFactoryValue::Get() const [member function]
- cls.add_method('Get',
- 'ns3::ObjectFactory',
- [],
- is_const=True)
- ## object-factory.h (module 'core'): std::string ns3::ObjectFactoryValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
- cls.add_method('SerializeToString',
- 'std::string',
- [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
- is_const=True, is_virtual=True)
- ## object-factory.h (module 'core'): void ns3::ObjectFactoryValue::Set(ns3::ObjectFactory const & value) [member function]
- cls.add_method('Set',
- 'void',
- [param('ns3::ObjectFactory const &', 'value')])
- return
-
def register_Ns3Packet_methods(root_module, cls):
cls.add_output_stream_operator()
## packet.h (module 'network'): ns3::Packet::Packet() [constructor]
--- a/src/mpi/bindings/modulegen__gcc_LP64.py Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/bindings/modulegen__gcc_LP64.py Fri Dec 06 14:57:33 2013 -0500
@@ -40,20 +40,14 @@
module.add_class('Item', import_from_module='ns.network', outer_class=root_module['ns3::ByteTagList::Iterator'])
## callback.h (module 'core'): ns3::CallbackBase [class]
module.add_class('CallbackBase', import_from_module='ns.core')
- ## event-id.h (module 'core'): ns3::EventId [class]
- module.add_class('EventId', import_from_module='ns.core')
## hash.h (module 'core'): ns3::Hasher [class]
module.add_class('Hasher', import_from_module='ns.core')
- ## distributed-simulator-impl.h (module 'mpi'): ns3::LbtsMessage [class]
- module.add_class('LbtsMessage')
## mpi-interface.h (module 'mpi'): ns3::MpiInterface [class]
module.add_class('MpiInterface')
## object-base.h (module 'core'): ns3::ObjectBase [class]
module.add_class('ObjectBase', allow_subclassing=True, import_from_module='ns.core')
## object.h (module 'core'): ns3::ObjectDeleter [struct]
module.add_class('ObjectDeleter', import_from_module='ns.core')
- ## object-factory.h (module 'core'): ns3::ObjectFactory [class]
- module.add_class('ObjectFactory', import_from_module='ns.core')
## packet-metadata.h (module 'network'): ns3::PacketMetadata [class]
module.add_class('PacketMetadata', import_from_module='ns.network')
## packet-metadata.h (module 'network'): ns3::PacketMetadata::Item [struct]
@@ -72,8 +66,8 @@
module.add_class('TagData', import_from_module='ns.network', outer_class=root_module['ns3::PacketTagList'])
## packet-tag-list.h (module 'network'): ns3::PacketTagList::TagData::TagData_e [enumeration]
module.add_enum('TagData_e', ['MAX_SIZE'], outer_class=root_module['ns3::PacketTagList::TagData'], import_from_module='ns.network')
- ## mpi-interface.h (module 'mpi'): ns3::SentBuffer [class]
- module.add_class('SentBuffer')
+ ## parallel-communication-interface.h (module 'mpi'): ns3::ParallelCommunicationInterface [class]
+ module.add_class('ParallelCommunicationInterface', allow_subclassing=True)
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::Object, ns3::ObjectBase, ns3::ObjectDeleter> [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::Object', 'ns3::ObjectBase', 'ns3::ObjectDeleter'], parent=root_module['ns3::ObjectBase'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## tag.h (module 'network'): ns3::Tag [class]
@@ -100,12 +94,6 @@
module.add_class('Object', import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::Object, ns3::ObjectBase, ns3::ObjectDeleter >'])
## object.h (module 'core'): ns3::Object::AggregateIterator [class]
module.add_class('AggregateIterator', import_from_module='ns.core', outer_class=root_module['ns3::Object'])
- ## scheduler.h (module 'core'): ns3::Scheduler [class]
- module.add_class('Scheduler', import_from_module='ns.core', parent=root_module['ns3::Object'])
- ## scheduler.h (module 'core'): ns3::Scheduler::Event [struct]
- module.add_class('Event', import_from_module='ns.core', outer_class=root_module['ns3::Scheduler'])
- ## scheduler.h (module 'core'): ns3::Scheduler::EventKey [struct]
- module.add_class('EventKey', import_from_module='ns.core', outer_class=root_module['ns3::Scheduler'])
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::AttributeAccessor', 'ns3::empty', 'ns3::DefaultDeleter<ns3::AttributeAccessor>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> > [class]
@@ -114,8 +102,6 @@
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::AttributeValue', 'ns3::empty', 'ns3::DefaultDeleter<ns3::AttributeValue>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::CallbackImplBase, ns3::empty, ns3::DefaultDeleter<ns3::CallbackImplBase> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::CallbackImplBase', 'ns3::empty', 'ns3::DefaultDeleter<ns3::CallbackImplBase>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
- ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> > [class]
- module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::EventImpl', 'ns3::empty', 'ns3::DefaultDeleter<ns3::EventImpl>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::Hash::Implementation, ns3::empty, ns3::DefaultDeleter<ns3::Hash::Implementation> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::Hash::Implementation', 'ns3::empty', 'ns3::DefaultDeleter<ns3::Hash::Implementation>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::NixVector, ns3::empty, ns3::DefaultDeleter<ns3::NixVector> > [class]
@@ -124,12 +110,10 @@
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::Packet', 'ns3::empty', 'ns3::DefaultDeleter<ns3::Packet>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::TraceSourceAccessor, ns3::empty, ns3::DefaultDeleter<ns3::TraceSourceAccessor> > [class]
module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::TraceSourceAccessor', 'ns3::empty', 'ns3::DefaultDeleter<ns3::TraceSourceAccessor>'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount'))
- ## simulator-impl.h (module 'core'): ns3::SimulatorImpl [class]
- module.add_class('SimulatorImpl', import_from_module='ns.core', parent=root_module['ns3::Object'])
## nstime.h (module 'core'): ns3::Time [class]
module.add_class('Time', import_from_module='ns.core')
## nstime.h (module 'core'): ns3::Time::Unit [enumeration]
- module.add_enum('Unit', ['S', 'MS', 'US', 'NS', 'PS', 'FS', 'LAST'], outer_class=root_module['ns3::Time'], import_from_module='ns.core')
+ module.add_enum('Unit', ['Y', 'D', 'H', 'MIN', 'S', 'MS', 'US', 'NS', 'PS', 'FS', 'LAST'], outer_class=root_module['ns3::Time'], import_from_module='ns.core')
## nstime.h (module 'core'): ns3::Time [class]
root_module['ns3::Time'].implicitly_converts_to(root_module['ns3::int64x64_t'])
## trace-source-accessor.h (module 'core'): ns3::TraceSourceAccessor [class]
@@ -148,20 +132,12 @@
module.add_class('CallbackImplBase', import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::CallbackImplBase, ns3::empty, ns3::DefaultDeleter<ns3::CallbackImplBase> >'])
## callback.h (module 'core'): ns3::CallbackValue [class]
module.add_class('CallbackValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
- ## distributed-simulator-impl.h (module 'mpi'): ns3::DistributedSimulatorImpl [class]
- module.add_class('DistributedSimulatorImpl', parent=root_module['ns3::SimulatorImpl'])
## attribute.h (module 'core'): ns3::EmptyAttributeValue [class]
module.add_class('EmptyAttributeValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
- ## event-impl.h (module 'core'): ns3::EventImpl [class]
- module.add_class('EventImpl', import_from_module='ns.core', parent=root_module['ns3::SimpleRefCount< ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> >'])
## mpi-receiver.h (module 'mpi'): ns3::MpiReceiver [class]
module.add_class('MpiReceiver', parent=root_module['ns3::Object'])
## nix-vector.h (module 'network'): ns3::NixVector [class]
module.add_class('NixVector', import_from_module='ns.network', parent=root_module['ns3::SimpleRefCount< ns3::NixVector, ns3::empty, ns3::DefaultDeleter<ns3::NixVector> >'])
- ## object-factory.h (module 'core'): ns3::ObjectFactoryChecker [class]
- module.add_class('ObjectFactoryChecker', import_from_module='ns.core', parent=root_module['ns3::AttributeChecker'])
- ## object-factory.h (module 'core'): ns3::ObjectFactoryValue [class]
- module.add_class('ObjectFactoryValue', import_from_module='ns.core', parent=root_module['ns3::AttributeValue'])
## packet.h (module 'network'): ns3::Packet [class]
module.add_class('Packet', import_from_module='ns.network', parent=root_module['ns3::SimpleRefCount< ns3::Packet, ns3::empty, ns3::DefaultDeleter<ns3::Packet> >'])
## nstime.h (module 'core'): ns3::TimeValue [class]
@@ -228,13 +204,10 @@
register_Ns3ByteTagListIterator_methods(root_module, root_module['ns3::ByteTagList::Iterator'])
register_Ns3ByteTagListIteratorItem_methods(root_module, root_module['ns3::ByteTagList::Iterator::Item'])
register_Ns3CallbackBase_methods(root_module, root_module['ns3::CallbackBase'])
- register_Ns3EventId_methods(root_module, root_module['ns3::EventId'])
register_Ns3Hasher_methods(root_module, root_module['ns3::Hasher'])
- register_Ns3LbtsMessage_methods(root_module, root_module['ns3::LbtsMessage'])
register_Ns3MpiInterface_methods(root_module, root_module['ns3::MpiInterface'])
register_Ns3ObjectBase_methods(root_module, root_module['ns3::ObjectBase'])
register_Ns3ObjectDeleter_methods(root_module, root_module['ns3::ObjectDeleter'])
- register_Ns3ObjectFactory_methods(root_module, root_module['ns3::ObjectFactory'])
register_Ns3PacketMetadata_methods(root_module, root_module['ns3::PacketMetadata'])
register_Ns3PacketMetadataItem_methods(root_module, root_module['ns3::PacketMetadata::Item'])
register_Ns3PacketMetadataItemIterator_methods(root_module, root_module['ns3::PacketMetadata::ItemIterator'])
@@ -242,7 +215,7 @@
register_Ns3PacketTagIteratorItem_methods(root_module, root_module['ns3::PacketTagIterator::Item'])
register_Ns3PacketTagList_methods(root_module, root_module['ns3::PacketTagList'])
register_Ns3PacketTagListTagData_methods(root_module, root_module['ns3::PacketTagList::TagData'])
- register_Ns3SentBuffer_methods(root_module, root_module['ns3::SentBuffer'])
+ register_Ns3ParallelCommunicationInterface_methods(root_module, root_module['ns3::ParallelCommunicationInterface'])
register_Ns3SimpleRefCount__Ns3Object_Ns3ObjectBase_Ns3ObjectDeleter_methods(root_module, root_module['ns3::SimpleRefCount< ns3::Object, ns3::ObjectBase, ns3::ObjectDeleter >'])
register_Ns3Tag_methods(root_module, root_module['ns3::Tag'])
register_Ns3TagBuffer_methods(root_module, root_module['ns3::TagBuffer'])
@@ -255,19 +228,14 @@
register_Ns3Header_methods(root_module, root_module['ns3::Header'])
register_Ns3Object_methods(root_module, root_module['ns3::Object'])
register_Ns3ObjectAggregateIterator_methods(root_module, root_module['ns3::Object::AggregateIterator'])
- register_Ns3Scheduler_methods(root_module, root_module['ns3::Scheduler'])
- register_Ns3SchedulerEvent_methods(root_module, root_module['ns3::Scheduler::Event'])
- register_Ns3SchedulerEventKey_methods(root_module, root_module['ns3::Scheduler::EventKey'])
register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >'])
register_Ns3SimpleRefCount__Ns3AttributeChecker_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeChecker__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeChecker, ns3::empty, ns3::DefaultDeleter<ns3::AttributeChecker> >'])
register_Ns3SimpleRefCount__Ns3AttributeValue_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeValue__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::AttributeValue, ns3::empty, ns3::DefaultDeleter<ns3::AttributeValue> >'])
register_Ns3SimpleRefCount__Ns3CallbackImplBase_Ns3Empty_Ns3DefaultDeleter__lt__ns3CallbackImplBase__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::CallbackImplBase, ns3::empty, ns3::DefaultDeleter<ns3::CallbackImplBase> >'])
- register_Ns3SimpleRefCount__Ns3EventImpl_Ns3Empty_Ns3DefaultDeleter__lt__ns3EventImpl__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> >'])
register_Ns3SimpleRefCount__Ns3HashImplementation_Ns3Empty_Ns3DefaultDeleter__lt__ns3HashImplementation__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::Hash::Implementation, ns3::empty, ns3::DefaultDeleter<ns3::Hash::Implementation> >'])
register_Ns3SimpleRefCount__Ns3NixVector_Ns3Empty_Ns3DefaultDeleter__lt__ns3NixVector__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::NixVector, ns3::empty, ns3::DefaultDeleter<ns3::NixVector> >'])
register_Ns3SimpleRefCount__Ns3Packet_Ns3Empty_Ns3DefaultDeleter__lt__ns3Packet__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::Packet, ns3::empty, ns3::DefaultDeleter<ns3::Packet> >'])
register_Ns3SimpleRefCount__Ns3TraceSourceAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3TraceSourceAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::TraceSourceAccessor, ns3::empty, ns3::DefaultDeleter<ns3::TraceSourceAccessor> >'])
- register_Ns3SimulatorImpl_methods(root_module, root_module['ns3::SimulatorImpl'])
register_Ns3Time_methods(root_module, root_module['ns3::Time'])
register_Ns3TraceSourceAccessor_methods(root_module, root_module['ns3::TraceSourceAccessor'])
register_Ns3Trailer_methods(root_module, root_module['ns3::Trailer'])
@@ -277,13 +245,9 @@
register_Ns3CallbackChecker_methods(root_module, root_module['ns3::CallbackChecker'])
register_Ns3CallbackImplBase_methods(root_module, root_module['ns3::CallbackImplBase'])
register_Ns3CallbackValue_methods(root_module, root_module['ns3::CallbackValue'])
- register_Ns3DistributedSimulatorImpl_methods(root_module, root_module['ns3::DistributedSimulatorImpl'])
register_Ns3EmptyAttributeValue_methods(root_module, root_module['ns3::EmptyAttributeValue'])
- register_Ns3EventImpl_methods(root_module, root_module['ns3::EventImpl'])
register_Ns3MpiReceiver_methods(root_module, root_module['ns3::MpiReceiver'])
register_Ns3NixVector_methods(root_module, root_module['ns3::NixVector'])
- register_Ns3ObjectFactoryChecker_methods(root_module, root_module['ns3::ObjectFactoryChecker'])
- register_Ns3ObjectFactoryValue_methods(root_module, root_module['ns3::ObjectFactoryValue'])
register_Ns3Packet_methods(root_module, root_module['ns3::Packet'])
register_Ns3TimeValue_methods(root_module, root_module['ns3::TimeValue'])
register_Ns3TypeIdChecker_methods(root_module, root_module['ns3::TypeIdChecker'])
@@ -703,51 +667,6 @@
is_static=True, visibility='protected')
return
-def register_Ns3EventId_methods(root_module, cls):
- cls.add_binary_comparison_operator('!=')
- cls.add_binary_comparison_operator('==')
- ## event-id.h (module 'core'): ns3::EventId::EventId(ns3::EventId const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::EventId const &', 'arg0')])
- ## event-id.h (module 'core'): ns3::EventId::EventId() [constructor]
- cls.add_constructor([])
- ## event-id.h (module 'core'): ns3::EventId::EventId(ns3::Ptr<ns3::EventImpl> const & impl, uint64_t ts, uint32_t context, uint32_t uid) [constructor]
- cls.add_constructor([param('ns3::Ptr< ns3::EventImpl > const &', 'impl'), param('uint64_t', 'ts'), param('uint32_t', 'context'), param('uint32_t', 'uid')])
- ## event-id.h (module 'core'): void ns3::EventId::Cancel() [member function]
- cls.add_method('Cancel',
- 'void',
- [])
- ## event-id.h (module 'core'): uint32_t ns3::EventId::GetContext() const [member function]
- cls.add_method('GetContext',
- 'uint32_t',
- [],
- is_const=True)
- ## event-id.h (module 'core'): uint64_t ns3::EventId::GetTs() const [member function]
- cls.add_method('GetTs',
- 'uint64_t',
- [],
- is_const=True)
- ## event-id.h (module 'core'): uint32_t ns3::EventId::GetUid() const [member function]
- cls.add_method('GetUid',
- 'uint32_t',
- [],
- is_const=True)
- ## event-id.h (module 'core'): bool ns3::EventId::IsExpired() const [member function]
- cls.add_method('IsExpired',
- 'bool',
- [],
- is_const=True)
- ## event-id.h (module 'core'): bool ns3::EventId::IsRunning() const [member function]
- cls.add_method('IsRunning',
- 'bool',
- [],
- is_const=True)
- ## event-id.h (module 'core'): ns3::EventImpl * ns3::EventId::PeekEventImpl() const [member function]
- cls.add_method('PeekEventImpl',
- 'ns3::EventImpl *',
- [],
- is_const=True)
- return
-
def register_Ns3Hasher_methods(root_module, cls):
## hash.h (module 'core'): ns3::Hasher::Hasher(ns3::Hasher const & arg0) [copy constructor]
cls.add_constructor([param('ns3::Hasher const &', 'arg0')])
@@ -777,35 +696,6 @@
[])
return
-def register_Ns3LbtsMessage_methods(root_module, cls):
- ## distributed-simulator-impl.h (module 'mpi'): ns3::LbtsMessage::LbtsMessage(ns3::LbtsMessage const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::LbtsMessage const &', 'arg0')])
- ## distributed-simulator-impl.h (module 'mpi'): ns3::LbtsMessage::LbtsMessage() [constructor]
- cls.add_constructor([])
- ## distributed-simulator-impl.h (module 'mpi'): ns3::LbtsMessage::LbtsMessage(uint32_t rxc, uint32_t txc, uint32_t id, bool isFinished, ns3::Time const & t) [constructor]
- cls.add_constructor([param('uint32_t', 'rxc'), param('uint32_t', 'txc'), param('uint32_t', 'id'), param('bool', 'isFinished'), param('ns3::Time const &', 't')])
- ## distributed-simulator-impl.h (module 'mpi'): uint32_t ns3::LbtsMessage::GetMyId() [member function]
- cls.add_method('GetMyId',
- 'uint32_t',
- [])
- ## distributed-simulator-impl.h (module 'mpi'): uint32_t ns3::LbtsMessage::GetRxCount() [member function]
- cls.add_method('GetRxCount',
- 'uint32_t',
- [])
- ## distributed-simulator-impl.h (module 'mpi'): ns3::Time ns3::LbtsMessage::GetSmallestTime() [member function]
- cls.add_method('GetSmallestTime',
- 'ns3::Time',
- [])
- ## distributed-simulator-impl.h (module 'mpi'): uint32_t ns3::LbtsMessage::GetTxCount() [member function]
- cls.add_method('GetTxCount',
- 'uint32_t',
- [])
- ## distributed-simulator-impl.h (module 'mpi'): bool ns3::LbtsMessage::IsFinished() [member function]
- cls.add_method('IsFinished',
- 'bool',
- [])
- return
-
def register_Ns3MpiInterface_methods(root_module, cls):
## mpi-interface.h (module 'mpi'): ns3::MpiInterface::MpiInterface() [constructor]
cls.add_constructor([])
@@ -826,11 +716,6 @@
'void',
[param('int *', 'pargc'), param('char * * *', 'pargv')],
is_static=True)
- ## mpi-interface.h (module 'mpi'): static uint32_t ns3::MpiInterface::GetRxCount() [member function]
- cls.add_method('GetRxCount',
- 'uint32_t',
- [],
- is_static=True)
## mpi-interface.h (module 'mpi'): static uint32_t ns3::MpiInterface::GetSize() [member function]
cls.add_method('GetSize',
'uint32_t',
@@ -841,31 +726,16 @@
'uint32_t',
[],
is_static=True)
- ## mpi-interface.h (module 'mpi'): static uint32_t ns3::MpiInterface::GetTxCount() [member function]
- cls.add_method('GetTxCount',
- 'uint32_t',
- [],
- is_static=True)
## mpi-interface.h (module 'mpi'): static bool ns3::MpiInterface::IsEnabled() [member function]
cls.add_method('IsEnabled',
'bool',
[],
is_static=True)
- ## mpi-interface.h (module 'mpi'): static void ns3::MpiInterface::ReceiveMessages() [member function]
- cls.add_method('ReceiveMessages',
- 'void',
- [],
- is_static=True)
## mpi-interface.h (module 'mpi'): static void ns3::MpiInterface::SendPacket(ns3::Ptr<ns3::Packet> p, ns3::Time const & rxTime, uint32_t node, uint32_t dev) [member function]
cls.add_method('SendPacket',
'void',
[param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Time const &', 'rxTime'), param('uint32_t', 'node'), param('uint32_t', 'dev')],
is_static=True)
- ## mpi-interface.h (module 'mpi'): static void ns3::MpiInterface::TestSendComplete() [member function]
- cls.add_method('TestSendComplete',
- 'void',
- [],
- is_static=True)
return
def register_Ns3ObjectBase_methods(root_module, cls):
@@ -941,42 +811,6 @@
is_static=True)
return
-def register_Ns3ObjectFactory_methods(root_module, cls):
- cls.add_output_stream_operator()
- ## object-factory.h (module 'core'): ns3::ObjectFactory::ObjectFactory(ns3::ObjectFactory const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::ObjectFactory const &', 'arg0')])
- ## object-factory.h (module 'core'): ns3::ObjectFactory::ObjectFactory() [constructor]
- cls.add_constructor([])
- ## object-factory.h (module 'core'): ns3::ObjectFactory::ObjectFactory(std::string typeId) [constructor]
- cls.add_constructor([param('std::string', 'typeId')])
- ## object-factory.h (module 'core'): ns3::Ptr<ns3::Object> ns3::ObjectFactory::Create() const [member function]
- cls.add_method('Create',
- 'ns3::Ptr< ns3::Object >',
- [],
- is_const=True)
- ## object-factory.h (module 'core'): ns3::TypeId ns3::ObjectFactory::GetTypeId() const [member function]
- cls.add_method('GetTypeId',
- 'ns3::TypeId',
- [],
- is_const=True)
- ## object-factory.h (module 'core'): void ns3::ObjectFactory::Set(std::string name, ns3::AttributeValue const & value) [member function]
- cls.add_method('Set',
- 'void',
- [param('std::string', 'name'), param('ns3::AttributeValue const &', 'value')])
- ## object-factory.h (module 'core'): void ns3::ObjectFactory::SetTypeId(ns3::TypeId tid) [member function]
- cls.add_method('SetTypeId',
- 'void',
- [param('ns3::TypeId', 'tid')])
- ## object-factory.h (module 'core'): void ns3::ObjectFactory::SetTypeId(char const * tid) [member function]
- cls.add_method('SetTypeId',
- 'void',
- [param('char const *', 'tid')])
- ## object-factory.h (module 'core'): void ns3::ObjectFactory::SetTypeId(std::string tid) [member function]
- cls.add_method('SetTypeId',
- 'void',
- [param('std::string', 'tid')])
- return
-
def register_Ns3PacketMetadata_methods(root_module, cls):
## packet-metadata.h (module 'network'): ns3::PacketMetadata::PacketMetadata(uint64_t uid, uint32_t size) [constructor]
cls.add_constructor([param('uint64_t', 'uid'), param('uint32_t', 'size')])
@@ -1168,23 +1002,46 @@
cls.add_instance_attribute('tid', 'ns3::TypeId', is_const=False)
return
-def register_Ns3SentBuffer_methods(root_module, cls):
- ## mpi-interface.h (module 'mpi'): ns3::SentBuffer::SentBuffer(ns3::SentBuffer const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::SentBuffer const &', 'arg0')])
- ## mpi-interface.h (module 'mpi'): ns3::SentBuffer::SentBuffer() [constructor]
+def register_Ns3ParallelCommunicationInterface_methods(root_module, cls):
+ ## parallel-communication-interface.h (module 'mpi'): ns3::ParallelCommunicationInterface::ParallelCommunicationInterface() [constructor]
cls.add_constructor([])
- ## mpi-interface.h (module 'mpi'): uint8_t * ns3::SentBuffer::GetBuffer() [member function]
- cls.add_method('GetBuffer',
- 'uint8_t *',
- [])
- ## mpi-interface.h (module 'mpi'): MPI_Request * ns3::SentBuffer::GetRequest() [member function]
- cls.add_method('GetRequest',
- 'MPI_Request *',
- [])
- ## mpi-interface.h (module 'mpi'): void ns3::SentBuffer::SetBuffer(uint8_t * buffer) [member function]
- cls.add_method('SetBuffer',
+ ## parallel-communication-interface.h (module 'mpi'): ns3::ParallelCommunicationInterface::ParallelCommunicationInterface(ns3::ParallelCommunicationInterface const & arg0) [copy constructor]
+ cls.add_constructor([param('ns3::ParallelCommunicationInterface const &', 'arg0')])
+ ## parallel-communication-interface.h (module 'mpi'): void ns3::ParallelCommunicationInterface::Destroy() [member function]
+ cls.add_method('Destroy',
+ 'void',
+ [],
+ is_pure_virtual=True, is_virtual=True)
+ ## parallel-communication-interface.h (module 'mpi'): void ns3::ParallelCommunicationInterface::Disable() [member function]
+ cls.add_method('Disable',
+ 'void',
+ [],
+ is_pure_virtual=True, is_virtual=True)
+ ## parallel-communication-interface.h (module 'mpi'): void ns3::ParallelCommunicationInterface::Enable(int * pargc, char * * * pargv) [member function]
+ cls.add_method('Enable',
'void',
- [param('uint8_t *', 'buffer')])
+ [param('int *', 'pargc'), param('char * * *', 'pargv')],
+ is_pure_virtual=True, is_virtual=True)
+ ## parallel-communication-interface.h (module 'mpi'): uint32_t ns3::ParallelCommunicationInterface::GetSize() [member function]
+ cls.add_method('GetSize',
+ 'uint32_t',
+ [],
+ is_pure_virtual=True, is_virtual=True)
+ ## parallel-communication-interface.h (module 'mpi'): uint32_t ns3::ParallelCommunicationInterface::GetSystemId() [member function]
+ cls.add_method('GetSystemId',
+ 'uint32_t',
+ [],
+ is_pure_virtual=True, is_virtual=True)
+ ## parallel-communication-interface.h (module 'mpi'): bool ns3::ParallelCommunicationInterface::IsEnabled() [member function]
+ cls.add_method('IsEnabled',
+ 'bool',
+ [],
+ is_pure_virtual=True, is_virtual=True)
+ ## parallel-communication-interface.h (module 'mpi'): void ns3::ParallelCommunicationInterface::SendPacket(ns3::Ptr<ns3::Packet> p, ns3::Time const & rxTime, uint32_t node, uint32_t dev) [member function]
+ cls.add_method('SendPacket',
+ 'void',
+ [param('ns3::Ptr< ns3::Packet >', 'p'), param('ns3::Time const &', 'rxTime'), param('uint32_t', 'node'), param('uint32_t', 'dev')],
+ is_pure_virtual=True, is_virtual=True)
return
def register_Ns3SimpleRefCount__Ns3Object_Ns3ObjectBase_Ns3ObjectDeleter_methods(root_module, cls):
@@ -1718,71 +1575,6 @@
[])
return
-def register_Ns3Scheduler_methods(root_module, cls):
- ## scheduler.h (module 'core'): ns3::Scheduler::Scheduler() [constructor]
- cls.add_constructor([])
- ## scheduler.h (module 'core'): ns3::Scheduler::Scheduler(ns3::Scheduler const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::Scheduler const &', 'arg0')])
- ## scheduler.h (module 'core'): static ns3::TypeId ns3::Scheduler::GetTypeId() [member function]
- cls.add_method('GetTypeId',
- 'ns3::TypeId',
- [],
- is_static=True)
- ## scheduler.h (module 'core'): void ns3::Scheduler::Insert(ns3::Scheduler::Event const & ev) [member function]
- cls.add_method('Insert',
- 'void',
- [param('ns3::Scheduler::Event const &', 'ev')],
- is_pure_virtual=True, is_virtual=True)
- ## scheduler.h (module 'core'): bool ns3::Scheduler::IsEmpty() const [member function]
- cls.add_method('IsEmpty',
- 'bool',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## scheduler.h (module 'core'): ns3::Scheduler::Event ns3::Scheduler::PeekNext() const [member function]
- cls.add_method('PeekNext',
- 'ns3::Scheduler::Event',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## scheduler.h (module 'core'): void ns3::Scheduler::Remove(ns3::Scheduler::Event const & ev) [member function]
- cls.add_method('Remove',
- 'void',
- [param('ns3::Scheduler::Event const &', 'ev')],
- is_pure_virtual=True, is_virtual=True)
- ## scheduler.h (module 'core'): ns3::Scheduler::Event ns3::Scheduler::RemoveNext() [member function]
- cls.add_method('RemoveNext',
- 'ns3::Scheduler::Event',
- [],
- is_pure_virtual=True, is_virtual=True)
- return
-
-def register_Ns3SchedulerEvent_methods(root_module, cls):
- cls.add_binary_comparison_operator('<')
- ## scheduler.h (module 'core'): ns3::Scheduler::Event::Event() [constructor]
- cls.add_constructor([])
- ## scheduler.h (module 'core'): ns3::Scheduler::Event::Event(ns3::Scheduler::Event const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::Scheduler::Event const &', 'arg0')])
- ## scheduler.h (module 'core'): ns3::Scheduler::Event::impl [variable]
- cls.add_instance_attribute('impl', 'ns3::EventImpl *', is_const=False)
- ## scheduler.h (module 'core'): ns3::Scheduler::Event::key [variable]
- cls.add_instance_attribute('key', 'ns3::Scheduler::EventKey', is_const=False)
- return
-
-def register_Ns3SchedulerEventKey_methods(root_module, cls):
- cls.add_binary_comparison_operator('<')
- cls.add_binary_comparison_operator('>')
- cls.add_binary_comparison_operator('!=')
- ## scheduler.h (module 'core'): ns3::Scheduler::EventKey::EventKey() [constructor]
- cls.add_constructor([])
- ## scheduler.h (module 'core'): ns3::Scheduler::EventKey::EventKey(ns3::Scheduler::EventKey const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::Scheduler::EventKey const &', 'arg0')])
- ## scheduler.h (module 'core'): ns3::Scheduler::EventKey::m_context [variable]
- cls.add_instance_attribute('m_context', 'uint32_t', is_const=False)
- ## scheduler.h (module 'core'): ns3::Scheduler::EventKey::m_ts [variable]
- cls.add_instance_attribute('m_ts', 'uint64_t', is_const=False)
- ## scheduler.h (module 'core'): ns3::Scheduler::EventKey::m_uid [variable]
- cls.add_instance_attribute('m_uid', 'uint32_t', is_const=False)
- return
-
def register_Ns3SimpleRefCount__Ns3AttributeAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3AttributeAccessor__gt___methods(root_module, cls):
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::AttributeAccessor, ns3::empty, ns3::DefaultDeleter<ns3::AttributeAccessor> >::SimpleRefCount() [constructor]
cls.add_constructor([])
@@ -1831,18 +1623,6 @@
is_static=True)
return
-def register_Ns3SimpleRefCount__Ns3EventImpl_Ns3Empty_Ns3DefaultDeleter__lt__ns3EventImpl__gt___methods(root_module, cls):
- ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> >::SimpleRefCount() [constructor]
- cls.add_constructor([])
- ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> >::SimpleRefCount(ns3::SimpleRefCount<ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> > const & o) [copy constructor]
- cls.add_constructor([param('ns3::SimpleRefCount< ns3::EventImpl, ns3::empty, ns3::DefaultDeleter< ns3::EventImpl > > const &', 'o')])
- ## simple-ref-count.h (module 'core'): static void ns3::SimpleRefCount<ns3::EventImpl, ns3::empty, ns3::DefaultDeleter<ns3::EventImpl> >::Cleanup() [member function]
- cls.add_method('Cleanup',
- 'void',
- [],
- is_static=True)
- return
-
def register_Ns3SimpleRefCount__Ns3HashImplementation_Ns3Empty_Ns3DefaultDeleter__lt__ns3HashImplementation__gt___methods(root_module, cls):
## simple-ref-count.h (module 'core'): ns3::SimpleRefCount<ns3::Hash::Implementation, ns3::empty, ns3::DefaultDeleter<ns3::Hash::Implementation> >::SimpleRefCount() [constructor]
cls.add_constructor([])
@@ -1891,108 +1671,6 @@
is_static=True)
return
-def register_Ns3SimulatorImpl_methods(root_module, cls):
- ## simulator-impl.h (module 'core'): ns3::SimulatorImpl::SimulatorImpl() [constructor]
- cls.add_constructor([])
- ## simulator-impl.h (module 'core'): ns3::SimulatorImpl::SimulatorImpl(ns3::SimulatorImpl const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::SimulatorImpl const &', 'arg0')])
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::Cancel(ns3::EventId const & ev) [member function]
- cls.add_method('Cancel',
- 'void',
- [param('ns3::EventId const &', 'ev')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::Destroy() [member function]
- cls.add_method('Destroy',
- 'void',
- [],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): uint32_t ns3::SimulatorImpl::GetContext() const [member function]
- cls.add_method('GetContext',
- 'uint32_t',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): ns3::Time ns3::SimulatorImpl::GetDelayLeft(ns3::EventId const & id) const [member function]
- cls.add_method('GetDelayLeft',
- 'ns3::Time',
- [param('ns3::EventId const &', 'id')],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): ns3::Time ns3::SimulatorImpl::GetMaximumSimulationTime() const [member function]
- cls.add_method('GetMaximumSimulationTime',
- 'ns3::Time',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): uint32_t ns3::SimulatorImpl::GetSystemId() const [member function]
- cls.add_method('GetSystemId',
- 'uint32_t',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): static ns3::TypeId ns3::SimulatorImpl::GetTypeId() [member function]
- cls.add_method('GetTypeId',
- 'ns3::TypeId',
- [],
- is_static=True)
- ## simulator-impl.h (module 'core'): bool ns3::SimulatorImpl::IsExpired(ns3::EventId const & ev) const [member function]
- cls.add_method('IsExpired',
- 'bool',
- [param('ns3::EventId const &', 'ev')],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): bool ns3::SimulatorImpl::IsFinished() const [member function]
- cls.add_method('IsFinished',
- 'bool',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): ns3::Time ns3::SimulatorImpl::Now() const [member function]
- cls.add_method('Now',
- 'ns3::Time',
- [],
- is_pure_virtual=True, is_const=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::Remove(ns3::EventId const & ev) [member function]
- cls.add_method('Remove',
- 'void',
- [param('ns3::EventId const &', 'ev')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::Run() [member function]
- cls.add_method('Run',
- 'void',
- [],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): ns3::EventId ns3::SimulatorImpl::Schedule(ns3::Time const & time, ns3::EventImpl * event) [member function]
- cls.add_method('Schedule',
- 'ns3::EventId',
- [param('ns3::Time const &', 'time'), param('ns3::EventImpl *', 'event')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): ns3::EventId ns3::SimulatorImpl::ScheduleDestroy(ns3::EventImpl * event) [member function]
- cls.add_method('ScheduleDestroy',
- 'ns3::EventId',
- [param('ns3::EventImpl *', 'event')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): ns3::EventId ns3::SimulatorImpl::ScheduleNow(ns3::EventImpl * event) [member function]
- cls.add_method('ScheduleNow',
- 'ns3::EventId',
- [param('ns3::EventImpl *', 'event')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::ScheduleWithContext(uint32_t context, ns3::Time const & time, ns3::EventImpl * event) [member function]
- cls.add_method('ScheduleWithContext',
- 'void',
- [param('uint32_t', 'context'), param('ns3::Time const &', 'time'), param('ns3::EventImpl *', 'event')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::SetScheduler(ns3::ObjectFactory schedulerFactory) [member function]
- cls.add_method('SetScheduler',
- 'void',
- [param('ns3::ObjectFactory', 'schedulerFactory')],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::Stop() [member function]
- cls.add_method('Stop',
- 'void',
- [],
- is_pure_virtual=True, is_virtual=True)
- ## simulator-impl.h (module 'core'): void ns3::SimulatorImpl::Stop(ns3::Time const & time) [member function]
- cls.add_method('Stop',
- 'void',
- [param('ns3::Time const &', 'time')],
- is_pure_virtual=True, is_virtual=True)
- return
-
def register_Ns3Time_methods(root_module, cls):
cls.add_binary_numeric_operator('+', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right'))
cls.add_binary_numeric_operator('-', root_module['ns3::Time'], root_module['ns3::Time'], param('ns3::Time const &', 'right'))
@@ -2052,6 +1730,11 @@
'ns3::Time',
[param('uint64_t', 'value'), param('ns3::Time::Unit', 'timeUnit')],
is_static=True)
+ ## nstime.h (module 'core'): double ns3::Time::GetDays() const [member function]
+ cls.add_method('GetDays',
+ 'double',
+ [],
+ is_const=True)
## nstime.h (module 'core'): double ns3::Time::GetDouble() const [member function]
cls.add_method('GetDouble',
'double',
@@ -2062,6 +1745,11 @@
'int64_t',
[],
is_const=True)
+ ## nstime.h (module 'core'): double ns3::Time::GetHours() const [member function]
+ cls.add_method('GetHours',
+ 'double',
+ [],
+ is_const=True)
## nstime.h (module 'core'): int64_t ns3::Time::GetInteger() const [member function]
cls.add_method('GetInteger',
'int64_t',
@@ -2077,6 +1765,11 @@
'int64_t',
[],
is_const=True)
+ ## nstime.h (module 'core'): double ns3::Time::GetMinutes() const [member function]
+ cls.add_method('GetMinutes',
+ 'double',
+ [],
+ is_const=True)
## nstime.h (module 'core'): int64_t ns3::Time::GetNanoSeconds() const [member function]
cls.add_method('GetNanoSeconds',
'int64_t',
@@ -2102,6 +1795,11 @@
'int64_t',
[],
is_const=True)
+ ## nstime.h (module 'core'): double ns3::Time::GetYears() const [member function]
+ cls.add_method('GetYears',
+ 'double',
+ [],
+ is_const=True)
## nstime.h (module 'core'): bool ns3::Time::IsNegative() const [member function]
cls.add_method('IsNegative',
'bool',
@@ -2362,113 +2060,6 @@
[param('ns3::CallbackBase', 'base')])
return
-def register_Ns3DistributedSimulatorImpl_methods(root_module, cls):
- ## distributed-simulator-impl.h (module 'mpi'): ns3::DistributedSimulatorImpl::DistributedSimulatorImpl(ns3::DistributedSimulatorImpl const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::DistributedSimulatorImpl const &', 'arg0')])
- ## distributed-simulator-impl.h (module 'mpi'): ns3::DistributedSimulatorImpl::DistributedSimulatorImpl() [constructor]
- cls.add_constructor([])
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::Cancel(ns3::EventId const & ev) [member function]
- cls.add_method('Cancel',
- 'void',
- [param('ns3::EventId const &', 'ev')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::Destroy() [member function]
- cls.add_method('Destroy',
- 'void',
- [],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): uint32_t ns3::DistributedSimulatorImpl::GetContext() const [member function]
- cls.add_method('GetContext',
- 'uint32_t',
- [],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): ns3::Time ns3::DistributedSimulatorImpl::GetDelayLeft(ns3::EventId const & id) const [member function]
- cls.add_method('GetDelayLeft',
- 'ns3::Time',
- [param('ns3::EventId const &', 'id')],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): ns3::Time ns3::DistributedSimulatorImpl::GetMaximumSimulationTime() const [member function]
- cls.add_method('GetMaximumSimulationTime',
- 'ns3::Time',
- [],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): uint32_t ns3::DistributedSimulatorImpl::GetSystemId() const [member function]
- cls.add_method('GetSystemId',
- 'uint32_t',
- [],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): static ns3::TypeId ns3::DistributedSimulatorImpl::GetTypeId() [member function]
- cls.add_method('GetTypeId',
- 'ns3::TypeId',
- [],
- is_static=True)
- ## distributed-simulator-impl.h (module 'mpi'): bool ns3::DistributedSimulatorImpl::IsExpired(ns3::EventId const & ev) const [member function]
- cls.add_method('IsExpired',
- 'bool',
- [param('ns3::EventId const &', 'ev')],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): bool ns3::DistributedSimulatorImpl::IsFinished() const [member function]
- cls.add_method('IsFinished',
- 'bool',
- [],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): ns3::Time ns3::DistributedSimulatorImpl::Now() const [member function]
- cls.add_method('Now',
- 'ns3::Time',
- [],
- is_const=True, is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::Remove(ns3::EventId const & ev) [member function]
- cls.add_method('Remove',
- 'void',
- [param('ns3::EventId const &', 'ev')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::Run() [member function]
- cls.add_method('Run',
- 'void',
- [],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): ns3::EventId ns3::DistributedSimulatorImpl::Schedule(ns3::Time const & time, ns3::EventImpl * event) [member function]
- cls.add_method('Schedule',
- 'ns3::EventId',
- [param('ns3::Time const &', 'time'), param('ns3::EventImpl *', 'event')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): ns3::EventId ns3::DistributedSimulatorImpl::ScheduleDestroy(ns3::EventImpl * event) [member function]
- cls.add_method('ScheduleDestroy',
- 'ns3::EventId',
- [param('ns3::EventImpl *', 'event')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): ns3::EventId ns3::DistributedSimulatorImpl::ScheduleNow(ns3::EventImpl * event) [member function]
- cls.add_method('ScheduleNow',
- 'ns3::EventId',
- [param('ns3::EventImpl *', 'event')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::ScheduleWithContext(uint32_t context, ns3::Time const & time, ns3::EventImpl * event) [member function]
- cls.add_method('ScheduleWithContext',
- 'void',
- [param('uint32_t', 'context'), param('ns3::Time const &', 'time'), param('ns3::EventImpl *', 'event')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::SetScheduler(ns3::ObjectFactory schedulerFactory) [member function]
- cls.add_method('SetScheduler',
- 'void',
- [param('ns3::ObjectFactory', 'schedulerFactory')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::Stop() [member function]
- cls.add_method('Stop',
- 'void',
- [],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::Stop(ns3::Time const & time) [member function]
- cls.add_method('Stop',
- 'void',
- [param('ns3::Time const &', 'time')],
- is_virtual=True)
- ## distributed-simulator-impl.h (module 'mpi'): void ns3::DistributedSimulatorImpl::DoDispose() [member function]
- cls.add_method('DoDispose',
- 'void',
- [],
- visibility='private', is_virtual=True)
- return
-
def register_Ns3EmptyAttributeValue_methods(root_module, cls):
## attribute.h (module 'core'): ns3::EmptyAttributeValue::EmptyAttributeValue(ns3::EmptyAttributeValue const & arg0) [copy constructor]
cls.add_constructor([param('ns3::EmptyAttributeValue const &', 'arg0')])
@@ -2491,30 +2082,6 @@
is_const=True, visibility='private', is_virtual=True)
return
-def register_Ns3EventImpl_methods(root_module, cls):
- ## event-impl.h (module 'core'): ns3::EventImpl::EventImpl(ns3::EventImpl const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::EventImpl const &', 'arg0')])
- ## event-impl.h (module 'core'): ns3::EventImpl::EventImpl() [constructor]
- cls.add_constructor([])
- ## event-impl.h (module 'core'): void ns3::EventImpl::Cancel() [member function]
- cls.add_method('Cancel',
- 'void',
- [])
- ## event-impl.h (module 'core'): void ns3::EventImpl::Invoke() [member function]
- cls.add_method('Invoke',
- 'void',
- [])
- ## event-impl.h (module 'core'): bool ns3::EventImpl::IsCancelled() [member function]
- cls.add_method('IsCancelled',
- 'bool',
- [])
- ## event-impl.h (module 'core'): void ns3::EventImpl::Notify() [member function]
- cls.add_method('Notify',
- 'void',
- [],
- is_pure_virtual=True, visibility='protected', is_virtual=True)
- return
-
def register_Ns3MpiReceiver_methods(root_module, cls):
## mpi-receiver.h (module 'mpi'): ns3::MpiReceiver::MpiReceiver() [constructor]
cls.add_constructor([])
@@ -2584,46 +2151,6 @@
is_const=True)
return
-def register_Ns3ObjectFactoryChecker_methods(root_module, cls):
- ## object-factory.h (module 'core'): ns3::ObjectFactoryChecker::ObjectFactoryChecker() [constructor]
- cls.add_constructor([])
- ## object-factory.h (module 'core'): ns3::ObjectFactoryChecker::ObjectFactoryChecker(ns3::ObjectFactoryChecker const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::ObjectFactoryChecker const &', 'arg0')])
- return
-
-def register_Ns3ObjectFactoryValue_methods(root_module, cls):
- ## object-factory.h (module 'core'): ns3::ObjectFactoryValue::ObjectFactoryValue() [constructor]
- cls.add_constructor([])
- ## object-factory.h (module 'core'): ns3::ObjectFactoryValue::ObjectFactoryValue(ns3::ObjectFactoryValue const & arg0) [copy constructor]
- cls.add_constructor([param('ns3::ObjectFactoryValue const &', 'arg0')])
- ## object-factory.h (module 'core'): ns3::ObjectFactoryValue::ObjectFactoryValue(ns3::ObjectFactory const & value) [constructor]
- cls.add_constructor([param('ns3::ObjectFactory const &', 'value')])
- ## object-factory.h (module 'core'): ns3::Ptr<ns3::AttributeValue> ns3::ObjectFactoryValue::Copy() const [member function]
- cls.add_method('Copy',
- 'ns3::Ptr< ns3::AttributeValue >',
- [],
- is_const=True, is_virtual=True)
- ## object-factory.h (module 'core'): bool ns3::ObjectFactoryValue::DeserializeFromString(std::string value, ns3::Ptr<ns3::AttributeChecker const> checker) [member function]
- cls.add_method('DeserializeFromString',
- 'bool',
- [param('std::string', 'value'), param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
- is_virtual=True)
- ## object-factory.h (module 'core'): ns3::ObjectFactory ns3::ObjectFactoryValue::Get() const [member function]
- cls.add_method('Get',
- 'ns3::ObjectFactory',
- [],
- is_const=True)
- ## object-factory.h (module 'core'): std::string ns3::ObjectFactoryValue::SerializeToString(ns3::Ptr<ns3::AttributeChecker const> checker) const [member function]
- cls.add_method('SerializeToString',
- 'std::string',
- [param('ns3::Ptr< ns3::AttributeChecker const >', 'checker')],
- is_const=True, is_virtual=True)
- ## object-factory.h (module 'core'): void ns3::ObjectFactoryValue::Set(ns3::ObjectFactory const & value) [member function]
- cls.add_method('Set',
- 'void',
- [param('ns3::ObjectFactory const &', 'value')])
- return
-
def register_Ns3Packet_methods(root_module, cls):
cls.add_output_stream_operator()
## packet.h (module 'network'): ns3::Packet::Packet() [constructor]
--- a/src/mpi/doc/distributed.rst Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/doc/distributed.rst Fri Dec 06 14:57:33 2013 -0500
@@ -32,10 +32,39 @@
events in time-stamped order to ensure proper simulation execution. If a LP
receives a message containing an event from the past, clearly this is an issue,
since this event could change other events which have already been executed. To
-address this problem, a conservative synchronization algorithm with lookahead is
+address this problem, two conservative synchronization algorithm with lookahead are
used in |ns3|. For more information on different synchronization approaches and
parallel and distributed simulation in general, please refer to "Parallel and
-Distributed Simulation Systems" by Richard Fujimoto.
+Distributed Simulation Systems" by Richard Fujimoto.
+
+The default parallel synchronization strategy implemented in the
+DistributedSimulatorImpl class is based on a globally synchronized
+algorithm using an MPI collective operation to synchronize simulation
+time across all LPs. A second synchronization strategy based on local
+communication and null messages is implemented in the
+NullMessageSimulatorImpl class, For the null message strategy the
+global all to all gather is not required; LPs only need to
+communication with LPs that have shared point-to-point links. The
+algorithm to use is controlled by which the |ns3| global value
+SimulatorImplementationType.
+
+The best algorithm to use is dependent on the communication and event
+scheduling pattern for the application. In general, null message
+synchronization algorithms will scale better due to local
+communication scaling better than a global all-to-all gather that is
+required by DistributedSimulatorImpl. There are two known cases where
+the global synchronization performs better. The first is when most
+LPs have point-to-point link with most other LPs, in other words the
+LPs are nearly fully connected. In this case the null message
+algorithm will generate more message passing traffic than the
+all-to-all gather. A second case where the global all-to-all gather
+is more efficient is when there are long periods of simulation time
+when no events are occurring. The all-to-all gather algorithm is able
+to quickly determine then next event time globally. The nearest
+neighbor behavior of the null message algorithm will require more
+communications to propagate that knowledge; each LP is only aware of
+neighbor next event times.
+
Remote point-to-point links
+++++++++++++++++++++++++++
@@ -147,12 +176,17 @@
$ ./waf
-After building |ns3| with mpi enabled, the example programs are now ready to run
-with mpirun. Here are a few examples (from the root |ns3| directory)::
+After building |ns3| with mpi enabled, the example programs are now
+ready to run with mpirun. Here are a few examples (from the root |ns3|
+directory)::
$ mpirun -np 2 ./waf --run simple-distributed
$ mpirun -np 4 -machinefile mpihosts ./waf --run 'nms-udp-nix --LAN=2 --CN=4 --nix=1'
+An examle using the null message synchronization algorithm::
+
+ $ mpirun -np 2 ./waf --run simple-distributed --nullmsg
+
The np switch is the number of logical processors to use. The machinefile switch
is which machines to use. In order to use machinefile, the target file must
exist (in this case mpihosts). This can simply contain something like:
@@ -173,6 +207,33 @@
$ cd build/debug
$ mpirun -np 2 src/mpi/examples/simple-distributed
+Setting synchronization algorithm to use
+++++++++++++++++++++++++++++++++++++++++
+
+The global value SimulatorImplementationType is used to set the
+synchronization algorithm to use. This value must be set before the
+MpiInterface::Enable method is invoked if the default
+DistributedSimulatorImpl is not used. Here is an example code snippet
+showing how to add a command line argument to control the
+synchronization algorithm choice:::
+
+ cmd.AddValue ("nullmsg", "Enable the use of null-message synchronization", nullmsg);
+ if(nullmsg)
+ {
+ GlobalValue::Bind ("SimulatorImplementationType",
+ StringValue ("ns3::NullMessageSimulatorImpl"));
+ }
+ else
+ {
+ GlobalValue::Bind ("SimulatorImplementationType",
+ StringValue ("ns3::DistributedSimulatorImpl"));
+ }
+
+ // Enable parallel simulator with the command line arguments
+ MpiInterface::Enable (&argc, &argv);
+
+
+
Creating custom topologies
++++++++++++++++++++++++++
.. highlight:: cpp
--- a/src/mpi/examples/nms-p2p-nix-distributed.cc Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/examples/nms-p2p-nix-distributed.cc Fri Dec 06 14:57:33 2013 -0500
@@ -49,10 +49,6 @@
#include "ns3/ipv4-list-routing-helper.h"
#include "ns3/ipv4-nix-vector-helper.h"
-#ifdef NS3_MPI
-#include <mpi.h>
-#endif
-
using namespace ns3;
typedef struct timeval TIMER_TYPE;
@@ -71,7 +67,8 @@
main (int argc, char *argv[])
{
#ifdef NS3_MPI
- // Enable MPI with the command line arguments
+
+ // Enable parallel simulator with the command line arguments
MpiInterface::Enable (&argc, &argv);
TIMER_TYPE t0, t1, t2;
@@ -608,7 +605,7 @@
TIMER_NOW (t2);
std::cout << "Simulator finished." << std::endl;
Simulator::Destroy ();
- // Exit the MPI execution environment
+ // Exit the parallel execution environment
MpiInterface::Disable ();
double d1 = TIMER_DIFF (t1, t0), d2 = TIMER_DIFF (t2, t1);
std::cout << "-----" << std::endl << "Runtime Stats:" << std::endl;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mpi/examples/simple-distributed-empty-node.cc Fri Dec 06 14:57:33 2013 -0500
@@ -0,0 +1,309 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * This test is equivalent to simple-distributed but tests boundary cases
+ * when one of the ranks has no Nodes on it. When run on two tasks
+ * rank 0 will have all the Nodes and rank 1 will be empty:
+ *
+ * ------- -------
+ * RANK 0 RANK 0
+ * ------- | -------
+ * |
+ * n0 ---------| | |---------- n6
+ * | | |
+ * n1 -------\ | | | /------- n7
+ * n4 ----------|---------- n5
+ * n2 -------/ | | | \------- n8
+ * | | |
+ * n3 ---------| | |---------- n9
+ *
+ *
+ * When run on three tasks rank 1 has the left half of the Nodes and rank 2
+ * will be empty.
+ *
+ * ------- -------
+ * RANK 0 RANK 1
+ * ------- | -------
+ * |
+ * n0 ---------| | |---------- n6
+ * | | |
+ * n1 -------\ | | | /------- n7
+ * n4 ----------|---------- n5
+ * n2 -------/ | | | \------- n8
+ * | | |
+ * n3 ---------| | |---------- n9
+ *
+ * OnOff clients are placed on each left leaf node. Each right leaf node
+ * is a packet sink for a left leaf node. As a packet travels from one
+ * logical processor to another (the link between n4 and n5), MPI messages
+ * are passed containing the serialized packet. The message is then
+ * deserialized into a new packet and sent on as normal.
+ *
+ * One packet is sent from each left leaf node. The packet sinks on the
+ * right leaf nodes output logging information when they receive the packet.
+ */
+
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/mpi-interface.h"
+#include "ns3/ipv4-global-routing-helper.h"
+#include "ns3/ipv4-static-routing-helper.h"
+#include "ns3/ipv4-list-routing-helper.h"
+#include "ns3/point-to-point-helper.h"
+#include "ns3/internet-stack-helper.h"
+#include "ns3/ipv4-nix-vector-helper.h"
+#include "ns3/ipv4-address-helper.h"
+#include "ns3/on-off-helper.h"
+#include "ns3/packet-sink-helper.h"
+
+#ifdef NS3_MPI
+#include <mpi.h>
+#endif
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("SimpleDistributed");
+
+int
+main (int argc, char *argv[])
+{
+#ifdef NS3_MPI
+
+ bool nix = true;
+ bool nullmsg = false;
+ bool tracing = false;
+
+ // Parse command line
+ CommandLine cmd;
+ cmd.AddValue ("nix", "Enable the use of nix-vector or global routing", nix);
+ cmd.AddValue ("nullmsg", "Enable the use of null-message synchronization", nullmsg);
+ cmd.AddValue ("tracing", "Enable pcap tracing", tracing);
+ cmd.Parse (argc, argv);
+
+ // Distributed simulation setup; by default use granted time window algorithm.
+ if(nullmsg)
+ {
+ GlobalValue::Bind ("SimulatorImplementationType",
+ StringValue ("ns3::NullMessageSimulatorImpl"));
+ }
+ else
+ {
+ GlobalValue::Bind ("SimulatorImplementationType",
+ StringValue ("ns3::DistributedSimulatorImpl"));
+ }
+
+ MpiInterface::Enable (&argc, &argv);
+
+ LogComponentEnable ("PacketSink", LOG_LEVEL_INFO);
+
+ uint32_t systemId = MpiInterface::GetSystemId ();
+ uint32_t systemCount = MpiInterface::GetSize ();
+
+ uint32_t rightHalfSystemId = 777;
+
+ // Check for valid distributed parameters.
+ // Must have 2 or 3 tasks.
+ if (systemCount == 2)
+ {
+ rightHalfSystemId = 0;
+ }
+ else if (systemCount == 3)
+ {
+ rightHalfSystemId = 1;
+ }
+ else
+ {
+ std::cout << "This simulation requires 2 or 3 logical processors." << std::endl;
+ return 1;
+ }
+
+ // Some default values
+ Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512));
+ Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("1Mbps"));
+ Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (512));
+
+ // Create leaf nodes on left with system id 0
+ NodeContainer leftLeafNodes;
+ leftLeafNodes.Create (4, 0);
+
+ // Create router nodes. Left router with system id 0, right router
+ // with system id dependent on number of processors using
+ // rightHalfSystemId
+ NodeContainer routerNodes;
+ Ptr<Node> routerNode1 = CreateObject<Node> (0);
+ Ptr<Node> routerNode2 = CreateObject<Node> (rightHalfSystemId);
+ routerNodes.Add (routerNode1);
+ routerNodes.Add (routerNode2);
+
+ // Create leaf nodes on left with system id rightHalfSystemId
+ NodeContainer rightLeafNodes;
+ rightLeafNodes.Create (4, rightHalfSystemId);
+
+ PointToPointHelper routerLink;
+ routerLink.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
+ routerLink.SetChannelAttribute ("Delay", StringValue ("5ms"));
+
+ PointToPointHelper leafLink;
+ leafLink.SetDeviceAttribute ("DataRate", StringValue ("1Mbps"));
+ leafLink.SetChannelAttribute ("Delay", StringValue ("2ms"));
+
+ // Add link connecting routers
+ NetDeviceContainer routerDevices;
+ routerDevices = routerLink.Install (routerNodes);
+
+ // Add links for left side leaf nodes to left router
+ NetDeviceContainer leftRouterDevices;
+ NetDeviceContainer leftLeafDevices;
+ for (uint32_t i = 0; i < 4; ++i)
+ {
+ NetDeviceContainer temp = leafLink.Install (leftLeafNodes.Get (i), routerNodes.Get (0));
+ leftLeafDevices.Add (temp.Get (0));
+ leftRouterDevices.Add (temp.Get (1));
+ }
+
+ // Add links for right side leaf nodes to right router
+ NetDeviceContainer rightRouterDevices;
+ NetDeviceContainer rightLeafDevices;
+ for (uint32_t i = 0; i < 4; ++i)
+ {
+ NetDeviceContainer temp = leafLink.Install (rightLeafNodes.Get (i), routerNodes.Get (1));
+ rightLeafDevices.Add (temp.Get (0));
+ rightRouterDevices.Add (temp.Get (1));
+ }
+
+ InternetStackHelper stack;
+ Ipv4NixVectorHelper nixRouting;
+ Ipv4StaticRoutingHelper staticRouting;
+
+ Ipv4ListRoutingHelper list;
+ list.Add (staticRouting, 0);
+ list.Add (nixRouting, 10);
+
+ if (nix)
+ {
+ stack.SetRoutingHelper (list); // has effect on the next Install ()
+ }
+
+ stack.InstallAll ();
+
+ Ipv4InterfaceContainer routerInterfaces;
+ Ipv4InterfaceContainer leftLeafInterfaces;
+ Ipv4InterfaceContainer leftRouterInterfaces;
+ Ipv4InterfaceContainer rightLeafInterfaces;
+ Ipv4InterfaceContainer rightRouterInterfaces;
+
+ Ipv4AddressHelper leftAddress;
+ leftAddress.SetBase ("10.1.1.0", "255.255.255.0");
+
+ Ipv4AddressHelper routerAddress;
+ routerAddress.SetBase ("10.2.1.0", "255.255.255.0");
+
+ Ipv4AddressHelper rightAddress;
+ rightAddress.SetBase ("10.3.1.0", "255.255.255.0");
+
+ // Router-to-Router interfaces
+ routerInterfaces = routerAddress.Assign (routerDevices);
+
+ // Left interfaces
+ for (uint32_t i = 0; i < 4; ++i)
+ {
+ NetDeviceContainer ndc;
+ ndc.Add (leftLeafDevices.Get (i));
+ ndc.Add (leftRouterDevices.Get (i));
+ Ipv4InterfaceContainer ifc = leftAddress.Assign (ndc);
+ leftLeafInterfaces.Add (ifc.Get (0));
+ leftRouterInterfaces.Add (ifc.Get (1));
+ leftAddress.NewNetwork ();
+ }
+
+ // Right interfaces
+ for (uint32_t i = 0; i < 4; ++i)
+ {
+ NetDeviceContainer ndc;
+ ndc.Add (rightLeafDevices.Get (i));
+ ndc.Add (rightRouterDevices.Get (i));
+ Ipv4InterfaceContainer ifc = rightAddress.Assign (ndc);
+ rightLeafInterfaces.Add (ifc.Get (0));
+ rightRouterInterfaces.Add (ifc.Get (1));
+ rightAddress.NewNetwork ();
+ }
+
+ if (!nix)
+ {
+ Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+ }
+
+ if (tracing == true)
+ {
+ if (systemId == 0)
+ {
+ routerLink.EnablePcap("router-left", routerDevices, true);
+ leafLink.EnablePcap("leaf-left", leftLeafDevices, true);
+ }
+
+ if (systemId == rightHalfSystemId)
+ {
+ routerLink.EnablePcap("router-right", routerDevices, true);
+ leafLink.EnablePcap("leaf-right", rightLeafDevices, true);
+ }
+ }
+
+ // Create a packet sink on the right leafs to receive packets from left leafs
+ uint16_t port = 50000;
+ if (systemId == rightHalfSystemId)
+ {
+ Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
+ PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress);
+ ApplicationContainer sinkApp;
+ for (uint32_t i = 0; i < 4; ++i)
+ {
+ sinkApp.Add (sinkHelper.Install (rightLeafNodes.Get (i)));
+ }
+ sinkApp.Start (Seconds (1.0));
+ sinkApp.Stop (Seconds (5));
+ }
+
+ // Create the OnOff applications to send
+ if (systemId == 0)
+ {
+ OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ());
+ clientHelper.SetAttribute
+ ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
+ clientHelper.SetAttribute
+ ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
+
+ ApplicationContainer clientApps;
+ for (uint32_t i = 0; i < 4; ++i)
+ {
+ AddressValue remoteAddress
+ (InetSocketAddress (rightLeafInterfaces.GetAddress (i), port));
+ clientHelper.SetAttribute ("Remote", remoteAddress);
+ clientApps.Add (clientHelper.Install (leftLeafNodes.Get (i)));
+ }
+ clientApps.Start (Seconds (1.0));
+ clientApps.Stop (Seconds (5));
+ }
+
+ Simulator::Stop (Seconds (5));
+ Simulator::Run ();
+ Simulator::Destroy ();
+ // Exit the MPI execution environment
+ MpiInterface::Disable ();
+ return 0;
+#else
+ NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
+#endif
+}
--- a/src/mpi/examples/simple-distributed.cc Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/examples/simple-distributed.cc Fri Dec 06 14:57:33 2013 -0500
@@ -66,10 +66,32 @@
main (int argc, char *argv[])
{
#ifdef NS3_MPI
- // Distributed simulation setup
+
+ bool nix = true;
+ bool nullmsg = false;
+ bool tracing = false;
+
+ // Parse command line
+ CommandLine cmd;
+ cmd.AddValue ("nix", "Enable the use of nix-vector or global routing", nix);
+ cmd.AddValue ("nullmsg", "Enable the use of null-message synchronization", nullmsg);
+ cmd.AddValue ("tracing", "Enable pcap tracing", tracing);
+ cmd.Parse (argc, argv);
+
+ // Distributed simulation setup; by default use granted time window algorithm.
+ if(nullmsg)
+ {
+ GlobalValue::Bind ("SimulatorImplementationType",
+ StringValue ("ns3::NullMessageSimulatorImpl"));
+ }
+ else
+ {
+ GlobalValue::Bind ("SimulatorImplementationType",
+ StringValue ("ns3::DistributedSimulatorImpl"));
+ }
+
+ // Enable parallel simulator with the command line arguments
MpiInterface::Enable (&argc, &argv);
- GlobalValue::Bind ("SimulatorImplementationType",
- StringValue ("ns3::DistributedSimulatorImpl"));
LogComponentEnable ("PacketSink", LOG_LEVEL_INFO);
@@ -88,12 +110,6 @@
Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512));
Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("1Mbps"));
Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (512));
- bool nix = true;
-
- // Parse command line
- CommandLine cmd;
- cmd.AddValue ("nix", "Enable the use of nix-vector or global routing", nix);
- cmd.Parse (argc, argv);
// Create leaf nodes on left with system id 0
NodeContainer leftLeafNodes;
@@ -206,6 +222,21 @@
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
}
+ if (tracing == true)
+ {
+ if (systemId == 0)
+ {
+ routerLink.EnablePcap("router-left", routerDevices, true);
+ leafLink.EnablePcap("leaf-left", leftLeafDevices, true);
+ }
+
+ if (systemId == 1)
+ {
+ routerLink.EnablePcap("router-right", routerDevices, true);
+ leafLink.EnablePcap("leaf-right", rightLeafDevices, true);
+ }
+ }
+
// Create a packet sink on the right leafs to receive packets from left leafs
uint16_t port = 50000;
if (systemId == 1)
--- a/src/mpi/examples/third-distributed.cc Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/examples/third-distributed.cc Fri Dec 06 14:57:33 2013 -0500
@@ -55,31 +55,18 @@
main (int argc, char *argv[])
{
#ifdef NS3_MPI
- // Distributed simulation setup
- MpiInterface::Enable (&argc, &argv);
- GlobalValue::Bind ("SimulatorImplementationType",
- StringValue ("ns3::DistributedSimulatorImpl"));
-
- uint32_t systemId = MpiInterface::GetSystemId ();
- uint32_t systemCount = MpiInterface::GetSize ();
-
- // Check for valid distributed parameters.
- // Must have 2 and only 2 Logical Processors (LPs)
- if (systemCount != 2)
- {
- std::cout << "This simulation requires 2 and only 2 logical processors." << std::endl;
- return 1;
- }
bool verbose = true;
uint32_t nCsma = 3;
uint32_t nWifi = 3;
+ bool nullmsg = false;
bool tracing = false;
CommandLine cmd;
cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi);
cmd.AddValue ("verbose", "Tell echo applications to log if true", verbose);
+ cmd.AddValue ("nullmsg", "Enable the use of null-message synchronization", nullmsg);
cmd.AddValue ("tracing", "Enable pcap tracing", tracing);
cmd.Parse (argc,argv);
@@ -98,6 +85,32 @@
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
}
+ // Distributed simulation setup; by default use granted time window algorithm.
+ if(nullmsg)
+ {
+ GlobalValue::Bind ("SimulatorImplementationType",
+ StringValue ("ns3::NullMessageSimulatorImpl"));
+ }
+ else
+ {
+ GlobalValue::Bind ("SimulatorImplementationType",
+ StringValue ("ns3::DistributedSimulatorImpl"));
+ }
+
+ MpiInterface::Enable (&argc, &argv);
+
+ uint32_t systemId = MpiInterface::GetSystemId ();
+ uint32_t systemCount = MpiInterface::GetSize ();
+
+ // Check for valid distributed parameters.
+ // Must have 2 and only 2 Logical Processors (LPs)
+ if (systemCount != 2)
+ {
+ std::cout << "This simulation requires 2 and only 2 logical processors." << std::endl;
+ return 1;
+ }
+
+
NodeContainer p2pNodes;
Ptr<Node> p2pNode1 = CreateObject<Node> (0); // Create node with rank 0
Ptr<Node> p2pNode2 = CreateObject<Node> (1); // Create node with rank 1
--- a/src/mpi/examples/wscript Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/examples/wscript Fri Dec 06 14:57:33 2013 -0500
@@ -12,3 +12,7 @@
obj = bld.create_ns3_program('nms-p2p-nix-distributed',
['point-to-point', 'internet', 'nix-vector-routing', 'applications'])
obj.source = 'nms-p2p-nix-distributed.cc'
+
+ obj = bld.create_ns3_program('simple-distributed-empty-node',
+ ['point-to-point', 'internet', 'nix-vector-routing', 'applications'])
+ obj.source = 'simple-distributed-empty-node.cc'
--- a/src/mpi/model/distributed-simulator-impl.cc Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/model/distributed-simulator-impl.cc Fri Dec 06 14:57:33 2013 -0500
@@ -14,9 +14,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: George Riley <riley@ece.gatech.edu>
+ *
*/
#include "distributed-simulator-impl.h"
+#include "granted-time-window-mpi-interface.h"
#include "mpi-interface.h"
#include "ns3/simulator.h"
@@ -89,6 +91,8 @@
DistributedSimulatorImpl::DistributedSimulatorImpl ()
{
+ NS_LOG_FUNCTION (this);
+
#ifdef NS3_MPI
m_myId = MpiInterface::GetSystemId ();
m_systemCount = MpiInterface::GetSize ();
@@ -102,6 +106,7 @@
#endif
m_stop = false;
+ m_globalFinished = false;
// uids are allocated from 4.
// uid 0 is "invalid" events
// uid 1 is "now" events
@@ -117,11 +122,14 @@
DistributedSimulatorImpl::~DistributedSimulatorImpl ()
{
+ NS_LOG_FUNCTION (this);
}
void
DistributedSimulatorImpl::DoDispose (void)
{
+ NS_LOG_FUNCTION (this);
+
while (!m_events->IsEmpty ())
{
Scheduler::Event next = m_events->RemoveNext ();
@@ -135,6 +143,8 @@
void
DistributedSimulatorImpl::Destroy ()
{
+ NS_LOG_FUNCTION (this);
+
while (!m_destroyEvents.empty ())
{
Ptr<EventImpl> ev = m_destroyEvents.front ().PeekEventImpl ();
@@ -153,6 +163,8 @@
void
DistributedSimulatorImpl::CalculateLookAhead (void)
{
+ NS_LOG_FUNCTION (this);
+
#ifdef NS3_MPI
if (MpiInterface::GetSize () <= 1)
{
@@ -162,6 +174,7 @@
else
{
DistributedSimulatorImpl::m_lookAhead = GetMaximumSimulationTime ();
+
m_grantedTime = GetMaximumSimulationTime ();
NodeContainer c = NodeContainer::GetGlobal ();
@@ -237,7 +250,7 @@
long recvbuf;
/* Tasks with no inter-task links do not contribute to max */
- if (m_lookAhead == GetMaximumSimulationTime ())
+ if (m_lookAhead == GetMaximumSimulationTime ())
{
sendbuf = 0;
}
@@ -254,7 +267,7 @@
* will proceed without synchronization until a single AllGather
* occurs when all tasks have finished.
*/
- if (m_lookAhead == GetMaximumSimulationTime () && recvbuf != 0)
+ if (m_lookAhead == GetMaximumSimulationTime () && recvbuf != 0)
{
m_lookAhead = Time (recvbuf);
m_grantedTime = m_lookAhead;
@@ -268,6 +281,8 @@
void
DistributedSimulatorImpl::SetScheduler (ObjectFactory schedulerFactory)
{
+ NS_LOG_FUNCTION (this << schedulerFactory);
+
Ptr<Scheduler> scheduler = schedulerFactory.Create<Scheduler> ();
if (m_events != 0)
@@ -284,6 +299,8 @@
void
DistributedSimulatorImpl::ProcessOneEvent (void)
{
+ NS_LOG_FUNCTION (this);
+
Scheduler::Event next = m_events->RemoveNext ();
NS_ASSERT (next.key.m_ts >= m_currentTs);
@@ -312,11 +329,14 @@
uint64_t
DistributedSimulatorImpl::NextTs (void) const
{
- // If local MPI task is has no more events or stop was called
+ // If local MPI task is has no more events or stop was called
// next event time is infinity.
- if (IsLocalFinished ()) {
+ if (IsLocalFinished ())
+ {
return GetMaximumSimulationTime ().GetTimeStep ();
- } else {
+ }
+ else
+ {
Scheduler::Event ev = m_events->PeekNext ();
return ev.key.m_ts;
}
@@ -331,6 +351,8 @@
void
DistributedSimulatorImpl::Run (void)
{
+ NS_LOG_FUNCTION (this);
+
#ifdef NS3_MPI
CalculateLookAhead ();
m_stop = false;
@@ -344,17 +366,17 @@
// synchronizations with other tasks until all tasks have
// completed.
if (nextTime > m_grantedTime || IsLocalFinished () )
- {
-
+ {
// Can't process next event, calculate a new LBTS
// First receive any pending messages
- MpiInterface::ReceiveMessages ();
+ GrantedTimeWindowMpiInterface::ReceiveMessages ();
// reset next time
nextTime = Next ();
// And check for send completes
- MpiInterface::TestSendComplete ();
+ GrantedTimeWindowMpiInterface::TestSendComplete ();
// Finally calculate the lbts
- LbtsMessage lMsg (MpiInterface::GetRxCount (), MpiInterface::GetTxCount (), m_myId, IsLocalFinished (), nextTime);
+ LbtsMessage lMsg (GrantedTimeWindowMpiInterface::GetRxCount (), GrantedTimeWindowMpiInterface::GetTxCount (),
+ m_myId, IsLocalFinished (), nextTime);
m_pLBTS[m_myId] = lMsg;
MPI_Allgather (&lMsg, sizeof (LbtsMessage), MPI_BYTE, m_pLBTS,
sizeof (LbtsMessage), MPI_BYTE, MPI_COMM_WORLD);
@@ -379,7 +401,7 @@
if (totRx == totTx)
{
// If lookahead is infinite then granted time should be as well.
- // Covers the edge case if all the tasks have no inter tasks
+ // Covers the edge case if all the tasks have no inter tasks
// links, prevents overflow of granted time.
if (m_lookAhead == GetMaximumSimulationTime ())
{
@@ -417,12 +439,16 @@
void
DistributedSimulatorImpl::Stop (void)
{
+ NS_LOG_FUNCTION (this);
+
m_stop = true;
}
void
DistributedSimulatorImpl::Stop (Time const &time)
{
+ NS_LOG_FUNCTION (this << time.GetTimeStep ());
+
Simulator::Schedule (time, &Simulator::Stop);
}
@@ -432,6 +458,8 @@
EventId
DistributedSimulatorImpl::Schedule (Time const &time, EventImpl *event)
{
+ NS_LOG_FUNCTION (this << time.GetTimeStep () << event);
+
Time tAbsolute = time + TimeStep (m_currentTs);
NS_ASSERT (tAbsolute.IsPositive ());
@@ -465,6 +493,8 @@
EventId
DistributedSimulatorImpl::ScheduleNow (EventImpl *event)
{
+ NS_LOG_FUNCTION (this << event);
+
Scheduler::Event ev;
ev.impl = event;
ev.key.m_ts = m_currentTs;
@@ -479,6 +509,8 @@
EventId
DistributedSimulatorImpl::ScheduleDestroy (EventImpl *event)
{
+ NS_LOG_FUNCTION (this << event);
+
EventId id (Ptr<EventImpl> (event, false), m_currentTs, 0xffffffff, 2);
m_destroyEvents.push_back (id);
m_uid++;
--- a/src/mpi/model/distributed-simulator-impl.h Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/model/distributed-simulator-impl.h Fri Dec 06 14:57:33 2013 -0500
@@ -14,10 +14,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: George Riley <riley@ece.gatech.edu>
+ *
*/
-#ifndef DISTRIBUTED_SIMULATOR_IMPL_H
-#define DISTRIBUTED_SIMULATOR_IMPL_H
+#ifndef NS3_DISTRIBUTED_SIMULATOR_IMPL_H
+#define NS3_DISTRIBUTED_SIMULATOR_IMPL_H
#include "ns3/simulator-impl.h"
#include "ns3/scheduler.h"
@@ -79,7 +80,7 @@
*/
uint32_t GetMyId ();
/**
- * \return true if LBTS message is finished
+ * \return true if system is finished
*/
bool IsFinished ();
@@ -95,7 +96,7 @@
* \ingroup simulator
* \ingroup mpi
*
- * \brief distributed simulator implementation using lookahead
+ * \brief Distributed simulator implementation using lookahead
*/
class DistributedSimulatorImpl : public SimulatorImpl
{
@@ -157,4 +158,4 @@
} // namespace ns3
-#endif /* DISTRIBUTED_SIMULATOR_IMPL_H */
+#endif /* NS3_DISTRIBUTED_SIMULATOR_IMPL_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mpi/model/granted-time-window-mpi-interface.cc Fri Dec 06 14:57:33 2013 -0500
@@ -0,0 +1,337 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: George Riley <riley@ece.gatech.edu>
+ *
+ */
+
+// This object contains static methods that provide an easy interface
+// to the necessary MPI information.
+
+#include <iostream>
+#include <iomanip>
+#include <list>
+
+#include "granted-time-window-mpi-interface.h"
+#include "mpi-receiver.h"
+#include "mpi-interface.h"
+
+#include "ns3/node.h"
+#include "ns3/node-list.h"
+#include "ns3/net-device.h"
+#include "ns3/simulator.h"
+#include "ns3/simulator-impl.h"
+#include "ns3/nstime.h"
+#include "ns3/log.h"
+
+#ifdef NS3_MPI
+#include <mpi.h>
+#endif
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("GrantedTimeWindowMpiInterface");
+
+
+SentBuffer::SentBuffer ()
+{
+ m_buffer = 0;
+ m_request = 0;
+}
+
+SentBuffer::~SentBuffer ()
+{
+ delete [] m_buffer;
+}
+
+uint8_t*
+SentBuffer::GetBuffer ()
+{
+ return m_buffer;
+}
+
+void
+SentBuffer::SetBuffer (uint8_t* buffer)
+{
+ m_buffer = buffer;
+}
+
+#ifdef NS3_MPI
+MPI_Request*
+SentBuffer::GetRequest ()
+{
+ return &m_request;
+}
+#endif
+
+uint32_t GrantedTimeWindowMpiInterface::m_sid = 0;
+uint32_t GrantedTimeWindowMpiInterface::m_size = 1;
+bool GrantedTimeWindowMpiInterface::m_initialized = false;
+bool GrantedTimeWindowMpiInterface::m_enabled = false;
+uint32_t GrantedTimeWindowMpiInterface::m_rxCount = 0;
+uint32_t GrantedTimeWindowMpiInterface::m_txCount = 0;
+std::list<SentBuffer> GrantedTimeWindowMpiInterface::m_pendingTx;
+
+#ifdef NS3_MPI
+MPI_Request* GrantedTimeWindowMpiInterface::m_requests;
+char** GrantedTimeWindowMpiInterface::m_pRxBuffers;
+#endif
+
+TypeId
+GrantedTimeWindowMpiInterface::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::GrantedTimeWindowMpiInterface")
+ .SetParent<Object> ()
+ ;
+ return tid;
+}
+
+void
+GrantedTimeWindowMpiInterface::Destroy ()
+{
+ NS_LOG_FUNCTION (this);
+
+#ifdef NS3_MPI
+ for (uint32_t i = 0; i < GetSize (); ++i)
+ {
+ delete [] m_pRxBuffers[i];
+ }
+ delete [] m_pRxBuffers;
+ delete [] m_requests;
+
+ m_pendingTx.clear ();
+#endif
+}
+
+uint32_t
+GrantedTimeWindowMpiInterface::GetRxCount ()
+{
+ return m_rxCount;
+}
+
+uint32_t
+GrantedTimeWindowMpiInterface::GetTxCount ()
+{
+ return m_txCount;
+}
+
+uint32_t
+GrantedTimeWindowMpiInterface::GetSystemId ()
+{
+ if (!m_initialized)
+ {
+ Simulator::GetImplementation ();
+ m_initialized = true;
+ }
+ return m_sid;
+}
+
+uint32_t
+GrantedTimeWindowMpiInterface::GetSize ()
+{
+ if (!m_initialized)
+ {
+ Simulator::GetImplementation ();
+ m_initialized = true;
+ }
+ return m_size;
+}
+
+bool
+GrantedTimeWindowMpiInterface::IsEnabled ()
+{
+ if (!m_initialized)
+ {
+ Simulator::GetImplementation ();
+ m_initialized = true;
+ }
+ return m_enabled;
+}
+
+void
+GrantedTimeWindowMpiInterface::Enable (int* pargc, char*** pargv)
+{
+ NS_LOG_FUNCTION (this << pargc << pargv);
+
+#ifdef NS3_MPI
+ // Initialize the MPI interface
+ MPI_Init (pargc, pargv);
+ MPI_Barrier (MPI_COMM_WORLD);
+ MPI_Comm_rank (MPI_COMM_WORLD, reinterpret_cast <int *> (&m_sid));
+ MPI_Comm_size (MPI_COMM_WORLD, reinterpret_cast <int *> (&m_size));
+ m_enabled = true;
+ m_initialized = true;
+ // Post a non-blocking receive for all peers
+ m_pRxBuffers = new char*[m_size];
+ m_requests = new MPI_Request[m_size];
+ for (uint32_t i = 0; i < GetSize (); ++i)
+ {
+ m_pRxBuffers[i] = new char[MAX_MPI_MSG_SIZE];
+ MPI_Irecv (m_pRxBuffers[i], MAX_MPI_MSG_SIZE, MPI_CHAR, MPI_ANY_SOURCE, 0,
+ MPI_COMM_WORLD, &m_requests[i]);
+ }
+#else
+ NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
+#endif
+}
+
+void
+GrantedTimeWindowMpiInterface::SendPacket (Ptr<Packet> p, const Time& rxTime, uint32_t node, uint32_t dev)
+{
+ NS_LOG_FUNCTION (this << p << rxTime.GetTimeStep () << node << dev);
+
+#ifdef NS3_MPI
+ SentBuffer sendBuf;
+ m_pendingTx.push_back (sendBuf);
+ std::list<SentBuffer>::reverse_iterator i = m_pendingTx.rbegin (); // Points to the last element
+
+ uint32_t serializedSize = p->GetSerializedSize ();
+ uint8_t* buffer = new uint8_t[serializedSize + 16];
+ i->SetBuffer (buffer);
+ // Add the time, dest node and dest device
+ uint64_t t = rxTime.GetInteger ();
+ uint64_t* pTime = reinterpret_cast <uint64_t *> (buffer);
+ *pTime++ = t;
+ uint32_t* pData = reinterpret_cast<uint32_t *> (pTime);
+ *pData++ = node;
+ *pData++ = dev;
+ // Serialize the packet
+ p->Serialize (reinterpret_cast<uint8_t *> (pData), serializedSize);
+
+ // Find the system id for the destination node
+ Ptr<Node> destNode = NodeList::GetNode (node);
+ uint32_t nodeSysId = destNode->GetSystemId ();
+
+ MPI_Isend (reinterpret_cast<void *> (i->GetBuffer ()), serializedSize + 16, MPI_CHAR, nodeSysId,
+ 0, MPI_COMM_WORLD, (i->GetRequest ()));
+ m_txCount++;
+#else
+ NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
+#endif
+}
+
+void
+GrantedTimeWindowMpiInterface::ReceiveMessages ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+#ifdef NS3_MPI
+ // Poll the non-block reads to see if data arrived
+ while (true)
+ {
+ int flag = 0;
+ int index = 0;
+ MPI_Status status;
+
+ MPI_Testany (MpiInterface::GetSize (), m_requests, &index, &flag, &status);
+ if (!flag)
+ {
+ break; // No more messages
+ }
+ int count;
+ MPI_Get_count (&status, MPI_CHAR, &count);
+ m_rxCount++; // Count this receive
+
+ // Get the meta data first
+ uint64_t* pTime = reinterpret_cast<uint64_t *> (m_pRxBuffers[index]);
+ uint64_t time = *pTime++;
+ uint32_t* pData = reinterpret_cast<uint32_t *> (pTime);
+ uint32_t node = *pData++;
+ uint32_t dev = *pData++;
+
+ Time rxTime (time);
+
+ count -= sizeof (time) + sizeof (node) + sizeof (dev);
+
+ Ptr<Packet> p = Create<Packet> (reinterpret_cast<uint8_t *> (pData), count, true);
+
+ // Find the correct node/device to schedule receive event
+ Ptr<Node> pNode = NodeList::GetNode (node);
+ Ptr<MpiReceiver> pMpiRec = 0;
+ uint32_t nDevices = pNode->GetNDevices ();
+ for (uint32_t i = 0; i < nDevices; ++i)
+ {
+ Ptr<NetDevice> pThisDev = pNode->GetDevice (i);
+ if (pThisDev->GetIfIndex () == dev)
+ {
+ pMpiRec = pThisDev->GetObject<MpiReceiver> ();
+ break;
+ }
+ }
+
+ NS_ASSERT (pNode && pMpiRec);
+
+ // Schedule the rx event
+ Simulator::ScheduleWithContext (pNode->GetId (), rxTime - Simulator::Now (),
+ &MpiReceiver::Receive, pMpiRec, p);
+
+ // Re-queue the next read
+ MPI_Irecv (m_pRxBuffers[index], MAX_MPI_MSG_SIZE, MPI_CHAR, MPI_ANY_SOURCE, 0,
+ MPI_COMM_WORLD, &m_requests[index]);
+ }
+#else
+ NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
+#endif
+}
+
+void
+GrantedTimeWindowMpiInterface::TestSendComplete ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+#ifdef NS3_MPI
+ std::list<SentBuffer>::iterator i = m_pendingTx.begin ();
+ while (i != m_pendingTx.end ())
+ {
+ MPI_Status status;
+ int flag = 0;
+ MPI_Test (i->GetRequest (), &flag, &status);
+ std::list<SentBuffer>::iterator current = i; // Save current for erasing
+ i++; // Advance to next
+ if (flag)
+ { // This message is complete
+ m_pendingTx.erase (current);
+ }
+ }
+#else
+ NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
+#endif
+}
+
+void
+GrantedTimeWindowMpiInterface::Disable ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+#ifdef NS3_MPI
+ int flag = 0;
+ MPI_Initialized (&flag);
+ if (flag)
+ {
+ MPI_Finalize ();
+ m_enabled = false;
+ m_initialized = false;
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Cannot disable MPI environment without Initializing it first");
+ }
+#else
+ NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
+#endif
+}
+
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mpi/model/granted-time-window-mpi-interface.h Fri Dec 06 14:57:33 2013 -0500
@@ -0,0 +1,175 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: George Riley <riley@ece.gatech.edu>
+ *
+ */
+
+// This object contains static methods that provide an easy interface
+// to the necessary MPI information.
+
+#ifndef NS3_GRANTED_TIME_WINDOW_MPI_INTERFACE_H
+#define NS3_GRANTED_TIME_WINDOW_MPI_INTERFACE_H
+
+#include <stdint.h>
+#include <list>
+
+#include "ns3/nstime.h"
+#include "ns3/buffer.h"
+
+#include "parallel-communication-interface.h"
+
+#ifdef NS3_MPI
+#include "mpi.h"
+#else
+typedef void* MPI_Request;
+#endif
+
+namespace ns3 {
+
+/**
+ * maximum MPI message size for easy
+ * buffer creation
+ */
+const uint32_t MAX_MPI_MSG_SIZE = 2000;
+
+/**
+ * \ingroup mpi
+ *
+ * \brief Tracks non-blocking sends
+ *
+ * This class is used to keep track of the asynchronous non-blocking
+ * sends that have been posted.
+ */
+class SentBuffer
+{
+public:
+ SentBuffer ();
+ ~SentBuffer ();
+
+ /**
+ * \return pointer to sent buffer
+ */
+ uint8_t* GetBuffer ();
+ /**
+ * \param buffer pointer to sent buffer
+ */
+ void SetBuffer (uint8_t* buffer);
+ /**
+ * \return MPI request
+ */
+ MPI_Request* GetRequest ();
+
+private:
+ uint8_t* m_buffer;
+ MPI_Request m_request;
+};
+
+class Packet;
+
+/**
+ * \ingroup mpi
+ *
+ * \brief Interface between ns-3 and MPI
+ *
+ * Implements the interface used by the singleton parallel controller
+ * to interface between NS3 and the communications layer being
+ * used for inter-task packet transfers.
+ */
+class GrantedTimeWindowMpiInterface : public ParallelCommunicationInterface, Object
+{
+public:
+ static TypeId GetTypeId (void);
+
+ /**
+ * Delete all buffers
+ */
+ virtual void Destroy ();
+ /**
+ * \return MPI rank
+ */
+ virtual uint32_t GetSystemId ();
+ /**
+ * \return MPI size (number of systems)
+ */
+ virtual uint32_t GetSize ();
+ /**
+ * \return true if using MPI
+ */
+ virtual bool IsEnabled ();
+ /**
+ * \param pargc number of command line arguments
+ * \param pargv command line arguments
+ *
+ * Sets up MPI interface
+ */
+ virtual void Enable (int* pargc, char*** pargv);
+ /**
+ * Terminates the MPI environment by calling MPI_Finalize
+ * This function must be called after Destroy ()
+ * It also resets m_initialized, m_enabled
+ */
+ virtual void Disable ();
+ /**
+ * \param p packet to send
+ * \param rxTime received time at destination node
+ * \param node destination node
+ * \param dev destination device
+ *
+ * Serialize and send a packet to the specified node and net device
+ */
+ virtual void SendPacket (Ptr<Packet> p, const Time &rxTime, uint32_t node, uint32_t dev);
+ /**
+ * Check for received messages complete
+ */
+ static void ReceiveMessages ();
+ /**
+ * Check for completed sends
+ */
+ static void TestSendComplete ();
+ /**
+ * \return received count in packets
+ */
+ static uint32_t GetRxCount ();
+ /**
+ * \return transmitted count in packets
+ */
+ static uint32_t GetTxCount ();
+
+private:
+ static uint32_t m_sid;
+ static uint32_t m_size;
+
+ // Total packets received
+ static uint32_t m_rxCount;
+
+ // Total packets sent
+ static uint32_t m_txCount;
+ static bool m_initialized;
+ static bool m_enabled;
+
+ // Pending non-blocking receives
+ static MPI_Request* m_requests;
+
+ // Data buffers for non-blocking reads
+ static char** m_pRxBuffers;
+
+ // List of pending non-blocking sends
+ static std::list<SentBuffer> m_pendingTx;
+};
+
+} // namespace ns3
+
+#endif /* NS3_GRANTED_TIME_WINDOW_MPI_INTERFACE_H */
--- a/src/mpi/model/mpi-interface.cc Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/model/mpi-interface.cc Fri Dec 06 14:57:33 2013 -0500
@@ -1,5 +1,7 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
+ * Copyright 2013. Lawrence Livermore National Security, LLC.
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
@@ -13,296 +15,114 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: George Riley <riley@ece.gatech.edu>
+ * Author: Steven Smith <smith84@llnl.gov>
+ *
*/
-// This object contains static methods that provide an easy interface
-// to the necessary MPI information.
-
-#include <iostream>
-#include <iomanip>
-#include <list>
-
#include "mpi-interface.h"
-#include "mpi-receiver.h"
+
+#include <ns3/global-value.h>
+#include <ns3/string.h>
+#include <ns3/log.h>
-#include "ns3/node.h"
-#include "ns3/node-list.h"
-#include "ns3/net-device.h"
-#include "ns3/simulator.h"
-#include "ns3/simulator-impl.h"
-#include "ns3/nstime.h"
+#include "null-message-mpi-interface.h"
+#include "granted-time-window-mpi-interface.h"
-#ifdef NS3_MPI
-#include <mpi.h>
-#endif
+NS_LOG_COMPONENT_DEFINE ("MpiInterface");
namespace ns3 {
-SentBuffer::SentBuffer ()
-{
- m_buffer = 0;
- m_request = 0;
-}
-
-SentBuffer::~SentBuffer ()
-{
- delete [] m_buffer;
-}
-
-uint8_t*
-SentBuffer::GetBuffer ()
-{
- return m_buffer;
-}
-
-void
-SentBuffer::SetBuffer (uint8_t* buffer)
-{
- m_buffer = buffer;
-}
-
-#ifdef NS3_MPI
-MPI_Request*
-SentBuffer::GetRequest ()
-{
- return &m_request;
-}
-#endif
-
-uint32_t MpiInterface::m_sid = 0;
-uint32_t MpiInterface::m_size = 1;
-bool MpiInterface::m_initialized = false;
-bool MpiInterface::m_enabled = false;
-uint32_t MpiInterface::m_rxCount = 0;
-uint32_t MpiInterface::m_txCount = 0;
-std::list<SentBuffer> MpiInterface::m_pendingTx;
-
-#ifdef NS3_MPI
-MPI_Request* MpiInterface::m_requests;
-char** MpiInterface::m_pRxBuffers;
-#endif
+ParallelCommunicationInterface* MpiInterface::g_parallelCommunicationInterface = 0;
void
MpiInterface::Destroy ()
{
-#ifdef NS3_MPI
- for (uint32_t i = 0; i < GetSize (); ++i)
- {
- delete [] m_pRxBuffers[i];
- }
- delete [] m_pRxBuffers;
- delete [] m_requests;
-
- m_pendingTx.clear ();
-#endif
-}
-
-uint32_t
-MpiInterface::GetRxCount ()
-{
- return m_rxCount;
-}
-
-uint32_t
-MpiInterface::GetTxCount ()
-{
- return m_txCount;
+ NS_ASSERT (g_parallelCommunicationInterface);
+ g_parallelCommunicationInterface->Destroy ();
}
uint32_t
MpiInterface::GetSystemId ()
{
- if (!m_initialized)
- {
- Simulator::GetImplementation ();
- m_initialized = true;
- }
- return m_sid;
+ if ( g_parallelCommunicationInterface )
+ return g_parallelCommunicationInterface->GetSystemId ();
+ else
+ return 0;
}
uint32_t
MpiInterface::GetSize ()
{
- if (!m_initialized)
- {
- Simulator::GetImplementation ();
- m_initialized = true;
- }
- return m_size;
+ if ( g_parallelCommunicationInterface )
+ return g_parallelCommunicationInterface->GetSize ();
+ else
+ return 1;
}
bool
MpiInterface::IsEnabled ()
{
- if (!m_initialized)
+ if (g_parallelCommunicationInterface)
{
- Simulator::GetImplementation ();
- m_initialized = true;
+ return g_parallelCommunicationInterface->IsEnabled ();
}
- return m_enabled;
+ else
+ {
+ return false;
+ }
}
void
MpiInterface::Enable (int* pargc, char*** pargv)
{
-#ifdef NS3_MPI
- // Initialize the MPI interface
- MPI_Init (pargc, pargv);
- MPI_Barrier (MPI_COMM_WORLD);
- MPI_Comm_rank (MPI_COMM_WORLD, reinterpret_cast <int *> (&m_sid));
- MPI_Comm_size (MPI_COMM_WORLD, reinterpret_cast <int *> (&m_size));
- m_enabled = true;
- m_initialized = true;
- // Post a non-blocking receive for all peers
- m_pRxBuffers = new char*[m_size];
- m_requests = new MPI_Request[m_size];
- for (uint32_t i = 0; i < GetSize (); ++i)
+ StringValue simulationTypeValue;
+ bool useDefault = true;
+
+ if (GlobalValue::GetValueByNameFailSafe ("SimulatorImplementationType", simulationTypeValue))
{
- m_pRxBuffers[i] = new char[MAX_MPI_MSG_SIZE];
- MPI_Irecv (m_pRxBuffers[i], MAX_MPI_MSG_SIZE, MPI_CHAR, MPI_ANY_SOURCE, 0,
- MPI_COMM_WORLD, &m_requests[i]);
+ std::string simulationType = simulationTypeValue.Get ();
+
+ // Set communication interface based on the simulation type being used.
+ // Defaults to synchronous.
+ if (simulationType.compare ("ns3::NullMessageSimulatorImpl") == 0)
+ {
+ g_parallelCommunicationInterface = new NullMessageMpiInterface ();
+ useDefault = false;
+ }
+ else if (simulationType.compare ("ns3::DistributedSimulatorImpl") == 0)
+ {
+ g_parallelCommunicationInterface = new GrantedTimeWindowMpiInterface ();
+ useDefault = false;
+ }
}
-#else
- NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
-#endif
+
+ // User did not specify a valid parallel simulator; use the default.
+ if (useDefault)
+ {
+ g_parallelCommunicationInterface = new GrantedTimeWindowMpiInterface ();
+ GlobalValue::Bind ("SimulatorImplementationType",
+ StringValue ("ns3::DistributedSimulatorImpl"));
+ NS_LOG_WARN ("SimulatorImplementationType was set to non-parallel simulator; setting type to ns3::DistributedSimulatorImp");
+ }
+
+ g_parallelCommunicationInterface->Enable (pargc, pargv);
}
void
MpiInterface::SendPacket (Ptr<Packet> p, const Time& rxTime, uint32_t node, uint32_t dev)
{
-#ifdef NS3_MPI
- SentBuffer sendBuf;
- m_pendingTx.push_back (sendBuf);
- std::list<SentBuffer>::reverse_iterator i = m_pendingTx.rbegin (); // Points to the last element
+ NS_ASSERT (g_parallelCommunicationInterface);
+ g_parallelCommunicationInterface->SendPacket (p, rxTime, node, dev);
+}
- uint32_t serializedSize = p->GetSerializedSize ();
- uint8_t* buffer = new uint8_t[serializedSize + 16];
- i->SetBuffer (buffer);
- // Add the time, dest node and dest device
- uint64_t t = rxTime.GetNanoSeconds ();
- uint64_t* pTime = reinterpret_cast <uint64_t *> (buffer);
- *pTime++ = t;
- uint32_t* pData = reinterpret_cast<uint32_t *> (pTime);
- *pData++ = node;
- *pData++ = dev;
- // Serialize the packet
- p->Serialize (reinterpret_cast<uint8_t *> (pData), serializedSize);
-
- // Find the system id for the destination node
- Ptr<Node> destNode = NodeList::GetNode (node);
- uint32_t nodeSysId = destNode->GetSystemId ();
-
- MPI_Isend (reinterpret_cast<void *> (i->GetBuffer ()), serializedSize + 16, MPI_CHAR, nodeSysId,
- 0, MPI_COMM_WORLD, (i->GetRequest ()));
- m_txCount++;
-#else
- NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
-#endif
-}
void
-MpiInterface::ReceiveMessages ()
-{ // Poll the non-block reads to see if data arrived
-#ifdef NS3_MPI
- while (true)
- {
- int flag = 0;
- int index = 0;
- MPI_Status status;
-
- MPI_Testany (GetSize (), m_requests, &index, &flag, &status);
- if (!flag)
- {
- break; // No more messages
- }
- int count;
- MPI_Get_count (&status, MPI_CHAR, &count);
- m_rxCount++; // Count this receive
-
- // Get the meta data first
- uint64_t* pTime = reinterpret_cast<uint64_t *> (m_pRxBuffers[index]);
- uint64_t nanoSeconds = *pTime++;
- uint32_t* pData = reinterpret_cast<uint32_t *> (pTime);
- uint32_t node = *pData++;
- uint32_t dev = *pData++;
-
- Time rxTime = NanoSeconds (nanoSeconds);
-
- count -= sizeof (nanoSeconds) + sizeof (node) + sizeof (dev);
-
- Ptr<Packet> p = Create<Packet> (reinterpret_cast<uint8_t *> (pData), count, true);
-
- // Find the correct node/device to schedule receive event
- Ptr<Node> pNode = NodeList::GetNode (node);
- Ptr<MpiReceiver> pMpiRec = 0;
- uint32_t nDevices = pNode->GetNDevices ();
- for (uint32_t i = 0; i < nDevices; ++i)
- {
- Ptr<NetDevice> pThisDev = pNode->GetDevice (i);
- if (pThisDev->GetIfIndex () == dev)
- {
- pMpiRec = pThisDev->GetObject<MpiReceiver> ();
- break;
- }
- }
-
- NS_ASSERT (pNode && pMpiRec);
-
- // Schedule the rx event
- Simulator::ScheduleWithContext (pNode->GetId (), rxTime - Simulator::Now (),
- &MpiReceiver::Receive, pMpiRec, p);
-
- // Re-queue the next read
- MPI_Irecv (m_pRxBuffers[index], MAX_MPI_MSG_SIZE, MPI_CHAR, MPI_ANY_SOURCE, 0,
- MPI_COMM_WORLD, &m_requests[index]);
- }
-#else
- NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
-#endif
-}
-
-void
-MpiInterface::TestSendComplete ()
-{
-#ifdef NS3_MPI
- std::list<SentBuffer>::iterator i = m_pendingTx.begin ();
- while (i != m_pendingTx.end ())
- {
- MPI_Status status;
- int flag = 0;
- MPI_Test (i->GetRequest (), &flag, &status);
- std::list<SentBuffer>::iterator current = i; // Save current for erasing
- i++; // Advance to next
- if (flag)
- { // This message is complete
- m_pendingTx.erase (current);
- }
- }
-#else
- NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
-#endif
-}
-
-void
MpiInterface::Disable ()
{
-#ifdef NS3_MPI
- int flag = 0;
- MPI_Initialized (&flag);
- if (flag)
- {
- MPI_Finalize ();
- m_enabled = false;
- m_initialized = false;
- }
- else
- {
- NS_FATAL_ERROR ("Cannot disable MPI environment without Initializing it first");
- }
-#else
- NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
-#endif
+ NS_ASSERT (g_parallelCommunicationInterface);
+ g_parallelCommunicationInterface->Disable ();
+ delete g_parallelCommunicationInterface;
+ g_parallelCommunicationInterface = 0;
}
--- a/src/mpi/model/mpi-interface.h Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/model/mpi-interface.h Fri Dec 06 14:57:33 2013 -0500
@@ -1,5 +1,7 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
+ * Copyright 2013. Lawrence Livermore National Security, LLC.
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
@@ -13,109 +15,74 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Author: George Riley <riley@ece.gatech.edu>
+ * Author: Steven Smith <smith84@llnl.gov>
+ *
*/
-// This object contains static methods that provide an easy interface
-// to the necessary MPI information.
-
#ifndef NS3_MPI_INTERFACE_H
#define NS3_MPI_INTERFACE_H
-#include <stdint.h>
-#include <list>
-
-#include "ns3/nstime.h"
-#include "ns3/buffer.h"
-
-#if defined(NS3_OPENMPI)
-struct ompi_request_t;
-typedef struct ompi_request_t* MPI_Request;
-#elif defined(NS3_MPICH)
-typedef int MPI_Request;
-#else
-typedef void* MPI_Request;
-#endif
+#include <ns3/nstime.h>
+#include <ns3/packet.h>
namespace ns3 {
-
/**
* \defgroup mpi MPI Distributed Simulation
*
*/
-/**
- * maximum MPI message size for easy
- * buffer creation
- */
-const uint32_t MAX_MPI_MSG_SIZE = 2000;
+class ParallelCommunicationInterface;
/**
* \ingroup mpi
*
- * Define a class for tracking the non-block sends
- */
-class SentBuffer
-{
-public:
- SentBuffer ();
- ~SentBuffer ();
-
- /**
- * \return pointer to sent buffer
- */
- uint8_t* GetBuffer ();
- /**
- * \param buffer pointer to sent buffer
- */
- void SetBuffer (uint8_t* buffer);
- /**
- * \return MPI request
- */
- MPI_Request* GetRequest ();
-
-private:
- uint8_t* m_buffer;
- MPI_Request m_request;
-};
-
-class Packet;
-
-/**
- * \ingroup mpi
+ * \brief Singleton used to interface to the communications infrastructure
+ * when running NS3 in parallel.
*
- * Interface between ns-3 and MPI
+ * Delegates the implementation to the specific parallel
+ * infrastructure being used. Implementation is defined in the
+ * ParallelCommunicationInterface virtual base class; this API mirrors
+ * that interface. This singleton is responsible for instantiating an
+ * instance of the communication interface based on
+ * SimulatorImplementationType attribute in ns3::GlobalValues. The
+ * attribute must be set before Enable is invoked.
*/
class MpiInterface
{
public:
/**
- * Delete all buffers
+ * Deletes storage used by the parallel environment.
*/
static void Destroy ();
/**
- * \return MPI rank
+ * \return system identification
+ *
+ * When running a sequential simulation this will return a systemID of 0.
*/
static uint32_t GetSystemId ();
/**
- * \return MPI size (number of systems)
+ * \return number of parallel tasks
+ *
+ * When running a sequential simulation this will return a size of 1.
*/
static uint32_t GetSize ();
/**
- * \return true if using MPI
+ * \return true if parallel communication is enabled
*/
static bool IsEnabled ();
/**
* \param pargc number of command line arguments
* \param pargv command line arguments
*
- * Sets up MPI interface
+ * \brief Sets up parallel communication interface.
+ *
+ * SimulatorImplementationType attribute in ns3::GlobalValues must be set before
+ * Enable is invoked.
*/
static void Enable (int* pargc, char*** pargv);
/**
- * Terminates the MPI environment by calling MPI_Finalize
+ * Terminates the parallel environment.
* This function must be called after Destroy ()
- * It also resets m_initialized, m_enabled
*/
static void Disable ();
/**
@@ -127,43 +94,12 @@
* Serialize and send a packet to the specified node and net device
*/
static void SendPacket (Ptr<Packet> p, const Time &rxTime, uint32_t node, uint32_t dev);
- /**
- * Check for received messages complete
- */
- static void ReceiveMessages ();
- /**
- * Check for completed sends
- */
- static void TestSendComplete ();
- /**
- * \return received count in packets
- */
- static uint32_t GetRxCount ();
- /**
- * \return transmitted count in packets
- */
- static uint32_t GetTxCount ();
+private:
-private:
- static uint32_t m_sid;
- static uint32_t m_size;
-
- // Total packets received
- static uint32_t m_rxCount;
-
- // Total packets sent
- static uint32_t m_txCount;
- static bool m_initialized;
- static bool m_enabled;
-
- // Pending non-blocking receives
- static MPI_Request* m_requests;
-
- // Data buffers for non-blocking reads
- static char** m_pRxBuffers;
-
- // List of pending non-blocking sends
- static std::list<SentBuffer> m_pendingTx;
+ /**
+ * Static instance of the instantiated parallel controller.
+ */
+ static ParallelCommunicationInterface* g_parallelCommunicationInterface;
};
} // namespace ns3
--- a/src/mpi/model/mpi-receiver.cc Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/model/mpi-receiver.cc Fri Dec 06 14:57:33 2013 -0500
@@ -33,13 +33,13 @@
{
}
-void
+void
MpiReceiver::SetReceiveCallback (Callback<void, Ptr<Packet> > callback)
{
m_rxCallback = callback;
}
-void
+void
MpiReceiver::Receive (Ptr<Packet> p)
{
NS_ASSERT (!m_rxCallback.IsNull ());
--- a/src/mpi/model/mpi-receiver.h Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/model/mpi-receiver.h Fri Dec 06 14:57:33 2013 -0500
@@ -16,7 +16,7 @@
* Author: George Riley <riley@ece.gatech.edu>
*/
-// Provides an interface to aggregate to MPI-compatible NetDevices
+// Provides an interface to aggregate to MPI-compatible NetDevices
#ifndef NS3_MPI_RECEIVER_H
#define NS3_MPI_RECEIVER_H
@@ -29,8 +29,8 @@
/**
* \ingroup mpi
*
- * Class to aggregate to a NetDevice if it supports MPI capability
- *
+ * \brief Class to aggregate to a NetDevice if it supports MPI capability
+ *
* MpiInterface::ReceiveMessages () needs to send packets to a NetDevice
* Receive() method. Since each NetDevice's Receive() method is specific
* to the derived class, and since we do not know whether such a NetDevice
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mpi/model/null-message-mpi-interface.cc Fri Dec 06 14:57:33 2013 -0500
@@ -0,0 +1,460 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2013. Lawrence Livermore National Security, LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Steven Smith <smith84@llnl.gov>
+ *
+ */
+
+#include "null-message-mpi-interface.h"
+
+#include "null-message-simulator-impl.h"
+#include "remote-channel-bundle-manager.h"
+#include "remote-channel-bundle.h"
+
+#include "ns3/mpi-receiver.h"
+#include "ns3/node.h"
+#include "ns3/node-list.h"
+#include "ns3/net-device.h"
+#include "ns3/nstime.h"
+#include "ns3/simulator.h"
+#include "ns3/log.h"
+
+#ifdef NS3_MPI
+#include <mpi.h>
+#endif
+
+#include <iostream>
+#include <iomanip>
+#include <list>
+
+NS_LOG_COMPONENT_DEFINE ("NullMessageMpiInterface");
+
+namespace ns3 {
+
+/**
+ * maximum MPI message size for easy
+ * buffer creation
+ */
+const uint32_t NULL_MESSAGE_MAX_MPI_MSG_SIZE = 2000;
+
+
+NullMessageSentBuffer::NullMessageSentBuffer ()
+{
+ m_buffer = 0;
+ m_request = 0;
+}
+
+NullMessageSentBuffer::~NullMessageSentBuffer ()
+{
+ delete [] m_buffer;
+}
+
+uint8_t*
+NullMessageSentBuffer::GetBuffer ()
+{
+ return m_buffer;
+}
+
+void
+NullMessageSentBuffer::SetBuffer (uint8_t* buffer)
+{
+ m_buffer = buffer;
+}
+
+MPI_Request*
+NullMessageSentBuffer::GetRequest ()
+{
+ return &m_request;
+}
+
+uint32_t NullMessageMpiInterface::g_sid = 0;
+uint32_t NullMessageMpiInterface::g_size = 1;
+uint32_t NullMessageMpiInterface::g_numNeighbors = 0;
+bool NullMessageMpiInterface::g_initialized = false;
+bool NullMessageMpiInterface::g_enabled = false;
+std::list<NullMessageSentBuffer> NullMessageMpiInterface::g_pendingTx;
+
+MPI_Request* NullMessageMpiInterface::g_requests;
+char** NullMessageMpiInterface::g_pRxBuffers;
+
+NullMessageMpiInterface::NullMessageMpiInterface ()
+{
+ NS_LOG_FUNCTION (this);
+
+#ifndef NS3_MPI
+ /*
+ * This class can only be constructed if MPI is available. Fail if an
+ * attempt is made to instantiate this class without MPI.
+ */
+ NS_FATAL_ERROR ("Must compile with MPI if Null Message simulator is used, see --enable-mpi option for waf");
+#endif
+}
+
+NullMessageMpiInterface::~NullMessageMpiInterface ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void
+NullMessageMpiInterface::Destroy ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+uint32_t
+NullMessageMpiInterface::GetSystemId ()
+{
+ NS_ASSERT (g_enabled);
+ return g_sid;
+}
+
+uint32_t
+NullMessageMpiInterface::GetSize ()
+{
+ NS_ASSERT (g_enabled);
+ return g_size;
+}
+
+bool
+NullMessageMpiInterface::IsEnabled ()
+{
+ if (!g_initialized)
+ {
+ Simulator::GetImplementation ();
+ g_initialized = true;
+ }
+ return g_enabled;
+}
+
+void
+NullMessageMpiInterface::Enable (int* pargc, char*** pargv)
+{
+ NS_LOG_FUNCTION (this << *pargc);
+#ifdef NS3_MPI
+
+ // Initialize the MPI interface
+ MPI_Init (pargc, pargv);
+ MPI_Barrier (MPI_COMM_WORLD);
+
+ // SystemId and Size are unit32_t in interface but MPI uses int so convert.
+ int mpiSystemId;
+ int mpiSize;
+ MPI_Comm_rank (MPI_COMM_WORLD, &mpiSystemId);
+ MPI_Comm_size (MPI_COMM_WORLD, &mpiSize);
+
+ g_sid = mpiSystemId;
+ g_size = mpiSize;
+
+ g_enabled = true;
+ g_initialized = true;
+
+#endif
+}
+
+void
+NullMessageMpiInterface::InitializeSendReceiveBuffers(void)
+{
+ NS_LOG_FUNCTION_NOARGS ();
+#ifdef NS3_MPI
+ NS_ASSERT (g_enabled);
+
+ g_numNeighbors = RemoteChannelBundleManager::Size();
+
+ // Post a non-blocking receive for all peers
+ g_requests = new MPI_Request[g_numNeighbors];
+ g_pRxBuffers = new char*[g_numNeighbors];
+ int index = 0;
+ for (uint32_t rank = 0; rank < g_size; ++rank)
+ {
+ Ptr<RemoteChannelBundle> bundle = RemoteChannelBundleManager::Find(rank);
+ if (bundle)
+ {
+ g_pRxBuffers[index] = new char[NULL_MESSAGE_MAX_MPI_MSG_SIZE];
+ MPI_Irecv (g_pRxBuffers[index], NULL_MESSAGE_MAX_MPI_MSG_SIZE, MPI_CHAR, rank, 0,
+ MPI_COMM_WORLD, &g_requests[index]);
+ ++index;
+ }
+ }
+#endif
+}
+
+void
+NullMessageMpiInterface::SendPacket (Ptr<Packet> p, const Time& rxTime, uint32_t node, uint32_t dev)
+{
+ NS_LOG_FUNCTION (this << p << rxTime.GetTimeStep () << node << dev);
+
+ NS_ASSERT (g_enabled);
+
+#ifdef NS3_MPI
+
+ // Find the system id for the destination node
+ Ptr<Node> destNode = NodeList::GetNode (node);
+ uint32_t nodeSysId = destNode->GetSystemId ();
+
+ NullMessageSentBuffer sendBuf;
+ g_pendingTx.push_back (sendBuf);
+ std::list<NullMessageSentBuffer>::reverse_iterator iter = g_pendingTx.rbegin (); // Points to the last element
+
+ uint32_t serializedSize = p->GetSerializedSize ();
+ uint32_t bufferSize = serializedSize + ( 2 * sizeof (uint64_t) ) + ( 2 * sizeof (uint32_t) );
+ uint8_t* buffer = new uint8_t[bufferSize];
+ iter->SetBuffer (buffer);
+ // Add the time, dest node and dest device
+ uint64_t t = rxTime.GetInteger ();
+ uint64_t* pTime = reinterpret_cast <uint64_t *> (buffer);
+ *pTime++ = t;
+
+ Time guarantee_update = NullMessageSimulatorImpl::GetInstance ()->CalculateGuaranteeTime (nodeSysId);
+ *pTime++ = guarantee_update.GetTimeStep ();
+
+ uint32_t* pData = reinterpret_cast<uint32_t *> (pTime);
+ *pData++ = node;
+ *pData++ = dev;
+ // Serialize the packet
+ p->Serialize (reinterpret_cast<uint8_t *> (pData), serializedSize);
+
+ MPI_Isend (reinterpret_cast<void *> (iter->GetBuffer ()), bufferSize, MPI_CHAR, nodeSysId,
+ 0, MPI_COMM_WORLD, (iter->GetRequest ()));
+
+ NullMessageSimulatorImpl::GetInstance ()->RescheduleNullMessageEvent (nodeSysId);
+
+#endif
+}
+
+void
+NullMessageMpiInterface::SendNullMessage (const Time& guarantee_update, Ptr<RemoteChannelBundle> bundle)
+{
+ NS_LOG_FUNCTION (guarantee_update.GetTimeStep () << bundle);
+
+ NS_ASSERT (g_enabled);
+
+#ifdef NS3_MPI
+
+ NullMessageSentBuffer sendBuf;
+ g_pendingTx.push_back (sendBuf);
+ std::list<NullMessageSentBuffer>::reverse_iterator iter = g_pendingTx.rbegin (); // Points to the last element
+
+ uint32_t bufferSize = 2 * sizeof (uint64_t) + 2 * sizeof (uint32_t);
+ uint8_t* buffer = new uint8_t[bufferSize];
+ iter->SetBuffer (buffer);
+ // Add the time, dest node and dest device
+ uint64_t* pTime = reinterpret_cast <uint64_t *> (buffer);
+ *pTime++ = 0;
+ *pTime++ = guarantee_update.GetInteger ();
+ uint32_t* pData = reinterpret_cast<uint32_t *> (pTime);
+ *pData++ = 0;
+ *pData++ = 0;
+
+ // Find the system id for the destination MPI rank
+ uint32_t nodeSysId = bundle->GetSystemId ();
+
+ MPI_Isend (reinterpret_cast<void *> (iter->GetBuffer ()), bufferSize, MPI_CHAR, nodeSysId,
+ 0, MPI_COMM_WORLD, (iter->GetRequest ()));
+#endif
+}
+
+void
+NullMessageMpiInterface::ReceiveMessagesBlocking ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ ReceiveMessages(true);
+}
+
+
+void
+NullMessageMpiInterface::ReceiveMessagesNonBlocking ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ ReceiveMessages(false);
+}
+
+
+void
+NullMessageMpiInterface::ReceiveMessages (bool blocking)
+{
+ NS_LOG_FUNCTION (blocking);
+
+ NS_ASSERT (g_enabled);
+
+#ifdef NS3_MPI
+
+ // stop flag set to true when no more messages are found to
+ // process.
+ bool stop = false;
+
+
+ if (!g_numNeighbors) {
+ // Not communicating with anyone.
+ return;
+ }
+
+ do
+ {
+ int messageReceived = 0;
+ int index = 0;
+ MPI_Status status;
+
+ if (blocking)
+ {
+ MPI_Waitany (g_numNeighbors, g_requests, &index, &status);
+ messageReceived = 1; /* Wait always implies message was received */
+ stop = true;
+ }
+ else
+ {
+ MPI_Testany (g_numNeighbors, g_requests, &index, &messageReceived, &status);
+ }
+
+ if (messageReceived)
+ {
+ int count;
+ MPI_Get_count (&status, MPI_CHAR, &count);
+
+ // Get the meta data first
+ uint64_t* pTime = reinterpret_cast<uint64_t *> (g_pRxBuffers[index]);
+ uint64_t time = *pTime++;
+ uint64_t guaranteeUpdate = *pTime++;
+
+ uint32_t* pData = reinterpret_cast<uint32_t *> (pTime);
+ uint32_t node = *pData++;
+ uint32_t dev = *pData++;
+
+ Time rxTime (time);
+
+ // rxtime == 0 means this is a Null Message
+ if (rxTime > 0)
+ {
+ count -= sizeof (time) + sizeof (guaranteeUpdate) + sizeof (node) + sizeof (dev);
+
+ Ptr<Packet> p = Create<Packet> (reinterpret_cast<uint8_t *> (pData), count, true);
+
+ // Find the correct node/device to schedule receive event
+ Ptr<Node> pNode = NodeList::GetNode (node);
+ Ptr<MpiReceiver> pMpiRec = 0;
+ uint32_t nDevices = pNode->GetNDevices ();
+ for (uint32_t i = 0; i < nDevices; ++i)
+ {
+ Ptr<NetDevice> pThisDev = pNode->GetDevice (i);
+ if (pThisDev->GetIfIndex () == dev)
+ {
+ pMpiRec = pThisDev->GetObject<MpiReceiver> ();
+ break;
+ }
+ }
+ NS_ASSERT (pNode && pMpiRec);
+
+ // Schedule the rx event
+ Simulator::ScheduleWithContext (pNode->GetId (), rxTime - Simulator::Now (),
+ &MpiReceiver::Receive, pMpiRec, p);
+
+ }
+
+ // Update guarantee time for both packet receives and Null Messages.
+ Ptr<RemoteChannelBundle> bundle = RemoteChannelBundleManager::Find (status.MPI_SOURCE);
+ NS_ASSERT (bundle);
+
+ bundle->SetGuaranteeTime (Time (guaranteeUpdate));
+
+ // Re-queue the next read
+ MPI_Irecv (g_pRxBuffers[index], NULL_MESSAGE_MAX_MPI_MSG_SIZE, MPI_CHAR, status.MPI_SOURCE, 0,
+ MPI_COMM_WORLD, &g_requests[index]);
+
+ }
+ else
+ {
+ // if non-blocking and no message received in testany then stop message loop
+ stop = true;
+ }
+ }
+ while (!stop);
+#endif
+}
+
+void
+NullMessageMpiInterface::TestSendComplete ()
+{
+ NS_LOG_FUNCTION_NOARGS ();
+
+ NS_ASSERT (g_enabled);
+
+#ifdef NS3_MPI
+ std::list<NullMessageSentBuffer>::iterator iter = g_pendingTx.begin ();
+ while (iter != g_pendingTx.end ())
+ {
+ MPI_Status status;
+ int flag = 0;
+ MPI_Test (iter->GetRequest (), &flag, &status);
+ std::list<NullMessageSentBuffer>::iterator current = iter; // Save current for erasing
+ ++iter; // Advance to next
+ if (flag)
+ { // This message is complete
+ g_pendingTx.erase (current);
+ }
+ }
+#endif
+}
+
+void
+NullMessageMpiInterface::Disable ()
+{
+ NS_LOG_FUNCTION (this);
+
+#ifdef NS3_MPI
+ int flag = 0;
+ MPI_Initialized (&flag);
+ if (flag)
+ {
+
+ for (std::list<NullMessageSentBuffer>::iterator iter = g_pendingTx.begin ();
+ iter != g_pendingTx.end ();
+ ++iter)
+ {
+ MPI_Cancel (iter->GetRequest ());
+ MPI_Request_free (iter->GetRequest ());
+ }
+
+ for (uint32_t i = 0; i < g_numNeighbors; ++i)
+ {
+ MPI_Cancel (&g_requests[i]);
+ MPI_Request_free (&g_requests[i]);
+ }
+
+ MPI_Finalize ();
+
+ for (uint32_t i = 0; i < g_numNeighbors; ++i)
+ {
+ delete [] g_pRxBuffers[i];
+ }
+ delete [] g_pRxBuffers;
+ delete [] g_requests;
+
+ g_pendingTx.clear ();
+
+ g_enabled = false;
+ g_initialized = false;
+
+ }
+ else
+ {
+ NS_FATAL_ERROR ("Cannot disable MPI environment without Initializing it first");
+ }
+#endif
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mpi/model/null-message-mpi-interface.h Fri Dec 06 14:57:33 2013 -0500
@@ -0,0 +1,228 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2013. Lawrence Livermore National Security, LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Steven Smith <smith84@llnl.gov>
+ *
+ */
+
+#ifndef NS3_NULLMESSAGE_MPI_INTERFACE_H
+#define NS3_NULLMESSAGE_MPI_INTERFACE_H
+
+#include "parallel-communication-interface.h"
+
+#include <ns3/nstime.h>
+#include <ns3/buffer.h>
+
+#ifdef NS3_MPI
+#include "mpi.h"
+#else
+typedef void* MPI_Request;
+#endif
+
+#include <list>
+
+namespace ns3 {
+
+class RemoteChannelBundle;
+class Packet;
+
+/**
+ * \ingroup mpi
+ *
+ * \brief Non-blocking send buffers for Null Message implementation.
+ *
+ * One buffer is allocated for each non-blocking send.
+ */
+class NullMessageSentBuffer
+{
+public:
+ NullMessageSentBuffer ();
+ ~NullMessageSentBuffer ();
+
+ /**
+ * \return pointer to sent buffer
+ */
+ uint8_t* GetBuffer ();
+ /**
+ * \param buffer pointer to sent buffer
+ */
+ void SetBuffer (uint8_t* buffer);
+ /**
+ * \return MPI request
+ */
+ MPI_Request* GetRequest ();
+
+private:
+
+ /**
+ * Buffer for send.
+ */
+ uint8_t* m_buffer;
+
+ /**
+ * MPI request posted for the send.
+ */
+ MPI_Request m_request;
+};
+
+/**
+ * \ingroup mpi
+ *
+ * \brief Interface between ns-3 and MPI for the Null Message
+ * distributed simulation implementation.
+ */
+class NullMessageMpiInterface : public ParallelCommunicationInterface
+{
+public:
+
+ NullMessageMpiInterface ();
+ ~NullMessageMpiInterface ();
+
+ /**
+ * Delete all buffers
+ */
+ virtual void Destroy ();
+ /**
+ * \return system id (MPI rank)
+ */
+ virtual uint32_t GetSystemId ();
+ /**
+ * \return number of systems (MPI size)
+ */
+ virtual uint32_t GetSize ();
+ /**
+ * \return true if interface is enabled
+ */
+ virtual bool IsEnabled ();
+ /**
+ * \param pargc number of command line arguments
+ * \param pargv command line arguments
+ *
+ * Sets up interface. Calls MPI Init and
+ * posts receives.
+ */
+ virtual void Enable (int* pargc, char*** pargv);
+ /**
+ * Terminates the MPI environment by calling MPI_Finalize This
+ * function must be called after Destroy (). Resets m_initialized
+ * and m_enabled.
+ */
+ virtual void Disable ();
+ /**
+ * \param p packet to send
+ * \param rxTime received time at destination node
+ * \param node destination node
+ * \param dev destination device
+ *
+ * Serialize and send a packet to the specified node and net device.
+ *
+ * \internal
+ * The MPI buffer format packs a delivery information and the serialized packet.
+ *
+ * uint64_t time the packed should be delivered
+ * uint64_t guarantee time for the Null Message algorithm.
+ * uint32_t node id of destination
+ * unit32_t dev id on destination
+ * uint8_t[] serialized packet
+ * \endinternal
+ */
+ virtual void SendPacket (Ptr<Packet> p, const Time &rxTime, uint32_t node, uint32_t dev);
+ /**
+ * \param guaranteeUpdate guarantee update time for the Null Message
+ * \bundle the destination bundle for the Null Message.
+ *
+ * \brief Send a Null Message to across the specified bundle.
+ *
+ * Guarantee update time is the lower bound time on the next
+ * possible event from this MPI task to the remote MPI task across
+ * the bundle. Remote task may execute events up to time.
+ *
+ * Null Messages are sent when a packet has not been sent across
+ * this bundle in order to allow time advancement on the remote
+ * MPI task.
+ *
+ * \internal
+ * The Null Message MPI buffer format is based on the format for sending a packet with
+ * several fields set to 0 to signal that it is a Null Message. Overloading the normal packet
+ * format simplifies receive logic.
+ *
+ * uint64_t 0 must be zero for Null Message
+ * uint64_t guarantee time
+ * uint32_t 0 must be zero for Null Message
+ * uint32_t 0 must be zero for Null Message
+ * \endinternal
+ */
+ static void SendNullMessage (const Time& guaranteeUpdate, Ptr<RemoteChannelBundle> bundle);
+ /**
+ * Non-blocking check for received messages complete. Will
+ * receive all messages that are queued up locally.
+ */
+ static void ReceiveMessagesNonBlocking ();
+ /**
+ * Blocking message receive. Will block until at least one message
+ * has been received.
+ */
+ static void ReceiveMessagesBlocking ();
+ /**
+ * Check for completed sends
+ */
+ static void TestSendComplete ();
+
+ /**
+ * \brief Initialize send and receive buffers.
+ *
+ * This method should be called after all links have been added to the RemoteChannelBundle
+ * manager to setup any required send and receive buffers.
+ */
+ static void InitializeSendReceiveBuffers (void);
+
+private:
+
+ /**
+ * Check for received messages complete. Will block until message
+ * has been received if blocking flag is true. When blocking will
+ * return after the first message is received. Non-blocking mode will
+ * Non-blocking check for received messages complete. Will
+ * receive all messages that are queued up locally.
+ */
+ static void ReceiveMessages (bool blocking = false);
+
+ // System ID (rank) for this task
+ static uint32_t g_sid;
+
+ // Size of the MPI COM_WORLD group.
+ static uint32_t g_size;
+
+ // Number of neighbor tasks, tasks that this task shares a link with.
+ static uint32_t g_numNeighbors;
+
+ static bool g_initialized;
+ static bool g_enabled;
+
+ // Pending non-blocking receives
+ static MPI_Request* g_requests;
+
+ // Data buffers for non-blocking receives
+ static char** g_pRxBuffers;
+
+ // List of pending non-blocking sends
+ static std::list<NullMessageSentBuffer> g_pendingTx;
+};
+
+} // namespace ns3
+
+#endif /* NS3_NULL_MESSAGE_MPI_INTERFACE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mpi/model/null-message-simulator-impl.cc Fri Dec 06 14:57:33 2013 -0500
@@ -0,0 +1,603 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2013. Lawrence Livermore National Security, LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Steven Smith <smith84@llnl.gov>
+ *
+ */
+
+#include "null-message-simulator-impl.h"
+
+#include "null-message-mpi-interface.h"
+#include "remote-channel-bundle-manager.h"
+#include "remote-channel-bundle.h"
+#include "mpi-interface.h"
+
+#include <ns3/simulator.h>
+#include <ns3/scheduler.h>
+#include <ns3/event-impl.h>
+#include <ns3/channel.h>
+#include <ns3/node-container.h>
+#include <ns3/double.h>
+#include <ns3/ptr.h>
+#include <ns3/pointer.h>
+#include <ns3/assert.h>
+#include <ns3/log.h>
+
+#include <cmath>
+#include <iostream>
+#include <fstream>
+#include <iomanip>
+
+NS_LOG_COMPONENT_DEFINE ("NullMessageSimulatorImpl");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (NullMessageSimulatorImpl);
+
+NullMessageSimulatorImpl* NullMessageSimulatorImpl::g_instance = 0;
+
+TypeId
+NullMessageSimulatorImpl::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::NullMessageSimulatorImpl")
+ .SetParent<Object> ()
+ .AddConstructor<NullMessageSimulatorImpl> ()
+ .AddAttribute ("SchedulerTune", "Null Message scheduler tuning parameter",
+ DoubleValue (1.0),
+ MakeDoubleAccessor (&NullMessageSimulatorImpl::m_schedulerTune),
+ MakeDoubleChecker<double> (0.01,1.0))
+ ;
+ return tid;
+}
+
+NullMessageSimulatorImpl::NullMessageSimulatorImpl ()
+{
+#ifdef NS3_MPI
+ NS_LOG_FUNCTION (this);
+
+ m_myId = MpiInterface::GetSystemId ();
+ m_systemCount = MpiInterface::GetSize ();
+
+ m_stop = false;
+ // uids are allocated from 4.
+ // uid 0 is "invalid" events
+ // uid 1 is "now" events
+ // uid 2 is "destroy" events
+ m_uid = 4;
+ // before ::Run is entered, the m_currentUid will be zero
+ m_currentUid = 0;
+ m_currentTs = 0;
+ m_currentContext = 0xffffffff;
+ m_unscheduledEvents = 0;
+ m_events = 0;
+
+ m_safeTime = Seconds (0);
+
+ NS_ASSERT (g_instance == 0);
+ g_instance = this;
+
+#else
+ NS_FATAL_ERROR ("Can't use Null Message simulator without MPI compiled in");
+#endif
+}
+
+NullMessageSimulatorImpl::~NullMessageSimulatorImpl ()
+{
+ NS_LOG_FUNCTION (this);
+}
+
+void
+NullMessageSimulatorImpl::DoDispose (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ while (!m_events->IsEmpty ())
+ {
+ Scheduler::Event next = m_events->RemoveNext ();
+ next.impl->Unref ();
+ }
+ m_events = 0;
+ SimulatorImpl::DoDispose ();
+}
+
+void
+NullMessageSimulatorImpl::Destroy ()
+{
+ NS_LOG_FUNCTION (this);
+
+ while (!m_destroyEvents.empty ())
+ {
+ Ptr<EventImpl> ev = m_destroyEvents.front ().PeekEventImpl ();
+ m_destroyEvents.pop_front ();
+ NS_LOG_LOGIC ("handle destroy " << ev);
+ if (!ev->IsCancelled ())
+ {
+ ev->Invoke ();
+ }
+ }
+
+ RemoteChannelBundleManager::Destroy();
+ MpiInterface::Destroy ();
+}
+
+void
+NullMessageSimulatorImpl::CalculateLookAhead (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ int num_local_nodes = 0;
+
+ if (MpiInterface::GetSize () > 1)
+ {
+ NodeContainer c = NodeContainer::GetGlobal ();
+ for (NodeContainer::Iterator iter = c.Begin (); iter != c.End (); ++iter)
+ {
+ if ((*iter)->GetSystemId () != MpiInterface::GetSystemId ())
+ {
+ continue;
+ }
+
+ num_local_nodes++;
+
+ for (uint32_t i = 0; i < (*iter)->GetNDevices (); ++i)
+ {
+ Ptr<NetDevice> localNetDevice = (*iter)->GetDevice (i);
+ // only works for p2p links currently
+ if (!localNetDevice->IsPointToPoint ())
+ {
+ continue;
+ }
+ Ptr<Channel> channel = localNetDevice->GetChannel ();
+ if (channel == 0)
+ {
+ continue;
+ }
+
+ // grab the adjacent node
+ Ptr<Node> remoteNode;
+ if (channel->GetDevice (0) == localNetDevice)
+ {
+ remoteNode = (channel->GetDevice (1))->GetNode ();
+ }
+ else
+ {
+ remoteNode = (channel->GetDevice (0))->GetNode ();
+ }
+
+ // if it's not remote, don't consider it
+ if (remoteNode->GetSystemId () == MpiInterface::GetSystemId ())
+ {
+ continue;
+ }
+
+ /**
+ * Add this channel to the remote channel bundle from this task to MPI task on other side of the channel.
+ */
+ Ptr<RemoteChannelBundle> remoteChannelBundle = RemoteChannelBundleManager::Find (remoteNode->GetSystemId ());
+ if (!remoteChannelBundle)
+ {
+ remoteChannelBundle = RemoteChannelBundleManager::Add (remoteNode->GetSystemId ());
+ }
+
+ TimeValue delay;
+ channel->GetAttribute ("Delay", delay);
+ remoteChannelBundle->AddChannel (channel, delay.Get () );
+ }
+ }
+ }
+
+ // Completed setup of remote channel bundles. Setup send and receive buffers.
+ NullMessageMpiInterface::InitializeSendReceiveBuffers ();
+
+ // Initialized to 0 as we don't have a simulation start time.
+ m_safeTime = Time (0);
+}
+
+void
+NullMessageSimulatorImpl::SetScheduler (ObjectFactory schedulerFactory)
+{
+ NS_LOG_FUNCTION (this << schedulerFactory);
+
+ Ptr<Scheduler> scheduler = schedulerFactory.Create<Scheduler> ();
+
+ if (m_events != 0)
+ {
+ while (!m_events->IsEmpty ())
+ {
+ Scheduler::Event next = m_events->RemoveNext ();
+ scheduler->Insert (next);
+ }
+ }
+ m_events = scheduler;
+}
+
+void
+NullMessageSimulatorImpl::ProcessOneEvent (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ Scheduler::Event next = m_events->RemoveNext ();
+
+ NS_ASSERT (next.key.m_ts >= m_currentTs);
+ m_unscheduledEvents--;
+
+ NS_LOG_LOGIC ("handle " << next.key.m_ts);
+ m_currentTs = next.key.m_ts;
+ m_currentContext = next.key.m_context;
+ m_currentUid = next.key.m_uid;
+ next.impl->Invoke ();
+ next.impl->Unref ();
+}
+
+bool
+NullMessageSimulatorImpl::IsFinished (void) const
+{
+ return m_events->IsEmpty () || m_stop;
+}
+
+Time
+NullMessageSimulatorImpl::Next (void) const
+{
+ NS_LOG_FUNCTION (this);
+
+ NS_ASSERT (!m_events->IsEmpty ());
+
+ Scheduler::Event ev = m_events->PeekNext ();
+ return TimeStep (ev.key.m_ts);
+}
+
+void
+NullMessageSimulatorImpl::ScheduleNullMessageEvent (Ptr<RemoteChannelBundle> bundle)
+{
+ NS_LOG_FUNCTION (this << bundle);
+
+ Time time (m_schedulerTune * bundle->GetDelay ().GetTimeStep ());
+
+ bundle->SetEventId (Simulator::Schedule (time, &NullMessageSimulatorImpl::NullMessageEventHandler,
+ this, PeekPointer(bundle)));
+}
+
+void
+NullMessageSimulatorImpl::RescheduleNullMessageEvent (Ptr<RemoteChannelBundle> bundle)
+{
+ NS_LOG_FUNCTION (this << bundle);
+
+ Simulator::Cancel (bundle->GetEventId ());
+
+ Time time (m_schedulerTune * bundle->GetDelay ().GetTimeStep ());
+
+ bundle->SetEventId (Simulator::Schedule (time, &NullMessageSimulatorImpl::NullMessageEventHandler,
+ this, PeekPointer(bundle)));
+}
+
+void
+NullMessageSimulatorImpl::RescheduleNullMessageEvent (uint32_t nodeSysId)
+{
+ NS_LOG_FUNCTION (this << nodeSysId);
+
+ Ptr<RemoteChannelBundle> bundle = RemoteChannelBundleManager::Find (nodeSysId);
+ NS_ASSERT (bundle);
+
+ RescheduleNullMessageEvent (bundle);
+}
+
+void
+NullMessageSimulatorImpl::Run (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ CalculateLookAhead ();
+
+ RemoteChannelBundleManager::InitializeNullMessageEvents ();
+
+ // Stop will be set if stop is called by simulation.
+ m_stop = false;
+ while (!IsFinished ())
+ {
+ Time nextTime = Next ();
+
+ if ( nextTime <= GetSafeTime () )
+ {
+ ProcessOneEvent ();
+ HandleArrivingMessagesNonBlocking ();
+ }
+ else
+ {
+ // Block until packet or Null Message has been received.
+ HandleArrivingMessagesBlocking ();
+ }
+ }
+}
+
+void
+NullMessageSimulatorImpl::HandleArrivingMessagesNonBlocking (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ NullMessageMpiInterface::ReceiveMessagesNonBlocking ();
+
+ CalculateSafeTime ();
+
+ // Check for send completes
+ NullMessageMpiInterface::TestSendComplete ();
+}
+
+void
+NullMessageSimulatorImpl::HandleArrivingMessagesBlocking (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ NullMessageMpiInterface::ReceiveMessagesBlocking ();
+
+ CalculateSafeTime ();
+
+ // Check for send completes
+ NullMessageMpiInterface::TestSendComplete ();
+}
+
+void
+NullMessageSimulatorImpl::CalculateSafeTime ()
+{
+ NS_LOG_FUNCTION (this);
+
+ m_safeTime = RemoteChannelBundleManager::GetSafeTime ();
+ NS_ASSERT (m_safeTime >= m_currentTs);
+}
+
+Time
+NullMessageSimulatorImpl::GetSafeTime ()
+{
+ return m_safeTime;
+}
+
+
+uint32_t
+NullMessageSimulatorImpl::GetSystemId () const
+{
+ return m_myId;
+}
+
+void
+NullMessageSimulatorImpl::RunOneEvent (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ ProcessOneEvent ();
+}
+
+void
+NullMessageSimulatorImpl::Stop (void)
+{
+ NS_LOG_FUNCTION (this);
+
+ m_stop = true;
+}
+
+void
+NullMessageSimulatorImpl::Stop (Time const &time)
+{
+ NS_LOG_FUNCTION (this << time.GetTimeStep ());
+
+ Simulator::Schedule (time, &Simulator::Stop);
+}
+
+//
+// Schedule an event for a _relative_ time in the future.
+//
+EventId
+NullMessageSimulatorImpl::Schedule (Time const &time, EventImpl *event)
+{
+ NS_LOG_FUNCTION (this << time.GetTimeStep () << event);
+
+ Time tAbsolute = time + TimeStep (m_currentTs);
+
+ NS_ASSERT (tAbsolute.IsPositive ());
+ NS_ASSERT (tAbsolute >= TimeStep (m_currentTs));
+ Scheduler::Event ev;
+ ev.impl = event;
+ ev.key.m_ts = static_cast<uint64_t> (tAbsolute.GetTimeStep ());
+ ev.key.m_context = GetContext ();
+ ev.key.m_uid = m_uid;
+ m_uid++;
+ m_unscheduledEvents++;
+ m_events->Insert (ev);
+ return EventId (event, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
+}
+
+void
+NullMessageSimulatorImpl::ScheduleWithContext (uint32_t context, Time const &time, EventImpl *event)
+{
+ NS_LOG_FUNCTION (this << context << time.GetTimeStep () << m_currentTs << event);
+
+ Time tAbsolute(m_currentTs + time.GetTimeStep ());
+
+ NS_ASSERT (tAbsolute.IsPositive ());
+ NS_ASSERT (tAbsolute >= TimeStep (m_currentTs));
+
+ Scheduler::Event ev;
+ ev.impl = event;
+ ev.key.m_ts = tAbsolute.GetTimeStep ();
+ ev.key.m_context = context;
+ ev.key.m_uid = m_uid;
+ m_uid++;
+ m_unscheduledEvents++;
+ m_events->Insert (ev);
+}
+
+EventId
+NullMessageSimulatorImpl::ScheduleNow (EventImpl *event)
+{
+ NS_LOG_FUNCTION (this << event);
+
+ Scheduler::Event ev;
+ ev.impl = event;
+ ev.key.m_ts = m_currentTs;
+ ev.key.m_context = GetContext ();
+ ev.key.m_uid = m_uid;
+ m_uid++;
+ m_unscheduledEvents++;
+ m_events->Insert (ev);
+ return EventId (event, ev.key.m_ts, ev.key.m_context, ev.key.m_uid);
+}
+
+EventId
+NullMessageSimulatorImpl::ScheduleDestroy (EventImpl *event)
+{
+ NS_LOG_FUNCTION (this << event);
+
+ EventId id (Ptr<EventImpl> (event, false), m_currentTs, 0xffffffff, 2);
+ m_destroyEvents.push_back (id);
+ m_uid++;
+ return id;
+}
+
+Time
+NullMessageSimulatorImpl::Now (void) const
+{
+ return TimeStep (m_currentTs);
+}
+
+Time
+NullMessageSimulatorImpl::GetDelayLeft (const EventId &id) const
+{
+ if (IsExpired (id))
+ {
+ return TimeStep (0);
+ }
+ else
+ {
+ return TimeStep (id.GetTs () - m_currentTs);
+ }
+}
+
+void
+NullMessageSimulatorImpl::Remove (const EventId &id)
+{
+ if (id.GetUid () == 2)
+ {
+ // destroy events.
+ for (DestroyEvents::iterator i = m_destroyEvents.begin (); i != m_destroyEvents.end (); i++)
+ {
+ if (*i == id)
+ {
+ m_destroyEvents.erase (i);
+ break;
+ }
+ }
+ return;
+ }
+ if (IsExpired (id))
+ {
+ return;
+ }
+ Scheduler::Event event;
+ event.impl = id.PeekEventImpl ();
+ event.key.m_ts = id.GetTs ();
+ event.key.m_context = id.GetContext ();
+ event.key.m_uid = id.GetUid ();
+ m_events->Remove (event);
+ event.impl->Cancel ();
+ // whenever we remove an event from the event list, we have to unref it.
+ event.impl->Unref ();
+
+ m_unscheduledEvents--;
+}
+
+void
+NullMessageSimulatorImpl::Cancel (const EventId &id)
+{
+ if (!IsExpired (id))
+ {
+ id.PeekEventImpl ()->Cancel ();
+ }
+}
+
+bool
+NullMessageSimulatorImpl::IsExpired (const EventId &ev) const
+{
+ if (ev.GetUid () == 2)
+ {
+ if (ev.PeekEventImpl () == 0
+ || ev.PeekEventImpl ()->IsCancelled ())
+ {
+ return true;
+ }
+ // destroy events.
+ for (DestroyEvents::const_iterator i = m_destroyEvents.begin (); i != m_destroyEvents.end (); i++)
+ {
+ if (*i == ev)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ if (ev.PeekEventImpl () == 0
+ || ev.GetTs () < m_currentTs
+ || (ev.GetTs () == m_currentTs
+ && ev.GetUid () <= m_currentUid)
+ || ev.PeekEventImpl ()->IsCancelled ())
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+Time
+NullMessageSimulatorImpl::GetMaximumSimulationTime (void) const
+{
+ // XXX: I am fairly certain other compilers use other non-standard
+ // post-fixes to indicate 64 bit constants.
+ return TimeStep (0x7fffffffffffffffLL);
+}
+
+uint32_t
+NullMessageSimulatorImpl::GetContext (void) const
+{
+ return m_currentContext;
+}
+
+Time NullMessageSimulatorImpl::CalculateGuaranteeTime (uint32_t nodeSysId)
+{
+ Ptr<RemoteChannelBundle> bundle = RemoteChannelBundleManager::Find (nodeSysId);
+ NS_ASSERT (bundle);
+
+ return Min (NullMessageSimulatorImpl::GetInstance ()->Next (), GetSafeTime ()) + bundle->GetDelay ();
+}
+
+void NullMessageSimulatorImpl::NullMessageEventHandler(RemoteChannelBundle* bundle)
+{
+ NS_LOG_FUNCTION (this << bundle);
+
+ Time time = Min (Next (), GetSafeTime ()) + bundle->GetDelay ();
+ NullMessageMpiInterface::SendNullMessage (time, bundle);
+
+ ScheduleNullMessageEvent (bundle);
+}
+
+
+NullMessageSimulatorImpl*
+NullMessageSimulatorImpl::GetInstance (void)
+{
+ NS_ASSERT (g_instance != 0);
+ return g_instance;
+}
+} // namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mpi/model/null-message-simulator-impl.h Fri Dec 06 14:57:33 2013 -0500
@@ -0,0 +1,212 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2013. Lawrence Livermore National Security, LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Steven Smith <smith84@llnl.gov>
+ *
+ */
+
+#ifndef NULLMESSAGE_SIMULATOR_IMPL_H
+#define NULLMESSAGE_SIMULATOR_IMPL_H
+
+#include <ns3/simulator-impl.h>
+#include <ns3/scheduler.h>
+#include <ns3/event-impl.h>
+#include <ns3/ptr.h>
+
+#include <list>
+#include <iostream>
+#include <fstream>
+
+namespace ns3 {
+
+class NullMessageEvent;
+class NullMessageMpiInterface;
+class RemoteChannelBundle;
+
+/**
+ * \ingroup mpi
+ *
+ * \brief Simulator implementation using MPI and a Null Message algorithm.
+ */
+class NullMessageSimulatorImpl : public SimulatorImpl
+{
+public:
+ static TypeId GetTypeId (void);
+
+ NullMessageSimulatorImpl ();
+
+ ~NullMessageSimulatorImpl ();
+
+ // virtual from SimulatorImpl
+ virtual void Destroy ();
+ virtual bool IsFinished (void) const;
+ virtual void Stop (void);
+ virtual void Stop (Time const &time);
+ virtual EventId Schedule (Time const &time, EventImpl *event);
+ virtual void ScheduleWithContext (uint32_t context, Time const &time, EventImpl *event);
+ virtual EventId ScheduleNow (EventImpl *event);
+ virtual EventId ScheduleDestroy (EventImpl *event);
+ virtual void Remove (const EventId &ev);
+ virtual void Cancel (const EventId &ev);
+ virtual bool IsExpired (const EventId &ev) const;
+ virtual void Run (void);
+ virtual void RunOneEvent (void);
+ virtual Time Now (void) const;
+ virtual Time GetDelayLeft (const EventId &id) const;
+ virtual Time GetMaximumSimulationTime (void) const;
+ virtual void SetScheduler (ObjectFactory schedulerFactory);
+ virtual uint32_t GetSystemId (void) const;
+ virtual uint32_t GetContext (void) const;
+
+ /**
+ * \return singleton instance
+ *
+ * Singleton accessor.
+ */
+ static NullMessageSimulatorImpl * GetInstance (void);
+
+private:
+ friend class NullMessageEvent;
+ friend class NullMessageMpiInterface;
+ friend class RemoteChannelBundleManager;
+
+ /**
+ * Non blocking receive of pending messages.
+ */
+ void HandleArrivingMessagesNonBlocking (void);
+
+ /**
+ * Blocking receive of arriving messages.
+ */
+ void HandleArrivingMessagesBlocking (void);
+
+ virtual void DoDispose (void);
+
+ /**
+ * Calculate the look ahead allowable for this MPI task. Basically
+ * the minimum latency on links to neighbor MPI tasks.
+ */
+ void CalculateLookAhead (void);
+
+ /**
+ * Process the next event on the queue.
+ */
+ void ProcessOneEvent (void);
+
+ /**
+ * \return next local event time.
+ */
+ Time Next (void) const;
+
+ /**
+ * Calculate the SafeTime. Should be called after message receives.
+ */
+ void CalculateSafeTime (void);
+
+ /**
+ * Get the current SafeTime; the maximum time that events can
+ * be processed based on information received from neighboring
+ * MPI tasks.
+ */
+ Time GetSafeTime (void);
+
+ /**
+ * \param bundle Bundle to schedule Null Message event for
+ *
+ * Schedule Null Message event for the specified RemoteChannelBundle.
+ */
+ void ScheduleNullMessageEvent (Ptr<RemoteChannelBundle> bundle);
+
+ /**
+ * \param bundle Bundle to reschedule Null Message event for
+ *
+ * Reschedule Null Message event for the specified
+ * RemoteChannelBundel. Existing event will be canceled.
+ */
+ void RescheduleNullMessageEvent (Ptr<RemoteChannelBundle> bundle);
+
+ /**
+ * \param nodeSysId SystemID to reschedule null event for
+ *
+ * Reschedule Null Message event for the RemoteChannelBundel to the
+ * task nodeSysId. Existing event will be canceled.
+ */
+ void RescheduleNullMessageEvent (uint32_t nodeSysId);
+
+ /**
+ * \param systemId SystemID to compute guarentee time for
+ *
+ * \return Guarentee time
+ *
+ * Calculate the guarantee time for incoming RemoteChannelBundel
+ * from task nodeSysId. No message should arrive from task
+ * nodeSysId with a receive time less than the guarantee time.
+ */
+ Time CalculateGuaranteeTime (uint32_t systemId);
+
+ /**
+ * \param bundle remote channel bundle to schedule an event for.
+ *
+ * Null message event handler. Scheduled to send a null message
+ * for the specified bundle at regular intervals. Will canceled
+ * and rescheduled when packets are sent.
+ */
+ void NullMessageEventHandler(RemoteChannelBundle* bundle);
+
+ typedef std::list<EventId> DestroyEvents;
+
+ DestroyEvents m_destroyEvents;
+ bool m_stop;
+ Ptr<Scheduler> m_events;
+ uint32_t m_uid;
+ uint32_t m_currentUid;
+ uint64_t m_currentTs;
+ uint32_t m_currentContext;
+ // number of events that have been inserted but not yet scheduled,
+ // not counting the "destroy" events; this is used for validation
+ int m_unscheduledEvents;
+
+ uint32_t m_myId; // MPI Rank
+ uint32_t m_systemCount; // MPI Size
+
+ /*
+ * The time for which it is safe for this task to execute events
+ * without danger of out-of-order events.
+ */
+ Time m_safeTime;
+
+ /*
+ * Null Message performance tuning parameter. Controls when Null
+ * messages are sent. When value is 1 the minimum number of Null
+ * messages are sent conserving bandwidth. The delay in arrival of
+ * lookahead information is the greatest resulting in maximum
+ * unnecessary blocking of the receiver. When the value is near 0
+ * Null Messages are sent with high frequency, costing more
+ * bandwidth and Null Message processing time, but there is minimum
+ * unnecessary block of the receiver.
+ */
+ double m_schedulerTune;
+
+ /*
+ * Singleton instance.
+ */
+ static NullMessageSimulatorImpl* g_instance;
+};
+
+} // namespace ns3
+
+#endif /* NULLMESSAGE_SIMULATOR_IMPL_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mpi/model/parallel-communication-interface.h Fri Dec 06 14:57:33 2013 -0500
@@ -0,0 +1,99 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2013. Lawrence Livermore National Security, LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Steven Smith <smith84@llnl.gov>
+ *
+ */
+
+#ifndef NS3_PARALLEL_COMMUNICATION_INTERFACE_H
+#define NS3_PARALLEL_COMMUNICATION_INTERFACE_H
+
+#include <stdint.h>
+#include <list>
+
+#include <ns3/object.h>
+#include <ns3/nstime.h>
+#include <ns3/buffer.h>
+#include <ns3/packet.h>
+
+#if defined(NS3_MPI)
+#include "mpi.h"
+#endif
+
+namespace ns3 {
+
+/**
+ * \ingroup mpi
+ *
+ * \brief Pure virtual base class for the interface between ns-3 and
+ * the parallel communication layer being used.
+ *
+ * Each type of parallel communication layer is required to implement
+ * this interface. This interface is called through the
+ * MpiInterface.
+ */
+ class ParallelCommunicationInterface
+{
+public:
+ /**
+ * Destructor
+ */
+ virtual ~ParallelCommunicationInterface() {}
+ /**
+ * Deletes storage used by the parallel environment.
+ */
+ virtual void Destroy () = 0;
+ /**
+ * \return system identification
+ */
+ virtual uint32_t GetSystemId () = 0;
+ /**
+ * \return number of parallel tasks
+ */
+ virtual uint32_t GetSize () = 0;
+ /**
+ * \return true if parallel communication is enabled
+ */
+ virtual bool IsEnabled () = 0;
+ /**
+ * \param pargc number of command line arguments
+ * \param pargv command line arguments
+ *
+ * Sets up parallel communication interface
+ */
+ virtual void Enable (int* pargc, char*** pargv) = 0;
+ /**
+ * Terminates the parallel environment.
+ * This function must be called after Destroy ()
+ */
+ virtual void Disable () = 0;
+ /**
+ * \param p packet to send
+ * \param rxTime received time at destination node
+ * \param node destination node
+ * \param dev destination device
+ *
+ * Serialize and send a packet to the specified node and net device
+ */
+ virtual void SendPacket (Ptr<Packet> p, const Time &rxTime, uint32_t node, uint32_t dev) = 0;
+
+private:
+};
+
+} // namespace ns3
+
+#endif /* NS3_PARALLEL_COMMUNICATION_INTERFACE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mpi/model/remote-channel-bundle-manager.cc Fri Dec 06 14:57:33 2013 -0500
@@ -0,0 +1,112 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2013. Lawrence Livermore National Security, LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Steven Smith <smith84@llnl.gov>
+ *
+ */
+
+#include "remote-channel-bundle-manager.h"
+
+#include "remote-channel-bundle.h"
+#include "null-message-simulator-impl.h"
+
+#include "ns3/simulator.h"
+
+namespace ns3 {
+
+bool ns3::RemoteChannelBundleManager::g_initialized = false;
+ns3::RemoteChannelBundleManager::RemoteChannelMap ns3::RemoteChannelBundleManager::g_remoteChannelBundles;
+
+Ptr<RemoteChannelBundle>
+RemoteChannelBundleManager::Find (uint32_t systemId)
+{
+ ns3::RemoteChannelBundleManager::RemoteChannelMap::iterator kv = g_remoteChannelBundles.find (systemId);
+
+ if ( kv == g_remoteChannelBundles.end ())
+ {
+ return 0;
+ }
+ else
+ {
+ return kv->second;
+ }
+}
+
+Ptr<RemoteChannelBundle>
+RemoteChannelBundleManager::Add (uint32_t systemId)
+{
+ NS_ASSERT (!g_initialized);
+ NS_ASSERT (g_remoteChannelBundles.find (systemId) == g_remoteChannelBundles.end ());
+
+ Ptr<RemoteChannelBundle> remoteChannelBundle = Create<RemoteChannelBundle> (systemId);
+
+ g_remoteChannelBundles[systemId] = remoteChannelBundle;
+
+ return remoteChannelBundle;
+}
+
+uint32_t
+RemoteChannelBundleManager::Size (void)
+{
+ return g_remoteChannelBundles.size();
+}
+
+void
+RemoteChannelBundleManager::InitializeNullMessageEvents (void)
+{
+ NS_ASSERT (!g_initialized);
+
+ for ( RemoteChannelMap::const_iterator iter = g_remoteChannelBundles.begin ();
+ iter != g_remoteChannelBundles.end ();
+ ++iter )
+ {
+ Ptr<RemoteChannelBundle> bundle = iter->second;
+ bundle->Send (bundle->GetDelay ());
+
+ NullMessageSimulatorImpl::GetInstance ()->ScheduleNullMessageEvent (bundle);
+ }
+
+ g_initialized = true;
+}
+
+Time
+RemoteChannelBundleManager::GetSafeTime (void)
+{
+ NS_ASSERT (g_initialized);
+
+ Time safeTime = Simulator::GetMaximumSimulationTime ();
+
+ for (RemoteChannelMap::const_iterator kv = g_remoteChannelBundles.begin ();
+ kv != g_remoteChannelBundles.end ();
+ ++kv)
+ {
+ safeTime = Min (safeTime, kv->second->GetGuaranteeTime ());
+ }
+
+ return safeTime;
+}
+
+void
+RemoteChannelBundleManager::Destroy (void)
+{
+ NS_ASSERT (g_initialized);
+
+ g_remoteChannelBundles.clear();
+ g_initialized = false;
+}
+
+} // namespace ns3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mpi/model/remote-channel-bundle-manager.h Fri Dec 06 14:57:33 2013 -0500
@@ -0,0 +1,107 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2013. Lawrence Livermore National Security, LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Steven Smith <smith84@llnl.gov>
+ *
+ */
+
+#ifndef NS3_REMOTE_CHANNEL_BUNDLE_MANAGER
+#define NS3_REMOTE_CHANNEL_BUNDLE_MANAGER
+
+#include <ns3/nstime.h>
+#include <ns3/ptr.h>
+#include <map>
+
+namespace ns3 {
+
+class RemoteChannelBundle;
+
+/*
+ * \ingroup mpi
+ *
+ * \brief Singleton for managing the RemoteChannelBundles for each process.
+ *
+ * Manages collective tasks associated with the bundle collection.
+ */
+class RemoteChannelBundleManager
+{
+
+public:
+ /**
+ * \return remote channel bundle for specified SystemId.
+ */
+ static Ptr<RemoteChannelBundle> Find (uint32_t systemId);
+
+ /**
+ * Add RemoteChannelBundle from this task to MPI task on other side of the link.
+ * Can not be invoked after InitializeNullMessageEvents has been invoked.
+ */
+ static Ptr<RemoteChannelBundle> Add (uint32_t systemId);
+
+ /**
+ * \return number of remote channel bundles
+ *
+ */
+ static uint32_t Size (void);
+
+ /**
+ * Setup initial Null Message events for every RemoteChannelBundle.
+ * All RemoteChannelBundles should be added before this method is invoked.
+ */
+ static void InitializeNullMessageEvents (void);
+
+ /**
+ * \return safe time across all remote channels.
+ */
+ static Time GetSafeTime (void);
+
+ /**
+ * Destroy the singleton.
+ */
+ static void Destroy (void);
+
+private:
+
+ /**
+ * Private ctor to prevent creation outside of singleton pattern.
+ */
+ RemoteChannelBundleManager ()
+ {
+ }
+
+ ~RemoteChannelBundleManager ()
+ {
+ }
+
+ /*
+ * Container for all remote channel bundles for this task.
+ *
+ * Would be more efficient to use unordered_map when C++11 is adopted for NS3.
+ */
+ typedef std::map<uint32_t, Ptr<RemoteChannelBundle> > RemoteChannelMap;
+ static RemoteChannelMap g_remoteChannelBundles;
+
+ /*
+ * Protect manager class from being initialized twice or incorrect
+ * ordering of method calls.
+ */
+ static bool g_initialized;
+};
+
+} // namespace ns3
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mpi/model/remote-channel-bundle.cc Fri Dec 06 14:57:33 2013 -0500
@@ -0,0 +1,130 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2013. Lawrence Livermore National Security, LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Steven Smith <smith84@llnl.gov>
+ *
+ */
+
+#include "remote-channel-bundle.h"
+
+#include "null-message-mpi-interface.h"
+#include "null-message-simulator-impl.h"
+
+#include <ns3/simulator.h>
+
+namespace ns3 {
+
+#define NS_TIME_INFINITY ns3::Time (0x7fffffffffffffffLL)
+
+TypeId RemoteChannelBundle::GetTypeId (void)
+{
+ static TypeId tid = TypeId ("ns3::RemoteChannelBundle")
+ .SetParent<Object> ()
+ .AddConstructor <RemoteChannelBundle> ();
+ return tid;
+}
+
+RemoteChannelBundle::RemoteChannelBundle ()
+ : m_remoteSystemId (-1),
+ m_guaranteeTime (0),
+ m_delay (NS_TIME_INFINITY)
+{
+}
+
+RemoteChannelBundle::RemoteChannelBundle (const uint32_t remoteSystemId)
+ : m_remoteSystemId (remoteSystemId),
+ m_guaranteeTime (0),
+ m_delay (NS_TIME_INFINITY)
+{
+}
+
+void
+RemoteChannelBundle::AddChannel (Ptr<Channel> channel, Time delay)
+{
+ m_channels[channel->GetId ()] = channel;
+ m_delay = ns3::Min (m_delay, delay);
+}
+
+uint32_t
+RemoteChannelBundle::GetSystemId () const
+{
+ return m_remoteSystemId;
+}
+
+Time
+RemoteChannelBundle::GetGuaranteeTime (void) const
+{
+ return m_guaranteeTime;
+}
+
+void
+RemoteChannelBundle::SetGuaranteeTime (Time time)
+{
+ NS_ASSERT (time >= Simulator::Now ());
+
+ m_guaranteeTime = time;
+}
+
+Time
+RemoteChannelBundle::GetDelay (void) const
+{
+ return m_delay;
+}
+
+void
+RemoteChannelBundle::SetEventId (EventId id)
+{
+ m_nullEventId = id;
+}
+
+EventId
+RemoteChannelBundle::GetEventId (void) const
+{
+ return m_nullEventId;
+}
+
+int
+RemoteChannelBundle::GetSize (void) const
+{
+ return m_channels.size ();
+}
+
+void
+RemoteChannelBundle::Send(Time time)
+{
+ NullMessageMpiInterface::SendNullMessage (time, this);
+}
+
+std::ostream& operator<< (std::ostream& out, ns3::RemoteChannelBundle& bundle )
+{
+ out << "RemoteChannelBundle Rank = " << bundle.m_remoteSystemId
+ << ", GuaranteeTime = " << bundle.m_guaranteeTime
+ << ", Delay = " << bundle.m_delay << std::endl;
+
+ for (std::map < uint32_t, Ptr < Channel > > ::const_iterator pair = bundle.m_channels.begin ();
+ pair != bundle.m_channels.end ();
+ ++pair)
+ {
+ out << "\t" << (*pair).second << std::endl;
+ }
+
+ return out;
+}
+
+
+} // namespace ns3
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/mpi/model/remote-channel-bundle.h Fri Dec 06 14:57:33 2013 -0500
@@ -0,0 +1,151 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright 2013. Lawrence Livermore National Security, LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Steven Smith <smith84@llnl.gov>
+ *
+ */
+
+#ifndef NS3_REMOTE_CHANNEL_BUNDLE
+#define NS3_REMOTE_CHANNEL_BUNDLE
+
+#include "null-message-simulator-impl.h"
+
+#include <ns3/channel.h>
+#include <ns3/ptr.h>
+#include <ns3/pointer.h>
+
+#include <map>
+
+namespace ns3 {
+
+/**
+ * \ingroup mpi
+ *
+ * \brief Collection of NS3 channels between local and remote nodes.
+ *
+ * An instance exists for each remote system that the local system is
+ * in communication with. These are created and managed by the
+ * RemoteChannelBundleManager class. Stores time information for each
+ * bundle.
+ */
+class RemoteChannelBundle : public Object
+{
+public:
+ static TypeId GetTypeId (void);
+
+ RemoteChannelBundle ();
+
+ RemoteChannelBundle (const uint32_t remoteSystemId);
+
+ ~RemoteChannelBundle ()
+ {
+ }
+
+ /**
+ * \param channel to add to the bundle
+ * \param delay time for the channel (usually the latency)
+ */
+ void AddChannel (Ptr<Channel> channel, Time delay);
+
+ /**
+ * \return SystemID for remote side of this bundle
+ */
+ uint32_t GetSystemId () const;
+
+ /**
+ * \return guarantee time
+ */
+ Time GetGuaranteeTime (void) const;
+
+ /**
+ * \param guarantee time
+ *
+ * Set the guarantee time for the bundle. This should be called
+ * after a packet or Null Message received.
+ */
+ void SetGuaranteeTime (Time time);
+
+ /**
+ * \return the minimum delay along any channel in this bundle
+ */
+ Time GetDelay (void) const;
+
+ /**
+ * Set the event ID of the Null Message send event current scheduled
+ * for this channel.
+ */
+ void SetEventId (EventId id);
+
+ /**
+ * \return the event ID of the Null Message send event for this bundle
+ */
+ EventId GetEventId (void) const;
+
+ /**
+ * \return number of NS3 channels in this bundle
+ */
+ int GetSize (void) const;
+
+ /**
+ * \param time
+ *
+ * Send Null Message to the remote task associated with this bundle.
+ * Message will be delivered at current simulation time + the time
+ * passed in.
+ */
+ void Send(Time time);
+
+ /**
+ * Output for debugging purposes.
+ */
+ friend std::ostream& operator<< (std::ostream& out, ns3::RemoteChannelBundle& bundle );
+
+private:
+ /*
+ * Remote rank.
+ */
+ uint32_t m_remoteSystemId;
+
+ /*
+ * NS3 Channels that are connected from nodes in this MPI task to remote_rank.
+ *
+ * Would be more efficient to use unordered_map when C++11 is adopted by NS3.
+ */
+ std::map < uint32_t, Ptr < Channel > > m_channels;
+
+ /*
+ * Guarentee time for the incoming Channels from MPI task remote_rank.
+ * No PacketMessage will ever arrive on any incoming channel in this bundle with a
+ * ReceiveTime less than this. Intialized to StartTime.
+ */
+ Time m_guaranteeTime;
+
+ /*
+ * Delay for this Channel bundle. min link delay over all incoming channels;
+ */
+ Time m_delay;
+
+ /*
+ * Event scheduled to send Null Message for this bundle.
+ */
+ EventId m_nullEventId;
+
+};
+
+}
+
+#endif
--- a/src/mpi/wscript Fri Dec 06 19:42:02 2013 +0100
+++ b/src/mpi/wscript Fri Dec 06 14:57:33 2013 -0500
@@ -36,16 +36,21 @@
sim = bld.create_ns3_module('mpi', ['core', 'network'])
sim.source = [
'model/distributed-simulator-impl.cc',
- 'model/mpi-interface.cc',
+ 'model/granted-time-window-mpi-interface.cc',
'model/mpi-receiver.cc',
+ 'model/null-message-simulator-impl.cc',
+ 'model/null-message-mpi-interface.cc',
+ 'model/remote-channel-bundle.cc',
+ 'model/remote-channel-bundle-manager.cc',
+ 'model/mpi-interface.cc',
]
headers = bld(features='ns3header')
headers.module = 'mpi'
headers.source = [
- 'model/distributed-simulator-impl.h',
+ 'model/mpi-receiver.h',
'model/mpi-interface.h',
- 'model/mpi-receiver.h',
+ 'model/parallel-communication-interface.h',
]
if env['ENABLE_MPI']:
--- a/src/point-to-point/helper/point-to-point-helper.cc Fri Dec 06 19:42:02 2013 +0100
+++ b/src/point-to-point/helper/point-to-point-helper.cc Fri Dec 06 14:57:33 2013 -0500
@@ -241,6 +241,7 @@
//use a normal p2p channel, otherwise use a remote channel
bool useNormalChannel = true;
Ptr<PointToPointChannel> channel = 0;
+
if (MpiInterface::IsEnabled ())
{
uint32_t n1SystemId = a->GetSystemId ();
--- a/src/point-to-point/model/point-to-point-net-device.cc Fri Dec 06 19:42:02 2013 +0100
+++ b/src/point-to-point/model/point-to-point-net-device.cc Fri Dec 06 14:57:33 2013 -0500
@@ -25,7 +25,6 @@
#include "ns3/trace-source-accessor.h"
#include "ns3/uinteger.h"
#include "ns3/pointer.h"
-#include "ns3/mpi-interface.h"
#include "point-to-point-net-device.h"
#include "point-to-point-channel.h"
#include "ppp-header.h"