Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
fix ns3
[simgrid.git] / src / surf / network_cm02.cpp
index 0145c1f..4c04ee8 100644 (file)
@@ -3,15 +3,17 @@
 /* This program is free software; you can redistribute it and/or modify it
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
-#include <algorithm>
-#include <numeric>
-
-#include "network_cm02.hpp"
+#include "src/surf/network_cm02.hpp"
 #include "simgrid/s4u/Host.hpp"
 #include "simgrid/sg_config.hpp"
+#include "src/kernel/resource/profile/Event.hpp"
+#include "src/surf/network_wifi.hpp"
 #include "src/surf/surf_interface.hpp"
 #include "surf/surf.hpp"
 
+#include <algorithm>
+#include <numeric>
+
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network);
 
 double sg_latency_factor = 1.0; /* default value; can be set by model or from command line */
@@ -65,59 +67,6 @@ void surf_network_model_init_CM02()
   surf_network_model = new simgrid::kernel::resource::NetworkCm02Model();
 }
 
-/***************************************************************************/
-/* The models from Steven H. Low                                           */
-/***************************************************************************/
-/* @article{Low03,                                                         */
-/*   author={Steven H. Low},                                               */
-/*   title={A Duality Model of {TCP} and Queue Management Algorithms},     */
-/*   year={2003},                                                          */
-/*   journal={{IEEE/ACM} Transactions on Networking},                      */
-/*    volume={11}, number={4},                                             */
-/*  }                                                                      */
-void surf_network_model_init_Reno()
-{
-  xbt_assert(surf_network_model == nullptr, "Cannot set the network model twice");
-
-  namespace lmm = simgrid::kernel::lmm;
-  lmm::Lagrange::set_default_protocol_function(lmm::func_reno_f, lmm::func_reno_fp, lmm::func_reno_fpi);
-
-  simgrid::config::set_default<double>("network/latency-factor", 13.01);
-  simgrid::config::set_default<double>("network/bandwidth-factor", 0.97);
-  simgrid::config::set_default<double>("network/weight-S", 20537);
-
-  surf_network_model = new simgrid::kernel::resource::NetworkCm02Model(&simgrid::kernel::lmm::make_new_lagrange_system);
-}
-
-
-void surf_network_model_init_Reno2()
-{
-  xbt_assert(surf_network_model == nullptr, "Cannot set the network model twice");
-
-  namespace lmm = simgrid::kernel::lmm;
-  lmm::Lagrange::set_default_protocol_function(lmm::func_reno2_f, lmm::func_reno2_fp, lmm::func_reno2_fpi);
-
-  simgrid::config::set_default<double>("network/latency-factor", 13.01);
-  simgrid::config::set_default<double>("network/bandwidth-factor", 0.97);
-  simgrid::config::set_default<double>("network/weight-S", 20537);
-
-  surf_network_model = new simgrid::kernel::resource::NetworkCm02Model(&simgrid::kernel::lmm::make_new_lagrange_system);
-}
-
-void surf_network_model_init_Vegas()
-{
-  xbt_assert(surf_network_model == nullptr, "Cannot set the network model twice");
-
-  namespace lmm = simgrid::kernel::lmm;
-  lmm::Lagrange::set_default_protocol_function(lmm::func_vegas_f, lmm::func_vegas_fp, lmm::func_vegas_fpi);
-
-  simgrid::config::set_default<double>("network/latency-factor", 13.01);
-  simgrid::config::set_default<double>("network/bandwidth-factor", 0.97);
-  simgrid::config::set_default<double>("network/weight-S", 20537);
-
-  surf_network_model = new simgrid::kernel::resource::NetworkCm02Model(&simgrid::kernel::lmm::make_new_lagrange_system);
-}
-
 namespace simgrid {
 namespace kernel {
 namespace resource {
@@ -138,26 +87,31 @@ NetworkCm02Model::NetworkCm02Model(kernel::lmm::System* (*make_new_lmm_system)(b
   }
 
   set_maxmin_system(make_new_lmm_system(select));
-  loopback_ = NetworkCm02Model::create_link("__loopback__", 498000000, 0.000015, s4u::Link::SharingPolicy::FATPIPE);
+  loopback_ = NetworkCm02Model::create_link("__loopback__", std::vector<double>(1, 498000000), 0.000015,
+                                            s4u::Link::SharingPolicy::FATPIPE);
 }
 
-LinkImpl* NetworkCm02Model::create_link(const std::string& name, double bandwidth, double latency,
+LinkImpl* NetworkCm02Model::create_link(const std::string& name, const std::vector<double>& bandwidths, double latency,
                                         s4u::Link::SharingPolicy policy)
 {
-  return new NetworkCm02Link(this, name, bandwidth, latency, policy, get_maxmin_system());
+  if (policy == s4u::Link::SharingPolicy::WIFI)
+    return new NetworkWifiLink(this, name, bandwidths, get_maxmin_system());
+
+  xbt_assert(bandwidths.size() == 1, "Non-WIFI links must use only 1 bandwidth.");
+  return new NetworkCm02Link(this, name, bandwidths[0], latency, policy, get_maxmin_system());
 }
 
 void NetworkCm02Model::update_actions_state_lazy(double now, double /*delta*/)
 {
   while (not get_action_heap().empty() && double_equals(get_action_heap().top_date(), now, sg_surf_precision)) {
 
-    NetworkCm02Action* action = static_cast<NetworkCm02Action*>(get_action_heap().pop());
+    auto* action = static_cast<NetworkCm02Action*>(get_action_heap().pop());
     XBT_DEBUG("Something happened to action %p", action);
 
     // if I am wearing a latency hat
     if (action->get_type() == ActionHeap::Type::latency) {
       XBT_DEBUG("Latency paid for action %p. Activating", action);
-      get_maxmin_system()->update_variable_weight(action->get_variable(), action->weight_);
+      get_maxmin_system()->update_variable_penalty(action->get_variable(), action->sharing_penalty_);
       get_action_heap().remove(action);
       action->set_last_update();
 
@@ -188,7 +142,7 @@ void NetworkCm02Model::update_actions_state_full(double /*now*/, double delta)
         action.latency_ = 0.0;
       }
       if (action.latency_ <= 0.0 && not action.is_suspended())
-        get_maxmin_system()->update_variable_weight(action.get_variable(), action.weight_);
+        get_maxmin_system()->update_variable_penalty(action.get_variable(), action.sharing_penalty_);
     }
 
     if (not action.get_variable()->get_number_of_constraint()) {
@@ -202,7 +156,7 @@ void NetworkCm02Model::update_actions_state_full(double /*now*/, double delta)
     if (action.get_max_duration() != NO_MAX_DURATION)
       action.update_max_duration(delta);
 
-    if (((action.get_remains() <= 0) && (action.get_variable()->get_weight() > 0)) ||
+    if (((action.get_remains() <= 0) && (action.get_variable()->get_penalty() > 0)) ||
         ((action.get_max_duration() != NO_MAX_DURATION) && (action.get_max_duration() <= 0))) {
       action.finish(Action::State::FINISHED);
     }
@@ -231,17 +185,18 @@ Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double siz
           std::any_of(back_route.begin(), back_route.end(), [](const LinkImpl* link) { return not link->is_on(); });
   }
 
-  NetworkCm02Action *action = new NetworkCm02Action(this, size, failed);
-  action->weight_ = latency;
+  auto* action              = new NetworkCm02Action(this, size, failed);
+  action->sharing_penalty_  = latency;
   action->latency_ = latency;
   action->rate_ = rate;
+
   if (get_update_algorithm() == Model::UpdateAlgo::LAZY) {
     action->set_last_update();
   }
 
   if (sg_weight_S_parameter > 0) {
-    action->weight_ =
-        std::accumulate(route.begin(), route.end(), action->weight_, [](double total, LinkImpl* const& link) {
+    action->sharing_penalty_ =
+        std::accumulate(route.begin(), route.end(), action->sharing_penalty_, [](double total, LinkImpl* const& link) {
           return total + sg_weight_S_parameter / link->get_bandwidth();
         });
   }
@@ -282,13 +237,48 @@ Action* NetworkCm02Model::communicate(s4u::Host* src, s4u::Host* dst, double siz
                                     : action->rate_);
   }
 
-  for (auto const& link : route)
-    get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), 1.0);
+  for (auto const& link : route) {
+    // Handle WIFI links
+    if (link->get_sharing_policy() == s4u::Link::SharingPolicy::WIFI) {
+      NetworkWifiLink* wifi_link = static_cast<NetworkWifiLink*>(link);
+
+      double rate = wifi_link->get_host_rate(src);
+      if (rate == -1)
+        rate = wifi_link->get_host_rate(dst);
+      xbt_assert(rate != -1,
+                 "None of the source (%s) or destination (%s) is connected to the Access Point '%s'. "
+                 "Please use set_host_rate() on all stations.",
+                 src->get_cname(), dst->get_cname(), link->get_cname());
+      get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), 1.0 / rate);
+
+    } else {
+      get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), 1.0);
+    }
+  }
 
   if (cfg_crosstraffic) {
     XBT_DEBUG("Crosstraffic active: adding backward flow using 5%% of the available bandwidth");
-    for (auto const& link : back_route)
-      get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), .05);
+    bool wifi_dst_assigned = false; // Used by wifi crosstraffic
+    for (auto const& link : back_route) {
+      if (link->get_sharing_policy() == s4u::Link::SharingPolicy::WIFI) {
+        NetworkWifiLink* wifi_link = static_cast<NetworkWifiLink*>(link);
+        /**
+         * For wifi links we should add 0.05/rate.
+         * However since we are using the "back_route" we should encounter in
+         * the first place the dst wifi link.
+         */
+        if (!wifi_dst_assigned && (wifi_link->get_host_rate(dst) != -1)) {
+          get_maxmin_system()->expand(link->get_constraint(), action->get_variable(),
+                                      .05 / wifi_link->get_host_rate(dst));
+          wifi_dst_assigned = true;
+        } else {
+          get_maxmin_system()->expand(link->get_constraint(), action->get_variable(),
+                                      .05 / wifi_link->get_host_rate(src));
+        }
+      } else {
+        get_maxmin_system()->expand(link->get_constraint(), action->get_variable(), .05);
+      }
+    }
 
     // Change concurrency_share here, if you want that cross-traffic is included in the SURF concurrency
     // (You would also have to change simgrid::kernel::lmm::Element::get_concurrency())
