Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'dev/s4u_tuto_fixes' into 'master'
authorArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Fri, 15 Apr 2022 11:33:05 +0000 (11:33 +0000)
committerArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Fri, 15 Apr 2022 11:33:05 +0000 (11:33 +0000)
Dev/s4u tuto fixes

See merge request simgrid/simgrid!94

51 files changed:
.mailmap
MANIFEST.in
docs/source/app_smpi.rst
examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp
include/simgrid/kernel/routing/NetZoneImpl.hpp
include/simgrid/kernel/routing/WifiZone.hpp
include/simgrid/s4u/Engine.hpp
include/simgrid/s4u/VirtualMachine.hpp
src/instr/instr_platform.cpp
src/kernel/EngineImpl.cpp
src/kernel/EngineImpl.hpp
src/kernel/activity/CommImpl.cpp
src/kernel/resource/LinkImpl.hpp
src/kernel/resource/NetworkModel.cpp [moved from src/kernel/resource/LinkImpl.cpp with 97% similarity]
src/kernel/resource/NetworkModel.hpp [new file with mode: 0644]
src/kernel/resource/StandardLinkImpl.cpp
src/kernel/resource/StandardLinkImpl.hpp
src/kernel/resource/VirtualMachineImpl.cpp
src/kernel/resource/VirtualMachineImpl.hpp
src/kernel/routing/DijkstraZone.cpp
src/kernel/routing/DragonflyZone.cpp
src/kernel/routing/FatTreeZone.cpp
src/kernel/routing/FloydZone.cpp
src/kernel/routing/FullZone.cpp
src/kernel/routing/NetZoneImpl.cpp
src/kernel/routing/StarZone.cpp
src/kernel/routing/TorusZone.cpp
src/kernel/routing/WifiZone.cpp
src/plugins/host_dvfs.cpp
src/plugins/link_load.cpp
src/plugins/vm/VmLiveMigration.cpp
src/s4u/s4u_Engine.cpp
src/s4u/s4u_Host.cpp
src/s4u/s4u_Netzone.cpp
src/s4u/s4u_VirtualMachine.cpp
src/smpi/colls/allgather/allgather-rhv.cpp
src/smpi/colls/allreduce/allreduce-smp-rsag-rab.cpp
src/smpi/colls/bcast/bcast-arrival-pattern-aware-wait.cpp
src/surf/HostImpl.cpp
src/surf/HostImpl.hpp
src/surf/host_clm03.cpp
src/surf/network_cm02.cpp
src/surf/network_cm02.hpp
src/surf/network_constant.hpp
src/surf/network_ns3.hpp
src/surf/ptask_L07.cpp
src/surf/ptask_L07.hpp
teshsuite/smpi/mpich3-test/coll/ibarrier.c
teshsuite/surf/surf_usage/surf_usage.cpp
teshsuite/surf/surf_usage2/surf_usage2.cpp
tools/cmake/DefinePackages.cmake

index ecbc0de..b1e29da 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -138,6 +138,7 @@ Mark Stillwell <marklee@fortawesome.org> <mstillwell@griffon-40.nancy.grid5000.f
 Mark Stillwell <marklee@fortawesome.org> <mstillwell@griffon-9.nancy.grid5000.fr>
 Frédéric Suter <frederic.suter@cc.in2p3.fr>
 Frédéric Suter <frederic.suter@cc.in2p3.fr> <suter@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
+Frédéric Suter <frederic.suter@cc.in2p3.fr> <suterf@ornl.gov>
 Frédéric Suter <frederic.suter@cc.in2p3.fr> <suter@youpi.(none)>
 Christophe Thiéry <christopho128@gmail.com> <christopho@solarus-engine.org>
 Christophe Thiéry <christopho128@gmail.com> <thiery@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
index 7f28604..aa2f7fa 100644 (file)
@@ -2216,9 +2216,10 @@ include src/kernel/resource/CpuImpl.cpp
 include src/kernel/resource/CpuImpl.hpp
 include src/kernel/resource/DiskImpl.cpp
 include src/kernel/resource/DiskImpl.hpp
-include src/kernel/resource/LinkImpl.cpp
 include src/kernel/resource/LinkImpl.hpp
 include src/kernel/resource/Model.cpp
+include src/kernel/resource/NetworkModel.cpp
+include src/kernel/resource/NetworkModel.hpp
 include src/kernel/resource/NetworkModelIntf_test.cpp
 include src/kernel/resource/Resource.hpp
 include src/kernel/resource/SplitDuplexLinkImpl.cpp
index 7e43c5d..24f8bf7 100644 (file)
@@ -749,11 +749,11 @@ them on top of SMPI.
 Troubleshooting with SMPI
 -------------------------
 
-.................................
-./configure refuses to use smpicc
-.................................
+.........................................
+./configure or cmake refuse to use smpicc
+.........................................
 
-If your ``./configure`` reports that the compiler is not
+If your configuration script (such as ``./configure`` or ``cmake``) reports that the compiler is not
 functional or that you are cross-compiling, try to define the
 ``SMPI_PRETEND_CC`` environment variable before running the
 configuration.
@@ -772,20 +772,20 @@ fail without ``smpirun``.
 
 .. warning::
 
-  Make sure that SMPI_PRETEND_CC is only set when calling ./configure,
+  Make sure that SMPI_PRETEND_CC is only set when calling the configuration script but
   not during the actual execution, or any program compiled with smpicc
   will stop before starting.
 
-..............................................
-./configure does not pick smpicc as a compiler
-..............................................
+.....................................................
+./configure or cmake do not pick smpicc as a compiler
+.....................................................
 
 In addition to the previous answers, some projects also need to be
 explicitly told what compiler to use, as follows:
 
 .. code-block:: console
 
