Browse Source

Null message scheduler

ndnSIM-v1
Steven Smith 12 years ago
parent
commit
f780559565
  1. 3
      src/internet/model/global-route-manager-impl.cc
  2. 597
      src/mpi/bindings/modulegen__gcc_ILP32.py
  3. 597
      src/mpi/bindings/modulegen__gcc_LP64.py
  4. 67
      src/mpi/doc/distributed.rst
  5. 9
      src/mpi/examples/nms-p2p-nix-distributed.cc
  6. 309
      src/mpi/examples/simple-distributed-empty-node.cc
  7. 47
      src/mpi/examples/simple-distributed.cc
  8. 43
      src/mpi/examples/third-distributed.cc
  9. 4
      src/mpi/examples/wscript
  10. 44
      src/mpi/model/distributed-simulator-impl.cc
  11. 11
      src/mpi/model/distributed-simulator-impl.h
  12. 337
      src/mpi/model/granted-time-window-mpi-interface.cc
  13. 175
      src/mpi/model/granted-time-window-mpi-interface.h
  14. 292
      src/mpi/model/mpi-interface.cc
  15. 130
      src/mpi/model/mpi-interface.h
  16. 2
      src/mpi/model/mpi-receiver.h
  17. 460
      src/mpi/model/null-message-mpi-interface.cc
  18. 228
      src/mpi/model/null-message-mpi-interface.h
  19. 603
      src/mpi/model/null-message-simulator-impl.cc
  20. 212
      src/mpi/model/null-message-simulator-impl.h
  21. 99
      src/mpi/model/parallel-communication-interface.h
  22. 112
      src/mpi/model/remote-channel-bundle-manager.cc
  23. 107
      src/mpi/model/remote-channel-bundle-manager.h
  24. 130
      src/mpi/model/remote-channel-bundle.cc
  25. 151
      src/mpi/model/remote-channel-bundle.h
  26. 11
      src/mpi/wscript
  27. 1
      src/point-to-point/helper/point-to-point-helper.cc
  28. 1
      src/point-to-point/model/point-to-point-net-device.cc

3
src/internet/model/global-route-manager-impl.cc

@ -711,8 +711,9 @@ GlobalRouteManagerImpl::InitializeRoutes ()
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;
}

597
src/mpi/bindings/modulegen__gcc_ILP32.py

@ -40,20 +40,14 @@ def register_types(module):
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 @@ def register_types(module):
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 @@ def register_types(module):
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 @@ def register_types(module):
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 @@ def register_types(module):
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 @@ def register_types(module):
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 @@ def register_methods(root_module):
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 @@ def register_methods(root_module):
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 @@ def register_methods(root_module):
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 @@ def register_methods(root_module):
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 @@ def register_Ns3CallbackBase_methods(root_module, cls):
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 @@ def register_Ns3Hasher_methods(root_module, cls):
[])
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 @@ def register_Ns3MpiInterface_methods(root_module, cls):
'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 @@ def register_Ns3MpiInterface_methods(root_module, cls):
'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 @@ def register_Ns3ObjectDeleter_methods(root_module, cls):
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 @@ def register_Ns3PacketTagListTagData_methods(root_module, cls):
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',
[param('uint8_t *', 'buffer')])
[],
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('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 @@ def register_Ns3ObjectAggregateIterator_methods(root_module, cls):
[])
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 @@ def register_Ns3SimpleRefCount__Ns3CallbackImplBase_Ns3Empty_Ns3DefaultDeleter__
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 @@ def register_Ns3SimpleRefCount__Ns3TraceSourceAccessor_Ns3Empty_Ns3DefaultDelete
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 @@ def register_Ns3Time_methods(root_module, cls):
'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 @@ def register_Ns3Time_methods(root_module, cls):
'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 @@ def register_Ns3Time_methods(root_module, cls):
'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 @@ def register_Ns3Time_methods(root_module, cls):
'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 @@ def register_Ns3CallbackValue_methods(root_module, cls):
[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 @@ def register_Ns3EmptyAttributeValue_methods(root_module, cls):
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 @@ def register_Ns3NixVector_methods(root_module, cls):
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]

597
src/mpi/bindings/modulegen__gcc_LP64.py

@ -40,20 +40,14 @@ def register_types(module):
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 @@ def register_types(module):
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 @@ def register_types(module):
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 @@ def register_types(module):
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 @@ def register_types(module):
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 @@ def register_types(module):
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 @@ def register_methods(root_module):
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 @@ def register_methods(root_module):
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 @@ def register_methods(root_module):
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 @@ def register_methods(root_module):
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 @@ def register_Ns3CallbackBase_methods(root_module, cls):
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 @@ def register_Ns3Hasher_methods(root_module, cls):
[])
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 @@ def register_Ns3MpiInterface_methods(root_module, cls):
'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 @@ def register_Ns3MpiInterface_methods(root_module, cls):
'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 @@ def register_Ns3ObjectDeleter_methods(root_module, cls):
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 @@ def register_Ns3PacketTagListTagData_methods(root_module, cls):
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',
[param('uint8_t *', 'buffer')])
[],
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('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 @@ def register_Ns3ObjectAggregateIterator_methods(root_module, cls):
[])
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 @@ def register_Ns3SimpleRefCount__Ns3CallbackImplBase_Ns3Empty_Ns3DefaultDeleter__
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 @@ def register_Ns3SimpleRefCount__Ns3TraceSourceAccessor_Ns3Empty_Ns3DefaultDelete
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 @@ def register_Ns3Time_methods(root_module, cls):
'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 @@ def register_Ns3Time_methods(root_module, cls):
'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 @@ def register_Ns3Time_methods(root_module, cls):
'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 @@ def register_Ns3Time_methods(root_module, cls):
'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 @@ def register_Ns3CallbackValue_methods(root_module, cls):
[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 @@ def register_Ns3EmptyAttributeValue_methods(root_module, cls):
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 @@ def register_Ns3NixVector_methods(root_module, cls):
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]

