1 /* Copyright (c) 2010-2021. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
6 /* This example shows how to build set customized communication factors
8 * It uses the interface provided by NetworkModelIntf to register 2 callbacks that
9 * are called everytime a communication occurs.
11 * These factors are used to change the communication time depending on the message size
14 * This example uses factors obtained by some experiments on dahu cluster in Grid'5000.
15 * You must change the values according to the calibration of your enviroment.
19 #include <simgrid/kernel/resource/NetworkModelIntf.hpp>
20 #include <simgrid/s4u.hpp>
21 namespace sg4 = simgrid::s4u;
23 XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_network_factors, "Messages specific for this s4u example");
25 /* Factors used in this platform, for remote and local communications
26 * Obtained from dahu cluster. Obs.: just an example, change the values according
27 * to the calibration on your environment */
28 static const std::map<double, double> REMOTE_BW_FACTOR = {
29 {0, 1.0000000000000002}, {8000, 1.0000000000000002}, {15798, 0.07435006650635523},
30 {64000, 0.3163352696348148}, {6000000, 0.13003278960133288}, {42672591, 0.10354740223279707},
31 {160097505, 0.40258935729656503}};
32 static const std::map<double, double> LOCAL_BW_FACTOR = {{0, 0.17591906192813994},
33 {16000, 0.12119203247138953},
34 {6000000, 0.07551057012803415},
35 {36900419, 0.04281516758309203},
36 {160097505, 0.17440518795992602}};
38 static const std::map<double, double> REMOTE_LAT_FACTOR = {{0, 0.0},
39 {8000, 1731.7102918851567},
40 {15798, 1441.073993161278},
41 {64000, 1761.4784830658123},
44 {160097505, 970913.4558162984}};
45 static const std::map<double, double> LOCAL_LAT_FACTOR = {
46 {0, 0.0}, {16000, 650.2212383180362}, {6000000, 0.0}, {36900419, 0.0}, {160097505, 1017885.3518765072}};
48 /* bandwidth and latency used on the platform */
49 constexpr static double BW_REMOTE = 12.5e9;
50 constexpr static double BW_LOCAL = 25e9;
51 constexpr static double LATENCY = .1e-6;
53 /*************************************************************************************************/
54 /** @brief Create a simple platform based on Dahu cluster */
55 static void load_platform(const sg4::Engine& e)
58 * Inspired on dahu cluster on Grenoble
64 * / / | | \ \ <-- 12.5GBps links
69 auto* root = sg4::create_star_zone("dahu");
70 std::string prefix = "dahu-", suffix = ".grid5000.fr";
72 for (int id = 0; id < 32; id++) {
73 std::string hostname = prefix + std::to_string(id) + suffix;
75 sg4::Host* host = root->create_host(hostname, 1)->set_core_count(32)->seal();
76 /* create UP/DOWN link */
77 sg4::Link* l_up = root->create_link(hostname + "_up", BW_REMOTE)->set_latency(LATENCY)->seal();
78 sg4::Link* l_down = root->create_link(hostname + "_down", BW_REMOTE)->set_latency(LATENCY)->seal();
80 /* add link UP/DOWN for communications from the host */
81 root->add_route(host->get_netpoint(), nullptr, nullptr, nullptr, std::vector<sg4::Link*>{l_up}, false);
82 root->add_route(nullptr, host->get_netpoint(), nullptr, nullptr, std::vector<sg4::Link*>{l_down}, false);
84 sg4::Link* loopback = root->create_link(hostname + "_loopback", BW_LOCAL)->set_latency(LATENCY)->seal();
85 root->add_route(host->get_netpoint(), host->get_netpoint(), nullptr, nullptr, std::vector<sg4::Link*>{loopback});
91 /*************************************************************************************************/
92 /** @brief Auxiliary method to get factor for a message size */
93 static double get_factor_from_map(const std::map<double, double>& factors, double size)
96 for (auto const& fact : factors) {
97 if (size < fact.first) {
100 factor = fact.second;
107 * @brief Callback to set latency factor for a communication
109 * Set different factors for local (loopback) and remote communications.
110 * Function signature is defined by API
112 * @param size Message size
113 * @param src Host origin
114 * @param dst Host destination
116 static double latency_factor_cb(double size, const sg4::Host* src, const sg4::Host* dst,
117 const std::vector<sg4::Link*>& /*links*/,
118 const std::unordered_set<sg4::NetZone*>& /*netzones*/)
120 if (src->get_name() == dst->get_name()) {
121 /* local communication factors */
122 return get_factor_from_map(LOCAL_LAT_FACTOR, size);
124 return get_factor_from_map(REMOTE_LAT_FACTOR, size);
129 * @brief Callback to set bandwidth factor for a communication
131 * Set different factors for local (loopback) and remote communications.
132 * Function signature is defined by API
134 * @param size Message size
135 * @param src Host origin
136 * @param dst Host destination
138 static double bandwidth_factor_cb(double size, const sg4::Host* src, const sg4::Host* dst,
139 const std::vector<sg4::Link*>& /*links*/,
140 const std::unordered_set<sg4::NetZone*>& /*netzones*/)
142 if (src->get_name() == dst->get_name()) {
143 /* local communication factors */
144 return get_factor_from_map(LOCAL_BW_FACTOR, size);
146 return get_factor_from_map(REMOTE_BW_FACTOR, size);
150 /*************************************************************************************************/
152 std::vector<sg4::Host*> hosts_;
155 explicit Sender(const std::vector<sg4::Host*>& hosts) : hosts_{hosts} {}
156 void operator()() const
158 const std::vector<double> msg_sizes = {64e3, 64e6, 64e9}; // 64KB, 64MB, 64GB
160 for (double size : msg_sizes) {
161 for (const auto* host : hosts_) {
163 /* calculating the estimated communication time depending of message size and destination */
164 if (host->get_name() == sg4::this_actor::get_host()->get_name()) {
165 double lat_factor = get_factor_from_map(LOCAL_LAT_FACTOR, size);
166 double bw_factor = get_factor_from_map(LOCAL_BW_FACTOR, size);
167 double est_time = sg4::Engine::get_clock() + size / (BW_LOCAL * bw_factor) + LATENCY * lat_factor;
169 msg = "Local communication: size=" + std::to_string(size) + ". Use bw_factor=" + std::to_string(bw_factor) +
170 " lat_factor=" + std::to_string(lat_factor) + ". Estimated finished time=" + std::to_string(est_time);
172 double lat_factor = get_factor_from_map(REMOTE_LAT_FACTOR, size);
173 double bw_factor = get_factor_from_map(REMOTE_BW_FACTOR, size);
174 double est_time = sg4::Engine::get_clock() + (size / (BW_REMOTE * bw_factor)) + LATENCY * lat_factor * 2;
175 msg = "Remote communication: size=" + std::to_string(size) + ". Use bw_factor=" + std::to_string(bw_factor) +
176 " lat_factor=" + std::to_string(lat_factor) + ". Estimated finished time=" + std::to_string(est_time);
179 /* Create a communication representing the ongoing communication */
180 auto mbox = sg4::Mailbox::by_name(host->get_name());
181 auto* payload = new std::string(msg);
182 mbox->put(payload, size);
186 XBT_INFO("Done dispatching all messages");
187 /* sending message to stop receivers */
188 for (const auto* host : hosts_) {
189 auto mbox = sg4::Mailbox::by_name(host->get_name());
190 mbox->put(new std::string("finalize"), 0);
195 /* Receiver actor: wait for messages on the mailbox identified by the hostname */
198 void operator()() const
200 auto mbox = sg4::Mailbox::by_name(sg4::this_actor::get_host()->get_name());
201 // Receiving the message was all we were supposed to do
202 for (bool cont = true; cont;) {
203 auto received = mbox->get_unique<std::string>();
204 XBT_INFO("I got a '%s'.", received->c_str());
205 cont = (*received != "finalize"); // If it's a finalize message, we're done
210 /*************************************************************************************************/
211 int main(int argc, char* argv[])
213 sg4::Engine e(&argc, argv);
214 /* setting network model to default one */
215 e.set_config("network/model:CM02");
217 /* create platform */
219 /* setting network factors callbacks */
220 simgrid::kernel::resource::NetworkModelIntf* model = e.get_netzone_root()->get_network_model();
221 model->set_lat_factor_cb(latency_factor_cb);
222 model->set_bw_factor_cb(bandwidth_factor_cb);
224 sg4::Host* host = e.host_by_name("dahu-1.grid5000.fr");
225 sg4::Host* host_remote = e.host_by_name("dahu-10.grid5000.fr");
226 sg4::Actor::create(std::string("receiver-local"), host, Receiver());
227 sg4::Actor::create(std::string("receiver-remote"), host_remote, Receiver());
228 sg4::Actor::create(std::string("sender") + std::string(host->get_name()), host, Sender({host, host_remote}));
230 /* runs the simulation */