-   $ SMPI_PRETEND_CC=1 ./configure CC=smpicc # here come the other configure parameters
+   $ SMPI_PRETEND_CC=1 cmake CC=smpicc # here come the other configure parameters
    $ make
 
 Maybe your configure is using another variable, such as ``cc`` (in
index 897ebcc..40a9ad3 100644 (file)
@@ -52,7 +52,7 @@ static std::vector<sg4::Exec*> get_ready_tasks(const std::vector<sg4::ActivityPt
   std::map<sg4::Exec*, unsigned int> candidate_execs;
 
   for (auto& a : dax) {
-    // Only loot at activity that have their dependencies solved but are not assigned
+    // Only look at activity that have their dependencies solved but are not assigned
     if (a->dependencies_solved() && not a->is_assigned()) {
       // if it is an exec, it's ready
       auto* exec = dynamic_cast<sg4::Exec*>(a.get());
index 9890254..d0c312a 100644 (file)
@@ -77,6 +77,11 @@ class XBT_PUBLIC NetZoneImpl : public xbt::PropertyHolder {
 
   // our content, as known to our graph routing algorithm (maps vertex_id -> vertex)
   std::vector<kernel::routing::NetPoint*> vertices_;
+  std::map<std::string, resource::StandardLinkImpl*, std::less<>> links_;
+  /* save split-duplex links separately, keep links_ with only LinkImpl* seen by the user
+   * members of a split-duplex are saved in the links_ */
+  std::map<std::string, std::unique_ptr<resource::SplitDuplexLinkImpl>, std::less<>> split_duplex_links_;
+  std::map<std::string, resource::HostImpl*, std::less<>> hosts_;
 
   NetZoneImpl* parent_ = nullptr;
   std::vector<NetZoneImpl*> children_; // sub-netzones
@@ -153,15 +158,68 @@ public:
   std::vector<s4u::Host*> get_all_hosts() const;
   size_t get_host_count() const;
 
+  /**
+   * @brief Recursively gets all links declared in this netzone
+   *
+   * Include children netzones.
+   * @return List of links
+   */
   std::vector<s4u::Link*> get_all_links() const;
+  /**
+   * @brief Recursively gets all links declared in this netzone.
+   *
+   * Using a filter function
+   * Include children netzones.
+   * @param filter Select links based on this filter
+   * @return List of links
+   */
+  std::vector<s4u::Link*> get_filtered_links(const std::function<bool(s4u::Link*)>& filter) const;
+  /** @brief Get total number of links declared in this netzone (and its children) */
   size_t get_link_count() const;
 
+  /**
+   * @brief Searches by the link by its name inside this netzone.
+   * Recursively searches in children netzones
+   *
+   * @param name Link name
+   * @return Link object or nullptr if not found
+   */
+  resource::StandardLinkImpl* get_link_by_name_or_null(const std::string& name) const;
+
+  /**
+   * @brief Searches for split-duplex links by its name inside this netzone.
+   * Recursively searches in child netzones
+   *
+   * @param name Split-duplex Link name
+   * @return Link object or nullptr if not found
+   */
+  resource::SplitDuplexLinkImpl* get_split_duplex_link_by_name_or_null(const std::string& name) const;
+
+  /**
+   * @brief Searches for a host by its name (recursively)
+   * Including children netzones and VMs on physival hosts
+   *
+   * @param name Host (or VM) name
+   * @return HostImpl pointer
+   */
+  resource::HostImpl* get_host_by_name_or_null(const std::string& name) const;
+
+  /**
+   * @brief Gets list of hosts on this netzone recursively.
+   *
+   * Note: This includes hosts on children netzones and VMs on physical hosts.
+   *
+   * @param filter Filter function to select specific nodes
+   * @return List of hosts
+   */
+  std::vector<s4u::Host*> get_filtered_hosts(const std::function<bool(s4u::Host*)>& filter) const;
+
   /** @brief Make a host within that NetZone */
   s4u::Host* create_host(const std::string& name, const std::vector<double>& speed_per_pstate);
   /** @brief Create a disk with the disk model from this NetZone */
   s4u::Disk* create_disk(const std::string& name, double read_bandwidth, double write_bandwidth);
   /** @brief Make a link within that NetZone */
-  virtual s4u::Link* create_link(const std::string& name, const std::vector<double>& bandwidths);
+  s4u::Link* create_link(const std::string& name, const std::vector<double>& bandwidths);
   s4u::SplitDuplexLink* create_split_duplex_link(const std::string& name, const std::vector<double>& bandwidths);
   /** @brief Make a router within that NetZone */
   NetPoint* create_router(const std::string& name);
@@ -220,6 +278,8 @@ private:
   virtual void do_seal()
   { /* obviously nothing to do by default */
   }
+  /** @brief Allows subclasses (wi-fi) to have their own create link method, but keep links_ updated */
+  virtual resource::StandardLinkImpl* do_create_link(const std::string& name, const std::vector<double>& bandwidths);
   void add_child(NetZoneImpl* new_zone);
 };
 } // namespace routing
index 5fa671a..ee3961b 100644 (file)
@@ -23,6 +23,7 @@ class XBT_PRIVATE WifiZone : public RoutedZone {
   NetPoint* access_point_        = nullptr; // Zone's gateway to the external world
 
   void do_seal() override;
+  resource::StandardLinkImpl* do_create_link(const std::string& name, const std::vector<double>& bandwidths) override;
 
 public:
   using RoutedZone::RoutedZone;
@@ -30,7 +31,6 @@ public:
   WifiZone& operator=(const WifiZone) = delete;
 
   void get_local_route(const NetPoint* src, const NetPoint* dst, Route* into, double* latency) override;
-  s4u::Link* create_link(const std::string& name, const std::vector<double>& bandwidths) override;
   NetPoint* get_access_point() const { return access_point_; }
 };
 } // namespace routing
index 87e1815..d20ae12 100644 (file)
@@ -107,8 +107,6 @@ protected:
   friend kernel::resource::StandardLinkImpl;
   void host_register(const std::string& name, Host* host);
   void host_unregister(const std::string& name);
-  void link_register(const std::string& name, const Link* link);
-  void link_unregister(const std::string& name);
   void netpoint_register(simgrid::kernel::routing::NetPoint* card);
   void netpoint_unregister(simgrid::kernel::routing::NetPoint* card);
   void set_netzone_root(const NetZone* netzone);
index f902d64..c4e7dd3 100644 (file)
@@ -45,8 +45,12 @@ class XBT_PUBLIC VirtualMachine : public s4u::Host {
   static xbt::signal<void(VirtualMachine const&)> on_migration_end;
   static xbt::signal<void(VirtualMachine const&)> on_destruction;
 
+#ifndef DOXYGEN
+  friend kernel::resource::VirtualMachineImpl; // calls signals from Impl
+#endif
+
 public:
-  explicit VirtualMachine(const std::string& name, Host* physical_host, int core_amount, size_t ramsize = 1024);
+  explicit VirtualMachine(const std::string& name, Host* physical_host, int core_amount, size_t ramsize);
 
 #ifndef DOXYGEN
   // No copy/move
index d1a1a98..deaa01a 100644 (file)
@@ -15,7 +15,7 @@
 
 #include "src/instr/instr_private.hpp"
 #include "src/kernel/resource/CpuImpl.hpp"
-#include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 #include "src/surf/surf_interface.hpp"
 
 #include <fstream>
index 04f762e..3d4b00e 100644 (file)
@@ -165,20 +165,11 @@ namespace kernel {
 
 EngineImpl::~EngineImpl()
 {
-  /* Since hosts_ is a std::map, the hosts are destroyed in the lexicographic order, which ensures that the output is
-   * reproducible.
-   */
-  while (not hosts_.empty())
-    hosts_.begin()->second->destroy();
-
   /* Also delete the other data */
   delete netzone_root_;
   for (auto const& kv : netpoints_)
     delete kv.second;
 
-  while (not links_.empty())
-    links_.begin()->second->destroy();
-
   for (auto const& kv : mailboxes_)
     delete kv.second;
 
@@ -332,9 +323,6 @@ void EngineImpl::seal_platform() const
     return;
   sealed = true;
 
-  /* sealing resources before run: links */
-  for (auto const& kv : links_)
-    kv.second->get_iface()->seal();
   /* seal netzone root, recursively seal children netzones, hosts and disks */
   netzone_root_->seal();
 }
@@ -396,11 +384,6 @@ void EngineImpl::add_model(std::shared_ptr<resource::Model> model, const std::ve
   models_prio_[model_name] = std::move(model);
 }
 
-void EngineImpl::add_split_duplex_link(const std::string& name, std::unique_ptr<resource::SplitDuplexLinkImpl> link)
-{
-  split_duplex_links_[name] = std::move(link);
-}
-
 /** Wake up all actors waiting for a Surf action to finish */
 void EngineImpl::handle_ended_actions() const
 {
index 28d6c57..8a8f973 100644 (file)
@@ -33,11 +33,6 @@ namespace simgrid {
 namespace kernel {
 
 class EngineImpl {
-  std::map<std::string, s4u::Host*, std::less<>> hosts_;
-  std::map<std::string, resource::StandardLinkImpl*, std::less<>> links_;
-  /* save split-duplex links separately, keep links_ with only LinkImpl* seen by the user
-   * members of a split-duplex are saved in the links_ */
-  std::map<std::string, std::unique_ptr<resource::SplitDuplexLinkImpl>, std::less<>> split_duplex_links_;
   std::unordered_map<std::string, routing::NetPoint*> netpoints_;
   std::unordered_map<std::string, activity::MailboxImpl*> mailboxes_;
 
@@ -141,7 +136,6 @@ public:
   actor::ActorImpl* get_actor_by_pid(aid_t pid);
   void add_actor(aid_t pid, actor::ActorImpl* actor) { actor_list_[pid] = actor; }
   void remove_actor(aid_t pid) { actor_list_.erase(pid); }
-  void add_split_duplex_link(const std::string& name, std::unique_ptr<resource::SplitDuplexLinkImpl> link);
 
 #if SIMGRID_HAVE_MC
   void reset_actor_dynar() { xbt_dynar_reset(actors_vector_); }
index 1e6483d..b73d706 100644 (file)
@@ -15,7 +15,7 @@
 #include "src/kernel/activity/MailboxImpl.hpp"
 #include "src/kernel/actor/SimcallObserver.hpp"
 #include "src/kernel/resource/CpuImpl.hpp"
-#include "src/kernel/resource/LinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 #include "src/kernel/resource/StandardLinkImpl.hpp"
 #include "src/mc/mc_replay.hpp"
 
index 1f07f85..0f2c36a 100644 (file)
@@ -6,95 +6,14 @@
 #ifndef SIMGRID_KERNEL_RESOURCE_LINKIMPL_HPP
 #define SIMGRID_KERNEL_RESOURCE_LINKIMPL_HPP
 
-#include "simgrid/kernel/resource/Model.hpp"
-#include "simgrid/kernel/resource/NetworkModelIntf.hpp"
 #include "simgrid/s4u/Link.hpp"
-#include "src/kernel/lmm/maxmin.hpp"
 #include "src/kernel/resource/Resource.hpp"
 #include "xbt/PropertyHolder.hpp"
 
-#include <list>
-#include <unordered_map>
-
-/***********
- * Classes *
- ***********/
-class StandardLinkImpl;
-
 namespace simgrid {
 namespace kernel {
 namespace resource {
 
-/*********
- * Model *
- *********/
-
-/** @ingroup SURF_network_interface
- * @brief SURF network model interface class
- * @details A model is an object which handles the interactions between its Resources and its Actions
- */
-class NetworkModel : public Model, public NetworkModelIntf {
-public:
-  static config::Flag<double> cfg_tcp_gamma;
-  static config::Flag<bool> cfg_crosstraffic;
-
-  using Model::Model;
-  NetworkModel(const NetworkModel&) = delete;
-  NetworkModel& operator=(const NetworkModel&) = delete;
-  ~NetworkModel() override;
-
-  /**
-   * @brief Create a [WiFi]Link
-   *
-   * @param name The name of the Link
-   * @param bandwidths The vector of bandwidths of the Link in bytes per second
-   */
-  virtual StandardLinkImpl* create_link(const std::string& name, const std::vector<double>& bandwidths) = 0;
-
-  virtual StandardLinkImpl* create_wifi_link(const std::string& name, const std::vector<double>& bandwidths) = 0;
-
-  /**
-   * @brief Create a communication between two hosts.
-   * @details It makes calls to the routing part, and execute the communication between the two end points.
-   *
-   * @param src The source of the communication
-   * @param dst The destination of the communication
-   * @param size The size of the communication in bytes
-   * @param rate Allows to limit the transfer rate. Negative value means unlimited.
-   * @return The action representing the communication
-   */
-  virtual Action* communicate(s4u::Host* src, s4u::Host* dst, double size, double rate) = 0;
-
-  /**
-   * @brief Get the right multiplicative factor for the latency.
-   * @details Depending on the model, the effective latency when sending a message might be different from the
-   * theoretical latency of the link, in function of the message size. In order to account for this, this function gets
-   * this factor.
-   *
-   * @param size The size of the message.
-   * @return The latency factor.
-   */
-  virtual double get_latency_factor(double /* size */) { return sg_latency_factor; }
-
-  /**
-   * @brief Get the right multiplicative factor for the bandwidth.
-   * @details Depending on the model, the effective bandwidth when sending a message might be different from the
-   * theoretical bandwidth of the link, in function of the message size. In order to account for this, this function
-   * gets this factor.
-   *
-   * @param size The size of the message.
-   * @return The bandwidth factor.
-   */
-  virtual double get_bandwidth_factor(double /* size*/) { return sg_bandwidth_factor; }
-
-  double next_occurring_event_full(double now) override;
-
-  void set_lat_factor_cb(const std::function<NetworkFactorCb>& cb) override { THROW_UNIMPLEMENTED; }
-  void set_bw_factor_cb(const std::function<NetworkFactorCb>& cb) override { THROW_UNIMPLEMENTED; }
-
-  StandardLinkImpl* loopback_ = nullptr;
-};
-
 /************
  * Resource *
  ************/
@@ -125,60 +44,6 @@ public:
   virtual void set_concurrency_limit(int limit) const = 0;
 };
 
-/**********
- * Action *
- **********/
-/** @ingroup SURF_network_interface
- * @brief SURF network action interface class
- * @details A NetworkAction represents a communication between two [hosts](@ref HostImpl)
- */
-class NetworkAction : public Action {
-  s4u::Host& src_;
-  s4u::Host& dst_;
-
-public:
-  /** @brief Constructor
-   *
-   * @param model The NetworkModel associated to this NetworkAction
-   * @param cost The cost of this  NetworkAction in [TODO]
-   * @param failed [description]
-   */
-  NetworkAction(Model* model, s4u::Host& src, s4u::Host& dst, double cost, bool failed)
-      : Action(model, cost, failed), src_(src), dst_(dst)
-  {
-  }
-
-  /**
-   * @brief NetworkAction constructor
-   *
-   * @param model The NetworkModel associated to this NetworkAction
-   * @param cost The cost of this  NetworkAction in bytes
-   * @param failed Actions can be created in a failed state
-   * @param var The lmm variable associated to this Action if it is part of a LMM component
-   */
-  NetworkAction(Model* model, s4u::Host& src, s4u::Host& dst, double cost, bool failed, lmm::Variable* var)
-      : Action(model, cost, failed, var), src_(src), dst_(dst){};
-
-  void set_state(Action::State state) override;
-  virtual std::list<StandardLinkImpl*> get_links() const;
-
-  double latency_         = 0.; // Delay before the action starts
-  double lat_current_     = 0.; // Used to compute the communication RTT, and accordingly limit the communication rate
-  double sharing_penalty_ = {};
-
-  s4u::Host& get_src() const { return src_; }
-  s4u::Host& get_dst() const { return dst_; }
-};
-
-/* Insert link(s) at the end of vector `result' (at the beginning, and reversed, for insert_link_latency()), and add
- * link->get_latency() to *latency when latency is not null
- */
-void add_link_latency(std::vector<StandardLinkImpl*>& result, StandardLinkImpl* link, double* latency);
-void add_link_latency(std::vector<StandardLinkImpl*>& result, const std::vector<StandardLinkImpl*>& links,
-                      double* latency);
-void insert_link_latency(std::vector<StandardLinkImpl*>& result, const std::vector<StandardLinkImpl*>& links,
-                         double* latency);
-
 } // namespace resource
 } // namespace kernel
 } // namespace simgrid
similarity index 97%
rename from src/kernel/resource/LinkImpl.cpp
rename to src/kernel/resource/NetworkModel.cpp
index 5369358..354489e 100644 (file)
@@ -6,8 +6,7 @@
 #include <simgrid/s4u/Engine.hpp>
 
 #include "simgrid/sg_config.hpp"
-#include "src/kernel/resource/LinkImpl.hpp"
-#include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 #include "src/kernel/resource/profile/Profile.hpp"
 #include "src/surf/surf_interface.hpp"
 
diff --git a/src/kernel/resource/NetworkModel.hpp b/src/kernel/resource/NetworkModel.hpp
new file mode 100644 (file)
index 0000000..bfe6aa3
--- /dev/null
@@ -0,0 +1,147 @@
+/* Copyright (c) 2004-2022. The SimGrid Team. All rights reserved.          */
+
+/* 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. */
+
+#ifndef SIMGRID_KERNEL_RESOURCE_NETWORKMODEL_HPP
+#define SIMGRID_KERNEL_RESOURCE_NETWORKMODEL_HPP
+
+#include "simgrid/kernel/resource/Model.hpp"
+#include "simgrid/kernel/resource/NetworkModelIntf.hpp"
+#include "src/kernel/resource/StandardLinkImpl.hpp"
+
+#include <list>
+
+namespace simgrid {
+namespace kernel {
+namespace resource {
+
+/*********
+ * Model *
+ *********/
+
+/** @ingroup SURF_network_interface
+ * @brief SURF network model interface class
+ * @details A model is an object which handles the interactions between its Resources and its Actions
+ */
+class NetworkModel : public Model, public NetworkModelIntf {
+public:
+  static config::Flag<double> cfg_tcp_gamma;
+  static config::Flag<bool> cfg_crosstraffic;
+
+  using Model::Model;
+  NetworkModel(const NetworkModel&) = delete;
+  NetworkModel& operator=(const NetworkModel&) = delete;
+  ~NetworkModel() override;
+
+  /**
+   * @brief Create a [WiFi]Link
+   *
+   * @param name The name of the Link
+   * @param bandwidths The vector of bandwidths of the Link in bytes per second
+   */
+  virtual StandardLinkImpl* create_link(const std::string& name, const std::vector<double>& bandwidths) = 0;
+
+  virtual StandardLinkImpl* create_wifi_link(const std::string& name, const std::vector<double>& bandwidths) = 0;
+
+  /**
+   * @brief Create a communication between two hosts.
+   * @details It makes calls to the routing part, and execute the communication between the two end points.
+   *
+   * @param src The source of the communication
+   * @param dst The destination of the communication
+   * @param size The size of the communication in bytes
+   * @param rate Allows to limit the transfer rate. Negative value means unlimited.
+   * @return The action representing the communication
+   */
+  virtual Action* communicate(s4u::Host* src, s4u::Host* dst, double size, double rate) = 0;
+
+  /**
+   * @brief Get the right multiplicative factor for the latency.
+   * @details Depending on the model, the effective latency when sending a message might be different from the
+   * theoretical latency of the link, in function of the message size. In order to account for this, this function gets
+   * this factor.
+   *
+   * @param size The size of the message.
+   * @return The latency factor.
+   */
+  virtual double get_latency_factor(double /* size */) { return sg_latency_factor; }
+
+  /**
+   * @brief Get the right multiplicative factor for the bandwidth.
+   * @details Depending on the model, the effective bandwidth when sending a message might be different from the
+   * theoretical bandwidth of the link, in function of the message size. In order to account for this, this function
+   * gets this factor.
+   *
+   * @param size The size of the message.
+   * @return The bandwidth factor.
+   */
+  virtual double get_bandwidth_factor(double /* size*/) { return sg_bandwidth_factor; }
+
+  double next_occurring_event_full(double now) override;
+
+  void set_lat_factor_cb(const std::function<NetworkFactorCb>& cb) override { THROW_UNIMPLEMENTED; }
+  void set_bw_factor_cb(const std::function<NetworkFactorCb>& cb) override { THROW_UNIMPLEMENTED; }
+
+  std::unique_ptr<StandardLinkImpl, StandardLinkImpl::Deleter> loopback_;
+};
+
+/**********
+ * Action *
+ **********/
+/** @ingroup SURF_network_interface
+ * @brief SURF network action interface class
+ * @details A NetworkAction represents a communication between two [hosts](@ref HostImpl)
+ */
+class NetworkAction : public Action {
+  s4u::Host& src_;
+  s4u::Host& dst_;
+
+public:
+  /** @brief Constructor
+   *
+   * @param model The NetworkModel associated to this NetworkAction
+   * @param cost The cost of this  NetworkAction in [TODO]
+   * @param failed [description]
+   */
+  NetworkAction(Model* model, s4u::Host& src, s4u::Host& dst, double cost, bool failed)
+      : Action(model, cost, failed), src_(src), dst_(dst)
+  {
+  }
+
+  /**
+   * @brief NetworkAction constructor
+   *
+   * @param model The NetworkModel associated to this NetworkAction
+   * @param cost The cost of this  NetworkAction in bytes
+   * @param failed Actions can be created in a failed state
+   * @param var The lmm variable associated to this Action if it is part of a LMM component
+   */
+  NetworkAction(Model* model, s4u::Host& src, s4u::Host& dst, double cost, bool failed, lmm::Variable* var)
+      : Action(model, cost, failed, var), src_(src), dst_(dst){};
+
+  void set_state(Action::State state) override;
+  virtual std::list<StandardLinkImpl*> get_links() const;
+
+  double latency_         = 0.; // Delay before the action starts
+  double lat_current_     = 0.; // Used to compute the communication RTT, and accordingly limit the communication rate
+  double sharing_penalty_ = {};
+
+  s4u::Host& get_src() const { return src_; }
+  s4u::Host& get_dst() const { return dst_; }
+};
+
+/* Insert link(s) at the end of vector `result' (at the beginning, and reversed, for insert_link_latency()), and add
+ * link->get_latency() to *latency when latency is not null
+ */
+void add_link_latency(std::vector<StandardLinkImpl*>& result, StandardLinkImpl* link, double* latency);
+void add_link_latency(std::vector<StandardLinkImpl*>& result, const std::vector<StandardLinkImpl*>& links,
+                      double* latency);
+void insert_link_latency(std::vector<StandardLinkImpl*>& result, const std::vector<StandardLinkImpl*>& links,
+                         double* latency);
+
+} // namespace resource
+} // namespace kernel
+} // namespace simgrid
+
+#endif /* SIMGRID_KERNEL_RESOURCE_NETWORKMODEL_HPP */
index ee06be4..92e4291 100644 (file)
@@ -24,10 +24,14 @@ StandardLinkImpl::StandardLinkImpl(const std::string& name) : LinkImpl(name), pi
   if (name != "__loopback__")
     xbt_assert(not s4u::Link::by_name_or_null(name), "Link '%s' declared several times in the platform.", name.c_str());
 
-  s4u::Engine::get_instance()->link_register(name, &piface_);
   XBT_DEBUG("Create link '%s'", name.c_str());
 }
 
+void StandardLinkImpl::Deleter::operator()(resource::StandardLinkImpl* link) const
+{
+  link->destroy();
+}
+
 /** @brief Fire the required callbacks and destroy the object
  *
  * Don't delete directly a Link, call l->destroy() instead.
@@ -35,7 +39,6 @@ StandardLinkImpl::StandardLinkImpl(const std::string& name) : LinkImpl(name), pi
 void StandardLinkImpl::destroy()
 {
   s4u::Link::on_destruction(piface_);
-  s4u::Engine::get_instance()->link_unregister(get_name());
   delete this;
 }
 
index f63b892..1b06a36 100644 (file)
@@ -34,6 +34,10 @@ protected:
 
 public:
   void destroy(); // Must be called instead of the destructor
+  class Deleter {
+  public:
+    void operator()(StandardLinkImpl* link) const;
+  };
 
   void latency_check(double latency) const;
 
index 2c36cac..9288d0b 100644 (file)
@@ -4,6 +4,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include <simgrid/Exception.hpp>
+#include <simgrid/kernel/routing/NetPoint.hpp>
 #include <simgrid/kernel/routing/NetZoneImpl.hpp>
 #include <simgrid/s4u/Exec.hpp>
 
@@ -183,7 +184,7 @@ Action* VMModel::execute_thread(const s4u::Host* host, double flops_amount, int
 
 VirtualMachineImpl::VirtualMachineImpl(const std::string& name, s4u::VirtualMachine* piface,
                                        simgrid::s4u::Host* host_PM, int core_amount, size_t ramsize)
-    : HostImpl(name, piface), piface_(piface), physical_host_(host_PM), core_amount_(core_amount), ramsize_(ramsize)
+    : HostImpl(name), piface_(piface), physical_host_(host_PM), core_amount_(core_amount), ramsize_(ramsize)
 {
   /* Register this VM to the list of all VMs */
   allVms_.push_back(piface);
@@ -196,7 +197,6 @@ VirtualMachineImpl::VirtualMachineImpl(const std::string& name, s4u::VirtualMach
 
   // It's empty for now, so it should not request resources in the PM
   update_action_weight();
-
   XBT_VERB("Create VM(%s)@PM(%s)", name.c_str(), physical_host_->get_cname());
 }
 
@@ -211,10 +211,51 @@ void VirtualMachineImpl::vm_destroy()
   /* Free the cpu_action of the VM. */
   XBT_ATTRIB_UNUSED bool ret = action_->unref();
   xbt_assert(ret, "Bug: some resource still remains");
+
+  // VM uses the host's netpoint, clean but don't destroy it
+  get_iface()->set_netpoint(nullptr);
+  // Take a temporary copy to delete iface safely after impl is destroy'ed
+  const auto* iface = get_iface();
+  // calls the HostImpl() destroy, it'll delete the impl object
+  destroy();
+
+  delete iface;
+}
+
+void VirtualMachineImpl::start()
+{
+  s4u::VirtualMachine::on_start(*get_iface());
+  s4u::VmHostExt::ensureVmExtInstalled();
+
+  if (physical_host_->extension<s4u::VmHostExt>() == nullptr)
+    physical_host_->extension_set(new s4u::VmHostExt());
+
+  size_t pm_ramsize = physical_host_->extension<s4u::VmHostExt>()->ramsize;
+  if (pm_ramsize &&
+      not physical_host_->extension<s4u::VmHostExt>()->overcommit) { /* Need to verify that we don't overcommit */
+    /* Retrieve the memory occupied by the VMs on that host. Yep, we have to traverse all VMs of all hosts for that */
+    size_t total_ramsize_of_vms = 0;
+    for (auto* const& ws_vm : allVms_)
+      if (physical_host_ == ws_vm->get_pm())
+        total_ramsize_of_vms += ws_vm->get_ramsize();
+
+    if (total_ramsize_of_vms + get_ramsize() > pm_ramsize) {
+      XBT_WARN("cannot start %s@%s due to memory shortage: get_ramsize() %zu, free %zu, pm_ramsize %zu (bytes).",
+               get_cname(), physical_host_->get_cname(), get_ramsize(), pm_ramsize - total_ramsize_of_vms, pm_ramsize);
+      throw VmFailureException(XBT_THROW_POINT,
+                               xbt::string_printf("Memory shortage on host '%s', VM '%s' cannot be started",
+                                                  physical_host_->get_cname(), get_cname()));
+    }
+  }
+  vm_state_ = s4u::VirtualMachine::State::RUNNING;
+
+  s4u::VirtualMachine::on_started(*get_iface());
 }
 
 void VirtualMachineImpl::suspend(const actor::ActorImpl* issuer)
 {
+  s4u::VirtualMachine::on_suspend(*get_iface());
+
   if (vm_state_ != s4u::VirtualMachine::State::RUNNING)
     throw VmFailureException(XBT_THROW_POINT,
                              xbt::string_printf("Cannot suspend VM %s: it is not running.", piface_->get_cname()));
@@ -252,6 +293,7 @@ void VirtualMachineImpl::resume()
   });
 
   vm_state_ = s4u::VirtualMachine::State::RUNNING;
+  s4u::VirtualMachine::on_resume(*get_iface());
 }
 
 /** @brief Power off a VM.
@@ -277,6 +319,7 @@ void VirtualMachineImpl::shutdown(actor::ActorImpl* issuer)
 
   set_state(s4u::VirtualMachine::State::DESTROYED);
 
+  s4u::VirtualMachine::on_shutdown(*get_iface());
   /* FIXME: we may have to do something at the surf layer, e.g., vcpu action */
 }
 
@@ -292,6 +335,7 @@ void VirtualMachineImpl::set_physical_host(s4u::Host* destination)
 
   /* update net_elm with that of the destination physical host */
   piface_->set_netpoint(destination->get_netpoint());
+  physical_host_->get_impl()->move_vm(this, destination->get_impl());
 
   /* Adapt the speed, pstate and other physical characteristics to the one of our new physical CPU */
   piface_->get_cpu()->reset_vcpu(destination->get_cpu());
@@ -342,6 +386,24 @@ void VirtualMachineImpl::update_action_weight()
   action_->set_bound(std::min(impact * physical_host_->get_speed(), user_bound_));
 }
 
+void VirtualMachineImpl::start_migration()
+{
+  is_migrating_ = true;
+  s4u::VirtualMachine::on_migration_start(*get_iface());
+}
+
+void VirtualMachineImpl::end_migration()
+{
+  is_migrating_ = false;
+  s4u::VirtualMachine::on_migration_end(*get_iface());
+}
+
+void VirtualMachineImpl::seal()
+{
+  HostImpl::seal();
+  s4u::VirtualMachine::on_creation(*get_iface());
+}
+
 } // namespace resource
 } // namespace kernel
 } // namespace simgrid
