blob: f15af34f623bb10a42dbabfe621f86d169a8d974 [file] [log] [blame]
Spyridon Mastorakisf34b3192015-02-16 17:42:01 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2011-2015 Regents of the University of California.
4 *
5 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
6 * contributors.
7 *
8 * ndnSIM is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * ndnSIM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ndnSIM, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
19
20// ndn-simple-mpi.cpp
21
22#include "ns3/core-module.h"
23#include "ns3/network-module.h"
24#include "ns3/point-to-point-module.h"
25#include "ns3/ndnSIM-module.h"
26#include "ns3/mpi-interface.h"
27
28#ifdef NS3_MPI
29#include <mpi.h>
30#else
31#error "ndn-simple-mpi scenario can be compiled only if NS3_MPI is enabled"
32#endif
33
34namespace ns3 {
35
36/**
37 * This scenario simulates a very simple network topology using mpi:
38 *
39 *
40 * +----------+ 1 Mbps +----------+
41 * | consumer | <------------> | producer |
42 * +----------+ 10ms +----------+
43 *
44 *
45 * Consumer requests data from producer with frequency 10 interests per second
46 * (interests contain constantly increasing sequence number).
47 *
48 * For every received interest, producer replies with a data packet, containing
49 * 1024 bytes of virtual payload.
50 *
51 * To run scenario and see what is happening, use the following command:
52 *
53 * NS_LOG=ndn.Consumer:ndn.Producer mpirun -np 2 ./waf --run=ndn-simple-mpi
54 *
55 * The default parallel synchronization strategy implemented in the
56 * DistributedSimulatorImpl class is based on a globally synchronized algorithm
57 * using an MPI collective operation to synchronize simulation time across all LPs.
58 * A second synchronization strategy based on local communication and null messages
59 * is implemented in the NullMessageSimulatorImpl class, For the null message strategy
60 * the global all to all gather is not required; LPs only need to communication with
61 * LPs that have shared point-to-point links. The algorithm to use is controlled by
62 * which the ns-3 global value SimulatorImplementationType.
63 *
64 * The strategy can be selected according to the value of nullmsg. If nullmsg is true,
65 * then the local communication strategy is selected. If nullmsg is false, then the
66 * globally synchronized strategy is selected. This parameter can be passed either
67 * as a command line argument or by directly modifying the simulation scenario.
68 *
69 */
70
71int
72main(int argc, char* argv[])
73{
74 // setting default parameters for PointToPoint links and channels
75 Config::SetDefault("ns3::PointToPointNetDevice::DataRate", StringValue("1Gbps"));
76 Config::SetDefault("ns3::PointToPointChannel::Delay", StringValue("1ms"));
Spyridon Mastorakisf98a3412017-10-30 11:47:58 -070077 Config::SetDefault("ns3::QueueBase::MaxPackets", UintegerValue(10));
Spyridon Mastorakisf34b3192015-02-16 17:42:01 -080078
79 bool nullmsg = false;
80
81 // Read optional command-line parameters (e.g., enable visualizer with ./waf --run=<> --visualize
82 CommandLine cmd;
83 cmd.AddValue("nullmsg", "Enable the use of null-message synchronization", nullmsg);
84 cmd.Parse(argc, argv);
85
86 // Distributed simulation setup; by default use granted time window algorithm.
87 if (nullmsg) {
88 GlobalValue::Bind("SimulatorImplementationType",
89 StringValue("ns3::NullMessageSimulatorImpl"));
90 }
91 else {
92 GlobalValue::Bind("SimulatorImplementationType",
93 StringValue("ns3::DistributedSimulatorImpl"));
94 }
95
96 // Enable parallel simulator with the command line arguments
97 MpiInterface::Enable(&argc, &argv);
98
99 uint32_t systemId = MpiInterface::GetSystemId();
100 uint32_t systemCount = MpiInterface::GetSize();
101
102 if (systemCount != 2) {
103 std::cout << "Simulation will run on a single processor only" << std::endl
104 << "To run using MPI, run" << std::endl
105 << " mpirun -np 2 ./waf --run=ndn-simple-mpi" << std::endl;
106 }
107
108 // Creating nodes
109
110 // consumer node is associated with system id 0
111 Ptr<Node> node1 = CreateObject<Node>(0);
112
113 // producer node is associated with system id 1 (or 0 when running on single CPU)
114 Ptr<Node> node2 = CreateObject<Node>(systemCount == 2 ? 1 : 0);
115
116 // Connecting nodes using a link
117 PointToPointHelper p2p;
118 p2p.Install(node1, node2);
119
120 // Install NDN stack on all nodes
121 ndn::StackHelper ndnHelper;
122 ndnHelper.InstallAll();
123
124 ndn::FibHelper::AddRoute(node1, "/prefix/1", node2, 1);
125 ndn::FibHelper::AddRoute(node2, "/prefix/2", node1, 1);
126
127 // Installing applications
128 ndn::AppHelper consumerHelper("ns3::ndn::ConsumerCbr");
129 consumerHelper.SetAttribute("Frequency", StringValue("100")); // 10 interests a second
130
131 ndn::AppHelper producerHelper("ns3::ndn::Producer");
132 producerHelper.SetAttribute("PayloadSize", StringValue("1024"));
133
134 // Run consumer application on the first processor only (if running on 2 CPUs)
135 if (systemCount != 2 || systemId == 0) {
136 consumerHelper.SetPrefix("/prefix/1"); // request /prefix/1/*
137 consumerHelper.Install(node1);
138
139 producerHelper.SetPrefix("/prefix/2"); // serve /prefix/2/*
140 producerHelper.Install(node1);
141
142 ndn::L3RateTracer::Install(node1, "node1.txt", Seconds(0.5));
143 }
144
145 // Run consumer application on the second processor only (if running on 2 CPUs)
146 if (systemCount != 2 || systemId == 1) {
147 // Producer
148 consumerHelper.SetPrefix("/prefix/2"); // request /prefix/2/*
149 consumerHelper.Install(node2);
150
151 producerHelper.SetPrefix("/prefix/1"); // serve /prefix/1/*
152 producerHelper.Install(node2);
153
154 ndn::L3RateTracer::Install(node2, "node2.txt", Seconds(0.5));
155 }
156
157 Simulator::Stop(Seconds(400.0));
158
159 Simulator::Run();
160 Simulator::Destroy();
161
162 MpiInterface::Disable();
163 return 0;
164}
165
166} // namespace ns3
167
168
169int
170main(int argc, char* argv[])
171{
172 return ns3::main(argc, argv);
173}