Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Allow to set a concurrency limit on disks and hosts
[simgrid.git] / include / simgrid / s4u / Host.hpp
1 /* Copyright (c) 2006-2023. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #ifndef SIMGRID_S4U_HOST_HPP
7 #define SIMGRID_S4U_HOST_HPP
8
9 #include <simgrid/forward.h>
10 #include <xbt/Extendable.hpp>
11 #include <xbt/signal.hpp>
12
13 #include <map>
14 #include <unordered_map>
15
16 namespace simgrid {
17
18 extern template class XBT_PUBLIC xbt::Extendable<s4u::Host>;
19
20 namespace s4u {
21 /** @ingroup s4u_api
22  *
23  * @tableofcontents
24  *
25  * Some physical resource with computing and networking capabilities on which Actors execute.
26  *
27  * @beginrst
28  * All hosts are automatically created during the call of the method
29  * :cpp:func:`simgrid::s4u::Engine::load_platform()`.
30  * You cannot create a host yourself.
31  *
32  * You can retrieve a particular host using :cpp:func:`simgrid::s4u::Host::by_name()`
33  * and actors can retrieve the host on which they run using :cpp:func:`simgrid::s4u::Host::current()` or
34  * :cpp:func:`simgrid::s4u::this_actor::get_host()`
35  * @endrst
36  */
37 class XBT_PUBLIC Host : public xbt::Extendable<Host> {
38 #ifndef DOXYGEN
39   friend kernel::resource::VMModel;            // Use the pimpl_cpu to compute the VM sharing
40   friend kernel::resource::VirtualMachineImpl; // creates the the pimpl_cpu
41   friend kernel::routing::NetZoneImpl;
42   friend kernel::resource::HostImpl; // call destructor from private implementation
43
44   // The private implementation, that never changes
45   kernel::resource::HostImpl* const pimpl_;
46
47   kernel::resource::CpuImpl* pimpl_cpu_      = nullptr;
48   kernel::routing::NetPoint* pimpl_netpoint_ = nullptr;
49
50 public:
51   explicit Host(kernel::resource::HostImpl* pimpl) : pimpl_(pimpl) {}
52
53 protected:
54   virtual ~Host(); // Call destroy() instead of manually deleting it.
55   Host* set_netpoint(kernel::routing::NetPoint* netpoint);
56
57   static xbt::signal<void(Host&)> on_creation;
58   static xbt::signal<void(Host const&)> on_destruction;
59
60 public:
61   static xbt::signal<void(Host const&)> on_speed_change;
62   static xbt::signal<void(Host const&)> on_state_change;
63 #endif
64   /** Add a callback fired on each newly created host */
65   static void on_creation_cb(const std::function<void(Host&)>& cb) { on_creation.connect(cb); }
66   /** Add a callback fired when the machine is turned on or off (called AFTER the change) */
67   static void on_state_change_cb(const std::function<void(Host const&)>& cb) { on_state_change.connect(cb); }
68   /** Add a callback fired when the speed of the machine is changed (called AFTER the change)
69    * (either because of a pstate switch or because of an external load event coming from the profile) */
70   static void on_speed_change_cb(const std::function<void(Host const&)>& cb) { on_speed_change.connect(cb); }
71   /** Add a callback fired just before destructing a host */
72   static void on_destruction_cb(const std::function<void(Host const&)>& cb) { on_destruction.connect(cb); }
73
74   virtual void destroy();
75 #ifndef DOXYGEN
76   // No copy/move
77   Host(Host const&) = delete;
78   Host& operator=(Host const&) = delete;
79 #endif
80
81   /** Retrieve a host from its name, or return nullptr */
82   static Host* by_name_or_null(const std::string& name);
83   /** Retrieve a host from its name, or die */
84   static Host* by_name(const std::string& name);
85   /** Retrieves the host on which the running actor is located */
86   static Host* current();
87
88   /** Retrieves the name of that host as a C++ string */
89   std::string const& get_name() const;
90   /** Retrieves the name of that host as a C string */
91   const char* get_cname() const;
92
93   Host* set_cpu(kernel::resource::CpuImpl* cpu);
94   kernel::resource::CpuImpl* get_cpu() const { return pimpl_cpu_; }
95   kernel::routing::NetPoint* get_netpoint() const { return pimpl_netpoint_; }
96   /**
97    * @brief Callback to set CPU factor
98    *
99    * This callback offers a flexible way to create variability in CPU executions
100    *
101    * @param flops Execution size in flops
102    * @return Multiply factor
103    */
104   using CpuFactorCb = double(double flops);
105   /**
106    * @brief Configure the factor callback to the CPU associated to this host
107    */
108   Host* set_factor_cb(const std::function<CpuFactorCb>& cb);
109
110   size_t get_actor_count() const;
111   std::vector<ActorPtr> get_all_actors() const;
112
113   /** Turns that host on if it was previously off
114    *
115    * This call does nothing if the host is already on. If it was off, all actors which were marked 'autorestart' on that
116    * host will be restarted automatically (note that this may differ from the actors that were initially running on the
117    * host).
118    *
119    * All other Host's properties are left unchanged; in particular, the pstate is left unchanged and not reset to its
120    * initial value.
121    */
122   void turn_on();
123   /** Turns that host off. All actors are forcefully stopped. */
124   void turn_off();
125   /** Returns if that host is currently up and running */
126   bool is_on() const;
127
128   const char* get_property(const std::string& key) const;
129   Host* set_property(const std::string& key, const std::string& value);
130   const std::unordered_map<std::string, std::string>* get_properties() const;
131   Host* set_properties(const std::unordered_map<std::string, std::string>& properties);
132
133   Host* set_state_profile(kernel::profile::Profile* p);
134   Host* set_speed_profile(kernel::profile::Profile* p);
135
136   /**
137    * @brief Set the max amount of executions that can take place on this host at the same time
138    *
139    * Use -1 to set no limit.
140    */
141   Host* set_concurrency_limit(int limit);
142   int get_concurrency_limit() const;
143
144   /** @brief Convert the CPU's speed from string to double */
145   static std::vector<double> convert_pstate_speed_vector(const std::vector<std::string>& speed_per_state);
146   /**
147    * @brief Set the CPU's speed
148    *
149    * @param speed_per_state list of powers for this processor (default power is at index 0)
150    */
151   Host* set_pstate_speed(const std::vector<double>& speed_per_state);
152   /**
153    * @brief Set the CPU's speed (string version)
154    *
155    * @throw std::invalid_argument if speed format is incorrect.
156    */
157   Host* set_pstate_speed(const std::vector<std::string>& speed_per_state);
158
159   /** @brief Get the peak computing speed in flops/s at the current pstate, NOT taking the external load into account.
160    *
161    *  The amount of flops per second available for computing depends on several things:
162    *    - The current pstate determines the maximal peak computing speed (use
163    *      @verbatim embed:rst:inline :cpp:func:`get_pstate_speed() <simgrid::s4u::Host::get_pstate_speed>` @endverbatim
164    *      to retrieve the computing speed you would get at another pstate)
165    *    - If you declared an external load (with
166    *      @verbatim embed:rst:inline :cpp:func:`set_speed_profile() <simgrid::s4u::Host::set_speed_profile>` @endverbatim ),
167    *      you must multiply the result of
168    *      @verbatim embed:rst:inline :cpp:func:`get_speed() <simgrid::s4u::Host::get_speed>` @endverbatim by
169    *      @verbatim embed:rst:inline :cpp:func:`get_available_speed() <simgrid::s4u::Host::get_available_speed>` @endverbatim
170    *      to retrieve what a new computation would get.
171    *
172    *  The remaining speed is then shared between the executions located on this host.
173    *  You can retrieve the amount of tasks currently running on this host with
174    *  @verbatim embed:rst:inline :cpp:func:`get_load() <simgrid::s4u::Host::get_load>` @endverbatim .
175    *
176    *  The host may have multiple cores, and your executions may be able to use more than a single core.
177    *
178    *  Finally, executions of priority 2 get twice the amount of flops than executions of priority 1.
179    */
180   double get_speed() const;
181   /** @brief Get the available speed ratio, between 0 and 1.
182    *
183    * This accounts for external load (see
184    * @verbatim embed:rst:inline :cpp:func:`set_speed_profile() <simgrid::s4u::Host::set_speed_profile>` @endverbatim ).
185    */
186   double get_available_speed() const;
187
188   /** Returns the number of core of the processor. */
189   int get_core_count() const;
190   Host* set_core_count(int core_count);
191
192   enum class SharingPolicy { NONLINEAR = 1, LINEAR = 0 };
193   /**
194    * @brief Describes how the CPU is shared between concurrent tasks
195    *
196    * Note that the NONLINEAR callback is in the critical path of the solver, so it should be fast.
197    *
198    * @param policy Sharing policy
199    * @param cb Callback for NONLINEAR policies
200    */
201   Host* set_sharing_policy(SharingPolicy policy, const s4u::NonLinearResourceCb& cb = {});
202   SharingPolicy get_sharing_policy() const;
203
204   /** Returns the current computation load (in flops per second)
205    *
206    * The external load (coming from an availability trace) is not taken in account.
207    * You may also be interested in the load plugin.
208    */
209   double get_load() const;
210
211   unsigned long get_pstate_count() const;
212   unsigned long get_pstate() const;
213   double get_pstate_speed(unsigned long pstate_index) const;
214   Host* set_pstate(unsigned long pstate_index);
215   Host* set_coordinates(const std::string& coords);
216
217   std::vector<Disk*> get_disks() const;
218   /**
219    * @brief Create and add disk in the host
220    *
221    * @param name Disk name
222    * @param read_bandwidth Reading speed of the disk
223    * @param write_bandwidth Writing speed of the disk
224    */
225   Disk* create_disk(const std::string& name, double read_bandwidth, double write_bandwidth);
226   /**
227    * @brief Human-friendly version of create_disk function.
228    *
229    * @throw std::invalid_argument if read/write speeds are incorrect
230    */
231   Disk* create_disk(const std::string& name, const std::string& read_bandwidth, const std::string& write_bandwidth);
232   void add_disk(const Disk* disk);
233   void remove_disk(const std::string& disk_name);
234
235   VirtualMachine* create_vm(const std::string& name, int core_amount);
236   VirtualMachine* create_vm(const std::string& name, int core_amount, size_t ramsize);
237   /** Retrieve a VM running on this host from its name, or return nullptr */
238   VirtualMachine* vm_by_name_or_null(const std::string& name);
239
240   void route_to(const Host* dest, std::vector<Link*>& links, double* latency) const;
241   void route_to(const Host* dest, std::vector<kernel::resource::StandardLinkImpl*>& links, double* latency) const;
242
243   /**
244    * @brief Seal this host
245    * No more configuration is allowed after the seal
246    */
247   Host* seal();
248
249   NetZone* get_englobing_zone() const;
250   /** Block the calling actor on an execution located on the called host
251    *
252    * It is not a problem if the actor is not located on the called host.
253    * The actor will not be migrated in this case. Such remote execution are easy in simulation.
254    */
255   void execute(double flops) const;
256   /** Start an asynchronous computation on that host (possibly remote) */
257   ExecPtr exec_init(double flops_amounts) const;
258   ExecPtr exec_async(double flops_amounts) const;
259
260   /** Block the calling actor on an execution located on the called host (with explicit priority) */
261   void execute(double flops, double priority) const;
262   kernel::resource::HostImpl* get_impl() const { return pimpl_; }
263 };
264 } // namespace s4u
265 } // namespace simgrid
266
267 #endif /* SIMGRID_S4U_HOST_HPP */