index 30355aa..c5a4bc0 100644 (file)
@@ -32,6 +32,7 @@ public:
   explicit VirtualMachineImpl(const std::string& name, s4u::VirtualMachine* piface, s4u::Host* host, int core_amount,
                               size_t ramsize);
 
+  void start();
   void suspend(const actor::ActorImpl* issuer);
   void resume();
   void shutdown(kernel::actor::ActorImpl* issuer);
@@ -42,8 +43,8 @@ public:
   /** @brief Get the physical host on which the given VM is running */
   s4u::Host* get_physical_host() const { return physical_host_; }
 
-  sg_size_t get_ramsize() const { return ramsize_; }
-  void set_ramsize(sg_size_t ramsize) { ramsize_ = ramsize; }
+  size_t get_ramsize() const { return ramsize_; }
+  void set_ramsize(size_t ramsize) { ramsize_ = ramsize; }
 
   s4u::VirtualMachine::State get_state() const { return vm_state_; }
   void set_state(s4u::VirtualMachine::State state) { vm_state_ = state; }
@@ -61,9 +62,10 @@ public:
   void add_active_exec() { active_execs_++; }
   void remove_active_exec() { active_execs_--; }
 
-  void start_migration() { is_migrating_ = true; }
-  void end_migration() { is_migrating_ = false; }
+  void start_migration();
+  void end_migration();
   bool is_migrating() const { return is_migrating_; }
