From 5faedc2049b92e342701e36b76cf072169ea19e6 Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Tue, 26 Apr 2011 14:57:48 -0400 Subject: [PATCH] fix mpi --- examples/mpi/wscript | 2 +- src/mpi/model/mpi-interface.cc | 11 ++-- src/mpi/model/mpi-net-device.h | 51 --------------- .../{mpi-net-device.cc => mpi-receiver.cc} | 26 ++++++-- src/mpi/model/mpi-receiver.h | 62 +++++++++++++++++++ src/mpi/wscript | 4 +- .../helper/point-to-point-helper.cc | 7 +++ .../model/point-to-point-net-device.h | 3 +- 8 files changed, 99 insertions(+), 67 deletions(-) delete mode 100644 src/mpi/model/mpi-net-device.h rename src/mpi/model/{mpi-net-device.cc => mpi-receiver.cc} (65%) create mode 100644 src/mpi/model/mpi-receiver.h diff --git a/examples/mpi/wscript b/examples/mpi/wscript index ad12028cc..d8a181bb6 100644 --- a/examples/mpi/wscript +++ b/examples/mpi/wscript @@ -2,7 +2,7 @@ def build(bld): obj = bld.create_ns3_program('simple-distributed', - ['point-to-point', 'internet', 'nix-vector-routing']) + ['point-to-point', 'internet', 'nix-vector-routing', 'applications']) obj.source = 'simple-distributed.cc' obj = bld.create_ns3_program('third-distributed', diff --git a/src/mpi/model/mpi-interface.cc b/src/mpi/model/mpi-interface.cc index 8d0d7e450..0b8fba514 100644 --- a/src/mpi/model/mpi-interface.cc +++ b/src/mpi/model/mpi-interface.cc @@ -24,7 +24,7 @@ #include #include "mpi-interface.h" -#include "mpi-net-device.h" +#include "mpi-receiver.h" #include "ns3/node.h" #include "ns3/node-list.h" @@ -235,24 +235,23 @@ MpiInterface::ReceiveMessages () // Find the correct node/device to schedule receive event Ptr pNode = NodeList::GetNode (node); + Ptr pMpiRec = 0; uint32_t nDevices = pNode->GetNDevices (); - Ptr pMpiDev; for (uint32_t i = 0; i < nDevices; ++i) { Ptr pThisDev = pNode->GetDevice (i); if (pThisDev->GetIfIndex () == dev) { - pDev = DynamicCast (pThisDev); + pMpiRec = pThisDev->GetObject (); break; } } - NS_ASSERT (pNode && pDev); + NS_ASSERT (pNode && pMpiRec); // Schedule the rx event Simulator::ScheduleWithContext (pNode->GetId (), rxTime - Simulator::Now (), - &MpiNetDevice::Receive, - pMpiDev, p); + &MpiReceiver::Receive, pMpiRec, p); // Re-queue the next read MPI_Irecv (m_pRxBuffers[index], MAX_MPI_MSG_SIZE, MPI_CHAR, MPI_ANY_SOURCE, 0, diff --git a/src/mpi/model/mpi-net-device.h b/src/mpi/model/mpi-net-device.h deleted file mode 100644 index 54d4798fa..000000000 --- a/src/mpi/model/mpi-net-device.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- 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 - */ - -// Provides a mixin interface to allow MPI-compatible NetDevices to inherit - -#ifndef NS3_MPI_NET_DEVICE_H -#define NS3_MPI_NET_DEVICE_H - -#include "ns3/packet.h" - -namespace ns3 { - -/** - * Class to mixin to a NetDevice if it supports MPI capability - * - * Subclass must implement DoMpiReceive to direct it to the device's - * normal Receive() method. - */ -class MpiNetDevice -{ -public: - virtual ~MpiNetDevice(); - /** - * - * Receive a packet - * - * \param p Ptr to the received packet. - */ - void MpiReceive (Ptr p); -protected: - virtual void DoMpiReceive (Ptr p) = 0; -}; - -} // namespace ns3 - -#endif /* NS3_MPI_NET_DEVICE_H */ diff --git a/src/mpi/model/mpi-net-device.cc b/src/mpi/model/mpi-receiver.cc similarity index 65% rename from src/mpi/model/mpi-net-device.cc rename to src/mpi/model/mpi-receiver.cc index 5a1696c44..005773ac3 100644 --- a/src/mpi/model/mpi-net-device.cc +++ b/src/mpi/model/mpi-receiver.cc @@ -16,18 +16,34 @@ * Author: George Riley */ -#include "mpi-net-device.h" +#include "mpi-receiver.h" namespace ns3 { -MpiNetDevice::~MpiNetDevice () +TypeId +MpiReceiver::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::MpiReceiver") + .SetParent () + .AddConstructor (); + return tid; +} + +MpiReceiver::~MpiReceiver () { } -void -MpiNetDevice::MpiReceive (Ptr p) +void +MpiReceiver::SetReceiveCallback (Callback > callback) { - DoMpiReceive (p); + m_rxCallback = callback; +} + +void +MpiReceiver::Receive (Ptr p) +{ + NS_ASSERT (! m_rxCallback.IsNull ()); + m_rxCallback (p); } } // namespace ns3 diff --git a/src/mpi/model/mpi-receiver.h b/src/mpi/model/mpi-receiver.h new file mode 100644 index 000000000..5b3d0cfec --- /dev/null +++ b/src/mpi/model/mpi-receiver.h @@ -0,0 +1,62 @@ +/* -*- 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 + */ + +// Provides an interface to aggregate to MPI-compatible NetDevices + +#ifndef NS3_MPI_RECEIVER_H +#define NS3_MPI_RECEIVER_H + +#include "ns3/object.h" +#include "ns3/packet.h" + +namespace ns3 { + +/** + * Class to aggregate to a NetDevice if it supports MPI capability + * + * MpiInterface::ReceiveMessages () needs to send packets to a NetDevice + * Receive() method. Since each NetDevice's Receive() method is specific + * to the derived class, and since we do not know whether such a NetDevice + * is MPI-capable, we aggregate one of these objects to each MPI-capable + * device. In addition, we must hook up a NetDevice::Receive() method + * to the callback. So the two steps to enable MPI capability are to + * aggregate this object to a NetDevice, and to set the callback. + */ +class MpiReceiver : public Object +{ +public: + static TypeId GetTypeId (void); + virtual ~MpiReceiver (); + + /** + * \brief Direct an incoming packet to the device Receive() method + * \param p Packet to receive + */ + void Receive (Ptr p); + /** + * \brief Set the receive callback to get packets to net devices + * \param callback the callback itself + */ + void SetReceiveCallback (Callback > callback); +private: + Callback > m_rxCallback; +}; + +} // namespace ns3 + +#endif /* NS3_MPI_RECEIVER_H */ diff --git a/src/mpi/wscript b/src/mpi/wscript index f48b828b0..3ff132b18 100644 --- a/src/mpi/wscript +++ b/src/mpi/wscript @@ -34,7 +34,7 @@ def build(bld): sim.source = [ 'model/distributed-simulator-impl.cc', 'model/mpi-interface.cc', - 'model/mpi-net-device.cc', + 'model/mpi-receiver.cc', ] headers = bld.new_task_gen('ns3header') @@ -42,7 +42,7 @@ def build(bld): headers.source = [ 'model/distributed-simulator-impl.h', 'model/mpi-interface.h', - 'model/mpi-net-device.h', + 'model/mpi-receiver.h', ] if env['ENABLE_MPI']: diff --git a/src/point-to-point/helper/point-to-point-helper.cc b/src/point-to-point/helper/point-to-point-helper.cc index b43b7b928..c01b68414 100644 --- a/src/point-to-point/helper/point-to-point-helper.cc +++ b/src/point-to-point/helper/point-to-point-helper.cc @@ -29,6 +29,7 @@ #include "ns3/packet.h" #include "ns3/names.h" #include "ns3/mpi-interface.h" +#include "ns3/mpi-receiver.h" #include "ns3/trace-helper.h" #include "point-to-point-helper.h" @@ -257,6 +258,12 @@ PointToPointHelper::Install (Ptr a, Ptr b) else { channel = m_remoteChannelFactory.Create (); + Ptr mpiRecA = CreateObject (); + Ptr mpiRecB = CreateObject (); + mpiRecA->SetReceiveCallback (MakeCallback (&PointToPointNetDevice::Receive, devA)); + mpiRecB->SetReceiveCallback (MakeCallback (&PointToPointNetDevice::Receive, devB)); + devA->AggregateObject (mpiRecA); + devB->AggregateObject (mpiRecB); } devA->Attach (channel); diff --git a/src/point-to-point/model/point-to-point-net-device.h b/src/point-to-point/model/point-to-point-net-device.h index 932baae17..ef2748275 100644 --- a/src/point-to-point/model/point-to-point-net-device.h +++ b/src/point-to-point/model/point-to-point-net-device.h @@ -30,7 +30,6 @@ #include "ns3/data-rate.h" #include "ns3/ptr.h" #include "ns3/mac48-address.h" -#include "ns3/mpi-net-device.h" namespace ns3 { @@ -50,7 +49,7 @@ class ErrorModel; * include a queue, data rate, and interframe transmission gap (the * propagation delay is set in the PointToPointChannel). */ -class PointToPointNetDevice : public NetDevice, public MpiNetDevice +class PointToPointNetDevice : public NetDevice { public: static TypeId GetTypeId (void);