A Discrete-Event Network Simulator
API
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/point-to-point-helper.h"
64 #include "ns3/internet-stack-helper.h"
65 #include "ns3/ipv4-nix-vector-helper.h"
66 #include "ns3/ipv4-address-helper.h"
67 #include "ns3/on-off-helper.h"
68 #include "ns3/packet-sink-helper.h"
69 #include <mpi.h>
70 
71 using namespace ns3;
72 
73 NS_LOG_COMPONENT_DEFINE ("SimpleDistributed");
74 
75 int
76 main (int argc, char *argv[])
77 {
78  bool nix = true;
79  bool nullmsg = false;
80  bool tracing = false;
81 
82  // Parse command line
83  CommandLine cmd (__FILE__);
84  cmd.AddValue ("nix", "Enable the use of nix-vector or global routing", nix);
85  cmd.AddValue ("nullmsg", "Enable the use of null-message synchronization", nullmsg);
86  cmd.AddValue ("tracing", "Enable pcap tracing", tracing);
87  cmd.Parse (argc, argv);
88 
89  // Distributed simulation setup; by default use granted time window algorithm.
90  if(nullmsg)
91  {
92  GlobalValue::Bind ("SimulatorImplementationType",
93  StringValue ("ns3::NullMessageSimulatorImpl"));
94  }
95  else
96  {
97  GlobalValue::Bind ("SimulatorImplementationType",
98  StringValue ("ns3::DistributedSimulatorImpl"));
99  }
100 
101  MpiInterface::Enable (&argc, &argv);
102 
103  LogComponentEnable ("PacketSink", LOG_LEVEL_INFO);
104 
105  uint32_t systemId = MpiInterface::GetSystemId ();
106  uint32_t systemCount = MpiInterface::GetSize ();
107 
108  uint32_t rightHalfSystemId = 777;
109 
110  // Check for valid distributed parameters.
111  // Must have 2 or 3 tasks.
112  if (systemCount == 2)
113  {
114  rightHalfSystemId = 0;
115  }
116  else if (systemCount == 3)
117  {
118  rightHalfSystemId = 1;
119  }
120  else
121  {
122  std::cout << "This simulation requires 2 or 3 logical processors." << std::endl;
123  return 1;
124  }
125 
126  // Some default values
127  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512));
128  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("1Mbps"));
129  Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (512));
130 
131  // Create leaf nodes on left with system id 0
132  NodeContainer leftLeafNodes;
133  leftLeafNodes.Create (4, 0);
134 
135  // Create router nodes. Left router with system id 0, right router
136  // with system id dependent on number of processors using
137  // rightHalfSystemId
138  NodeContainer routerNodes;
139  Ptr<Node> routerNode1 = CreateObject<Node> (0);
140  Ptr<Node> routerNode2 = CreateObject<Node> (rightHalfSystemId);
141  routerNodes.Add (routerNode1);
142  routerNodes.Add (routerNode2);
143 
144  // Create leaf nodes on left with system id rightHalfSystemId
145  NodeContainer rightLeafNodes;
146  rightLeafNodes.Create (4, rightHalfSystemId);
147 
148  PointToPointHelper routerLink;
149  routerLink.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
150  routerLink.SetChannelAttribute ("Delay", StringValue ("5ms"));
151 
152  PointToPointHelper leafLink;
153  leafLink.SetDeviceAttribute ("DataRate", StringValue ("1Mbps"));
154  leafLink.SetChannelAttribute ("Delay", StringValue ("2ms"));
155 
156  // Add link connecting routers
157  NetDeviceContainer routerDevices;
158  routerDevices = routerLink.Install (routerNodes);
159 
160  // Add links for left side leaf nodes to left router
161  NetDeviceContainer leftRouterDevices;
162  NetDeviceContainer leftLeafDevices;
163  for (uint32_t i = 0; i < 4; ++i)
164  {
165  NetDeviceContainer temp = leafLink.Install (leftLeafNodes.Get (i), routerNodes.Get (0));
166  leftLeafDevices.Add (temp.Get (0));
167  leftRouterDevices.Add (temp.Get (1));
168  }
169 
170  // Add links for right side leaf nodes to right router
171  NetDeviceContainer rightRouterDevices;
172  NetDeviceContainer rightLeafDevices;
173  for (uint32_t i = 0; i < 4; ++i)
174  {
175  NetDeviceContainer temp = leafLink.Install (rightLeafNodes.Get (i), routerNodes.Get (1));
176  rightLeafDevices.Add (temp.Get (0));
177  rightRouterDevices.Add (temp.Get (1));
178  }
179 
181  if (nix)
182  {
183  Ipv4NixVectorHelper nixRouting;
184  stack.SetRoutingHelper (nixRouting); // has effect on the next Install ()
185  }
186 
187  stack.InstallAll ();
188 
189  Ipv4InterfaceContainer routerInterfaces;
190  Ipv4InterfaceContainer leftLeafInterfaces;
191  Ipv4InterfaceContainer leftRouterInterfaces;
192  Ipv4InterfaceContainer rightLeafInterfaces;
193  Ipv4InterfaceContainer rightRouterInterfaces;
194 
195  Ipv4AddressHelper leftAddress;
196  leftAddress.SetBase ("10.1.1.0", "255.255.255.0");
197 
198  Ipv4AddressHelper routerAddress;
199  routerAddress.SetBase ("10.2.1.0", "255.255.255.0");
200 
201  Ipv4AddressHelper rightAddress;
202  rightAddress.SetBase ("10.3.1.0", "255.255.255.0");
203 
204  // Router-to-Router interfaces
205  routerInterfaces = routerAddress.Assign (routerDevices);
206 
207  // Left interfaces
208  for (uint32_t i = 0; i < 4; ++i)
209  {
210  NetDeviceContainer ndc;
211  ndc.Add (leftLeafDevices.Get (i));
212  ndc.Add (leftRouterDevices.Get (i));
213  Ipv4InterfaceContainer ifc = leftAddress.Assign (ndc);
214  leftLeafInterfaces.Add (ifc.Get (0));
215  leftRouterInterfaces.Add (ifc.Get (1));
216  leftAddress.NewNetwork ();
217  }
218 
219  // Right interfaces
220  for (uint32_t i = 0; i < 4; ++i)
221  {
222  NetDeviceContainer ndc;
223  ndc.Add (rightLeafDevices.Get (i));
224  ndc.Add (rightRouterDevices.Get (i));
225  Ipv4InterfaceContainer ifc = rightAddress.Assign (ndc);
226  rightLeafInterfaces.Add (ifc.Get (0));
227  rightRouterInterfaces.Add (ifc.Get (1));
228  rightAddress.NewNetwork ();
229  }
230 
231  if (!nix)
232  {
234  }
235 
236  if (tracing == true)
237  {
238  if (systemId == 0)
239  {
240  routerLink.EnablePcap("router-left", routerDevices, true);
241  leafLink.EnablePcap("leaf-left", leftLeafDevices, true);
242  }
243 
244  if (systemId == rightHalfSystemId)
245  {
246  routerLink.EnablePcap("router-right", routerDevices, true);
247  leafLink.EnablePcap("leaf-right", rightLeafDevices, true);
248  }
249  }
250 
251  // Create a packet sink on the right leafs to receive packets from left leafs
252  uint16_t port = 50000;
253  if (systemId == rightHalfSystemId)
254  {
255  Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
256  PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress);
257  ApplicationContainer sinkApp;
258  for (uint32_t i = 0; i < 4; ++i)
259  {
260  sinkApp.Add (sinkHelper.Install (rightLeafNodes.Get (i)));
261  }
262  sinkApp.Start (Seconds (1.0));
263  sinkApp.Stop (Seconds (5));
264  }
265 
266  // Create the OnOff applications to send
267  if (systemId == 0)
268  {
269  OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ());
270  clientHelper.SetAttribute
271  ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
272  clientHelper.SetAttribute
273  ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
274 
276  for (uint32_t i = 0; i < 4; ++i)
277  {
278  AddressValue remoteAddress
279  (InetSocketAddress (rightLeafInterfaces.GetAddress (i), port));
280  clientHelper.SetAttribute ("Remote", remoteAddress);
281  clientApps.Add (clientHelper.Install (leftLeafNodes.Get (i)));
282  }
283  clientApps.Start (Seconds (1.0));
284  clientApps.Stop (Seconds (5));
285  }
286 
287  Simulator::Stop (Seconds (5));
288  Simulator::Run ();
290  // Exit the MPI execution environment
292  return 0;
293 }
holds a vector of ns3::Application pointers.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
an Inet address class
static Ipv4Address GetAny(void)
holds a vector of std::pair of Ptr<Ipv4> 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:41
NetDeviceContainer Install(NodeContainer c)
void Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container. ...
void Add(const Ipv4InterfaceContainer &other)
Concatenate the entries in the other container with ours.
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Helper class that adds Nix-vector routing to nodes.
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
cmd
Definition: second.py:35
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
stack
Definition: first.py:41
uint16_t port
Definition: dsdv-manet.cc:45
a polymophic address class
Definition: address.h:90
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:361
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
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:44
LOG_INFO and above.
Definition: log.h:107
holds a vector of ns3::NetDevice pointers
static void Bind(std::string name, const AttributeValue &value)
Iterate over the set of GlobalValues until a matching name is found and then set its value with Globa...
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:226
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
AttributeValue implementation for Address.
Definition: address.h:278
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()
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> 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...
clientApps
Definition: first.py:61
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 EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
std::pair< Ptr< Ipv4 >, uint32_t > Get(uint32_t i) const
Get the std::pair of an Ptr<Ipv4> and interface stored at the location specified by the index...
static uint32_t GetSize()
bool tracing
Flag to enable/disable generation of tracing files.
Definition: wifi-bianchi.cc:82
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.