@@ -333,21 +323,8 @@ void NetworkCm02Link::apply_event(kernel::profile::Event* triggered, double valu
   } else if (triggered == state_event_) {
     if (value > 0)
       turn_on();
-    else {
-      kernel::lmm::Variable* var = nullptr;
-      const kernel::lmm::Element* elem = nullptr;
-      double now               = surf_get_clock();
-
+    else
       turn_off();
-      while ((var = get_constraint()->get_variable(&elem))) {
-        Action* action = static_cast<Action*>(var->get_id());
-
-        if (action->get_state() == Action::State::INITED || action->get_state() == Action::State::STARTED) {
-          action->set_finish_time(now);
-          action->set_state(Action::State::FAILED);
-        }
-      }
-    }
     tmgr_trace_event_unref(&state_event_);
   } else {
     xbt_die("Unknown event!\n");
@@ -374,10 +351,10 @@ void NetworkCm02Link::set_bandwidth(double value)
     const kernel::lmm::Element* nextelem = nullptr;
     int numelem                  = 0;
     while ((var = get_constraint()->get_variable_safe(&elem, &nextelem, &numelem))) {
-      NetworkCm02Action* action = static_cast<NetworkCm02Action*>(var->get_id());
-      action->weight_ += delta;
+      auto* action = static_cast<NetworkCm02Action*>(var->get_id());
+      action->sharing_penalty_ += delta;
       if (not action->is_suspended())
-        get_model()->get_maxmin_system()->update_variable_weight(action->get_variable(), action->weight_);
+        get_model()->get_maxmin_system()->update_variable_penalty(action->get_variable(), action->sharing_penalty_);
     }
   }
 }