+  void seal() override;
 
 private:
   s4u::VirtualMachine* piface_;
index c46b5f3..e8d23ae 100644 (file)
@@ -7,7 +7,7 @@
 #include <simgrid/kernel/routing/NetPoint.hpp>
 #include <xbt/string.hpp>
 
-#include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 
 #include <climits>
 #include <queue>
@@ -53,7 +53,7 @@ void DijkstraZone::do_seal()
 
       if (not found) {
         auto* route = new Route();
-        route->link_list_.push_back(get_network_model()->loopback_);
+        route->link_list_.push_back(get_network_model()->loopback_.get());
         xbt_graph_new_edge(route_graph_.get(), node, node, route);
       }
     }
index 8273672..de5aa58 100644 (file)
@@ -5,7 +5,7 @@
 
 #include "simgrid/kernel/routing/DragonflyZone.hpp"
 #include "simgrid/kernel/routing/NetPoint.hpp"
-#include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 
 #include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/split.hpp>
index 2183e2f..3c24baa 100644 (file)
@@ -6,7 +6,7 @@
 #include <simgrid/kernel/routing/FatTreeZone.hpp>
 #include <simgrid/kernel/routing/NetPoint.hpp>
 
-#include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 #include "src/surf/xml/platf.hpp" // surf_parse_error() and surf_parse_assert()
 
 #include <fstream>
index 0fea4c0..867c140 100644 (file)
@@ -7,7 +7,7 @@
 #include <simgrid/kernel/routing/NetPoint.hpp>
 #include <xbt/string.hpp>
 
-#include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 
 #include <climits>
 
@@ -135,7 +135,7 @@ void FloydZone::do_seal()
       auto& route = link_table_[i][i];
       if (not route) {
         route.reset(new Route());
-        route->link_list_.push_back(get_network_model()->loopback_);
+        route->link_list_.push_back(get_network_model()->loopback_.get());
         predecessor_table_[i][i] = i;
         cost_table_[i][i]        = 1;
       }
index c716b8f..8112081 100644 (file)
@@ -6,7 +6,7 @@
 #include <simgrid/kernel/routing/FullZone.hpp>
 #include <simgrid/kernel/routing/NetPoint.hpp>
 
-#include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_full, ker_routing, "Kernel Full Routing");
 
@@ -35,7 +35,7 @@ void FullZone::do_seal()
       auto& route = routing_table_[i][i];
       if (not route) {
         route.reset(new Route());
-        route->link_list_.push_back(get_network_model()->loopback_);
+        route->link_list_.push_back(get_network_model()->loopback_.get());
       }
     }
   }
index fd03d35..cc37733 100644 (file)
@@ -7,15 +7,17 @@
 #include <simgrid/kernel/routing/NetZoneImpl.hpp>
 #include <simgrid/s4u/Engine.hpp>
 #include <simgrid/s4u/Host.hpp>
+#include <simgrid/s4u/VirtualMachine.hpp>
 
 #include "src/include/simgrid/sg_config.hpp"
 #include "src/kernel/EngineImpl.hpp"
 #include "src/kernel/resource/CpuImpl.hpp"
 #include "src/kernel/resource/DiskImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 #include "src/kernel/resource/SplitDuplexLinkImpl.hpp"
-#include "src/surf/HostImpl.hpp"
-
 #include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/VirtualMachineImpl.hpp"
+#include "src/surf/HostImpl.hpp"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing, kernel, "Kernel routing-related information");
 
@@ -107,6 +109,18 @@ NetZoneImpl::~NetZoneImpl()
   for (auto const& nz : children_)
     delete nz;
 
+  /* Since hosts_ and links_ are a std::map, the hosts are destroyed in the lexicographic order, which ensures that the
+   * output is reproducible.
+   */
+  for (auto& host : hosts_) {
+    host.second->destroy();
+  }
+  hosts_.clear();
+  for (auto& link : links_) {
+    link.second->destroy();
+  }
+  links_.clear();
+
   for (auto const& kv : bypass_routes_)
     delete kv.second;
 
@@ -136,15 +150,35 @@ size_t NetZoneImpl::get_host_count() const
   return get_all_hosts().size();
 }
 
+std::vector<s4u::Link*> NetZoneImpl::get_filtered_links(const std::function<bool(s4u::Link*)>& filter) const
+{
+  std::vector<s4u::Link*> filtered_list;
+  for (auto const& kv : links_) {
+    s4u::Link* l = kv.second->get_iface();
+    if (filter(l))
+      filtered_list.push_back(l);
+  }
+
+  for (const auto* child : children_) {
+    auto child_links = child->get_filtered_links(filter);
+    filtered_list.insert(filtered_list.end(), std::make_move_iterator(child_links.begin()),
+                         std::make_move_iterator(child_links.end()));
+  }
+  return filtered_list;
+}
+
 std::vector<s4u::Link*> NetZoneImpl::get_all_links() const
 {
-  return s4u::Engine::get_instance()->get_filtered_links(
-      [this](const s4u::Link* link) { return link->get_impl()->get_englobing_zone() == this; });
+  return get_filtered_links([](const s4u::Link*) { return true; });
 }
 
 size_t NetZoneImpl::get_link_count() const
 {
-  return get_all_links().size();
+  size_t total = links_.size();
+  for (const auto* child : children_) {
+    total += child->get_link_count();
+  }
+  return total;
 }
 
 s4u::Host* NetZoneImpl::create_host(const std::string& name, const std::vector<double>& speed_per_pstate)
