LEFT | RIGHT |
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * This program is free software; you can redistribute it and/or modify | 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 | 4 * it under the terms of the GNU General Public License version 2 as |
5 * published by the Free Software Foundation; | 5 * published by the Free Software Foundation; |
6 * | 6 * |
7 * This program is distributed in the hope that it will be useful, | 7 * This program is distributed in the hope that it will be useful, |
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 * GNU General Public License for more details. | 10 * GNU General Public License for more details. |
11 * | 11 * |
12 * You should have received a copy of the GNU General Public License | 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 | 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 | 14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
15 * | 15 * |
16 * | 16 * |
17 * TestDistributed creates a dumbbell topology and logically splits it in | 17 * TestDistributed creates a dumbbell topology and logically splits it in |
18 * half. The left half is placed on logical processor 0 and the right half | 18 * half. The left half is placed on logical processor 0 and the right half |
19 * is placed on logical processor 1. | 19 * is placed on logical processor 1. |
20 * | 20 * |
21 * ------- ------- | 21 * ------- ------- |
22 * RANK 0 RANK 1 | 22 * RANK 0 RANK 1 |
23 * ------- | ------- | 23 * ------- | ------- |
24 * | | 24 * | |
25 * n0 ---------| | |---------- n6 | 25 * n0 ---------| | |---------- n6 |
26 * | | | | 26 * | | | |
27 * n1 -------\ | | | /------- n7 | 27 * n1 -------\ | | | /------- n7 |
28 * n4 ----------|---------- n5 | 28 * n4 ----------|---------- n5 |
29 * n2 -------/ | | | \------- n8 | 29 * n2 -------/ | | | \------- n8 |
30 * | | | | 30 * | | | |
31 * n3 ---------| | |---------- n9 | 31 * n3 ---------| | |---------- n9 |
32 * | 32 * |
33 * | 33 * |
34 * OnOff clients are placed on each left leaf node. Each right leaf node | 34 * OnOff clients are placed on each left leaf node. Each right leaf node |
35 * is a packet sink for a left leaf node. As a packet travels from one | 35 * is a packet sink for a left leaf node. As a packet travels from one |
36 * logical processor to another (the link between n4 and n5), MPI messages | 36 * logical processor to another (the link between n4 and n5), MPI messages |
37 * are passed containing the serialized packet. The message is then | 37 * are passed containing the serialized packet. The message is then |
38 * deserialized into a new packet and sent on as normal. | 38 * deserialized into a new packet and sent on as normal. |
39 * | 39 * |
40 * One packet is sent from each left leaf node. The packet sinks on the | 40 * One packet is sent from each left leaf node. The packet sinks on the |
41 * right leaf nodes output logging information when they receive the packet. | 41 * right leaf nodes output logging information when they receive the packet. |
42 */ | 42 */ |
43 | 43 |
44 #include "ns3/core-module.h" | 44 #include "ns3/core-module.h" |
45 #include "ns3/simulator-module.h" | 45 #include "ns3/simulator-module.h" |
46 #include "ns3/node-module.h" | 46 #include "ns3/node-module.h" |
47 #include "ns3/helper-module.h" | 47 #include "ns3/helper-module.h" |
48 #include "ns3/mpi-interface.h" | 48 #include "ns3/mpi-interface.h" |
49 | 49 |
50 #ifdef NS3_MPI | 50 #ifdef NS3_MPI |
51 #include <mpi.h> | 51 #include <mpi.h> |
52 #endif | 52 #endif |
53 | 53 |
54 using namespace ns3; | 54 using namespace ns3; |
55 | 55 |
56 NS_LOG_COMPONENT_DEFINE ("SimpleDistributed"); | 56 NS_LOG_COMPONENT_DEFINE ("SimpleDistributed"); |
57 | 57 |
58 int | 58 int |
59 main (int argc, char *argv[]) | 59 main (int argc, char *argv[]) |
60 { | 60 { |
61 #ifdef NS3_MPI | 61 #ifdef NS3_MPI |
62 // Distributed simulation setup | 62 // Distributed simulation setup |
63 MPIInterface::Enable (&argc, &argv); | 63 MpiInterface::Enable (&argc, &argv); |
64 GlobalValue::Bind ("SimulatorImplementationType", | 64 GlobalValue::Bind ("SimulatorImplementationType", |
65 StringValue ("ns3::DistributedSimulatorImpl")); | 65 StringValue ("ns3::DistributedSimulatorImpl")); |
66 | 66 |
67 LogComponentEnable ("PacketSink", LOG_LEVEL_INFO); | 67 LogComponentEnable ("PacketSink", LOG_LEVEL_INFO); |
68 | 68 |
69 uint32_t rank = MPIInterface::Rank (); | 69 uint32_t systemId = MpiInterface::GetSystemId (); |
70 uint32_t systemCount = MPIInterface::Size (); | 70 uint32_t systemCount = MpiInterface::GetSize (); |
71 | 71 |
72 // Check for valid distributed parameters. | 72 // Check for valid distributed parameters. |
73 // Must have 2 and only 2 Logical Processors (LPs) | 73 // Must have 2 and only 2 Logical Processors (LPs) |
74 if (systemCount != 2) | 74 if (systemCount != 2) |
75 { | 75 { |
76 std::cout << "This simulation requires 2 and only 2 logical processors." <
< std::endl; | 76 std::cout << "This simulation requires 2 and only 2 logical processors." <
< std::endl; |
77 return 1; | 77 return 1; |
78 } | 78 } |
79 | 79 |
80 // Some default values | 80 // Some default values |
81 Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512)); | 81 Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512)); |
82 Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("1Mbps")); | 82 Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("1Mbps")); |
83 Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (512)); | 83 Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (512)); |
84 bool nix = true; | 84 bool nix = true; |
85 | 85 |
86 // Parse command line | 86 // Parse command line |
87 CommandLine cmd; | 87 CommandLine cmd; |
88 cmd.AddValue ("nix", "Toggle the use of nix-vector or global routing", nix); | 88 cmd.AddValue ("nix", "Enable the use of nix-vector or global routing", nix); |
89 cmd.Parse (argc, argv); | 89 cmd.Parse (argc, argv); |
90 | 90 |
91 // Create leaf nodes on left with | 91 // Create leaf nodes on left with system id 0 |
92 // rank 0 | |
93 NodeContainer leftLeafNodes; | 92 NodeContainer leftLeafNodes; |
94 for (uint32_t i = 0; i < 4; ++i) | 93 leftLeafNodes.Create (4, 0); |
95 { | 94 |
96 Ptr<Node> node = CreateObject<Node> (0); | 95 // Create router nodes. Left router |
97 leftLeafNodes.Add (node); | 96 // with system id 0, right router with |
98 } | 97 // system id 1 |
99 | |
100 // Create router nodes. Left router· | |
101 // with rank 0, right router with· | |
102 // rank 1 | |
103 NodeContainer routerNodes; | 98 NodeContainer routerNodes; |
104 Ptr<Node> routerNode1 = CreateObject<Node> (0); | 99 Ptr<Node> routerNode1 = CreateObject<Node> (0); |
105 Ptr<Node> routerNode2 = CreateObject<Node> (1); | 100 Ptr<Node> routerNode2 = CreateObject<Node> (1); |
106 routerNodes.Add (routerNode1); | 101 routerNodes.Add (routerNode1); |
107 routerNodes.Add (routerNode2); | 102 routerNodes.Add (routerNode2); |
108 | 103 |
109 // Create right nodes on left with | 104 // Create leaf nodes on left with system id 1 |
110 // rank 1 | |
111 NodeContainer rightLeafNodes; | 105 NodeContainer rightLeafNodes; |
112 for (uint32_t i = 0; i < 4; ++i) | 106 rightLeafNodes.Create (4, 1); |
113 { | |
114 Ptr<Node> node = CreateObject<Node> (1); | |
115 rightLeafNodes.Add (node); | |
116 } | |
117 | 107 |
118 PointToPointHelper routerLink; | 108 PointToPointHelper routerLink; |
119 routerLink.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); | 109 routerLink.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); |
120 routerLink.SetChannelAttribute ("Delay", StringValue ("5ms")); | 110 routerLink.SetChannelAttribute ("Delay", StringValue ("5ms")); |
121 | 111 |
122 PointToPointHelper leafLink; | 112 PointToPointHelper leafLink; |
123 leafLink.SetDeviceAttribute ("DataRate", StringValue ("1Mbps")); | 113 leafLink.SetDeviceAttribute ("DataRate", StringValue ("1Mbps")); |
124 leafLink.SetChannelAttribute ("Delay", StringValue ("2ms")); | 114 leafLink.SetChannelAttribute ("Delay", StringValue ("2ms")); |
125 | 115 |
126 // Add link connecting routers | 116 // Add link connecting routers |
127 NetDeviceContainer routerDevices; | 117 NetDeviceContainer routerDevices; |
128 routerDevices = routerLink.Install (routerNodes); | 118 routerDevices = routerLink.Install (routerNodes); |
129 | 119 |
130 // Add links for left side links | 120 // Add links for left side leaf nodes to left router |
131 NetDeviceContainer leftRouterDevices; | 121 NetDeviceContainer leftRouterDevices; |
132 NetDeviceContainer leftLeafDevices; | 122 NetDeviceContainer leftLeafDevices; |
133 for (uint32_t i = 0; i < 4; ++i) | 123 for (uint32_t i = 0; i < 4; ++i) |
134 { | 124 { |
135 NetDeviceContainer temp = leafLink.Install (leftLeafNodes.Get (i), routerN
odes.Get (0)); | 125 NetDeviceContainer temp = leafLink.Install (leftLeafNodes.Get (i), routerN
odes.Get (0)); |
136 leftLeafDevices.Add (temp.Get (0)); | 126 leftLeafDevices.Add (temp.Get (0)); |
137 leftRouterDevices.Add (temp.Get (1)); | 127 leftRouterDevices.Add (temp.Get (1)); |
138 } | 128 } |
139 | 129 |
140 // Add links for right side links | 130 // Add links for right side leaf nodes to right router |
141 NetDeviceContainer rightRouterDevices; | 131 NetDeviceContainer rightRouterDevices; |
142 NetDeviceContainer rightLeafDevices; | 132 NetDeviceContainer rightLeafDevices; |
143 for (uint32_t i = 0; i < 4; ++i) | 133 for (uint32_t i = 0; i < 4; ++i) |
144 { | 134 { |
145 NetDeviceContainer temp = leafLink.Install (rightLeafNodes.Get (i), router
Nodes.Get (1)); | 135 NetDeviceContainer temp = leafLink.Install (rightLeafNodes.Get (i), router
Nodes.Get (1)); |
146 rightLeafDevices.Add (temp.Get (0)); | 136 rightLeafDevices.Add (temp.Get (0)); |
147 rightRouterDevices.Add (temp.Get (1)); | 137 rightRouterDevices.Add (temp.Get (1)); |
148 } | 138 } |
149 | 139 |
150 InternetStackHelper stack; | 140 InternetStackHelper stack; |
151 Ipv4NixVectorHelper nixRouting; | 141 Ipv4NixVectorHelper nixRouting; |
152 Ipv4StaticRoutingHelper staticRouting; | 142 Ipv4StaticRoutingHelper staticRouting; |
153 | 143 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 rightAddress.NewNetwork (); | 194 rightAddress.NewNetwork (); |
205 } | 195 } |
206 | 196 |
207 if (!nix) | 197 if (!nix) |
208 { | 198 { |
209 Ipv4GlobalRoutingHelper::PopulateRoutingTables (); | 199 Ipv4GlobalRoutingHelper::PopulateRoutingTables (); |
210 } | 200 } |
211 | 201 |
212 // Create a packet sink on the right leafs to receive packets from left leafs | 202 // Create a packet sink on the right leafs to receive packets from left leafs |
213 uint16_t port = 50000; | 203 uint16_t port = 50000; |
214 if (rank == 1) | 204 if (systemId == 1) |
215 { | 205 { |
216 Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port)
); | 206 Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port)
); |
217 PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress); | 207 PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress); |
218 ApplicationContainer sinkApp; | 208 ApplicationContainer sinkApp; |
219 for (uint32_t i = 0; i < 4; ++i) | 209 for (uint32_t i = 0; i < 4; ++i) |
220 { | 210 { |
221 sinkApp.Add (sinkHelper.Install (rightLeafNodes.Get (i))); | 211 sinkApp.Add (sinkHelper.Install (rightLeafNodes.Get (i))); |
222 } | 212 } |
223 sinkApp.Start (Seconds (1.0)); | 213 sinkApp.Start (Seconds (1.0)); |
224 sinkApp.Stop (Seconds (5)); | 214 sinkApp.Stop (Seconds (5)); |
225 } | 215 } |
226 | 216 |
227 // Create the OnOff applications to send | 217 // Create the OnOff applications to send |
228 if (rank == 0) | 218 if (systemId == 0) |
229 { | 219 { |
230 OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ()); | 220 OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ()); |
231 clientHelper.SetAttribute | 221 clientHelper.SetAttribute |
232 ("OnTime", RandomVariableValue (ConstantVariable (1))); | 222 ("OnTime", RandomVariableValue (ConstantVariable (1)))
; |
233 clientHelper.SetAttribute | 223 clientHelper.SetAttribute |
234 ("OffTime", RandomVariableValue (ConstantVariable (0))); | 224 ("OffTime", RandomVariableValue (ConstantVariable (0))
); |
235 | 225 |
236 ApplicationContainer clientApps; | 226 ApplicationContainer clientApps; |
237 for(uint32_t i = 0; i < 4; ++i) | 227 for (uint32_t i = 0; i < 4; ++i) |
238 { | 228 { |
239 AddressValue remoteAddress | 229 AddressValue remoteAddress |
240 (InetSocketAddress (rightLeafInterfaces.GetAddress (i), port
)); | 230 (InetSocketAddress (rightLeafInterfaces.GetAddress (i)
, port)); |
241 clientHelper.SetAttribute ("Remote", remoteAddress); | 231 clientHelper.SetAttribute ("Remote", remoteAddress); |
242 clientApps.Add(clientHelper.Install (leftLeafNodes.Get (i))); | 232 clientApps.Add (clientHelper.Install (leftLeafNodes.Get (i))); |
243 } | 233 } |
244 clientApps.Start (Seconds (1.0)); | 234 clientApps.Start (Seconds (1.0)); |
245 clientApps.Stop (Seconds (5)); | 235 clientApps.Stop (Seconds (5)); |
246 } | 236 } |
247 | 237 |
248 Simulator::Stop (Seconds (5)); | 238 Simulator::Stop (Seconds (5)); |
249 Simulator::Run (); | 239 Simulator::Run (); |
250 Simulator::Destroy (); | 240 Simulator::Destroy (); |
251 return 0; | 241 return 0; |
252 #else | 242 #else |
253 NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in"); | 243 NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in"); |
254 #endif | 244 #endif |
255 } | 245 } |
LEFT | RIGHT |