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 | 49 |
49 #ifdef NS3_MPI | 50 #ifdef NS3_MPI |
50 #include <mpi.h> | 51 #include <mpi.h> |
51 #endif | 52 #endif |
52 | 53 |
53 using namespace ns3; | 54 using namespace ns3; |
54 | 55 |
55 NS_LOG_COMPONENT_DEFINE ("SimpleDistributed"); | 56 NS_LOG_COMPONENT_DEFINE ("SimpleDistributed"); |
56 | 57 |
57 int | 58 int |
58 main (int argc, char *argv[]) | 59 main (int argc, char *argv[]) |
59 { | 60 { |
60 #ifdef NS3_MPI | 61 #ifdef NS3_MPI |
61 // Distributed simulation setup | 62 // Distributed simulation setup |
62 MPIInterface::Enable (&argc, &argv); | 63 MpiInterface::Enable (&argc, &argv); |
63 GlobalValue::Bind ("SimulatorImplementationType", | 64 GlobalValue::Bind ("SimulatorImplementationType", |
64 StringValue ("ns3::DistributedSimulatorImpl")); | 65 StringValue ("ns3::DistributedSimulatorImpl")); |
65 | 66 |
66 LogComponentEnable ("PacketSink", LOG_LEVEL_INFO); | 67 LogComponentEnable ("PacketSink", LOG_LEVEL_INFO); |
67 | 68 |
68 uint32_t rank = MPIInterface::Rank (); | 69 uint32_t systemId = MpiInterface::GetSystemId (); |
69 uint32_t systemCount = MPIInterface::Size (); | 70 uint32_t systemCount = MpiInterface::GetSize (); |
70 | 71 |
71 // Check for valid distributed parameters. | 72 // Check for valid distributed parameters. |
72 // Must have 2 and only 2 Logical Processors (LPs) | 73 // Must have 2 and only 2 Logical Processors (LPs) |
73 if (systemCount != 2) | 74 if (systemCount != 2) |
74 { | 75 { |
75 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; |
76 return 1; | 77 return 1; |
77 } | 78 } |
78 | 79 |
79 // Some default values | 80 // Some default values |
80 Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512)); | 81 Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512)); |
81 Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("1Mbps")); | 82 Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("1Mbps")); |
82 Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (512)); | 83 Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (512)); |
83 bool nix = true; | 84 bool nix = true; |
84 | 85 |
85 // Parse command line | 86 // Parse command line |
86 CommandLine cmd; | 87 CommandLine cmd; |
87 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); |
88 cmd.Parse (argc, argv); | 89 cmd.Parse (argc, argv); |
89 | 90 |
90 // Create leaf nodes on left with | 91 // Create leaf nodes on left with system id 0 |
91 // rank 0 | |
92 NodeContainer leftLeafNodes; | 92 NodeContainer leftLeafNodes; |
93 for (uint32_t i = 0; i < 4; ++i) | 93 leftLeafNodes.Create (4, 0); |
94 { | 94 |
95 Ptr<Node> node = CreateObject<Node> (0); | 95 // Create router nodes. Left router |
96 leftLeafNodes.Add (node); | 96 // with system id 0, right router with |
97 } | 97 // system id 1 |
98 | |
99 // Create router nodes. Left router· | |
100 // with rank 0, right router with· | |
101 // rank 1 | |
102 NodeContainer routerNodes; | 98 NodeContainer routerNodes; |
103 Ptr<Node> routerNode1 = CreateObject<Node> (0); | 99 Ptr<Node> routerNode1 = CreateObject<Node> (0); |
104 Ptr<Node> routerNode2 = CreateObject<Node> (1); | 100 Ptr<Node> routerNode2 = CreateObject<Node> (1); |
105 routerNodes.Add (routerNode1); | 101 routerNodes.Add (routerNode1); |
106 routerNodes.Add (routerNode2); | 102 routerNodes.Add (routerNode2); |
107 | 103 |
108 // Create right nodes on left with | 104 // Create leaf nodes on left with system id 1 |
109 // rank 1 | |
110 NodeContainer rightLeafNodes; | 105 NodeContainer rightLeafNodes; |
111 for (uint32_t i = 0; i < 4; ++i) | 106 rightLeafNodes.Create (4, 1); |
112 { | |
113 Ptr<Node> node = CreateObject<Node> (1); | |
114 rightLeafNodes.Add (node); | |
115 } | |
116 | 107 |
117 PointToPointHelper routerLink; | 108 PointToPointHelper routerLink; |
118 routerLink.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); | 109 routerLink.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); |
119 routerLink.SetChannelAttribute ("Delay", StringValue ("5ms")); | 110 routerLink.SetChannelAttribute ("Delay", StringValue ("5ms")); |
120 | 111 |
121 PointToPointHelper leafLink; | 112 PointToPointHelper leafLink; |
122 leafLink.SetDeviceAttribute ("DataRate", StringValue ("1Mbps")); | 113 leafLink.SetDeviceAttribute ("DataRate", StringValue ("1Mbps")); |
123 leafLink.SetChannelAttribute ("Delay", StringValue ("2ms")); | 114 leafLink.SetChannelAttribute ("Delay", StringValue ("2ms")); |
124 | 115 |
125 // Add link connecting routers | 116 // Add link connecting routers |
126 NetDeviceContainer routerDevices; | 117 NetDeviceContainer routerDevices; |
127 routerDevices = routerLink.Install (routerNodes); | 118 routerDevices = routerLink.Install (routerNodes); |
128 | 119 |
129 // Add links for left side links | 120 // Add links for left side leaf nodes to left router |
130 NetDeviceContainer leftRouterDevices; | 121 NetDeviceContainer leftRouterDevices; |
131 NetDeviceContainer leftLeafDevices; | 122 NetDeviceContainer leftLeafDevices; |
132 for (uint32_t i = 0; i < 4; ++i) | 123 for (uint32_t i = 0; i < 4; ++i) |
133 { | 124 { |
134 NetDeviceContainer temp = leafLink.Install (leftLeafNodes.Get (i), routerN
odes.Get (0)); | 125 NetDeviceContainer temp = leafLink.Install (leftLeafNodes.Get (i), routerN
odes.Get (0)); |
135 leftLeafDevices.Add (temp.Get (0)); | 126 leftLeafDevices.Add (temp.Get (0)); |
136 leftRouterDevices.Add (temp.Get (1)); | 127 leftRouterDevices.Add (temp.Get (1)); |
137 } | 128 } |
138 | 129 |
139 // Add links for right side links | 130 // Add links for right side leaf nodes to right router |
140 NetDeviceContainer rightRouterDevices; | 131 NetDeviceContainer rightRouterDevices; |
141 NetDeviceContainer rightLeafDevices; | 132 NetDeviceContainer rightLeafDevices; |
142 for (uint32_t i = 0; i < 4; ++i) | 133 for (uint32_t i = 0; i < 4; ++i) |
143 { | 134 { |
144 NetDeviceContainer temp = leafLink.Install (rightLeafNodes.Get (i), router
Nodes.Get (1)); | 135 NetDeviceContainer temp = leafLink.Install (rightLeafNodes.Get (i), router
Nodes.Get (1)); |
145 rightLeafDevices.Add (temp.Get (0)); | 136 rightLeafDevices.Add (temp.Get (0)); |
146 rightRouterDevices.Add (temp.Get (1)); | 137 rightRouterDevices.Add (temp.Get (1)); |
147 } | 138 } |
148 | 139 |
149 InternetStackHelper stack; | 140 InternetStackHelper stack; |
150 Ipv4NixVectorHelper nixRouting; | 141 Ipv4NixVectorHelper nixRouting; |
151 Ipv4StaticRoutingHelper staticRouting; | 142 Ipv4StaticRoutingHelper staticRouting; |
152 | 143 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 rightAddress.NewNetwork (); | 194 rightAddress.NewNetwork (); |
204 } | 195 } |
205 | 196 |
206 if (!nix) | 197 if (!nix) |
207 { | 198 { |
208 Ipv4GlobalRoutingHelper::PopulateRoutingTables (); | 199 Ipv4GlobalRoutingHelper::PopulateRoutingTables (); |
209 } | 200 } |
210 | 201 |
211 // 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 |
212 uint16_t port = 50000; | 203 uint16_t port = 50000; |
213 if (rank == 1) | 204 if (systemId == 1) |
214 { | 205 { |
215 Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port)
); | 206 Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port)
); |
216 PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress); | 207 PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress); |
217 ApplicationContainer sinkApp; | 208 ApplicationContainer sinkApp; |
218 for (uint32_t i = 0; i < 4; ++i) | 209 for (uint32_t i = 0; i < 4; ++i) |
219 { | 210 { |
220 sinkApp.Add (sinkHelper.Install (rightLeafNodes.Get (i))); | 211 sinkApp.Add (sinkHelper.Install (rightLeafNodes.Get (i))); |
221 } | 212 } |
222 sinkApp.Start (Seconds (1.0)); | 213 sinkApp.Start (Seconds (1.0)); |
223 sinkApp.Stop (Seconds (5)); | 214 sinkApp.Stop (Seconds (5)); |
224 } | 215 } |
225 | 216 |
226 // Create the OnOff applications to send | 217 // Create the OnOff applications to send |
227 if (rank == 0) | 218 if (systemId == 0) |
228 { | 219 { |
229 OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ()); | 220 OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ()); |
230 clientHelper.SetAttribute | 221 clientHelper.SetAttribute |
231 ("OnTime", RandomVariableValue (ConstantVariable (1))); | 222 ("OnTime", RandomVariableValue (ConstantVariable (1)))
; |
232 clientHelper.SetAttribute | 223 clientHelper.SetAttribute |
233 ("OffTime", RandomVariableValue (ConstantVariable (0))); | 224 ("OffTime", RandomVariableValue (ConstantVariable (0))
); |
234 | 225 |
235 ApplicationContainer clientApps; | 226 ApplicationContainer clientApps; |
236 for(uint32_t i = 0; i < 4; ++i) | 227 for (uint32_t i = 0; i < 4; ++i) |
237 { | 228 { |
238 AddressValue remoteAddress | 229 AddressValue remoteAddress |
239 (InetSocketAddress (rightLeafInterfaces.GetAddress (i), port
)); | 230 (InetSocketAddress (rightLeafInterfaces.GetAddress (i)
, port)); |
240 clientHelper.SetAttribute ("Remote", remoteAddress); | 231 clientHelper.SetAttribute ("Remote", remoteAddress); |
241 clientApps.Add(clientHelper.Install (leftLeafNodes.Get (i))); | 232 clientApps.Add (clientHelper.Install (leftLeafNodes.Get (i))); |
242 } | 233 } |
243 clientApps.Start (Seconds (1.0)); | 234 clientApps.Start (Seconds (1.0)); |
244 clientApps.Stop (Seconds (5)); | 235 clientApps.Stop (Seconds (5)); |
245 } | 236 } |
246 | 237 |
247 Simulator::Stop (Seconds (5)); | 238 Simulator::Stop (Seconds (5)); |
248 Simulator::Run (); | 239 Simulator::Run (); |
249 Simulator::Destroy (); | 240 Simulator::Destroy (); |
250 return 0; | 241 return 0; |
251 #else | 242 #else |
252 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"); |
253 #endif | 244 #endif |
254 } | 245 } |
LEFT | RIGHT |