Remove the concept of type for a model (CPU, VM, NETWORK, etc).
Explicitly declare the dependencies between models when adding them to
the engine.
Internally, they are organized in a ordered list, respecting the
dependencies described by the user.
Changes in APIs:
s4u_Engine.hpp:
- Delete get_model_list(simgrid::kernel::resource::Model::Type type)
- Modify add_model(std::shared_ptr<simgrid::kernel::resource::Model> model, std::vector<std::string>&& dep_models = {}): added list of dependencies
Model.hpp:
- set_name(), get_name(): add methods to associate a name to the model
*/
class XBT_PUBLIC Model {
public:
- /** @brief Possible model types */
- enum class Type {
- HOST, /**< Host models: see surf_host_model_description for more details */
- NETWORK, /**< Network models: see surf_network_model_description for more details */
- CPU_PM, /**< CPU model for physical machines: see surf_cpu_model_description for more details */
- CPU_VM, /**< CPU model for virtual machines: see surf_cpu_model_description for more details */
- DISK, /**< Disk models: see surf_disk_model_description for more details */
- VM /**< VM model */
- };
-
/** @brief Possible update mechanisms */
enum class UpdateAlgo {
FULL, /**< Full update mechanism: the remaining time of every action is recomputed at each step */
return next_occurring_event_is_idempotent();
}
+ /** @brief Gets the model name */
+ std::string get_name() const { return name_; }
+ /** @brief Sets the model name */
+ Model* set_name(const std::string& name);
+
private:
UpdateAlgo update_algorithm_ = UpdateAlgo::FULL;
std::unique_ptr<lmm::System> maxmin_system_;
Action::StateSet failed_action_set_; /**< Done with failure */
Action::StateSet finished_action_set_; /**< Done successful */
Action::StateSet ignored_action_set_; /**< not considered (failure detectors?) */
+ std::string name_ = "Unnamed"; /**< Model name */
ActionHeap action_heap_;
};
/**
* @brief Add a model to engine list
*
- * @param type Model type (network, disk, etc)
* @param model Pointer to model
+ * @param list List of dependencies for this model (optional)
*/
- void add_model(simgrid::kernel::resource::Model::Type type, std::shared_ptr<simgrid::kernel::resource::Model> model);
-
- /** @brief Get list of models created for a resource type */
- const std::vector<simgrid::kernel::resource::Model*>& get_model_list(simgrid::kernel::resource::Model::Type type);
+ void add_model(std::shared_ptr<simgrid::kernel::resource::Model> model, std::vector<std::string>&& dep_models = {});
/** @brief Get list of all models managed by this engine */
- const std::vector<std::shared_ptr<simgrid::kernel::resource::Model>>& get_all_models() const;
+ const std::vector<simgrid::kernel::resource::Model*>& get_all_models() const;
/** @brief Retrieves all netzones of the type indicated by the template argument */
template <class T> std::vector<T*> get_filtered_netzones() const
default_function = code;
}
-void EngineImpl::add_model(resource::Model::Type type, std::shared_ptr<resource::Model> model, bool is_default)
+void EngineImpl::add_model(std::shared_ptr<resource::Model> model, std::vector<std::string>&& dep_models)
{
- if (is_default)
- models_by_type_[type].insert(models_by_type_[type].begin(), model.get());
- else
- models_by_type_[type].push_back(model.get());
+ auto model_name = model->get_name();
+ xbt_assert(models_prio_.find(model_name) == models_prio_.end(),
+ "Model %s already exists, use model.set_name() to change its name", model_name.c_str());
+ int order = -1;
+ for (const auto& dep_name : dep_models) {
+ xbt_assert(models_prio_.find(dep_name) != models_prio_.end(),
+ "Model %s doesn't exists. Impossible to use it as dependency.", dep_name.c_str());
+ if (models_prio_[dep_name].prio > order) {
+ order = models_prio_[dep_name].prio;
+ }
+ }
+ models_prio_[model_name] = {++order, std::move(model)};
- models_.push_back(std::move(model));
-}
-
-resource::Model* EngineImpl::get_default_model(resource::Model::Type type) const
-{
- resource::Model* model = nullptr;
- if (models_by_type_.find(type) != models_by_type_.end() and models_by_type_.at(type).size() > 0)
- return models_by_type_.at(type)[0];
- return model;
-}
-
-const std::vector<resource::Model*>& EngineImpl::get_model_list(resource::Model::Type type)
-{
- return models_by_type_[type];
+ auto sorted_models = std::vector<std::pair<std::string, ModelStruct>>(models_prio_.begin(), models_prio_.end());
+ std::sort(
+ sorted_models.begin(), sorted_models.end(),
+ [](const std::pair<std::string, ModelStruct>& first, const std::pair<std::string, ModelStruct>& second) -> bool {
+ return first.second.prio < second.second.prio;
+ });
+ models_.clear();
+ for (const auto& model : sorted_models) {
+ models_.push_back(model.second.ptr.get());
+ }
}
} // namespace kernel
std::unordered_map<std::string, routing::NetPoint*> netpoints_;
std::unordered_map<std::string, actor::ActorCodeFactory> registered_functions; // Maps function names to actor code
actor::ActorCodeFactory default_function; // Function to use as a fallback when the provided name matches nothing
- std::vector<std::shared_ptr<resource::Model>> models_;
- std::unordered_map<resource::Model::Type, std::vector<resource::Model*>> models_by_type_;
+ std::vector<resource::Model*> models_;
+ struct ModelStruct {
+ int prio;
+ std::shared_ptr<resource::Model> ptr;
+ };
+ std::unordered_map<std::string, struct ModelStruct> models_prio_;
routing::NetZoneImpl* netzone_root_ = nullptr;
friend s4u::Engine;
/**
* @brief Add a model to engine list
*
- * @param type Model type (network, disk, etc)
* @param model Pointer to model
- * @param is_default Is this the default model for this type of resource in this exp
+ * @param list List of dependencies for this model
*/
- void add_model(resource::Model::Type type, std::shared_ptr<resource::Model> model, bool is_default = false);
- /** @brief Get current default model for a resource type */
- resource::Model* get_default_model(resource::Model::Type type) const;
-
- /** @brief Get list of models created for a resource type */
- const std::vector<resource::Model*>& get_model_list(resource::Model::Type type);
+ void add_model(std::shared_ptr<simgrid::kernel::resource::Model> model, std::vector<std::string>&& dep_models);
/** @brief Get list of all models managed by this engine */
- const std::vector<std::shared_ptr<resource::Model>>& get_all_models() const { return models_; }
+ const std::vector<resource::Model*>& get_all_models() const { return models_; }
static EngineImpl* get_instance() { return simgrid::s4u::Engine::get_instance()->pimpl; }
actor::ActorCodeFactory get_function(const std::string& name)
namespace kernel {
namespace resource {
-Model::~Model() = default; // Don't move this declaration to the header, or it will break external projects such as SimGrid-FMI
+Model::~Model() =
+ default; // Don't move this declaration to the header, or it will break external projects such as SimGrid-FMI
Model* Model::set_update_algorithm(Model::UpdateAlgo algo)
{
if ((action->get_max_duration() != NO_MAX_DURATION) &&
(min <= -1 || action->get_start_time() + action->get_max_duration() < min)) {
// when the task will complete anyway because of the deadline if any
- min = action->get_start_time() + action->get_max_duration();
- action_type = ActionHeap::Type::max_duration;
+ min = action->get_start_time() + action->get_max_duration();
+ action_type = ActionHeap::Type::max_duration;
}
XBT_DEBUG("Action(%p) corresponds to variable %d", action, action->get_variable()->rank_);
THROW_UNIMPLEMENTED;
}
+Model* Model::set_name(const std::string& name)
+{
+ name_ = name;
+ return this;
+}
+
} // namespace resource
} // namespace kernel
} // namespace simgrid
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(res_vm, ker_resource, "Virtual Machines, containing actors and mobile accross hosts");
-void surf_vm_model_init_HL13()
+void surf_vm_model_init_HL13(simgrid::kernel::resource::CpuModel* cpu_pm_model)
{
- auto cpu_optim = simgrid::config::get_value<std::string>("cpu/optim");
+ auto vm_model = std::make_shared<simgrid::vm::VMModel>();
+ vm_model->set_name("VM_HL13");
+
+ simgrid::kernel::EngineImpl::get_instance()->add_model(vm_model, {cpu_pm_model->get_name()});
std::shared_ptr<simgrid::kernel::resource::CpuModel> cpu_model_vm;
+
+ auto cpu_optim = simgrid::config::get_value<std::string>("cpu/optim");
if (cpu_optim == "TI") {
cpu_model_vm = std::make_shared<simgrid::kernel::resource::CpuTiModel>();
+ cpu_model_vm->set_name("VmCpu_TI");
} else {
cpu_model_vm = std::make_shared<simgrid::kernel::resource::CpuCas01Model>();
+ cpu_model_vm->set_name("VmCpu_Cas01");
}
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::CPU_VM, cpu_model_vm,
- true);
+ simgrid::kernel::EngineImpl::get_instance()->add_model(cpu_model_vm,
+ {cpu_pm_model->get_name(), vm_model->get_name()});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_cpu_vm_model(cpu_model_vm);
-
- auto vm_model = std::make_shared<simgrid::vm::VMModel>();
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::VM,
- std::move(vm_model), true);
}
namespace simgrid {
kernel::lmm::System* vcpu_system = cpu->get_model()->get_maxmin_system();
vcpu_system->update_constraint_bound(cpu->get_constraint(), virt_overhead * solved_value);
}
-
/* actual next occurring event is determined by VM CPU model at surf_solve */
return -1.0;
}
return SIMIX_get_clock();
}
-void Engine::add_model(simgrid::kernel::resource::Model::Type type,
- std::shared_ptr<simgrid::kernel::resource::Model> model)
+void Engine::add_model(std::shared_ptr<simgrid::kernel::resource::Model> model, std::vector<std::string>&& dep_models)
{
- simgrid::kernel::actor::simcall([this, type, &model] { pimpl->add_model(type, std::move(model)); });
-}
-
-/** @brief Get list of models created for a resource type */
-const std::vector<simgrid::kernel::resource::Model*>& Engine::get_model_list(simgrid::kernel::resource::Model::Type type)
-{
- return pimpl->get_model_list(type);
+ simgrid::kernel::actor::simcall([this, &model, &dep_models] {
+ pimpl->add_model(std::move(model), std::forward<decltype(dep_models)>(dep_models));
+ });
}
-const std::vector<std::shared_ptr<simgrid::kernel::resource::Model>>& Engine::get_all_models() const
+const std::vector<simgrid::kernel::resource::Model*>& Engine::get_all_models() const
{
return pimpl->get_all_models();
}
}
auto cpu_model_pm = std::make_shared<simgrid::kernel::resource::CpuCas01Model>();
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::CPU_PM, cpu_model_pm,
- true);
+ cpu_model_pm->set_name("Cpu_Cas01");
+ simgrid::kernel::EngineImpl::get_instance()->add_model(cpu_model_pm, {});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_cpu_pm_model(cpu_model_pm);
}
void CpuTiModel::create_pm_models()
{
auto cpu_model_pm = std::make_shared<CpuTiModel>();
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::CPU_PM, cpu_model_pm,
- true);
+ cpu_model_pm->set_name("Cpu_TI");
+ simgrid::kernel::EngineImpl::get_instance()->add_model(cpu_model_pm, {});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_cpu_pm_model(cpu_model_pm);
}
void surf_disk_model_init_default()
{
auto disk_model = std::make_shared<simgrid::kernel::resource::DiskS19Model>();
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::DISK, disk_model,
- true);
+ disk_model->set_name("Disk");
+ simgrid::kernel::EngineImpl::get_instance()->add_model(disk_model, {});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_disk_model(disk_model);
}
{
auto host_model = std::make_shared<simgrid::surf::HostCLM03Model>();
simgrid::config::set_default<bool>("network/crosstraffic", true);
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::HOST, host_model,
- true);
+ host_model->set_name("Host_CLM03");
+ simgrid::kernel::EngineImpl::get_instance()->add_model(host_model, {});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_host_model(host_model);
surf_cpu_model_init_Cas01();
surf_network_model_init_LegrandVelho();
void surf_host_model_init_compound()
{
auto host_model = std::make_shared<simgrid::surf::HostCLM03Model>();
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::HOST, host_model,
- true);
+ host_model->set_name("Host_CLM03");
+ simgrid::kernel::EngineImpl::get_instance()->add_model(host_model, {});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_host_model(host_model);
}
void surf_network_model_init_LegrandVelho()
{
auto net_model = std::make_shared<simgrid::kernel::resource::NetworkCm02Model>();
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::NETWORK, net_model,
- true);
+ net_model->set_name("Network_LegrandVelho");
+ simgrid::kernel::EngineImpl::get_instance()->add_model(net_model, {});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_network_model(net_model);
simgrid::config::set_default<double>("network/latency-factor", 13.01);
simgrid::config::set_default<double>("network/weight-S", 0.0);
auto net_model = std::make_shared<simgrid::kernel::resource::NetworkCm02Model>();
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::NETWORK, net_model,
- true);
+ net_model->set_name("Network_CM02");
+ simgrid::kernel::EngineImpl::get_instance()->add_model(net_model, {});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_network_model(net_model);
}
void surf_network_model_init_Constant()
{
auto net_model = std::make_shared<simgrid::kernel::resource::NetworkConstantModel>();
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::NETWORK, net_model,
- true);
+ net_model->set_name("Network_Constant");
+ simgrid::kernel::EngineImpl::get_instance()->add_model(net_model, {});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_network_model(net_model);
}
void surf_network_model_init_IB()
{
auto net_model = std::make_shared<simgrid::kernel::resource::NetworkIBModel>();
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::NETWORK, net_model,
- true);
+ net_model->set_name("Network_IB");
+ simgrid::kernel::EngineImpl::get_instance()->add_model(net_model, {});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_network_model(net_model);
simgrid::s4u::Link::on_communication_state_change.connect(IB_action_state_changed_callback);
void surf_network_model_init_NS3()
{
auto net_model = std::make_shared<simgrid::kernel::resource::NetworkNS3Model>();
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::NETWORK, net_model,
- true);
+ simgrid::kernel::EngineImpl::get_instance()->add_model(net_model);
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_network_model(net_model);
}
void surf_network_model_init_SMPI()
{
auto net_model = std::make_shared<simgrid::kernel::resource::NetworkSmpiModel>();
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::NETWORK, net_model,
- true);
+ net_model->set_name("Network_SMPI");
+ simgrid::kernel::EngineImpl::get_instance()->add_model(net_model, {});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_network_model(net_model);
simgrid::config::set_default<double>("network/weight-S", 8775);
XBT_CINFO(xbt_cfg, "Switching to the L07 model to handle parallel tasks.");
auto host_model = std::make_shared<simgrid::surf::HostL07Model>();
- simgrid::kernel::EngineImpl::get_instance()->add_model(simgrid::kernel::resource::Model::Type::HOST, host_model,
- true);
+ host_model->set_name("Host_Ptask");
+ simgrid::kernel::EngineImpl::get_instance()->add_model(host_model, {});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_host_model(host_model);
}
auto net_model = std::make_shared<NetworkL07Model>(this, maxmin_system);
auto engine = simgrid::kernel::EngineImpl::get_instance();
- engine->add_model(simgrid::kernel::resource::Model::Type::NETWORK, net_model, true);
+ net_model->set_name("Network_Ptask");
+ engine->add_model(net_model, {});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_network_model(net_model);
auto cpu_model = std::make_shared<CpuL07Model>(this, maxmin_system);
- engine->add_model(simgrid::kernel::resource::Model::Type::CPU_PM, cpu_model, true);
+ cpu_model->set_name("Cpu_Ptask");
+ engine->add_model(cpu_model, {});
simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->set_cpu_pm_model(cpu_model);
}
surf_host_model_description[host_id].model_init_preparse();
XBT_DEBUG("Call vm_model_init");
- surf_vm_model_init_HL13();
+ /* ideally we should get back the pointer to CpuModel from model_init_preparse(), but this
+ * requires changing the declaration of surf_cpu_model_description.
+ * To be reviewed in the future */
+ surf_vm_model_init_HL13(
+ simgrid::s4u::Engine::get_instance()->get_netzone_root()->get_impl()->get_cpu_pm_model().get());
XBT_DEBUG("Call disk_model_init");
int disk_id = find_model_description(surf_disk_model_description, disk_model_name);
model->update_actions_state(NOW, 0.0);
}
-/**
- * @brief Auxiliary function to get next event from a list of models
- *
- * @param models list of models to explore (cpu, host, vm) (IN)
- * @param time_delta delta for the next event (IN/OUT)
- */
-static void surf_update_next_event(std::vector<simgrid::kernel::resource::Model*> const& models, double& time_delta)
-{
- for (auto* model : models) {
- if (not model->next_occurring_event_is_idempotent()) {
- continue;
- }
- double next_event = model->next_occurring_event(NOW);
- if ((time_delta < 0.0 || next_event < time_delta) && next_event >= 0.0) {
- time_delta = next_event;
- }
- }
-}
-
double surf_solve(double max_date)
{
double time_delta = -1.0; /* duration */
time_delta = max_date - NOW;
}
- /* Physical models MUST be resolved first */
- XBT_DEBUG("Looking for next event in physical models");
+ XBT_DEBUG("Looking for next event in all models");
auto engine = simgrid::kernel::EngineImpl::get_instance();
- surf_update_next_event(engine->get_model_list(simgrid::kernel::resource::Model::Type::HOST), time_delta);
-
- // following the order it was done in HostCLM03Model->next_occurring_event
- XBT_DEBUG("Looking for next event in CPU models");
- surf_update_next_event(engine->get_model_list(simgrid::kernel::resource::Model::Type::CPU_PM), time_delta);
-
- XBT_DEBUG("Looking for next event in network models");
- surf_update_next_event(engine->get_model_list(simgrid::kernel::resource::Model::Type::NETWORK), time_delta);
- XBT_DEBUG("Looking for next event in disk models");
- surf_update_next_event(engine->get_model_list(simgrid::kernel::resource::Model::Type::DISK), time_delta);
-
- XBT_DEBUG("Looking for next event in virtual models");
- surf_update_next_event(engine->get_model_list(simgrid::kernel::resource::Model::Type::VM), time_delta);
- surf_update_next_event(engine->get_model_list(simgrid::kernel::resource::Model::Type::CPU_VM), time_delta);
+ for (auto model : engine->get_all_models()) {
+ if (not model->next_occurring_event_is_idempotent()) {
+ continue;
+ }
+ double next_event = model->next_occurring_event(NOW);
+ if ((time_delta < 0.0 || next_event < time_delta) && next_event >= 0.0) {
+ time_delta = next_event;
+ }
+ }
XBT_DEBUG("Min for resources (remember that NS3 don't update that value): %f", time_delta);
double next_event_date = simgrid::kernel::profile::future_evt_set.next_date();
XBT_DEBUG("Next TRACE event: %f", next_event_date);
- for (auto* model : engine->get_model_list(simgrid::kernel::resource::Model::Type::NETWORK)) {
+ for (auto model : engine->get_all_models()) {
/* Skip all idempotent models, they were already treated above
* NS3 is the one to handled here */
if (model->next_occurring_event_is_idempotent())
XBT_PUBLIC void surf_network_model_init_NS3();
/** @ingroup SURF_models
- * @brief Initializes the platform with the current best network and cpu models at hand
+ * @brief Initializes the VM model used in the platform
+ *
+ * A VM model depends on the physical CPU model to share the resources inside the VM
+ * It will also creates the CPU model for actions running inside the VM
*
- * This platform model separates the host model and the network model.
- * The host model will be initialized with the model compound, the network model with the model LV08 (with cross
- * traffic support) and the CPU model with the model Cas01.
* Such model is subject to modification with warning in the ChangeLog so monitor it!
*/
-XBT_PUBLIC void surf_vm_model_init_HL13();
+XBT_PUBLIC void surf_vm_model_init_HL13(simgrid::kernel::resource::CpuModel* cpu_pm_model);
/** @ingroup SURF_models
* @brief Initializes the platform with a compound host model