@@ -153,12 +187,18 @@ s4u::Host* NetZoneImpl::create_host(const std::string& name, const std::vector<d
              "Impossible to create host: %s. Invalid CPU model: nullptr. Have you set the parent of this NetZone: %s?",
              name.c_str(), get_cname());
   xbt_assert(not sealed_, "Impossible to create host: %s. NetZone %s already sealed", name.c_str(), get_cname());
-  auto* res = (new resource::HostImpl(name))->set_englobing_zone(this)->get_iface();
-  res->set_netpoint((new NetPoint(name, NetPoint::Type::Host))->set_englobing_zone(this));
+  auto* host   = (new resource::HostImpl(name))->set_englobing_zone(this);
+  hosts_[name] = host;
+  host->get_iface()->set_netpoint((new NetPoint(name, NetPoint::Type::Host))->set_englobing_zone(this));
+
+  cpu_model_pm_->create_cpu(host->get_iface(), speed_per_pstate);
 
-  cpu_model_pm_->create_cpu(res, speed_per_pstate);
+  return host->get_iface();
+}
 
-  return res;
+resource::StandardLinkImpl* NetZoneImpl::do_create_link(const std::string& name, const std::vector<double>& bandwidths)
+{
+  return network_model_->create_link(name, bandwidths);
 }
 
 s4u::Link* NetZoneImpl::create_link(const std::string& name, const std::vector<double>& bandwidths)
@@ -168,7 +208,8 @@ s4u::Link* NetZoneImpl::create_link(const std::string& name, const std::vector<d
       "Impossible to create link: %s. Invalid network model: nullptr. Have you set the parent of this NetZone: %s?",
       name.c_str(), get_cname());
   xbt_assert(not sealed_, "Impossible to create link: %s. NetZone %s already sealed", name.c_str(), get_cname());
-  return network_model_->create_link(name, bandwidths)->set_englobing_zone(this)->get_iface();
+  links_[name] = do_create_link(name, bandwidths)->set_englobing_zone(this);
+  return links_[name]->get_iface();
 }
 
 s4u::SplitDuplexLink* NetZoneImpl::create_split_duplex_link(const std::string& name,
@@ -180,12 +221,10 @@ s4u::SplitDuplexLink* NetZoneImpl::create_split_duplex_link(const std::string& n
       name.c_str(), get_cname());
   xbt_assert(not sealed_, "Impossible to create link: %s. NetZone %s already sealed", name.c_str(), get_cname());
 
-  auto* link_up                  = network_model_->create_link(name + "_UP", bandwidths)->set_englobing_zone(this);
-  auto* link_down                = network_model_->create_link(name + "_DOWN", bandwidths)->set_englobing_zone(this);
-  auto link                      = std::make_unique<resource::SplitDuplexLinkImpl>(name, link_up, link_down);
-  auto* link_iface               = link->get_iface();
-  EngineImpl::get_instance()->add_split_duplex_link(name, std::move(link));
-  return link_iface;
+  auto* link_up             = create_link(name + "_UP", bandwidths)->get_impl()->set_englobing_zone(this);
+  auto* link_down           = create_link(name + "_DOWN", bandwidths)->get_impl()->set_englobing_zone(this);
+  split_duplex_links_[name] = std::make_unique<resource::SplitDuplexLinkImpl>(name, link_up, link_down);
+  return split_duplex_links_[name]->get_iface();
 }
 
 s4u::Disk* NetZoneImpl::create_disk(const std::string& name, double read_bandwidth, double write_bandwidth)
@@ -251,6 +290,80 @@ std::vector<resource::StandardLinkImpl*> NetZoneImpl::get_link_list_impl(const s
   return links;
 }
 
+resource::StandardLinkImpl* NetZoneImpl::get_link_by_name_or_null(const std::string& name) const
+{
+  auto link_it = links_.find(name);
+  if (link_it != links_.end())
+    return link_it->second;
+
+  for (const auto* child : children_) {
+    auto* link = child->get_link_by_name_or_null(name);
+    if (link)
+      return link;
+  }
+
+  return nullptr;
+}
+
+resource::SplitDuplexLinkImpl* NetZoneImpl::get_split_duplex_link_by_name_or_null(const std::string& name) const
+{
+  auto link_it = split_duplex_links_.find(name);
+  if (link_it != split_duplex_links_.end())
+    return link_it->second.get();
+
+  for (const auto* child : children_) {
+    auto* link = child->get_split_duplex_link_by_name_or_null(name);
+    if (link)
+      return link;
+  }
+
+  return nullptr;
+}
+
+resource::HostImpl* NetZoneImpl::get_host_by_name_or_null(const std::string& name) const
+{
+  for (auto const& kv : hosts_) {
+    auto* host = kv.second;
+    if (host->get_name() == name)
+      return host;
+    /* keep old behavior where host and VMs were saved together on EngineImpl::hosts_
+     * get hosts returns VMs too */
+    auto* vm = host->get_vm_by_name_or_null(name);
+    if (vm)
+      return vm;
+  }
+
+  for (const auto* child : children_) {
+    auto* host = child->get_host_by_name_or_null(name);
+    if (host)
+      return host;
+  }
+
+  return nullptr;
+}
+
+std::vector<s4u::Host*> NetZoneImpl::get_filtered_hosts(const std::function<bool(s4u::Host*)>& filter) const
+{
+  std::vector<s4u::Host*> filtered_list;
+  for (auto const& kv : hosts_) {
+    s4u::Host* h = kv.second->get_iface();
+    if (filter(h))
+      filtered_list.push_back(h);
+    /* Engine::get_hosts returns the VMs too */
+    for (auto* vm : h->get_impl()->get_vms()) {
+      if (filter(vm))
+        filtered_list.push_back(vm);
+    }
+  }
+
+  for (const auto* child : children_) {
+    auto child_links = child->get_filtered_hosts(filter);
+    filtered_list.insert(filtered_list.end(), std::make_move_iterator(child_links.begin()),
+                         std::make_move_iterator(child_links.end()));
+  }
+  return filtered_list;
+}
+
 void NetZoneImpl::add_route(NetPoint* /*src*/, NetPoint* /*dst*/, NetPoint* /*gw_src*/, NetPoint* /*gw_dst*/,
                             const std::vector<s4u::LinkInRoute>& /*link_list_*/, bool /*symmetrical*/)
 {
@@ -544,6 +657,11 @@ void NetZoneImpl::seal()
   for (auto* host : get_all_hosts()) {
     host->seal();
   }
+
+  /* sealing links */
+  for (auto const& kv : links_)
+    kv.second->get_iface()->seal();
+
   for (auto* sub_net : get_children()) {
     sub_net->seal();
   }
index ddbbd50..489ecd9 100644 (file)
@@ -6,7 +6,7 @@
 #include "simgrid/kernel/routing/StarZone.hpp"
 #include "simgrid/kernel/routing/NetPoint.hpp"
 #include "simgrid/kernel/routing/RoutedZone.hpp"
-#include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 #include "xbt/string.hpp"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_star, ker_routing, "Kernel Star Routing");
index 4e19277..33454a5 100644 (file)
@@ -6,7 +6,7 @@
 #include "simgrid/kernel/routing/TorusZone.hpp"
 #include "simgrid/kernel/routing/NetPoint.hpp"
 #include "simgrid/s4u/Host.hpp"
-#include "src/kernel/resource/LinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 
 #include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/split.hpp>
index 81596ca..a9b941c 100644 (file)
@@ -6,7 +6,7 @@
 #include <simgrid/kernel/routing/NetPoint.hpp>
 #include <simgrid/kernel/routing/WifiZone.hpp>
 
-#include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_routing_wifi, ker_routing, "Kernel Wifi Routing");
 
@@ -45,14 +45,14 @@ void WifiZone::get_local_route(const NetPoint* src, const NetPoint* dst, Route*
   }
 }
 
-s4u::Link* WifiZone::create_link(const std::string& name, const std::vector<double>& bandwidths)
+resource::StandardLinkImpl* WifiZone::do_create_link(const std::string& name, const std::vector<double>& bandwidths)
 {
   xbt_assert(wifi_link_ == nullptr,
              "WIFI netzone %s contains more than one link. Please only declare one, the wifi link.", get_cname());
 
-  wifi_link_ = get_network_model()->create_wifi_link(name, bandwidths)->set_englobing_zone(this);
+  wifi_link_ = get_network_model()->create_wifi_link(name, bandwidths);
   wifi_link_->set_sharing_policy(s4u::Link::SharingPolicy::WIFI, {});
-  return wifi_link_->get_iface();
+  return wifi_link_;
 }
 } // namespace routing
 } // namespace kernel
index db1af09..c6cf779 100644 (file)
@@ -13,7 +13,7 @@
 
 #include "src/internal_config.h" // HAVE_SMPI
 #include "src/kernel/activity/CommImpl.hpp"
-#include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 #if HAVE_SMPI
 #include "src/smpi/include/smpi_request.hpp"
 #include "src/smpi/plugins/ampi/ampi.hpp"
index d29e708..f6089c9 100644 (file)
@@ -7,7 +7,7 @@
 #include <simgrid/s4u/Engine.hpp>
 
 #include "src/kernel/activity/CommImpl.hpp"
-#include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 
 #include <limits>
 
