A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
simple-distributed-empty-node.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  *
16  *
17  * This test is equivalent to simple-distributed but tests boundary cases
18  * when one of the ranks has no Nodes on it. When run on two tasks
19  * rank 0 will have all the Nodes and rank 1 will be empty:
20  *
21  * ------- -------
22  * RANK 0 RANK 0
23  * ------- | -------
24  * |
25  * n0 ---------| | |---------- n6
26  * | | |
27  * n1 -------\ | | | /------- n7
28  * n4 ----------|---------- n5
29  * n2 -------/ | | | \------- n8
30  * | | |
31  * n3 ---------| | |---------- n9
32  *
33  *
34  * When run on three tasks rank 1 has the left half of the Nodes and rank 2
35  * will be empty.
36  *
37  * ------- -------
38  * RANK 0 RANK 1
39  * ------- | -------
40  * |
41  * n0 ---------| | |---------- n6
42  * | | |
43  * n1 -------\ | | | /------- n7
44  * n4 ----------|---------- n5
45  * n2 -------/ | | | \------- n8
46  * | | |
47  * n3 ---------| | |---------- n9
48  *
49  * OnOff clients are placed on each left leaf node. Each right leaf node
50  * is a packet sink for a left leaf node. As a packet travels from one
51  * logical processor to another (the link between n4 and n5), MPI messages
52  * are passed containing the serialized packet. The message is then
53  * deserialized into a new packet and sent on as normal.
54  *
55  * One packet is sent from each left leaf node. The packet sinks on the
56  * right leaf nodes output logging information when they receive the packet.
57  */
58 
59 #include "ns3/core-module.h"
60 #include "ns3/network-module.h"
61 #include "ns3/mpi-interface.h"
62 #include "ns3/ipv4-global-routing-helper.h"
63 #include "ns3/ipv4-static-routing-helper.h"
64 #include "ns3/ipv4-list-routing-helper.h"
65 #include "ns3/point-to-point-helper.h"
66 #include "ns3/internet-stack-helper.h"
67 #include "ns3/ipv4-nix-vector-helper.h"
68 #include "ns3/ipv4-address-helper.h"
69 #include "ns3/on-off-helper.h"
70 #include "ns3/packet-sink-helper.h"
71 
72 #ifdef NS3_MPI
73 #include <mpi.h>
74 #endif
75 
76 using namespace ns3;
77 
78 NS_LOG_COMPONENT_DEFINE ("SimpleDistributed");
79 
80 int
81 main (int argc, char *argv[])
82 {
83 #ifdef NS3_MPI
84 
85  bool nix = true;
86  bool nullmsg = false;
87  bool tracing = false;
88 
89  // Parse command line
90  CommandLine cmd;
91  cmd.AddValue ("nix", "Enable the use of nix-vector or global routing", nix);
92  cmd.AddValue ("nullmsg", "Enable the use of null-message synchronization", nullmsg);
93  cmd.AddValue ("tracing", "Enable pcap tracing", tracing);
94  cmd.Parse (argc, argv);
95 
96  // Distributed simulation setup; by default use granted time window algorithm.
97  if(nullmsg)
98  {
99  GlobalValue::Bind ("SimulatorImplementationType",
100  StringValue ("ns3::NullMessageSimulatorImpl"));
101  }
102  else
103  {
104  GlobalValue::Bind ("SimulatorImplementationType",
105  StringValue ("ns3::DistributedSimulatorImpl"));
106  }
107 
108  MpiInterface::Enable (&argc, &argv);
109 
110  LogComponentEnable ("PacketSink", LOG_LEVEL_INFO);
111 
112  uint32_t systemId = MpiInterface::GetSystemId ();
113  uint32_t systemCount = MpiInterface::GetSize ();
114 
115  uint32_t rightHalfSystemId = 777;
116 
117  // Check for valid distributed parameters.
118  // Must have 2 or 3 tasks.
119  if (systemCount == 2)
120  {
121  rightHalfSystemId = 0;
122  }
123  else if (systemCount == 3)
124  {
125  rightHalfSystemId = 1;
126  }
127  else
128  {
129  std::cout << "This simulation requires 2 or 3 logical processors." << std::endl;
130  return 1;
131  }
132 
133  // Some default values
134  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512));
135  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("1Mbps"));
136  Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (512));
137 
138  // Create leaf nodes on left with system id 0
139  NodeContainer leftLeafNodes;
140  leftLeafNodes.Create (4, 0);
141 
142  // Create router nodes. Left router with system id 0, right router
143  // with system id dependent on number of processors using
144  // rightHalfSystemId
145  NodeContainer routerNodes;
146  Ptr<Node> routerNode1 = CreateObject<Node> (0);
147  Ptr<Node> routerNode2 = CreateObject<Node> (rightHalfSystemId);
148  routerNodes.Add (routerNode1);
149  routerNodes.Add (routerNode2);
150 
151  // Create leaf nodes on left with system id rightHalfSystemId
152  NodeContainer rightLeafNodes;
153  rightLeafNodes.Create (4, rightHalfSystemId);
154 
155  PointToPointHelper routerLink;
156  routerLink.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
157  routerLink.SetChannelAttribute ("Delay", StringValue ("5ms"));
158 
159  PointToPointHelper leafLink;
160  leafLink.SetDeviceAttribute ("DataRate", StringValue ("1Mbps"));
161  leafLink.SetChannelAttribute ("Delay", StringValue ("2ms"));
162 
163  // Add link connecting routers
164  NetDeviceContainer routerDevices;
165  routerDevices = routerLink.Install (routerNodes);
166 
167  // Add links for left side leaf nodes to left router
168  NetDeviceContainer leftRouterDevices;
169  NetDeviceContainer leftLeafDevices;
170  for (uint32_t i = 0; i < 4; ++i)
171  {
172  NetDeviceContainer temp = leafLink.Install (leftLeafNodes.Get (i), routerNodes.Get (0));
173  leftLeafDevices.Add (temp.Get (0));
174  leftRouterDevices.Add (temp.Get (1));
175  }
176 
177  // Add links for right side leaf nodes to right router
178  NetDeviceContainer rightRouterDevices;
179  NetDeviceContainer rightLeafDevices;
180  for (uint32_t i = 0; i < 4; ++i)
181  {
182  NetDeviceContainer temp = leafLink.Install (rightLeafNodes.Get (i), routerNodes.Get (1));
183  rightLeafDevices.Add (temp.Get (0));
184  rightRouterDevices.Add (temp.Get (1));
185  }
186 
188  Ipv4NixVectorHelper nixRouting;
189  Ipv4StaticRoutingHelper staticRouting;
190 
192  list.Add (staticRouting, 0);
193  list.Add (nixRouting, 10);
194 
195  if (nix)
196  {
197  stack.SetRoutingHelper (list); // has effect on the next Install ()
198  }
199 
200  stack.InstallAll ();
201 
202  Ipv4InterfaceContainer routerInterfaces;
203  Ipv4InterfaceContainer leftLeafInterfaces;
204  Ipv4InterfaceContainer leftRouterInterfaces;
205  Ipv4InterfaceContainer rightLeafInterfaces;
206  Ipv4InterfaceContainer rightRouterInterfaces;
207 
208  Ipv4AddressHelper leftAddress;
209  leftAddress.SetBase ("10.1.1.0", "255.255.255.0");
210 
211  Ipv4AddressHelper routerAddress;
212  routerAddress.SetBase ("10.2.1.0", "255.255.255.0");
213 
214  Ipv4AddressHelper rightAddress;
215  rightAddress.SetBase ("10.3.1.0", "255.255.255.0");
216 
217  // Router-to-Router interfaces
218  routerInterfaces = routerAddress.Assign (routerDevices);
219 
220  // Left interfaces
221  for (uint32_t i = 0; i < 4; ++i)
222  {
223  NetDeviceContainer ndc;
224  ndc.Add (leftLeafDevices.Get (i));
225  ndc.Add (leftRouterDevices.Get (i));
226  Ipv4InterfaceContainer ifc = leftAddress.Assign (ndc);
227  leftLeafInterfaces.Add (ifc.Get (0));
228  leftRouterInterfaces.Add (ifc.Get (1));
229  leftAddress.NewNetwork ();
230  }
231 
232  // Right interfaces
233  for (uint32_t i = 0; i < 4; ++i)
234  {
235  NetDeviceContainer ndc;
236  ndc.Add (rightLeafDevices.Get (i));
237  ndc.Add (rightRouterDevices.Get (i));
238  Ipv4InterfaceContainer ifc = rightAddress.Assign (ndc);
239  rightLeafInterfaces.Add (ifc.Get (0));
240  rightRouterInterfaces.Add (ifc.Get (1));
241  rightAddress.NewNetwork ();
242  }
243 
244  if (!nix)
245  {
247  }
248 
249  if (tracing == true)
250  {
251  if (systemId == 0)
252  {
253  routerLink.EnablePcap("router-left", routerDevices, true);
254  leafLink.EnablePcap("leaf-left", leftLeafDevices, true);
255  }
256 
257  if (systemId == rightHalfSystemId)
258  {
259  routerLink.EnablePcap("router-right", routerDevices, true);
260  leafLink.EnablePcap("leaf-right", rightLeafDevices, true);
261  }
262  }
263 
264  // Create a packet sink on the right leafs to receive packets from left leafs
265  uint16_t port = 50000;
266  if (systemId == rightHalfSystemId)
267  {
268  Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
269  PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress);
270  ApplicationContainer sinkApp;
271  for (uint32_t i = 0; i < 4; ++i)
272  {
273  sinkApp.Add (sinkHelper.Install (rightLeafNodes.Get (i)));
274  }
275  sinkApp.Start (Seconds (1.0));
276  sinkApp.Stop (Seconds (5));
277  }
278 
279  // Create the OnOff applications to send
280  if (systemId == 0)
281  {
282  OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ());
283  clientHelper.SetAttribute
284  ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
285  clientHelper.SetAttribute
286  ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
287 
289  for (uint32_t i = 0; i < 4; ++i)
290  {
291  AddressValue remoteAddress
292  (InetSocketAddress (rightLeafInterfaces.GetAddress (i), port));
293  clientHelper.SetAttribute ("Remote", remoteAddress);
294  clientApps.Add (clientHelper.Install (leftLeafNodes.Get (i)));
295  }
296  clientApps.Start (Seconds (1.0));
297  clientApps.Stop (Seconds (5));
298  }
299 
300  Simulator::Stop (Seconds (5));
301  Simulator::Run ();
303  // Exit the MPI execution environment
305  return 0;
306 #else
307  NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
308 #endif
309 }
holds a vector of ns3::Application pointers.
an Inet address class
static Ipv4Address GetAny(void)
std::pair< Ptr< Ipv4 >, uint32_t > Get(uint32_t i) const
Get the std::pair of an Ptr and interface stored at the location specified by the index...
holds a vector of std::pair of Ptr and interface index.
static void PopulateRoutingTables(void)
Build a routing database and initialize the routing tables of the nodes in the simulation.
hold variables of type string
Definition: string.h:18
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
NetDeviceContainer Install(NodeContainer c)
void Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container. ...
static void Run(void)
Run the simulation until one of:
Definition: simulator.cc:157
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
Helper class that adds Nix-vector routing to nodes.
aggregate IP/TCP/UDP functionality to existing Nodes.
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:95
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
static void Disable()
Terminates the parallel environment.
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:42
uint16_t port
Definition: dsdv-manet.cc:44
a polymophic address class
Definition: address.h:86
tuple clientApps
Definition: first.py:53
void InstallAll(void) const
Aggregate IPv4, IPv6, UDP, and TCP stacks to all nodes in the simulation.
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
static void Enable(int *pargc, char ***pargv)
Sets up parallel communication interface.
Hold an unsigned integer type.
Definition: uinteger.h:46
holds a vector of ns3::NetDevice pointers
static void Bind(std::string name, const AttributeValue &value)
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter...
Parse command-line arguments.
Definition: command-line.h:177
#define list
static void Destroy(void)
Every event scheduled by the Simulator::insertAtDestroy method is invoked.
Definition: simulator.cc:121
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:667
keep track of a set of node pointers.
int main(int argc, char *argv[])
void Add(const Ipv4RoutingHelper &routing, int16_t priority)
tuple stack
Definition: first.py:34
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
hold objects of type ns3::Address
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter...
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
void Add(NodeContainer other)
Append the contents of another NodeContainer to the end of this container.
static uint32_t GetSystemId()
Helper class that adds ns3::Ipv4StaticRouting objects.
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:435
static void Stop(void)
If an event invokes this method, it will be the last event scheduled by the Simulator::run method bef...
Definition: simulator.cc:165
Ptr< Node > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
Ipv4Address NewNetwork(void)
Increment the network number and reset the IP address counter to the base value provided in the SetBa...
Helper class that adds ns3::Ipv4ListRouting objects.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
void Parse(int argc, char *argv[])
Parse the program arguments.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void Add(Ipv4InterfaceContainer other)
Concatenate the entries in the other container with ours.
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::OnOffApplication on each node of the input container configured with all the attribut...
static uint32_t GetSize()
void SetRoutingHelper(const Ipv4RoutingHelper &routing)
void SetAttribute(std::string name, const AttributeValue &value)
Helper function used to set the underlying application attributes.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:318
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const