@@ -393,9 +370,9 @@ void NetworkCm02Link::set_latency(double value)
   latency_.peak = value;
 
   while ((var = get_constraint()->get_variable_safe(&elem, &nextelem, &numelem))) {
-    NetworkCm02Action* action = static_cast<NetworkCm02Action*>(var->get_id());
+    auto* action = static_cast<NetworkCm02Action*>(var->get_id());
     action->lat_current_ += delta;
-    action->weight_ += delta;
+    action->sharing_penalty_ += delta;
     if (action->rate_ < 0)
       get_model()->get_maxmin_system()->update_variable_bound(action->get_variable(), NetworkModel::cfg_tcp_gamma /
                                                                                           (2.0 * action->lat_current_));
@@ -410,7 +387,7 @@ void NetworkCm02Link::set_latency(double value)
       }
     }
     if (not action->is_suspended())
-      get_model()->get_maxmin_system()->update_variable_weight(action->get_variable(), action->weight_);
+      get_model()->get_maxmin_system()->update_variable_penalty(action->get_variable(), action->sharing_penalty_);
   }
 }
 
@@ -435,7 +412,7 @@ void NetworkCm02Action::update_remains_lazy(double now)
 
   update_max_duration(delta);
 
-  if ((get_remains_no_update() <= 0 && (get_variable()->get_weight() > 0)) ||
+  if ((get_remains_no_update() <= 0 && (get_variable()->get_penalty() > 0)) ||
       ((get_max_duration() != NO_MAX_DURATION) && (get_max_duration() <= 0))) {
     finish(Action::State::FINISHED);
     get_model()->get_action_heap().remove(this);
@@ -445,6 +422,6 @@ void NetworkCm02Action::update_remains_lazy(double now)
   set_last_value(get_variable()->get_value());
 }
 
-}
-}
+} // namespace resource
+} // namespace kernel
 } // namespace simgrid