index 2c20df8..4ac6b36 100644 (file)
@@ -95,22 +95,20 @@ static sg_size_t get_updated_size(double computed, double dp_rate, sg_size_t dp_
 sg_size_t MigrationTx::sendMigrationData(sg_size_t size, int stage, int stage2_round, double mig_speed, double timeout)
 {
   sg_size_t sent   = size;
-  auto* msg        = new std::string("__mig_stage");
-  *msg             = *msg + std::to_string(stage) + ":" + vm_->get_cname() + "(" + src_pm_->get_cname() + "-" +
-         dst_pm_->get_cname() + ")";
-
+  auto msg = std::make_unique<std::string>(xbt::string_printf("__mig_stage%d:%s(%s-%s)", stage, vm_->get_cname(),
+                                                              src_pm_->get_cname(), dst_pm_->get_cname()));
   double clock_sta = s4u::Engine::get_clock();
 
-  s4u::CommPtr comm = mbox->put_init(msg, size);
+  s4u::CommPtr comm = mbox->put_init(msg.get(), size);
   if (mig_speed > 0)
     comm->set_rate(mig_speed);
   try {
     comm->wait_for(timeout);
+    msg.release();
   } catch (const Exception&) {
     auto remaining = static_cast<sg_size_t>(comm->get_remaining());
     XBT_VERB("timeout (%lf s) in sending_migration_data, remaining %llu bytes of %llu", timeout, remaining, size);
     sent -= remaining;
-    delete msg;
   }
 
   double clock_end    = s4u::Engine::get_clock();
index d9da9e1..858ee1f 100644 (file)
 #include "mc/mc.h"
 #include "src/instr/instr_private.hpp"
 #include "src/kernel/EngineImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
+#include "src/kernel/resource/SplitDuplexLinkImpl.hpp"
+#include "src/kernel/resource/StandardLinkImpl.hpp"
 #include "src/mc/mc_replay.hpp"
+#include "src/surf/HostImpl.hpp"
 #include "xbt/config.hpp"
 
 #include <algorithm>
@@ -179,55 +183,49 @@ void Engine::load_deployment(const std::string& deploy) const
 /** Returns the amount of hosts in the platform */
 size_t Engine::get_host_count() const
 {
-  return pimpl->hosts_.size();
+  return get_all_hosts().size();
 }
 
 std::vector<Host*> Engine::get_all_hosts() const
 {
-  std::vector<Host*> res;
-  for (auto const& kv : pimpl->hosts_)
-    res.push_back(kv.second);
-  return res;
+  return get_filtered_hosts([](const Host*) { return true; });
 }
 
 std::vector<Host*> Engine::get_filtered_hosts(const std::function<bool(Host*)>& filter) const
 {
   std::vector<Host*> hosts;
-  for (auto const& kv : pimpl->hosts_) {
-    if (filter(kv.second))
-      hosts.push_back(kv.second);
+  if (pimpl->netzone_root_) {
+    hosts = pimpl->netzone_root_->get_filtered_hosts(filter);
   }
+  /* Sort hosts in lexicographical order: keep same behavior when the hosts were saved on Engine
+   * Some tests do a get_all_hosts() and selects hosts in this order */
+  std::sort(hosts.begin(), hosts.end(), [](const auto* h1, const auto* h2) { return h1->get_name() < h2->get_name(); });
 
   return hosts;
 }
 
-void Engine::host_register(const std::string& name, Host* host)
-{
-  pimpl->hosts_[name] = host;
-}
-
-void Engine::host_unregister(const std::string& name)
-{
-  pimpl->hosts_.erase(name);
-}
-
 /** @brief Find a host from its name.
  *
  *  @throw std::invalid_argument if the searched host does not exist.
  */
 Host* Engine::host_by_name(const std::string& name) const
 {
-  auto host = pimpl->hosts_.find(name);
-  if (host == pimpl->hosts_.end())
+  auto* host = host_by_name_or_null(name);
+  if (not host)
     throw std::invalid_argument(std::string("Host not found: '") + name + std::string("'"));
-  return host->second;
+  return host;
 }
 
 /** @brief Find a host from its name (or nullptr if that host does not exist) */
 Host* Engine::host_by_name_or_null(const std::string& name) const
 {
-  auto host = pimpl->hosts_.find(name);
-  return host == pimpl->hosts_.end() ? nullptr : host->second;
+  Host* host = nullptr;
+  if (pimpl->netzone_root_) {
+    auto* host_impl = pimpl->netzone_root_->get_host_by_name_or_null(name);
+    if (host_impl)
+      host = host_impl->get_iface();
+  }
+  return host;
 }
 
 /** @brief Find a link from its name.
@@ -236,25 +234,33 @@ Host* Engine::host_by_name_or_null(const std::string& name) const
  */
 Link* Engine::link_by_name(const std::string& name) const
 {
-  auto link = pimpl->links_.find(name);
-  if (link == pimpl->links_.end())
+  auto* link = link_by_name_or_null(name);
+  if (not link)
     throw std::invalid_argument(std::string("Link not found: ") + name);
-  return link->second->get_iface();
+  return link;
 }
 
 SplitDuplexLink* Engine::split_duplex_link_by_name(const std::string& name) const
 {
-  auto link = pimpl->split_duplex_links_.find(name);
-  if (link == pimpl->split_duplex_links_.end())
+  auto* link_impl = pimpl->netzone_root_ ? pimpl->netzone_root_->get_split_duplex_link_by_name_or_null(name) : nullptr;
+  if (not link_impl)
     throw std::invalid_argument(std::string("Link not found: ") + name);
-  return link->second->get_iface();
+  return link_impl->get_iface();
 }
 
 /** @brief Find a link from its name (or nullptr if that link does not exist) */
 Link* Engine::link_by_name_or_null(const std::string& name) const
 {
-  auto link = pimpl->links_.find(name);
-  return link == pimpl->links_.end() ? nullptr : link->second->get_iface();
+  Link* link = nullptr;
+  if (pimpl->netzone_root_) {
+    /* keep behavior where internal __loopback__ link from network model is given to user */
+    if (name == "__loopback__")
+      return pimpl->netzone_root_->get_network_model()->loopback_->get_iface();
+    auto* link_impl = pimpl->netzone_root_->get_link_by_name_or_null(name);
+    if (link_impl)
+      link = link_impl->get_iface();
+  }
+  return link;
 }
 
 /** @brief Find a mailbox from its name or create one if it does not exist) */
@@ -272,40 +278,35 @@ Mailbox* Engine::mailbox_by_name_or_create(const std::string& name) const
   return mbox->get_iface();
 }
 
-void Engine::link_register(const std::string& name, const Link* link)
-{
-  pimpl->links_[name] = link->get_impl();
-}
-
-void Engine::link_unregister(const std::string& name)
-{
-  pimpl->links_.erase(name);
-}
-
 /** @brief Returns the amount of links in the platform */
 size_t Engine::get_link_count() const
 {
-  return pimpl->links_.size();
+  int count = 0;
+  if (pimpl->netzone_root_) {
+    count += pimpl->netzone_root_->get_link_count();
+    /* keep behavior where internal __loopback__ link from network model is given to user */
+    count += pimpl->netzone_root_->get_network_model()->loopback_ ? 1 : 0;
+  }
+  return count;
 }
 
 /** @brief Returns the list of all links found in the platform */
 std::vector<Link*> Engine::get_all_links() const
 {
-  std::vector<Link*> res;
-  for (auto const& kv : pimpl->links_)
-    res.push_back(kv.second->get_iface());
-  return res;
+  return get_filtered_links([](const Link*) { return true; });
 }
 
 std::vector<Link*> Engine::get_filtered_links(const std::function<bool(Link*)>& filter) const
 {
-  std::vector<Link*> filtered_list;
-  for (auto const& kv : pimpl->links_) {
-    Link* l = kv.second->get_iface();
-    if (filter(l))
-      filtered_list.push_back(l);
+  std::vector<Link*> res;
+  if (pimpl->netzone_root_) {
+    res = pimpl->netzone_root_->get_filtered_links(filter);
+    /* keep behavior where internal __loopback__ link from network model is given to user */
+    if (pimpl->netzone_root_->get_network_model()->loopback_ &&
+        filter(pimpl->netzone_root_->get_network_model()->loopback_->get_iface()))
+      res.push_back(pimpl->netzone_root_->get_network_model()->loopback_->get_iface());
   }
-  return filtered_list;
+  return res;
 }
 
 size_t Engine::get_actor_count() const
index d84f23e..9c0ab22 100644 (file)
@@ -111,11 +111,6 @@ void Host::turn_off()
   if (is_on()) {
     const kernel::actor::ActorImpl* self = kernel::actor::ActorImpl::self();
     kernel::actor::simcall_answered([this, self] {
-      for (VirtualMachine* const& vm : kernel::resource::VirtualMachineImpl::allVms_)
-        if (vm->get_pm() == this) {
-          vm->shutdown();
-          vm->turn_off();
-        }
       this->pimpl_cpu_->turn_off();
       this->pimpl_->turn_off(self);
 
@@ -368,12 +363,14 @@ void Host::remove_disk(const std::string& disk_name)
 
 VirtualMachine* Host::create_vm(const std::string& name, int core_amount)
 {
-  return new VirtualMachine(name, this, core_amount);
+  return kernel::actor::simcall_answered(
+      [this, &name, core_amount] { return this->pimpl_->create_vm(name, core_amount); });
 }
 
 VirtualMachine* Host::create_vm(const std::string& name, int core_amount, size_t ramsize)
 {
-  return new VirtualMachine(name, this, core_amount, ramsize);
+  return kernel::actor::simcall_answered(
+      [this, &name, core_amount, ramsize] { return this->pimpl_->create_vm(name, core_amount, ramsize); });
 }
 
 ExecPtr Host::exec_init(double flops) const
index 699116c..8f01821 100644 (file)
@@ -12,8 +12,7 @@
 #include <simgrid/zone.h>
 #include <xbt/parse_units.hpp>
 
-#include "src/kernel/resource/LinkImpl.hpp"
-#include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 
 namespace simgrid {
 namespace s4u {
index b53de10..b0bb757 100644 (file)
@@ -36,66 +36,15 @@ VirtualMachine::VirtualMachine(const std::string& name, s4u::Host* physical_host
     : Host(new kernel::resource::VirtualMachineImpl(name, this, physical_host, core_amount, ramsize))
     , pimpl_vm_(dynamic_cast<kernel::resource::VirtualMachineImpl*>(Host::get_impl()))
 {
-  XBT_DEBUG("Create VM %s", get_cname());
-
-  /* Currently, a VM uses the network resource of its physical host */
-  set_netpoint(physical_host->get_netpoint());
-
-  // Create a VCPU for this VM
-  std::vector<double> speeds;
-  for (unsigned long i = 0; i < physical_host->get_pstate_count(); i++)
-    speeds.push_back(physical_host->get_pstate_speed(i));
-
-  physical_host->get_netpoint()
-      ->get_englobing_zone()
-      ->get_cpu_vm_model()
-      ->create_cpu(this, speeds)
-      ->set_core_count(core_amount)
-      ->seal();
-
-  if (physical_host->get_pstate() != 0)
-    set_pstate(physical_host->get_pstate());
-
-  seal(); // seal this host
-  s4u::VirtualMachine::on_creation(*this);
 }
 
 void VirtualMachine::start()
 {
-  on_start(*this);
-
-  VmHostExt::ensureVmExtInstalled();
-
-  kernel::actor::simcall_answered([this]() {
-    Host* pm = this->pimpl_vm_->get_physical_host();
-    if (pm->extension<VmHostExt>() == nullptr)
-      pm->extension_set(new VmHostExt());
-
-    size_t pm_ramsize = pm->extension<VmHostExt>()->ramsize;
-    if (pm_ramsize && not pm->extension<VmHostExt>()->overcommit) { /* Need to verify that we don't overcommit */
-      /* Retrieve the memory occupied by the VMs on that host. Yep, we have to traverse all VMs of all hosts for that */
-      size_t total_ramsize_of_vms = 0;
-      for (VirtualMachine* const& ws_vm : kernel::resource::VirtualMachineImpl::allVms_)
-        if (pm == ws_vm->get_pm())
-          total_ramsize_of_vms += ws_vm->get_ramsize();
-
-      if (total_ramsize_of_vms + get_ramsize() > pm_ramsize) {
-        XBT_WARN("cannot start %s@%s due to memory shortage: get_ramsize() %zu, free %zu, pm_ramsize %zu (bytes).",
-                 get_cname(), pm->get_cname(), get_ramsize(), pm_ramsize - total_ramsize_of_vms, pm_ramsize);
-        throw VmFailureException(XBT_THROW_POINT,
-                                 xbt::string_printf("Memory shortage on host '%s', VM '%s' cannot be started",
-                                                    pm->get_cname(), get_cname()));
-      }
-    }
-    this->pimpl_vm_->set_state(State::RUNNING);
-  });
-
-  on_started(*this);
+  kernel::actor::simcall_answered([this]() { pimpl_vm_->start(); });
 }
 
 void VirtualMachine::suspend()
 {
-  on_suspend(*this);
   const kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self();
   kernel::actor::simcall_answered([this, issuer]() { pimpl_vm_->suspend(issuer); });
 }
@@ -103,14 +52,12 @@ void VirtualMachine::suspend()
 void VirtualMachine::resume()
 {
   pimpl_vm_->resume();
-  on_resume(*this);
 }
 
 void VirtualMachine::shutdown()
 {
   kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self();
   kernel::actor::simcall_answered([this, issuer]() { pimpl_vm_->shutdown(issuer); });
-  on_shutdown(*this);
 }
 
 void VirtualMachine::destroy()
@@ -122,14 +69,8 @@ void VirtualMachine::destroy()
     XBT_DEBUG("destroy %s", get_cname());
     on_destruction(*this);
     /* Then, destroy the VM object */
-    kernel::actor::simcall_answered([this]() {
-      get_vm_impl()->vm_destroy();
-      get_impl()->destroy();
-
-      /* Don't free these things twice: they are the ones of my physical host */
-      set_netpoint(nullptr);
-      delete this;
-    });
+    kernel::actor::simcall_answered(
+        [this]() { get_vm_impl()->get_physical_host()->get_impl()->destroy_vm(get_name()); });
   };
 
   if (not this_actor::is_maestro() && this_actor::get_host() == this) {
@@ -204,13 +145,11 @@ VirtualMachine* VirtualMachine::set_bound(double bound)
 void VirtualMachine::start_migration() const
 {
   pimpl_vm_->start_migration();
-  on_migration_start(*this);
 }
 
 void VirtualMachine::end_migration() const
 {
   pimpl_vm_->end_migration();
-  on_migration_end(*this);
 }
 
 } // namespace s4u
index b321f34..e7dae7a 100644 (file)
@@ -63,8 +63,6 @@ allgather__rhv(const void *sbuf, int send_count,
     size /= 2;
   }
 
-  //  printf("node %d base_offset %d\n",rank,base_offset);
-
   //perform a remote copy
 
   dst = base_offset;
@@ -75,7 +73,6 @@ allgather__rhv(const void *sbuf, int send_count,
 
   mask >>= 1;
   i = 1;
-  int phase = 0;
   curr_count = recv_count;
   while (mask >= 1) {
     // destination pair for both send and recv
@@ -92,15 +89,12 @@ allgather__rhv(const void *sbuf, int send_count,
     send_offset = send_base_offset * recv_chunk;
     recv_offset = recv_base_offset * recv_chunk;
 
-    //  printf("node %d send to %d in phase %d s_offset = %d r_offset = %d count = %d\n",rank,dst,phase, send_base_offset, recv_base_offset, curr_count);
-
     Request::sendrecv((char*)rbuf + send_offset, curr_count, recv_type, dst, tag, (char*)rbuf + recv_offset, curr_count,
                       recv_type, dst, tag, comm, &status);
 
     curr_count *= 2;
     i *= 2;
     mask >>= 1;
-    phase++;
   }
 
   return MPI_SUCCESS;
index 838d1fe..cbc8ab7 100644 (file)
@@ -51,8 +51,6 @@ int allreduce__smp_rsag_rab(const void *sbuf, void *rbuf, int count,
   intra_rank = rank % num_core;
   inter_rank = rank / num_core;
 
-  //printf("node %d intra_rank = %d, inter_rank = %d\n", rank, intra_rank, inter_rank);
-
   int inter_comm_size = (comm_size + num_core - 1) / num_core;
 
   Request::sendrecv(sbuf, count, dtype, rank, tag,
@@ -67,13 +65,11 @@ int allreduce__smp_rsag_rab(const void *sbuf, void *rbuf, int count,
       if (src < comm_size) {
         Request::recv(tmp_buf, count, dtype, src, tag, comm, &status);
         if(op!=MPI_OP_NULL) op->apply( tmp_buf, rbuf, &count, dtype);
-        //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
       }
     } else {
 
       dst = (inter_rank * num_core) + (intra_rank & (~mask));
       Request::send(rbuf, count, dtype, dst, tag, comm);
-      //printf("Node %d send to node %d when mask is %d\n", rank, dst, mask);
       break;
     }
     mask <<= 1;
@@ -92,7 +88,6 @@ int allreduce__smp_rsag_rab(const void *sbuf, void *rbuf, int count,
 
     mask = 1;
     curr_count = count / 2;
-    int phase = 0;
     base_offset = 0;
 
     while (mask < (comm_size / num_core)) {
@@ -113,9 +108,6 @@ int allreduce__smp_rsag_rab(const void *sbuf, void *rbuf, int count,
       send_offset = send_base_offset * extent;
       recv_offset = recv_base_offset * extent;
 
-      //      if (rank==7)
-      //      printf("node %d send to %d in phase %d s_offset = %d r_offset = %d count = %d\n",rank,dst,phase, send_offset, recv_offset, curr_count);
-
       Request::sendrecv((char *)rbuf + send_offset, curr_count, dtype, (dst * num_core), tag,
                    tmp_buf, curr_count, dtype, (dst * num_core), tag,
                    comm, &status);
@@ -124,7 +116,6 @@ int allreduce__smp_rsag_rab(const void *sbuf, void *rbuf, int count,
 
       mask *= 2;
       curr_count /= 2;
-      phase++;
     }
 
 
@@ -144,7 +135,6 @@ int allreduce__smp_rsag_rab(const void *sbuf, void *rbuf, int count,
     curr_count *= 2;
     mask >>= 1;
     i = 1;
-    phase = 0;
     while (mask >= 1) {
       // destination pair for both send and recv
       dst = inter_rank ^ mask;
@@ -160,9 +150,6 @@ int allreduce__smp_rsag_rab(const void *sbuf, void *rbuf, int count,
       send_offset = send_base_offset * recv_chunk;
       recv_offset = recv_base_offset * recv_chunk;
 
-      //      if (rank==7)
-      //printf("node %d send to %d in phase %d s_offset = %d r_offset = %d count = %d\n",rank,dst,phase, send_offset, recv_offset, curr_count);
-
       Request::sendrecv((char *)rbuf + send_offset, curr_count, dtype, (dst * num_core), tag,
                    (char *)rbuf + recv_offset, curr_count, dtype, (dst * num_core), tag,
                    comm, &status);
@@ -171,7 +158,6 @@ int allreduce__smp_rsag_rab(const void *sbuf, void *rbuf, int count,
       curr_count *= 2;
       i *= 2;
       mask >>= 1;
-      phase++;
     }
 
 
@@ -183,12 +169,10 @@ int allreduce__smp_rsag_rab(const void *sbuf, void *rbuf, int count,
   if (inter_rank == (inter_comm_size - 1)) {
     num_core_in_current_smp = comm_size - (inter_rank * num_core);
   }
-  //  printf("Node %d num_core = %d\n",rank, num_core_in_current_smp);
   mask = 1;
   while (mask < num_core_in_current_smp) {
     if (intra_rank & mask) {
       src = (inter_rank * num_core) + (intra_rank - mask);
-      //printf("Node %d recv from node %d when mask is %d\n", rank, src, mask);
       Request::recv(rbuf, count, dtype, src, tag, comm, &status);
       break;
     }
@@ -196,12 +180,10 @@ int allreduce__smp_rsag_rab(const void *sbuf, void *rbuf, int count,
   }
 
   mask >>= 1;
-  //printf("My rank = %d my mask = %d\n", rank,mask);
 
   while (mask > 0) {
     dst = (inter_rank * num_core) + (intra_rank + mask);
     if (dst < comm_size) {
-      //printf("Node %d send to node %d when mask is %d\n", rank, dst, mask);
       Request::send(rbuf, count, dtype, dst, tag, comm);
     }
     mask >>= 1;
index d52574a..7367b40 100644 (file)
@@ -101,13 +101,10 @@ int bcast__arrival_pattern_aware_wait(void *buf, int count,
   /* root */
   if (rank == 0) {
     sent_count = 0;
-    int iteration = 0;
 
     for (i = 0; i < BCAST_ARRIVAL_PATTERN_AWARE_MAX_NODE; i++)
       will_send[i] = 0;
     while (sent_count < (size - 1)) {
-      iteration++;
-
       /* loop k times to let more processes arrive before start sending data */
       for (k = 0; k < 3; k++) {
         for (i = 1; i < size; i++) {
index 0b28ab2..3e763b5 100644 (file)
@@ -28,16 +28,9 @@ namespace resource {
 /************
  * Resource *
  ************/
-HostImpl::HostImpl(const std::string& name, s4u::Host* piface) : piface_(this), name_(name)
-{
-  xbt_assert(s4u::Host::by_name_or_null(name_) == nullptr, "Refusing to create a second host named '%s'.", get_cname());
-  s4u::Engine::get_instance()->host_register(name_, piface);
-}
-
 HostImpl::HostImpl(const std::string& name) : piface_(this), name_(name)
 {
   xbt_assert(s4u::Host::by_name_or_null(name_) == nullptr, "Refusing to create a second host named '%s'.", get_cname());
-  s4u::Engine::get_instance()->host_register(name_, &piface_);
 }
 
 HostImpl::~HostImpl()
@@ -57,6 +50,9 @@ HostImpl::~HostImpl()
 
   for (auto const& d : disks_)
     d.second->destroy();
+
+  for (auto const& vm : vms_)
+    vm.second->vm_destroy();
 }
 
 /** @brief Fire the required callbacks and destroy the object
@@ -66,7 +62,6 @@ HostImpl::~HostImpl()
 void HostImpl::destroy()
 {
   s4u::Host::on_destruction(*this->get_iface());
-  s4u::Engine::get_instance()->host_unregister(std::string(name_));
   delete this;
 }
 
@@ -85,6 +80,12 @@ void HostImpl::turn_on() const
 /** Kill all actors hosted here */
 void HostImpl::turn_off(const actor::ActorImpl* issuer)
 {
+  /* turn_off VMs running on host */
+  for (const auto& kv : vms_) {
+    auto* actor = kernel::actor::ActorImpl::self();
+    kv.second->shutdown(actor);
+    kv.second->turn_off(actor);
+  }
   for (auto& actor : actor_list_) {
     XBT_DEBUG("Killing Actor %s@%s on behalf of %s which turned off that host.", actor.get_cname(),
               actor.get_host()->get_cname(), issuer->get_cname());
@@ -137,6 +138,63 @@ std::vector<s4u::Disk*> HostImpl::get_disks() const
   return disks;
 }
 
+s4u::VirtualMachine* HostImpl::create_vm(const std::string& name, int core_amount, size_t ramsize)
+{
+  auto* vm   = new s4u::VirtualMachine(name, get_iface(), core_amount, ramsize);
+  vms_[name] = vm->get_vm_impl();
+
+  // Create a VCPU for this VM
+  std::vector<double> speeds;
+  for (unsigned long i = 0; i < get_iface()->get_pstate_count(); i++)
+    speeds.push_back(get_iface()->get_pstate_speed(i));
+
+  auto* cpu = englobing_zone_->get_cpu_vm_model()->create_cpu(vm, speeds)->set_core_count(core_amount);
+
+  if (get_iface()->get_pstate() != 0)
+    cpu->set_pstate(get_iface()->get_pstate());
+
+  cpu->seal();
+
+  /* Currently, a VM uses the network resource of its physical host */
+  vm->set_netpoint(get_iface()->get_netpoint());
+
+  vm->seal();
+
+  return vm;
+}
+
+void HostImpl::move_vm(VirtualMachineImpl* vm, HostImpl* destination)
+{
+  xbt_assert(vm && destination);
+
+  vms_.erase(vm->get_name());
+  destination->vms_[vm->get_name()] = vm;
+}
+
+void HostImpl::destroy_vm(const std::string& name)
+{
+  auto* vm = vms_[name];
+  vms_.erase(name);
+  vm->vm_destroy();
+}
+
+VirtualMachineImpl* HostImpl::get_vm_by_name_or_null(const std::string& name) const
+{
+  auto vm_it = vms_.find(name);
+  if (vm_it != vms_.end())
+    return vm_it->second;
+  return nullptr;
+}
+
+std::vector<s4u::VirtualMachine*> HostImpl::get_vms() const
+{
+  std::vector<s4u::VirtualMachine*> vms;
+  for (const auto& kv : vms_) {
+    vms.push_back(kv.second->get_iface());
+  }
+  return vms;
+}
+
 s4u::Disk* HostImpl::create_disk(const std::string& name, double read_bandwidth, double write_bandwidth)
 {
   auto disk = piface_.get_netpoint()->get_englobing_zone()->get_disk_model()->create_disk(name, read_bandwidth,
@@ -166,6 +224,10 @@ void HostImpl::seal()
   /* seal its disks */
   for (auto const& disk : disks_)
     disk.second->seal();
+
+  /* seal its VMs */
+  for (auto const& vm : vms_)
+    vm.second->seal();
 }
 } // namespace resource
 } // namespace kernel
index e9a291c..944844b 100644 (file)
@@ -9,7 +9,6 @@
 #include "src/kernel/actor/ActorImpl.hpp"
 #include "src/kernel/resource/CpuImpl.hpp"
 #include "src/kernel/resource/DiskImpl.hpp"
-#include "src/kernel/resource/LinkImpl.hpp"
 #include <xbt/PropertyHolder.hpp>
 
 #include <vector>
@@ -51,13 +50,13 @@ class XBT_PRIVATE HostImpl : public xbt::PropertyHolder {
   std::vector<actor::ProcessArg*> actors_at_boot_;
   s4u::Host piface_;
   std::map<std::string, DiskImpl*, std::less<>> disks_;
+  std::map<std::string, VirtualMachineImpl*, std::less<>> vms_;
   xbt::string name_{"noname"};
   routing::NetZoneImpl* englobing_zone_ = nullptr;
   bool sealed_ = false;
 
 protected:
   virtual ~HostImpl(); // Use destroy() instead of this destructor.
-  HostImpl(const std::string& name, s4u::Host* piface);
 
 public:
   friend VirtualMachineImpl;
@@ -67,8 +66,14 @@ public:
 
   std::vector<s4u::Disk*> get_disks() const;
   s4u::Disk* create_disk(const std::string& name, double read_bandwidth, double write_bandwidth);
+  s4u::VirtualMachine* create_vm(const std::string& name, int core_amount, size_t ramsize = 1024);
+  void destroy_vm(const std::string& name);
   void add_disk(const s4u::Disk* disk);
   void remove_disk(const std::string& name);
+  /** @brief Moves VM from this host to destination. Only sets the vm_ accordingly */
+  void move_vm(VirtualMachineImpl* vm, HostImpl* destination);
+  std::vector<s4u::VirtualMachine*> get_vms() const;
+  VirtualMachineImpl* get_vm_by_name_or_null(const std::string& name) const;
 
   virtual const s4u::Host* get_iface() const { return &piface_; }
   virtual s4u::Host* get_iface() { return &piface_; }
@@ -90,7 +95,7 @@ public:
   void remove_actor(actor::ActorImpl* actor) { xbt::intrusive_erase(actor_list_, *actor); }
   void add_actor_at_boot(actor::ProcessArg* arg) { actors_at_boot_.emplace_back(arg); }
 
-  void seal();
+  virtual void seal();
 
   template <class F> void foreach_actor(F function)
   {
index d7353cf..87e1ec3 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "simgrid/sg_config.hpp"
 #include "src/kernel/EngineImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 #include "src/surf/host_clm03.hpp"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(res_host);
index 010b39c..e981df7 100644 (file)
@@ -97,10 +97,10 @@ NetworkCm02Model::NetworkCm02Model(const std::string& name) : NetworkModel(name)
 
   set_maxmin_system(lmm::System::build(cfg_network_solver, select));
 
-  loopback_ = create_link("__loopback__", {config::get_value<double>("network/loopback-bw")});
+  loopback_.reset(create_link("__loopback__", {config::get_value<double>("network/loopback-bw")}));
   loopback_->set_sharing_policy(s4u::Link::SharingPolicy::FATPIPE, {});
   loopback_->set_latency(config::get_value<double>("network/loopback-lat"));
-  loopback_->seal();
+  loopback_->get_iface()->seal();
 }
 
 void NetworkCm02Model::check_lat_factor_cb()
index 8cabad5..eb93747 100644 (file)
@@ -8,8 +8,7 @@
 
 #include <xbt/base.h>
 
-#include "simgrid/kernel/resource/NetworkModelIntf.hpp"
-#include "src/kernel/resource/LinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 #include "src/kernel/resource/StandardLinkImpl.hpp"
 #include "xbt/graph.h"
 #include "xbt/string.hpp"
index 2a8c70f..5828d69 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef NETWORK_CONSTANT_HPP_
 #define NETWORK_CONSTANT_HPP_
 
-#include "src/kernel/resource/LinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 
 namespace simgrid {
 namespace kernel {
index 02036a3..275d45d 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "xbt/base.h"
 
+#include "src/kernel/resource/NetworkModel.hpp"
 #include "src/kernel/resource/StandardLinkImpl.hpp"
 
 namespace simgrid {
index a7030b9..e89e762 100644 (file)
@@ -76,10 +76,10 @@ NetworkL07Model::NetworkL07Model(const std::string& name, HostL07Model* hmodel,
     : NetworkModel(name), hostModel_(hmodel)
 {
   set_maxmin_system(sys);
-  loopback_ = create_link("__loopback__", {simgrid::config::get_value<double>("network/loopback-bw")});
+  loopback_.reset(create_link("__loopback__", {simgrid::config::get_value<double>("network/loopback-bw")}));
   loopback_->set_sharing_policy(s4u::Link::SharingPolicy::FATPIPE, {});
   loopback_->set_latency(simgrid::config::get_value<double>("network/loopback-lat"));
-  loopback_->seal();
+  loopback_->get_iface()->seal();
 }
 
 NetworkL07Model::~NetworkL07Model()
index fa57e85..9c0cbf2 100644 (file)
@@ -3,6 +3,7 @@
 /* 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 "src/kernel/resource/NetworkModel.hpp"
 #include "src/surf/HostImpl.hpp"
 #include <cstdlib>
 #include <vector>
index a672da0..7bf954f 100644 (file)
 int main(int argc, char *argv[])
 {
     MPI_Request barrier;
-    int rank, i, done;
+    int rank, done;
 
     MPI_Init(&argc, &argv);
     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
     MPI_Ibarrier(MPI_COMM_WORLD, &barrier);
-    for (i = 0, done = 0; !done; i++) {
-        usleep(1000);
-        /*printf("[%d] MPI_Test: %d\n",rank,i); */
-        MPI_Test(&barrier, &done, MPI_STATUS_IGNORE);
+    done = 0;
+    while (!done) {
+      usleep(1000);
+      MPI_Test(&barrier, &done, MPI_STATUS_IGNORE);
     }
 
     if (rank == 0)
index b241ca6..ff7c14a 100644 (file)
@@ -11,7 +11,7 @@
 #include "simgrid/zone.h"
 #include "src/kernel/EngineImpl.hpp"
 #include "src/kernel/resource/CpuImpl.hpp"
-#include "src/kernel/resource/LinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 #include "xbt/config.hpp"
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(surf_test, "Messages specific for surf example");
index 4354c4a..1af5762 100644 (file)
@@ -11,7 +11,7 @@
 #include "simgrid/zone.h"
 #include "src/kernel/EngineImpl.hpp"
 #include "src/kernel/resource/CpuImpl.hpp"
-#include "src/kernel/resource/LinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
 #include "src/surf/surf_interface.hpp"
 #include "xbt/config.hpp"
 
index 1332be4..b1f7bf7 100644 (file)
@@ -14,6 +14,7 @@ set(EXTRA_DIST
   src/include/xxhash.hpp
   src/kernel/actor/Simcall.hpp
   src/kernel/resource/LinkImpl.hpp
+  src/kernel/resource/NetworkModel.hpp
   src/kernel/resource/SplitDuplexLinkImpl.hpp
   src/kernel/resource/StandardLinkImpl.hpp
   src/kernel/resource/WifiLinkImpl.hpp
@@ -305,8 +306,8 @@ set(SURF_SRC
   src/kernel/resource/DiskImpl.cpp
   src/kernel/resource/DiskImpl.hpp
   src/kernel/resource/Model.cpp
+  src/kernel/resource/NetworkModel.cpp
   src/kernel/resource/Resource.hpp
-  src/kernel/resource/LinkImpl.cpp
   src/kernel/resource/SplitDuplexLinkImpl.cpp
   src/kernel/resource/StandardLinkImpl.cpp
   src/kernel/resource/VirtualMachineImpl.hpp