67
src/mpi/doc/distributed.rst

@ -32,11 +32,40 @@ on each LP to determine which events to process. It is important to process
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.
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 @@ Next, build |ns3|::
$ ./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 @@ alternative way to run distributed examples is shown below::
$ 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

9
src/mpi/examples/nms-p2p-nix-distributed.cc

@ -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 @@ int
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 @@ main (int argc, char *argv[])
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;

309
src/mpi/examples/simple-distributed-empty-node.cc

@ -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
}

47
src/mpi/examples/simple-distributed.cc

@ -66,10 +66,32 @@ int
main (int argc, char *argv[])
{
#ifdef NS3_MPI
// Distributed simulation setup
MpiInterface::Enable (&argc, &argv);
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);
LogComponentEnable ("PacketSink", LOG_LEVEL_INFO);
@ -88,12 +110,6 @@ main (int argc, char *argv[])
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 @@ main (int argc, char *argv[])
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)

43
src/mpi/examples/third-distributed.cc

@ -55,31 +55,18 @@ int
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 @@ main (int argc, char *argv[])
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

4
src/mpi/examples/wscript

@ -12,3 +12,7 @@ def build(bld):
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'

44
src/mpi/model/distributed-simulator-impl.cc

@ -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::GetTypeId (void)
DistributedSimulatorImpl::DistributedSimulatorImpl ()
{
NS_LOG_FUNCTION (this);
#ifdef NS3_MPI
m_myId = MpiInterface::GetSystemId ();
m_systemCount = MpiInterface::GetSize ();
@ -102,6 +106,7 @@ DistributedSimulatorImpl::DistributedSimulatorImpl ()
#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 ()
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 @@ DistributedSimulatorImpl::DoDispose (void)
void
DistributedSimulatorImpl::Destroy ()
{
NS_LOG_FUNCTION (this);
while (!m_destroyEvents.empty ())
{
Ptr<EventImpl> ev = m_destroyEvents.front ().PeekEventImpl ();
@ -153,6 +163,8 @@ DistributedSimulatorImpl::Destroy ()
void
DistributedSimulatorImpl::CalculateLookAhead (void)
{
NS_LOG_FUNCTION (this);
#ifdef NS3_MPI
if (MpiInterface::GetSize () <= 1)
{
@ -162,6 +174,7 @@ DistributedSimulatorImpl::CalculateLookAhead (void)
else
{
DistributedSimulatorImpl::m_lookAhead = GetMaximumSimulationTime ();
m_grantedTime = GetMaximumSimulationTime ();
NodeContainer c = NodeContainer::GetGlobal ();
@ -268,6 +281,8 @@ DistributedSimulatorImpl::CalculateLookAhead (void)
void
DistributedSimulatorImpl::SetScheduler (ObjectFactory schedulerFactory)
{
NS_LOG_FUNCTION (this << schedulerFactory);
Ptr<Scheduler> scheduler = schedulerFactory.Create<Scheduler> ();
if (m_events != 0)
@ -284,6 +299,8 @@ DistributedSimulatorImpl::SetScheduler (ObjectFactory schedulerFactory)
void
DistributedSimulatorImpl::ProcessOneEvent (void)
{
NS_LOG_FUNCTION (this);
Scheduler::Event next = m_events->RemoveNext ();
NS_ASSERT (next.key.m_ts >= m_currentTs);
@ -314,9 +331,12 @@ DistributedSimulatorImpl::NextTs (void) const
{
// 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 @@ DistributedSimulatorImpl::Next (void) const
void
DistributedSimulatorImpl::Run (void)
{
NS_LOG_FUNCTION (this);
#ifdef NS3_MPI
CalculateLookAhead ();
m_stop = false;
@ -345,16 +367,16 @@ DistributedSimulatorImpl::Run (void)
// 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);
@ -417,12 +439,16 @@ uint32_t DistributedSimulatorImpl::GetSystemId () const
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 @@ DistributedSimulatorImpl::Stop (Time const &time)
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 @@ DistributedSimulatorImpl::ScheduleWithContext (uint32_t context, Time const &tim
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 @@ DistributedSimulatorImpl::ScheduleNow (EventImpl *event)
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++;

11
src/mpi/model/distributed-simulator-impl.h

@ -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 @@ public:
*/
uint32_t GetMyId ();
/**
* \return true if LBTS message is finished
* \return true if system is finished
*/
bool IsFinished ();
@ -95,7 +96,7 @@ private:
* \ingroup simulator
* \ingroup mpi
*
* \brief distributed simulator implementation using lookahead
* \brief Distributed simulator implementation using lookahead
*/
class DistributedSimulatorImpl : public SimulatorImpl
{
@ -157,4 +158,4 @@ private:
} // namespace ns3
#endif /* DISTRIBUTED_SIMULATOR_IMPL_H */
#endif /* NS3_DISTRIBUTED_SIMULATOR_IMPL_H */

337
src/mpi/model/granted-time-window-mpi-interface.cc

@ -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

175
src/mpi/model/granted-time-window-mpi-interface.h

@ -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 */

292
src/mpi/model/mpi-interface.cc

@ -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/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"
#ifdef NS3_MPI
#include <mpi.h>
#endif
namespace ns3 {
SentBuffer::SentBuffer ()
{
m_buffer = 0;
m_request = 0;
}
SentBuffer::~SentBuffer ()
{
delete [] m_buffer;
}
#include <ns3/global-value.h>
#include <ns3/string.h>
#include <ns3/log.h>
uint8_t*
SentBuffer::GetBuffer ()
{
return m_buffer;
}
void
SentBuffer::SetBuffer (uint8_t* buffer)
{
m_buffer = buffer;
}
#include "null-message-mpi-interface.h"
#include "granted-time-window-mpi-interface.h"
#ifdef NS3_MPI
MPI_Request*
SentBuffer::GetRequest ()
{
return &m_request;
}
#endif
NS_LOG_COMPONENT_DEFINE ("MpiInterface");
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;
namespace ns3 {
#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;
}
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)
else
{
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]);
return false;
}
#else
NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
#endif
}
void
MpiInterface::SendPacket (Ptr<Packet> p, const Time& rxTime, uint32_t node, uint32_t dev)
MpiInterface::Enable (int* pargc, char*** pargv)
{
#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.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);
StringValue simulationTypeValue;
bool useDefault = true;
// 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)
if (GlobalValue::GetValueByNameFailSafe ("SimulatorImplementationType", simulationTypeValue))
{
int flag = 0;
int index = 0;
MPI_Status status;
std::string simulationType = simulationTypeValue.Get ();
MPI_Testany (GetSize (), m_requests, &index, &flag, &status);
if (!flag)
// Set communication interface based on the simulation type being used.
// Defaults to synchronous.
if (simulationType.compare ("ns3::NullMessageSimulatorImpl") == 0)
{
break; // No more messages
g_parallelCommunicationInterface = new NullMessageMpiInterface ();
useDefault = false;
}
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)
else if (simulationType.compare ("ns3::DistributedSimulatorImpl") == 0)
{
Ptr<NetDevice> pThisDev = pNode->GetDevice (i);
if (pThisDev->GetIfIndex () == dev)
{
pMpiRec = pThisDev->GetObject<MpiReceiver> ();
break;
g_parallelCommunicationInterface = new GrantedTimeWindowMpiInterface ();
useDefault = false;
}
}
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]);
// 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");
}
#else
NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
#endif
g_parallelCommunicationInterface->Enable (pargc, pargv);
}
void
MpiInterface::TestSendComplete ()
MpiInterface::SendPacket (Ptr<Packet> p, const Time& rxTime, uint32_t node, uint32_t dev)
{
#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
NS_ASSERT (g_parallelCommunicationInterface);
g_parallelCommunicationInterface->SendPacket (p, rxTime, node, dev);
}
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;
}

130
src/mpi/model/mpi-interface.h

@ -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 @@ public:
* 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:
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

2
src/mpi/model/mpi-receiver.h

@ -29,7 +29,7 @@ namespace ns3 {
/**
* \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

460
src/mpi/model/null-message-mpi-interface.cc

@ -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

228
src/mpi/model/null-message-mpi-interface.h

@ -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 */

603
src/mpi/model/null-message-simulator-impl.cc

@ -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

212
src/mpi/model/null-message-simulator-impl.h

@ -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 */

99
src/mpi/model/parallel-communication-interface.h

@ -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 */

112
src/mpi/model/remote-channel-bundle-manager.cc

@ -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

107
src/mpi/model/remote-channel-bundle-manager.h

@ -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

130
src/mpi/model/remote-channel-bundle.cc

@ -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

151
src/mpi/model/remote-channel-bundle.h

@ -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

11
src/mpi/wscript

@ -36,16 +36,21 @@ def build(bld):
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-interface.h',
'model/mpi-receiver.h',
'model/mpi-interface.h',
'model/parallel-communication-interface.h',
]
if env['ENABLE_MPI']:

1
src/point-to-point/helper/point-to-point-helper.cc

@ -241,6 +241,7 @@ PointToPointHelper::Install (Ptr<Node> a, Ptr<Node> b)
//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 ();

1
src/point-to-point/model/point-to-point-net-device.cc

@ -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"

Loading…
Cancel
Save