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>
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
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.
.. 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
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());
// 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
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);
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
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;
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
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);
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
#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>
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;
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();
}
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
{
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_;
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_); }
#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"
#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 *
************/
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
#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"
--- /dev/null
+/* 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 */
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.
void StandardLinkImpl::destroy()
{
s4u::Link::on_destruction(piface_);
- s4u::Engine::get_instance()->link_unregister(get_name());
delete this;
}
public:
void destroy(); // Must be called instead of the destructor
+ class Deleter {
+ public:
+ void operator()(StandardLinkImpl* link) const;
+ };
void latency_check(double latency) const;
* 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>
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);
// 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());
}
/* 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()));
});
vm_state_ = s4u::VirtualMachine::State::RUNNING;
+ s4u::VirtualMachine::on_resume(*get_iface());
}
/** @brief Power off a VM.
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 */
}
/* 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());
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
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);
/** @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; }
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_;
#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>
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);
}
}
#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>
#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>
#include <simgrid/kernel/routing/NetPoint.hpp>
#include <xbt/string.hpp>
-#include "src/kernel/resource/StandardLinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
#include <climits>
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;
}
#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");
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());
}
}
}
#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");
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;
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)
"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)
"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,
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)
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*/)
{
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();
}
#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");
#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>
#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");
}
}
-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
#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"
#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>
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();
#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>
/** 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.
*/
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) */
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
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);
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
#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 {
: 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); });
}
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()
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) {
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
size /= 2;
}
- // printf("node %d base_offset %d\n",rank,base_offset);
-
//perform a remote copy
dst = base_offset;
mask >>= 1;
i = 1;
- int phase = 0;
curr_count = recv_count;
while (mask >= 1) {
// destination pair for both send and recv
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;
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,
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;
mask = 1;
curr_count = count / 2;
- int phase = 0;
base_offset = 0;
while (mask < (comm_size / num_core)) {
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);
mask *= 2;
curr_count /= 2;
- phase++;
}
curr_count *= 2;
mask >>= 1;
i = 1;
- phase = 0;
while (mask >= 1) {
// destination pair for both send and recv
dst = inter_rank ^ mask;
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);
curr_count *= 2;
i *= 2;
mask >>= 1;
- phase++;
}
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;
}
}
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;
/* 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++) {
/************
* 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()
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
void HostImpl::destroy()
{
s4u::Host::on_destruction(*this->get_iface());
- s4u::Engine::get_instance()->host_unregister(std::string(name_));
delete this;
}
/** 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());
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,
/* 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
#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>
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;
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_; }
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)
{
#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);
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()
#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"
#ifndef NETWORK_CONSTANT_HPP_
#define NETWORK_CONSTANT_HPP_
-#include "src/kernel/resource/LinkImpl.hpp"
+#include "src/kernel/resource/NetworkModel.hpp"
namespace simgrid {
namespace kernel {
#include "xbt/base.h"
+#include "src/kernel/resource/NetworkModel.hpp"
#include "src/kernel/resource/StandardLinkImpl.hpp"
namespace simgrid {
: 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()
/* 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>
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)
#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");
#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"
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
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