The S4U Interface



The S4U interface (SimGrid for you) mixes the full power of SimGrid with the full power of C++. This is the preferred interface to describe abstract algorithms in the domains of Cloud, P2P, HPC, IoT, and similar settings.

Since v3.33 (Spring 2023), S4U is the main interface of SimGrid for algorithms. It is feature complete, but may still evolve slightly in future releases. When this happens, compiling your code will produce deprecation warnings for 4 releases (one year) before the removal of the old symbols.

Main Concepts

A typical SimGrid simulation is composed of several Actors, that execute user-provided functions. The actors have to explicitly use the S4U interface to express their computation, communication, disk usage, and other Activities, so that they get reflected within the simulator. These activities take place on resources such as Hosts, Links, and Disks. SimGrid predicts the time taken by each activity and orchestrates the actors accordingly, waiting for the completion of these activities.

When communicating, data is not directly sent to other actors but posted onto a Mailbox that serves as a rendezvous point between communicating actors. This means that you don’t need to know who you are talking to, you just put your communication Put request in a mailbox, and it will be matched with a complementary Get request. Alternatively, actors can interact through classical synchronization mechanisms such as Barrier, Semaphore, Mutex, and ConditionVariable.

Each actor is located on a simulated Host. Each host is located in a NetZone, that knows the networking path between one resource to another. Each NetZone is included in another one, forming a tree of NetZones which root zone contains the whole platform. The actors can also be located on a VirtualMachines that may restrict the activities it contains to a limited amount of cores. Virtual machines can also be migrated between hosts.

The simgrid::s4u::this_actor namespace provides many helper functions to simplify the code of actors.

Activities

Activities represent the actions that consume a resource, such as a Comm that consumes the transmitting power of Link resources, or an Exec that consumes the computing power of Host resources. See also the full API below.

Asynchronous Activities

Every activity can be either blocking or asynchronous. For example, s4u::Mailbox::put() and s4u::Mailbox::get() create blocking communications: the actor is blocked until the completion of that communication. Asynchronous communications do not block the actor during their execution but progress on their own.

Once your asynchronous activity is started, you can test for its completion using s4u::Activity::test(). This function returns true if the activity is completed already. You can also use s4u::Activity::wait() to block until the completion of the activity. To wait for at most a given amount of time, use s4u::Activity::wait_for(). Finally, to wait at most until a specified time limit, use s4u::Activity::wait_until().

Every kind of activity can be asynchronous. s4u::CommPtr are created with s4u::Mailbox::put_async() and s4u::Mailbox::get_async(); s4u::IoPtr are created with s4u::Disk::read_async() and s4u::Disk::write_async(); and s4u::ExecPtr are created with s4u::Host::exec_async(). In the future, it will become possible to have asynchronous IPC such as asynchronous mutex lock requests (it is already possible internally, but the interface is not exposed in S4U yet).

If you want for the completion of any activity in a given set, to react to the earlier occuring completion, then you need an activity set. Please refer to the relevant examples for more information.

Activities Life Cycle

Sometimes, you want to change the setting of an activity before it even starts.

Todo

write this section

Repeatable Activities

In order to simulate the execution of Dataflow applications, we introduced the concept of Tasks, that can be seen as repeatable activities. A Dataflow is defined as a graph of Tasks, where each Tasks has a set of successors and predecessors. When a Tasks ends it sends a token to each of its successors. Each Tasks has to receive a token from each of its predecessor to start. Tokens can carry any user-defined data.

Tasks are composed of several instances: a dispatcher, a collector, and instance_0 to instance_n. The dispatcher rely on a load balancing function to select the next instance to fire. Once this instance finishes it fires the collector.

Each instance of an |API_s4u_ExecTask| can be placed on a different host. |API_s4u_Comm| activities are automatically created when an instance triggers another instance on a different host. Each instance has its own parallelism degree to scale horizontally on several cores.

To initiate the execution of a Dataflow, it is possible to some make Tasks fire one or more activities without waiting for any token with the s4u::Task::enqueue_firings() function.

The parameters of Tasks can be redefined at runtime by attaching callbacks to the s4u::Task::on_this_start and s4u::Task::on_this_completion signals. The former is triggered by instances others than the dispatcher and the collector, and the latter is triggered by the collector.

Mailboxes

Please also refer to the API reference for s4u::Mailbox.

What are Mailboxes?

Mailboxes are rendezvous points for network communications, similar to URLs on which you could post and retrieve data. Actually, the mailboxes are not involved in the communication once it starts, but only to find the contact with which you want to communicate.

They are similar to many common things: The phone number, which allows the caller to find the receiver. The Twitter hashtag, which helps senders and receivers to find each other. In TCP, the pair {host name, host port} to which you can connect to find your peer. In HTTP, URLs through which the clients can connect to the servers. In ZeroMQ, the queues are used to match senders and receivers.

One big difference with most of these systems is that no actor is the exclusive owner of a mailbox, neither in sending nor in receiving. Many actors can send into and/or receive from the same mailbox. TCP socket ports for example are shared on the sender side but exclusive on the receiver side (only one process can receive from a given socket at a given point of time).

A big difference with TCP sockets or MPI communications is that communications do not start right away after a Mailbox::put(), but wait for the corresponding Mailbox::get(). You can change this by declaring a receiving actor.

A big difference with Twitter hashtags is that SimGrid does not offer easy support to broadcast a given message to many receivers. So that would be like a Twitter tag where each message is consumed by the first receiver.

A big difference with the ZeroMQ queues is that you cannot filter on the data you want to get from the mailbox. To model such settings in SimGrid, you’d have one mailbox per potential topic, and subscribe to each topic individually with a get_async() on each mailbox. Then, use an class ActivtySet to get the first message on any of the mailboxes you are subscribed to.

The mailboxes are not located on the network, and you can access them without any latency. The network delays are only related to the location of the sender and receiver once the match between them is done on the mailbox. This is just like the phone number that you can use locally, and the geographical distance only comes into play once you start the communication by dialing this number.

How to use Mailboxes?

You can retrieve any existing mailbox from its name (which is a unique string, just like a Twitter tag). This results in a versatile tool that can be used to build many different situations.

To model classical socket communications, use “hostname:port” as mailbox names, and make sure that only one actor reads into a given mailbox. This does not make it easy to build a perfectly realistic model of the TCP sockets, but in most cases, this system is too cumbersome for your simulations anyway. You probably want something simpler, that turns out to be easy to build with the mailboxes.

Many SimGrid examples use a sort of yellow page system where the mailbox names are the name of the service (such as “worker”, “master”, or “reducer”). That way, you don’t have to know where your peer is located to contact it. You don’t even need its name. Its function is enough for that. This also gives you some sort of load balancing for free if more than one actor pulls from the mailbox: the first actor that can deal with the request will handle it.

How are put() and get() requests matched?

The matching algorithm simple: first come, first serve. When a new send arrives, it matches the oldest enqueued receive. If no receive is currently enqueued, then the incoming send is enqueued. As you can see, the mailbox cannot contain both send and receive requests: all enqueued requests must be of the same sort.

Declaring a Receiving Actor

The last twist is that by default in the simulator, the data starts to be exchanged only when both the sender and the receiver are announced (it waits until both put() and get() are posted). In TCP, since you establish connections beforehand, the data starts to flow as soon as the sender posts it, even if the receiver did not post its put() yet.

To model this in SimGrid, you can declare a specific receiver to a given mailbox (with the function set_receiver()). That way, any put() posted to that mailbox will start as soon as possible, and the data will already be there on the receiver host when the receiver actor posts its get()

Note that being permanent receivers of a mailbox prevents actors to be garbage-collected. If your simulation creates many short-lived actors that are marked as permanent receiver, you should call mailbox->set_receiver(nullptr) by the end of the actors so that their memory gets properly reclaimed. This call should be at the end of the actor’s function, not in an on_exit callback.

Communicating without Mailboxes

Sometimes you don’t want to simulate communications between actors as allowed by mailboxes, but you want to create a direct communication between two arbitrary hosts. This can arise when you write a high-level model of a centralized scheduler, or when you model direct communications such as one-sided communications in MPI or remote memory direct access in PGAS.

For that, Comm::sendto() simulates a direct communication between the two specified hosts. No mailbox is used, and there is no rendezvous between actors. You can freely mix such direct communications and rendezvous-based communications. Alternatively, Comm::sendto_init() and Comm::sendto_async() create asynchronous direct communications.

Memory Management

For sake of simplicity, we use RAII for many classes in S4U. This is an idiom where resources are automatically managed through the context. Provided that you never manipulate objects of type Foo directly but always FooPtr references (which are defined as boost::intrusive_ptr <Foo>), you will never have to explicitly release the resource that you use nor to free the memory of unused objects. Here is a little example:

void myFunc()
{
  simgrid::s4u::MutexPtr mutex = simgrid::s4u::Mutex::create(); // Too bad we cannot use `new`

  mutex->lock();   // use the mutex as a simple reference
  //  bla bla
  mutex->unlock();

} // The mutex gets automatically freed because the only existing reference gets out of scope

Note that Mailboxes, Hosts, and Links are not handled through smart pointers (yet?). This means that it is currently impossible to destroy a mailbox or a link. You can still destroy a host (but probably shouldn’t), using simgrid::s4u::Host::destroy().

API Reference

Simulation objects

⁣  class Actor

class Actor : public xbt::Extendable<Actor>

An actor is an independent stream of execution in your distributed application.

It is located on a (simulated) host, but can interact with the whole simulated platform.

You can think of an actor as a process in your distributed application, or as a thread in a multithreaded program. This is the only component in SimGrid that actually does something on its own, executing its own code. A resource will not get used if you don’t schedule activities on them. This is the code of Actors that create and schedule these activities. Please refer to the examples for more information.

This API is strongly inspired from the C++11 threads. The documentation of this standard may help to understand the philosophy of the SimGrid actors.

typedef long aid_t

Actor’s ID, just like the classical processes’ have PID in UNIX

Basic management

#include <simgrid/s4u/Actor.hpp>
using simgrid::s4u::ActorPtr = boost::intrusive_ptr<Actor>

Smart pointer to a simgrid::s4u::Actor

Creating actors

See also the relevant example.

static ActorPtr simgrid::s4u::Actor::create(const std::string &name, s4u::Host *host, const std::function<void()> &code)

Create an actor from a std::function<void()>. If the actor is restarted, it gets a fresh copy of the function. See the example.

template<class F>
static inline ActorPtr simgrid::s4u::Actor::create(const std::string &name, s4u::Host *host, F code)

Create an actor from a callable thing. See the example.

template<class F, class ...Args>
static inline ActorPtr simgrid::s4u::Actor::create(const std::string &name, s4u::Host *host, F code, Args... args)

Create an actor using a callable thing and its arguments.

Note that the arguments will be copied, so move-only parameters are forbidden. See the example.

static ActorPtr simgrid::s4u::Actor::create(const std::string &name, s4u::Host *host, const std::string &function, std::vector<std::string> args)

Create actor from function name and a vector of strings as arguments. See the example.

static ActorPtr simgrid::s4u::Actor::init(const std::string &name, s4u::Host *host)

Create an actor, but don’t start it yet.

This is useful to set some properties or extension before actually starting it

ActorPtr simgrid::s4u::Actor::start(const std::function<void()> &code)

Start a previously initialized actor

ActorPtr simgrid::s4u::Actor::set_stacksize(unsigned stacksize)

Set a non-default stack size for this context (in Kb)

This must be done before starting the actor, and it won’t work with the thread factory.

Retrieving actors

static ActorPtr simgrid::s4u::Actor::by_pid(aid_t pid)

Retrieves the actor that have the given PID (or nullptr if not existing)

static Actor *simgrid::s4u::Actor::self()

Retrieve a reference to myself

Querying info

const char *simgrid::s4u::Actor::get_cname() const

Retrieves the name of that actor as a C string

const std::string &simgrid::s4u::Actor::get_name() const

Retrieves the name of that actor as a C++ string

aid_t simgrid::s4u::Actor::get_pid() const

Retrieves the actor ID of that actor

aid_t simgrid::s4u::Actor::get_ppid() const

Retrieves the actor ID of that actor’s creator

const std::unordered_map<std::string, std::string> *simgrid::s4u::Actor::get_properties() const

Retrieve the list of properties for that actor

const char *simgrid::s4u::Actor::get_property(const std::string &key) const

Retrieve the property value (or nullptr if not set)

void simgrid::s4u::Actor::set_property(const std::string &key, const std::string &value)

Set a property (old values will be overwritten)

Host *simgrid::s4u::Actor::get_host() const

Retrieves the host on which that actor is running

void simgrid::s4u::Actor::set_host(Host *new_host)

Moves the actor to another host.

If the actor is currently blocked on an execution activity, the activity is also migrated to the new host. If it’s blocked on another kind of activity, an error is raised as the mandated code is not written yet. Please report that bug if you need it.

Asynchronous activities started by the actor are not migrated automatically, so you have to take care of this yourself (only you knows which ones should be migrated).

int simgrid::s4u::Actor::get_refcount() const

Retrieve the amount of references on that object. Useful to debug the automatic refcounting

inline kernel::actor::ActorImpl *simgrid::s4u::Actor::get_impl() const

Returns the internal implementation of this actor

Suspending and resuming actors

void simgrid::s4u::Actor::suspend()

Suspend an actor, that is blocked until resumed by another actor.

void simgrid::s4u::Actor::resume()

Resume an actor that was previously suspended

bool simgrid::s4u::Actor::is_suspended() const

Returns true if the actor is suspended.

Specifying when actors should terminate

void simgrid::s4u::Actor::kill()

Ask the actor to die.

Any blocking activity will be canceled, and it will be rescheduled to free its memory. Being killed is not something that actors can defer or avoid.

static void simgrid::s4u::Actor::kill_all()

Kill all actors (but the issuer). Being killed is not something that actors can delay or avoid.

void simgrid::s4u::Actor::set_kill_time(double time)

Sets the time at which that actor should be killed

double simgrid::s4u::Actor::get_kill_time() const

Get the kill time of an actor(or 0 if unset).

Retrieves the time at which that actor will be killed (or -1 if not set)

Actor *simgrid::s4u::Actor::restart()

Kill that actor and restart it from start.

Actor *simgrid::s4u::Actor::daemonize()

This actor will be automatically terminated when the last non-daemon actor finishes.

Daemons are killed as soon as the last regular actor disappears. If another regular actor gets restarted later on by a timer or when its host reboots, the daemons do not get restarted.

bool simgrid::s4u::Actor::is_daemon() const

Returns whether or not this actor has been daemonized or not

Reacting to the end of actors

void simgrid::s4u::Actor::on_exit(const std::function<void(bool)> &fun) const

Add a function to the list of “on_exit” functions for the current actor. The on_exit functions are the functions executed when your actor is killed. You should use them to free the data used by your actor.

Please note that functions registered in this signal cannot do any simcall themselves. It means that they cannot send or receive messages, acquire or release mutexes, nor even modify a host property or something. Not only are blocking functions forbidden in this setting, but also modifications to the global state.

The parameter of on_exit’s callbacks denotes whether or not the actor’s execution failed. It will be set to true if the actor was killed or failed because of an exception, while it will remain to false if the actor terminated gracefully.

void simgrid::s4u::Actor::join() const

Wait for the actor to finish.

Blocks the calling actor until the joined actor is terminated. If actor alice executes bob.join(), then alice is blocked until bob terminates.

void simgrid::s4u::Actor::join(double timeout) const

Wait for the actor to finish, or for the timeout to elapse.

Blocks the calling actor until the joined actor is terminated. If actor alice executes bob.join(), then alice is blocked until bob terminates.

Actor *simgrid::s4u::Actor::set_auto_restart(bool autorestart = true)

If set to true, the actor will automatically restart when its host reboots.

Some elements of the actor are remembered over reboots: name, host, properties, the on_exit functions, whether it is daemonized and whether it should automatically restart when its host reboots. Note that the state after reboot is the one when set_auto_restart() is called.

If you daemonize your actor after marking it auto_restart, then the new actor after rebooot will not be a daemon.

The on_exit functions are the one defined when the actor dies, not the ones given when it was marked auto_restart (sorry for the inconsistency &#8212; speak to us if it’s too hard to bear).

int simgrid::s4u::Actor::get_restart_count() const

Returns the number of reboots that this actor did. Before the first reboot, this function returns 0.

Signals

static inline void simgrid::s4u::Actor::on_creation_cb(const std::function<void(Actor&)> &cb)

Add a callback fired when a new actor has been created

static inline void simgrid::s4u::Actor::on_suspend_cb(const std::function<void(Actor const&)> &cb)

Add a callback fired when any actor is suspended (right before the suspend)

inline void simgrid::s4u::Actor::on_this_suspend_cb(const std::function<void(Actor const&)> &cb)

Add a callback fired when this specific actor is suspended (right before the suspend)

static inline void simgrid::s4u::Actor::on_host_change_cb(const std::function<void(const Actor&, const Host &previous_location)> &cb)

Add a callback fired when any actor is has been migrated to another host

inline void simgrid::s4u::Actor::on_this_host_change_cb(const std::function<void(const Actor&, const Host &previous_location)> &cb)

Add a callback fired when this specific actor is has been migrated to another host

static inline void simgrid::s4u::Actor::on_resume_cb(const std::function<void(Actor const&)> &cb)

Add a callback fired when any actor is resumed (right before the resume)

inline void simgrid::s4u::Actor::on_this_resume_cb(const std::function<void(Actor const&)> &cb)

Add a callback fired when this specific actor is resumed (right before the resume)

static inline void simgrid::s4u::Actor::on_sleep_cb(const std::function<void(Actor const&)> &cb)

Add a callback fired when any actor starts sleeping

inline void simgrid::s4u::Actor::on_this_sleep_cb(const std::function<void(Actor const&)> &cb)

Add a callback fired when this specific actor starts sleeping

static inline void simgrid::s4u::Actor::on_wake_up_cb(const std::function<void(Actor const&)> &cb)

Add a callback fired when any actor wakes up from a sleep

inline void simgrid::s4u::Actor::on_this_wake_up_cb(const std::function<void(Actor const&)> &cb)

Add a callback fired when this specific actor wakes up from a sleep

static inline void simgrid::s4u::Actor::on_termination_cb(const std::function<void(Actor const&)> &cb)

Add a callback fired when any actor terminates its code.

The actor may continue to exist if it is still referenced in the simulation, but it’s not active anymore. If you want to free extra data when the actor’s destructor is called, use Actor::on_destruction_cb(). If you want to register to the termination of a given actor, use this_actor::on_exit() instead.

inline void simgrid::s4u::Actor::on_this_termination_cb(const std::function<void(Actor const&)> &cb)

Add a callback fired when this specific actor terminates its code.

The actor may continue to exist if it is still referenced in the simulation, but it’s not active anymore. If you want to free extra data when the actor’s destructor is called, use Actor::on_this_destruction_cb().

static inline void simgrid::s4u::Actor::on_destruction_cb(const std::function<void(Actor const&)> &cb)

Add a callback fired when an actor is about to disappear (its destructor was called). This signal is fired for any destructed actor, which is mostly useful when designing plugins and extensions.

inline void simgrid::s4u::Actor::on_this_destruction_cb(const std::function<void(Actor const&)> &cb)

Add a callback fired when this specific actor is about to disappear (its destructor was called).

⁣  The current actor

These functions can be used in your user code to interact with the actor currently running (the one retrieved with simgrid::s4u::Actor::self()). Using these functions can greatly improve the code readability.

Querying info

const char *simgrid::s4u::this_actor::get_cname()

Returns the name of the current actor as a C string.

std::string simgrid::s4u::this_actor::get_name()

Returns the name of the current actor.

aid_t simgrid::s4u::this_actor::get_pid()

Returns the actor ID of the current actor.

aid_t simgrid::s4u::this_actor::get_ppid()

Returns the ancestor’s actor ID of the current actor.

bool simgrid::s4u::this_actor::is_maestro()

Returns true if run from the kernel mode, and false if run from a real actor

Everything that is run out of any actor (simulation setup before the engine is run, computing the model evolutions as a result to the actors’ action, etc) is run in kernel mode, just as in any operating systems.

In SimGrid, the actor in charge of doing the stuff in kernel mode is called Maestro, because it is the one scheduling when the others should move or wait.

Host *simgrid::s4u::this_actor::get_host()

Returns the name of the host on which the current actor is running.

void simgrid::s4u::this_actor::set_host(Host *new_host)

Migrate the current actor to a new host.

Moves the current actor to another host.

See also

simgrid::s4u::Actor::migrate() for more information

Suspending and resuming

void simgrid::s4u::this_actor::suspend()

Suspend the current actor, that is blocked until resume()ed by another actor.

void simgrid::s4u::this_actor::yield()

Yield the current actor.

Logging messages

Please refer to the relevant documentation.

Sleeping

void simgrid::s4u::this_actor::sleep_for(double duration)

Block the current actor sleeping for that amount of seconds

template<class Rep, class Period>
inline void simgrid::s4u::this_actor::sleep_for(std::chrono::duration<Rep, Period> duration)
template<class Duration>
inline void simgrid::s4u::this_actor::sleep_until(const SimulationTimePoint<Duration> &wakeup_time)
void simgrid::s4u::this_actor::sleep_until(double wakeup_time)

Block the current actor sleeping until the specified timestamp

Simulating executions

Simulate the execution of some code on this actor. You can either simulate parallel or sequential code and you can either block upon the termination of the execution, or start an asynchronous activity.

ExecPtr simgrid::s4u::this_actor::exec_async(double flops_amounts)
ExecPtr simgrid::s4u::this_actor::exec_init(const std::vector<s4u::Host*> &hosts, const std::vector<double> &flops_amounts, const std::vector<double> &bytes_amounts)

Initialize a parallel execution that must then be started manually

ExecPtr simgrid::s4u::this_actor::exec_init(double flops_amounts)

Initialize a sequential execution that must then be started manually

void simgrid::s4u::this_actor::execute(double flop)

Block the current actor, computing the given amount of flops

void simgrid::s4u::this_actor::execute(double flop, double priority)

Block the current actor, computing the given amount of flops at the given priority. An execution of priority 2 computes twice as fast as an execution at priority 1.

void simgrid::s4u::this_actor::parallel_execute(const std::vector<s4u::Host*> &hosts, const std::vector<double> &flops_amounts, const std::vector<double> &bytes_amounts)

Block the current actor until the built parallel execution terminates

Example of use: examples/cpp/exec-ptask/s4u-exec-ptask.cpp

Parallel executions convenient abstractions of parallel computational kernels that span over several machines, such as a PDGEM and the other ScaLAPACK routines. If you are interested in the effects of such parallel kernel on the platform (e.g. to schedule them wisely), there is no need to model them in all details of their internal execution and communications. It is much more convenient to model them as a single execution activity that spans over several hosts. This is exactly what s4u’s Parallel Executions are.

To build such an object, you need to provide a list of hosts that are involved in the parallel kernel (the actor’s own host may or may not be in this list) and specify the amount of computations that should be done by each host, using a vector of flops amount. Then, you should specify the amount of data exchanged between each hosts during the parallel kernel. For that, a matrix of values is expected.

It is OK to build a parallel execution without any computation and/or without any communication. Just pass an empty vector to the corresponding parameter.

For example, if your list of hosts is [host0, host1], passing a vector [1000, 2000] as a flops_amount vector means that host0 should compute 1000 flops while host1 will compute 2000 flops. A matrix of communications’ sizes of [0, 1, 2, 3] specifies the following data exchanges:

  • from host0: [ to host0: 0 bytes; to host1: 1 byte ]

  • from host1: [ to host0: 2 bytes; to host1: 3 bytes ]

Or, in other words:

  • From host0 to host0: 0 bytes are exchanged

  • From host0 to host1: 1 byte is exchanged

  • From host1 to host0: 2 bytes are exchanged

  • From host1 to host1: 3 bytes are exchanged

In a parallel execution, all parts (all executions on each hosts, all communications) progress exactly at the same pace, so they all terminate at the exact same pace. If one part is slow because of a slow resource or because of contention, this slows down the parallel execution as a whole.

These objects are somewhat surprising from a modeling point of view. For example, the unit of their speed is somewhere between flop/sec and byte/sec. Arbitrary parallel executions will simply not work with the usual platform models, and you must use the ptask_L07 host model for that. Note that you can mix regular executions and communications with parallel executions, provided that the host model is ptask_L07.

Block the current actor until the built parallel execution completes.

void simgrid::s4u::this_actor::thread_execute(s4u::Host *host, double flop_amounts, int thread_count)

Block the current actor until the built multi-thread execution completes.

Exiting

void simgrid::s4u::this_actor::exit()

kill the current actor.

void simgrid::s4u::this_actor::on_exit(const std::function<void(bool)> &fun)

Add a function to the list of “on_exit” functions of the current actor.

The on_exit functions are the functions executed when your actor is killed. You should use them to free the data used by your actor.

Please note that functions registered in this signal cannot do any simcall themselves. It means that they cannot send or receive messages, acquire or release mutexes, nor even modify a host property or something. Not only are blocking functions forbidden in this setting, but also modifications to the global state.

The parameter of on_exit’s callbacks denotes whether or not the actor’s execution failed. It will be set to true if the actor was killed or failed because of an exception or if the simulation deadlocked, while it will remain to false if the actor terminated gracefully.

⁣  Simulation Engine

class Engine

Simulation engine.

This is a singleton containing all the main functions of the simulation.

Engin initialization

explicit simgrid::s4u::Engine::Engine(int *argc, char **argv)

Constructor, taking the command line parameters of your main function

static bool simgrid::s4u::Engine::is_initialized()

Returns whether SimGrid was initialized yet &#8212; mostly for internal use

static s4u::Engine *simgrid::s4u::Engine::get_instance()

Retrieve the engine singleton.

Simulation setup

static void simgrid::s4u::Engine::set_config(const std::string &str)

set a configuration variable

Do –help on any SimGrid binary to see the list of currently existing configuration variables (see also Configuring SimGrid).

Example: simgrid::s4u::Engine::set_config(“host/model:ptask_L07”);

static void simgrid::s4u::Engine::set_config(const std::string &name, bool value)
static void simgrid::s4u::Engine::set_config(const std::string &name, double value)
static void simgrid::s4u::Engine::set_config(const std::string &name, int value)
static void simgrid::s4u::Engine::set_config(const std::string &name, const std::string &value)
void simgrid::s4u::Engine::load_deployment(const std::string &deploy) const

Load a deployment file. See:ref:deploy and the example.

void simgrid::s4u::Engine::load_platform(const std::string &platf) const

Creates a new platform, including hosts, links, and the routing table.

See also: Describing your Simulated Platform.

std::string simgrid::s4u::Engine::flatify_platform() const

Get a debug output of the platform.

It looks like a XML platform file, but it may be very different from the input platform file: All netzones are flatified into a unique zone. This representation is mostly useful to debug your platform configuration and ensure that your assumptions over your configuration hold. This enables you to verify the exact list of links traversed between any two hosts, and the characteristics of every host and link. But you should not use the resulting file as an input platform file: it is very verbose, and thus much less efficient (in parsing time and runtime performance) than a regular platform file with the sufficient amount of intermediary netzones. Even if you use one zone only, specialized zones (such as clusters) are more efficient than the one with fully explicit routing used here.

template<class F>
inline void simgrid::s4u::Engine::register_actor(const std::string &name)

Bind an actor name that could be found in <actor> tag to a class name passed as a template parameter. See the example.

template<class F>
inline void simgrid::s4u::Engine::register_actor(const std::string &name, F code)

Bind an actor name that could be found in <actor> tag to a function name passed as a parameter. See the example.

void simgrid::s4u::Engine::register_default(const std::function<void(int, char**)> &code)

Provide a default function to be used when the name used in a <actor> tag was not binded with register_function nor register_actor.

void simgrid::s4u::Engine::register_default(const kernel::actor::ActorCodeFactory &factory)
void simgrid::s4u::Engine::register_function(const std::string &name, const std::function<void(int, char**)> &code)

Bind an actor name that could be found in <actor> tag to a function taking classical argc/argv parameters. See the example.

void simgrid::s4u::Engine::register_function(const std::string &name, const std::function<void(std::vector<std::string>)> &code)

Bind an actor name that could be found in <actor> tag to a function taking a vector of strings as a parameter. See the example.

void simgrid::s4u::Engine::register_function(const std::string &name, const kernel::actor::ActorCodeFactory &factory)

Run the simulation

static double simgrid::s4u::Engine::get_clock()

Retrieve the simulation time (in seconds)

void simgrid::s4u::Engine::run() const

Run the simulation until its end

void simgrid::s4u::Engine::run_until(double max_date) const

Run the simulation until the specified date

Retrieving actors

size_t simgrid::s4u::Engine::get_actor_count() const
std::vector<ActorPtr> simgrid::s4u::Engine::get_all_actors() const
std::vector<ActorPtr> simgrid::s4u::Engine::get_filtered_actors(const std::function<bool(ActorPtr)> &filter) const

Retrieving hosts

std::vector<Host*> simgrid::s4u::Engine::get_all_hosts() const

Returns a vector of all hosts found in the platform.

The order is generally different from the creation/declaration order in the XML platform because we use a hash table internally.

size_t simgrid::s4u::Engine::get_host_count() const

Returns the amount of hosts existing in the platform.

std::vector<Host*> simgrid::s4u::Engine::get_filtered_hosts(const std::function<bool(Host*)> &filter) const
Host *simgrid::s4u::Engine::host_by_name(const std::string &name) const
Host *simgrid::s4u::Engine::host_by_name_or_null(const std::string &name) const

Interacting with the routing

std::vector<kernel::routing::NetPoint*> simgrid::s4u::Engine::get_all_netpoints() const
template<class T>
inline std::vector<T*> simgrid::s4u::Engine::get_filtered_netzones() const

Retrieves all netzones of the type indicated by the template argument.

NetZone *simgrid::s4u::Engine::get_netzone_root() const
kernel::routing::NetPoint *simgrid::s4u::Engine::netpoint_by_name_or_null(const std::string &name) const
NetZone *simgrid::s4u::Engine::netzone_by_name_or_null(const std::string &name) const

Signals

static inline void simgrid::s4u::Engine::on_deadlock_cb(const std::function<void(void)> &cb)

Add a callback fired when the time cannot advance because of inter-actors deadlock. Note that the on_exit of each actor is also executed on deadlock.

static inline void simgrid::s4u::Engine::on_platform_created_cb(const std::function<void()> &cb)

Add a callback fired when the platform is created (ie, the xml file parsed), right before the actual simulation starts.

static inline void simgrid::s4u::Engine::on_platform_creation_cb(const std::function<void()> &cb)

Add a callback fired when the platform is about to be created (ie, after any configuration change and just before the resource creation)

static inline void simgrid::s4u::Engine::on_simulation_start_cb(const std::function<void()> &cb)

Add a callback fired when the main simulation loop starts, at the beginning of the first call to Engine::run()

static inline void simgrid::s4u::Engine::on_simulation_end_cb(const std::function<void()> &cb)

Add a callback fired when the main simulation loop ends, just before the end of Engine::run()

static inline void simgrid::s4u::Engine::on_time_advance_cb(const std::function<void(double)> &cb)

Add a callback fired when the time jumps into the future.

It is fired right after the time change (use get_clock() to get the new timestamp). The callback parameter is the time delta since previous timestamp.

⁣  class Mailbox

class Mailbox

Mailboxes: Network rendez-vous points.

Please also refer to the full doc on s4u::Mailbox.

Basic management

#include <simgrid/s4u/Mailbox.hpp>

Note that there is no MailboxPtr type and that you cannot use the RAII idiom on mailboxes because they are internal objects to the simulation engine. Once created, there is no way to destroy a mailbox before the end of the simulation.

static Mailbox *simgrid::s4u::Mailbox::by_name(const std::string &name)

Retrieve the mailbox associated to the given name. Mailboxes are created on demand.

Querying info

const char *simgrid::s4u::Mailbox::get_cname() const

Retrieves the name of that mailbox as a C string.

const std::string &simgrid::s4u::Mailbox::get_name() const

Retrieves the name of that mailbox as a C++ string.

Sending data

void simgrid::s4u::Mailbox::put(void *payload, uint64_t simulated_size_in_bytes)

Blocking data transmission.

Please note that if you send a pointer to some data, you must ensure that your data remains live during the communication, or the receiver will get a pointer to a garbled memory area.

void simgrid::s4u::Mailbox::put(void *payload, uint64_t simulated_size_in_bytes, double timeout)

Blocking data transmission with timeout

CommPtr simgrid::s4u::Mailbox::put_async(void *data, uint64_t simulated_size_in_bytes)

Creates and start a data transmission to that mailbox.

Please note that if you send a pointer to some data, you must ensure that your data remains live during the communication, or the receiver will get a pointer to a garbled memory area.

CommPtr simgrid::s4u::Mailbox::put_init()

Creates (but don’t start) a data transmission to that mailbox

CommPtr simgrid::s4u::Mailbox::put_init(void *data, uint64_t simulated_size_in_bytes)

Creates (but don’t start) a data transmission to that mailbox.

Please note that if you send a pointer to some data, you must ensure that your data remains live during the communication, or the receiver will get a pointer to a garbled memory area.

Receiving data

bool simgrid::s4u::Mailbox::empty() const

Returns whether the mailbox contains queued communications

kernel::activity::CommImplPtr simgrid::s4u::Mailbox::front() const

Gets the first element in the queue (without dequeuing it), or nullptr if none is there

template<typename T>
T *simgrid::s4u::Mailbox::get()

Blocking data reception

template<typename T>
T *simgrid::s4u::Mailbox::get(double timeout)

Blocking data reception with timeout

template<typename T>
CommPtr simgrid::s4u::Mailbox::get_async(T **data)

Creates and start an async data reception to that mailbox

CommPtr simgrid::s4u::Mailbox::get_init()

Creates (but don’t start) a data reception onto that mailbox. You probably want to use simgrid::s4u::Comm::set_dst_data() and friends before* starting that activity.

kernel::activity::ActivityImplPtr simgrid::s4u::Mailbox::iprobe(int type, const std::function<bool(void*, void*, kernel::activity::CommImpl*)> &match_fun, void *data)
bool simgrid::s4u::Mailbox::listen() const

Check if there is a communication going on in a mailbox.

bool simgrid::s4u::Mailbox::ready() const

Check if there is a communication ready to be consumed from a mailbox.

See this example.

Receiving actor

See Declaring a Receiving Actor.

ActorPtr simgrid::s4u::Mailbox::get_receiver() const

Return the actor declared as permanent receiver, or nullptr if none

void simgrid::s4u::Mailbox::set_receiver(ActorPtr actor)

Declare that the specified actor is a permanent receiver on that mailbox

It means that the communications sent to this mailbox will start flowing to its host even before it does a get(). This models the real behavior of TCP and MPI communications, amongst other. It will improve the accuracy of predictions, in particular if your application exhibits swarms of small messages.

SimGrid does not enforces any kind of ownership over the mailbox. Even if a receiver was declared, any other actors can still get() data from the mailbox. The timings will then probably be off tracks, so you should strive on your side to not get data from someone else’s mailbox.

Note that being permanent receivers of a mailbox prevents actors to be garbage-collected. If your simulation creates many short-lived actors that marked as permanent receiver, you should call mailbox->set_receiver(nullptr) by the end of the actors so that their memory gets properly reclaimed. This call should be at the end of the actor’s function, not in an on_exit callback.

Resources

⁣  class Disk

class Disk : public xbt::Extendable<Disk>

Disk represent the disk resources associated to a host

By default, SimGrid does not keep track of the actual data being written but only computes the time taken by the corresponding data movement.

Basic management

#include <simgrid/s4u/Disk.hpp>

Note that there is no DiskPtr type and that you cannot use the RAII idiom on disks because SimGrid does not allow (yet) to create nor destroy resources once the simulation is started.

Disk *simgrid::s4u::Disk::seal()

Querying info

const char *simgrid::s4u::Disk::get_cname() const

Retrieves the name of that disk as a C string.

Host *simgrid::s4u::Disk::get_host() const
std::string const &simgrid::s4u::Disk::get_name() const
const std::unordered_map<std::string, std::string> *simgrid::s4u::Disk::get_properties() const
const char *simgrid::s4u::Disk::get_property(const std::string &key) const
double simgrid::s4u::Disk::get_read_bandwidth() const
double simgrid::s4u::Disk::get_write_bandwidth() const
Disk *simgrid::s4u::Disk::set_property(const std::string&, const std::string &value)
Disk *simgrid::s4u::Disk::set_sharing_policy(Operation op, SharingPolicy policy, const s4u::NonLinearResourceCb &cb = {})

Describes how the disk is shared between activities for each operation.

Disks have different bandwidths for read and write operations, that can have different policies:

  • Read: resource sharing for read operation

  • Write: resource sharing for write

  • ReadWrite: global sharing for read and write operations

Note that the NONLINEAR callback is in the critical path of the solver, so it should be fast.

Parameters:
  • op – Operation type

  • policy – Sharing policy

  • cb – Callback for NONLINEAR policies

enum class simgrid::s4u::Disk::Operation

Values:

enumerator READ
enumerator WRITE
enumerator READWRITE
enum class simgrid::s4u::Disk::SharingPolicy

Policy for sharing the disk among activities.

Values:

enumerator NONLINEAR
enumerator LINEAR

I/O operations

IoPtr simgrid::s4u::Disk::io_init(sg_size_t size, s4u::Io::OpType type) const
sg_size_t simgrid::s4u::Disk::read(sg_size_t size) const
IoPtr simgrid::s4u::Disk::read_async(sg_size_t size) const
sg_size_t simgrid::s4u::Disk::write(sg_size_t size) const
IoPtr simgrid::s4u::Disk::write_async(sg_size_t size) const

Signals

static inline void simgrid::s4u::Disk::on_creation_cb(const std::function<void(Disk&)> &cb)

Add a callback fired when a new Disk is created.

static inline void simgrid::s4u::Disk::on_destruction_cb(const std::function<void(Disk const&)> &cb)

Add a callback fired when any Disk is destroyed.

inline void simgrid::s4u::Disk::on_this_destruction_cb(const std::function<void(Disk const&)> &cb)

Add a callback fired when this specific Disk is destroyed.

static inline void simgrid::s4u::Disk::on_onoff_cb(const std::function<void(Disk const&)> &cb)

Add a callback fired when any Disk is turned on or off.

inline void simgrid::s4u::Disk::on_this_onoff_cb(const std::function<void(Disk const&)> &cb)

Add a callback fired when this specific Disk is turned on or off.

⁣  class Host

class Host : public xbt::Extendable<Host>

Some physical resource with computing and networking capabilities on which Actors execute.

All hosts are automatically created during the call of the method simgrid::s4u::Engine::load_platform(). You cannot create a host yourself.

You can retrieve a particular host using simgrid::s4u::Host::by_name() and actors can retrieve the host on which they run using simgrid::s4u::Host::current() or simgrid::s4u::this_actor::get_host()

Subclassed by simgrid::s4u::VirtualMachine

Basic management

#include <simgrid/s4u/Host.hpp>

Note that there is no HostPtr type, and that you cannot use the RAII idiom on hosts because SimGrid does not allow (yet) to create nor destroy resources once the simulation is started.

virtual void simgrid::s4u::Host::destroy()

Fire the required callbacks and destroy the object.

Don’t delete directly a host, call h->destroy() instead.

This is cumbersome but this is the simplest solution to ensure that the on_destruction() callback receives a valid object (because of the destructor order in a class hierarchy).

Host *simgrid::s4u::Host::seal()

Seal this host No more configuration is allowed after the seal.

Retrieving hosts

See also simgrid::s4u::Engine::get_all_hosts().

static Host *simgrid::s4u::Host::by_name(const std::string &name)

Retrieve a host from its name, or die

static Host *simgrid::s4u::Host::by_name_or_null(const std::string &name)

Retrieve a host from its name, or return nullptr

static Host *simgrid::s4u::Host::current()

Retrieves the host on which the running actor is located

Modifying characteristics

Host *simgrid::s4u::Host::set_core_count(int core_count)
Host *simgrid::s4u::Host::set_coordinates(const std::string &coords)
Host *simgrid::s4u::Host::set_sharing_policy(SharingPolicy policy, const s4u::NonLinearResourceCb &cb = {})

Describes how the CPU is shared between concurrent tasks.

Note that the NONLINEAR callback is in the critical path of the solver, so it should be fast.

Parameters:
  • policy – Sharing policy

  • cb – Callback for NONLINEAR policies

Querying info

const char *simgrid::s4u::Host::get_cname() const

Retrieves the name of that host as a C string

int simgrid::s4u::Host::get_core_count() const

Returns the number of core of the processor.

std::string const &simgrid::s4u::Host::get_name() const

Retrieves the name of that host as a C++ string

double simgrid::s4u::Host::get_available_speed() const

Get the available speed ratio, between 0 and 1.

This accounts for external load (see set_speed_profile() ).

double simgrid::s4u::Host::get_load() const

Returns the current computation load (in flops per second)

The external load (coming from an availability trace) is not taken in account. You may also be interested in the load plugin.

double simgrid::s4u::Host::get_speed() const

Get the peak computing speed in flops/s at the current pstate, NOT taking the external load into account.

The amount of flops per second available for computing depends on several things:

The remaining speed is then shared between the executions located on this host. You can retrieve the amount of tasks currently running on this host with get_load() .

The host may have multiple cores, and your executions may be able to use more than a single core.

Finally, executions of priority 2 get twice the amount of flops than executions of priority 1.

User data and properties

const std::unordered_map<std::string, std::string> *simgrid::s4u::Host::get_properties() const

Get the properties assigned to a host

const char *simgrid::s4u::Host::get_property(const std::string &key) const

Retrieve the property value (or nullptr if not set)

Host *simgrid::s4u::Host::set_properties(const std::unordered_map<std::string, std::string> &properties)
Host *simgrid::s4u::Host::set_property(const std::string &key, const std::string &value)

Retrieving components

void simgrid::s4u::Host::add_disk(const Disk *disk)
size_t simgrid::s4u::Host::get_actor_count() const

Returns how many actors (daemonized or not) have been launched on this host.

std::vector<ActorPtr> simgrid::s4u::Host::get_all_actors() const

Return a copy of the list of actors that are executing on this host.

Daemons and regular actors are all mixed in this list.

std::vector<Disk*> simgrid::s4u::Host::get_disks() const
void simgrid::s4u::Host::remove_disk(const std::string &disk_name)

On/Off

bool simgrid::s4u::Host::is_on() const

Returns if that host is currently up and running

void simgrid::s4u::Host::turn_off()

Stop the host if it is on.

Turns that host off. All actors are forcefully stopped.

void simgrid::s4u::Host::turn_on()

Turns that host on if it was previously off

This call does nothing if the host is already on. If it was off, all actors which were marked ‘autorestart’ on that host will be restarted automatically (note that this may differ from the actors that were initially running on the host).

All other Host’s properties are left unchanged; in particular, the pstate is left unchanged and not reset to its initial value.

DVFS

See also the relevant examples.

unsigned long simgrid::s4u::Host::get_pstate() const

Retrieve the pstate at which the host is currently running.

unsigned long simgrid::s4u::Host::get_pstate_count() const
double simgrid::s4u::Host::get_pstate_speed(unsigned long pstate_index) const

Get the peak processor speed (in flops/s), at the specified pstate

Host *simgrid::s4u::Host::set_pstate(unsigned long pstate_index)

Set the pstate at which the host should run.

Dynamic profiles

Host *simgrid::s4u::Host::set_speed_profile(kernel::profile::Profile *p)

Specify a profile modeling the external load according to an exhaustive list or a stochastic law.

Each event of the profile represent a peak speed change that is due to external load. The values are given as a rate of the initial value. This means that the actual value is obtained by multiplying the initial value (the peek speed at this pstate level) by the rate coming from the profile.

Host *simgrid::s4u::Host::set_state_profile(kernel::profile::Profile *p)

Specify a profile turning the host on and off according to an exhaustive list or a stochastic law. The profile must contain boolean values.

Execution

ExecPtr simgrid::s4u::Host::exec_async(double flops_amounts) const
void simgrid::s4u::Host::execute(double flops) const

Block the calling actor on an execution located on the called host

It is not a problem if the actor is not located on the called host. The actor will not be migrated in this case. Such remote execution are easy in simulation.

void simgrid::s4u::Host::execute(double flops, double priority) const

Block the calling actor on an execution located on the called host (with explicit priority)

Platform and routing

You can also start direct communications between two arbitrary hosts using Comm::sendto().

NetZone *simgrid::s4u::Host::get_englobing_zone() const

Returns the networking zone englobing that host.

inline kernel::routing::NetPoint *simgrid::s4u::Host::get_netpoint() const
void simgrid::s4u::Host::route_to(const Host *dest, std::vector<Link*> &links, double *latency) const

Find a route toward another host.

walk through the routing components tree and find a route between hosts by calling each “get_route” function in each routing component.

Parameters:
  • dest – [IN] where to

  • links – [OUT] where to store the list of links (must exist, cannot be nullptr).

  • latency – [OUT] where to store the latency experienced on the path (or nullptr if not interested) It is the caller responsibility to initialize latency to 0 (we add to provided route)

void simgrid::s4u::Host::route_to(const Host *dest, std::vector<kernel::resource::StandardLinkImpl*> &links, double *latency) const

Just like Host::routeTo, but filling an array of link implementations.

Disk *simgrid::s4u::Host::create_disk(const std::string &name, double read_bandwidth, double write_bandwidth)

Create and add disk in the host.

Parameters:
  • name – Disk name

  • read_bandwidth – Reading speed of the disk

  • write_bandwidth – Writing speed of the disk

Disk *simgrid::s4u::Host::create_disk(const std::string &name, const std::string &read_bandwidth, const std::string &write_bandwidth)

Human-friendly version of create_disk function.

Throws:

std::invalid_argument – if read/write speeds are incorrect

Signals

static inline void simgrid::s4u::Host::on_creation_cb(const std::function<void(Host&)> &cb)

Add a callback fired on each newly created host

static inline void simgrid::s4u::Host::on_destruction_cb(const std::function<void(Host const&)> &cb)

Add a callback fired just before destructing any host

inline void simgrid::s4u::Host::on_this_destruction_cb(const std::function<void(Host const&)> &cb)

Add a callback fired just before destructing this specific host

static inline void simgrid::s4u::Host::on_speed_change_cb(const std::function<void(Host const&)> &cb)

Add a callback fired when the speed of any machine is changed (called AFTER the change) (either because of a pstate switch or because of an external load event coming from the profile)

inline void simgrid::s4u::Host::on_this_speed_change_cb(const std::function<void(Host const&)> &cb)

Add a callback fired when the speed of this specific machine is changed (called AFTER the change) (either because of a pstate switch or because of an external load event coming from the profile)

static inline void simgrid::s4u::Host::on_onoff_cb(const std::function<void(Host const&)> &cb)

Add a callback fired when any machine is turned on or off (called AFTER the change)

inline void simgrid::s4u::Host::on_this_onoff_cb(const std::function<void(Host const&)> &cb)

Add a callback fired when this specific machine is turned on or off (called AFTER the change)

static inline void simgrid::s4u::Host::on_exec_state_change_cb(const std::function<void(kernel::resource::CpuAction&, kernel::resource::Action::State previous)> &cb)

Add a callback fired when the state of any exec activity changes

⁣  class NetZone

class NetZone

Networking Zones.

A netzone is a network container, in charge of routing information between elements (hosts) and to the nearby netzones. In SimGrid, there is a hierarchy of netzones, with a unique root zone (that you can retrieve from the s4u::Engine).

Basic management

#include <simgrid/s4u/NetZone.hpp>

Note that there is no NetZonePtr type and that you cannot use the RAII idiom on network zones because SimGrid does not allow (yet) to create nor destroy resources once the simulation is started.

NetZone *simgrid::s4u::NetZone::seal()

Seal this netzone configuration.

Retrieving zones

Querying info

const char *simgrid::s4u::NetZone::get_cname() const

Retrieves the name of that netzone as a C string.

const std::string &simgrid::s4u::NetZone::get_name() const

Retrieves the name of that netzone as a C++ string.

kernel::routing::NetPoint *simgrid::s4u::NetZone::get_netpoint() const

Get the netpoint associated to this netzone.

User data and properties

const std::unordered_map<std::string, std::string> *simgrid::s4u::NetZone::get_properties() const

Get the properties assigned to a netzone

const char *simgrid::s4u::NetZone::get_property(const std::string &key) const

Retrieve the property value (or nullptr if not set)

void simgrid::s4u::NetZone::set_property(const std::string &key, const std::string &value)

Retrieving components

std::vector<Host*> simgrid::s4u::NetZone::get_all_hosts() const
size_t simgrid::s4u::NetZone::get_host_count() const

Routing data

unsigned long simgrid::s4u::NetZone::add_component(kernel::routing::NetPoint *elm)
void simgrid::s4u::NetZone::add_route(const Host *src, const Host *dst, const std::vector<LinkInRoute> &link_list, bool symmetrical = true)

Add a route between 2 hosts.

Parameters:
  • src – Source host

  • dst – Destination host

  • link_list – List of links and their direction used in this communication

  • symmetrical – Bi-directional communication

void simgrid::s4u::NetZone::add_route(const Host *src, const Host *dst, const std::vector<const Link*> &links)

Add a route between 2 hosts.

Parameters:
  • src – Source host

  • dst – Destination host

  • links – List of links. The UP direction will be used on src->dst and DOWN direction on dst->src

void simgrid::s4u::NetZone::add_route(const NetZone *src, const NetZone *dst, const std::vector<LinkInRoute> &link_list, bool symmetrical = true)

Add a route between 2 netzones, and same in other direction.

Parameters:
  • src – Source netzone

  • dst – Destination netzone

  • link_list – List of links and their direction used in this communication

  • symmetrical – Bi-directional communication

void simgrid::s4u::NetZone::add_route(const NetZone *src, const NetZone *dst, const std::vector<const Link*> &links)

Add a route between 2 netzones, and same in other direction.

Parameters:
  • src – Source netzone

  • dst – Destination netzone

  • links – List of links

std::vector<NetZone*> simgrid::s4u::NetZone::get_children() const
NetZone *simgrid::s4u::NetZone::get_parent() const
NetZone *simgrid::s4u::NetZone::set_parent(const NetZone *parent)

Signals

static inline void simgrid::s4u::NetZone::on_creation_cb(const std::function<void(NetZone const&)> &cb)

Add a callback fired on each newly created NetZone

static inline void simgrid::s4u::NetZone::on_seal_cb(const std::function<void(NetZone const&)> &cb)

Add a callback fired on each newly sealed NetZone

Creating resources

Zones
NetZone *simgrid::s4u::create_full_zone(const std::string &name)
NetZone *simgrid::s4u::create_empty_zone(const std::string &name)
NetZone *simgrid::s4u::create_star_zone(const std::string &name)
NetZone *simgrid::s4u::create_dijkstra_zone(const std::string &name, bool cache)
NetZone *simgrid::s4u::create_floyd_zone(const std::string &name)
NetZone *simgrid::s4u::create_vivaldi_zone(const std::string &name)
NetZone *simgrid::s4u::create_wifi_zone(const std::string &name)
NetZone *simgrid::s4u::create_torus_zone(const std::string &name, const NetZone *parent, const std::vector<unsigned long> &dimensions, const ClusterCallbacks &set_callbacks, double bandwidth, double latency, Link::SharingPolicy sharing_policy)

Create a torus zone.

Torus clusters are characterized by:

  • dimensions, eg. {3,3,3} creates a torus with X = 3 elements, Y = 3 and Z = 3. In total, this cluster have 27 elements

  • inter-node communication: (bandwidth, latency, sharing_policy) the elements are connected through regular links with these characteristics More details in: Torus Cluster

Moreover, this method accepts 3 callbacks to populate the cluster: set_netpoint, set_loopback and set_limiter .

Note that the all elements in a Torus cluster must have (or not) the same elements (loopback and limiter)

Parameters:
  • name – NetZone’s name

  • parent – Pointer to parent’s netzone (nullptr if root netzone). Needed to be able to create the resources inside the netzone

  • dimensions – List of positive integers (> 0) which determines the torus’ dimensions

  • set_callbacks – Callbacks to set properties from cluster elements (netpoint, loopback and limiter)

  • bandwidth – Characteristics of the inter-nodes link

  • latency – Characteristics of the inter-nodes link

  • sharing_policy – Characteristics of the inter-nodes link

Returns:

Pointer to new netzone

NetZone *simgrid::s4u::create_fatTree_zone(const std::string &name, const NetZone *parent, const FatTreeParams &parameters, const ClusterCallbacks &set_callbacks, double bandwidth, double latency, Link::SharingPolicy sharing_policy)

Create a Fat-Tree zone.

Fat-Tree clusters are characterized by:

  • levels: number of levels in the cluster, e.g. 2 (the final tree will have n+1 levels)

  • downlinks: for each level, how many connections between elements below them, e.g. 2, 3: level 1 nodes are connected to 2 nodes in level 2, which are connected to 3 nodes below. Determines the number total of leaves in the tree.

  • uplinks: for each level, how nodes are connected, e.g. 1, 2

  • link count: for each level, number of links connecting the nodes, e.g. 1, 1

The best way to understand it is looking to the doc available in: Fat Tree Cluster

Moreover, this method accepts 3 callbacks to populate the cluster: set_netpoint, set_loopback and set_limiter .

Note that the all elements in a Fat-Tree cluster must have (or not) the same elements (loopback and limiter)

Parameters:
  • name – NetZone’s name

  • parent – Pointer to parent’s netzone (nullptr if root netzone). Needed to be able to create the resources inside the netzone

  • parameters – Characteristics of this Fat-Tree

  • set_callbacks – Callbacks to set properties from cluster elements (netpoint, loopback and limiter)

  • bandwidth – Characteristics of the inter-nodes link

  • latency – Characteristics of the inter-nodes link

  • sharing_policy – Characteristics of the inter-nodes link

Returns:

Pointer to new netzone

NetZone *simgrid::s4u::create_dragonfly_zone(const std::string &name, const NetZone *parent, const DragonflyParams &parameters, const ClusterCallbacks &set_callbacks, double bandwidth, double latency, Link::SharingPolicy sharing_policy)

Create a Dragonfly zone.

Dragonfly clusters are characterized by:

  • groups: number of groups and links between each group, e.g. 2,2.

  • chassis: number of chassis in each group and the number of links used to connect the chassis, e.g. 2,3

  • routers: number of routers in each chassis and their links, e.g. 3,1

  • nodes: number of nodes connected to each router using a single link, e.g. 2

In total, the cluster will have groups * chassis * routers * nodes elements/leaves.

The best way to understand it is looking to the doc available in: Dragonfly Cluster

Moreover, this method accepts 3 callbacks to populate the cluster: set_netpoint, set_loopback and set_limiter .

Note that the all elements in a Dragonfly cluster must have (or not) the same elements (loopback and limiter)

Parameters:
  • name – NetZone’s name

  • parent – Pointer to parent’s netzone (nullptr if root netzone). Needed to be able to create the resources inside the netzone

  • parameters – Characteristics of this Dragonfly

  • set_callbacks – Callbacks to set properties from cluster elements (netpoint, loopback and limiter)

  • bandwidth – Characteristics of the inter-nodes link

  • latency – Characteristics of the inter-nodes link

  • sharing_policy – Characteristics of the inter-nodes link

Returns:

Pointer to new netzone

Hosts
s4u::Host *simgrid::s4u::NetZone::create_host(const std::string &name, const std::vector<double> &speed_per_pstate)

Create a host.

Parameters:
  • name – Host name

  • speed_per_pstate – Vector of CPU’s speeds

s4u::Host *simgrid::s4u::NetZone::create_host(const std::string &name, double speed)
s4u::Host *simgrid::s4u::NetZone::create_host(const std::string &name, const std::vector<std::string> &speed_per_pstate)

Create a Host (string version)

Throws:

std::invalid_argument – if speed format is incorrect.

s4u::Host *simgrid::s4u::NetZone::create_host(const std::string &name, const std::string &speed)
s4u::Host *simgrid::s4u::NetZone::create_host(const std::string &name, const std::string &speed)
s4u::Host *simgrid::s4u::NetZone::create_host(const std::string &name, const std::vector<double> &speed_per_pstate)

Create a host.

Parameters:
  • name – Host name

  • speed_per_pstate – Vector of CPU’s speeds

s4u::Host *simgrid::s4u::NetZone::create_host(const std::string &name, const std::vector<std::string> &speed_per_pstate)

Create a Host (string version)

Throws:

std::invalid_argument – if speed format is incorrect.

s4u::Host *simgrid::s4u::NetZone::create_host(const std::string &name, double speed)
Router
kernel::routing::NetPoint *simgrid::s4u::NetZone::create_router(const std::string &name)

Make a router within that NetZone.

Parameters:

name – Router name

⁣  class VirtualMachine

class VirtualMachine : public simgrid::s4u::Host

A VM represents a virtual machine (or a container) that hosts actors. The total computing power that the contained actors can get is constrained to the virtual machine size.

Basic management

#include <simgrid/s4u/VirtualMachine.hpp>

Note that there is no VirtualMachinePtr type, and that you cannot use the RAII idiom on virtual machines. There is no good reason for that and should change in the future.

Creating VMs

VirtualMachine *simgrid::s4u::Host::create_vm(const std::string &name, int core_amount)
VirtualMachine *simgrid::s4u::Host::create_vm(const std::string &name, int core_amount, size_t ramsize)
virtual void simgrid::s4u::VirtualMachine::destroy() override

Fire the required callbacks and destroy the object.

Don’t delete directly a host, call h->destroy() instead.

This is cumbersome but this is the simplest solution to ensure that the on_destruction() callback receives a valid object (because of the destructor order in a class hierarchy).

Querying info

Host *simgrid::s4u::VirtualMachine::get_pm() const
size_t simgrid::s4u::VirtualMachine::get_ramsize() const
State simgrid::s4u::VirtualMachine::get_state() const
VirtualMachine *simgrid::s4u::VirtualMachine::set_bound(double bound)
VirtualMachine *simgrid::s4u::VirtualMachine::set_pm(Host *pm)
VirtualMachine *simgrid::s4u::VirtualMachine::set_ramsize(size_t ramsize)

Life cycle

void simgrid::s4u::VirtualMachine::resume()
void simgrid::s4u::VirtualMachine::shutdown()
void simgrid::s4u::VirtualMachine::start()
void simgrid::s4u::VirtualMachine::suspend()

Signals

static inline void simgrid::s4u::VirtualMachine::on_creation_cb(const std::function<void(VirtualMachine&)> &cb)

Add a callback fired when any VM is created

static inline void simgrid::s4u::VirtualMachine::on_destruction_cb(const std::function<void(VirtualMachine const&)> &cb)

Add a callback fired when any VM is destroyed

inline void simgrid::s4u::VirtualMachine::on_this_destruction_cb(const std::function<void(VirtualMachine const&)> &cb)

Add a callback fired when this specific VM is destroyed

static inline void simgrid::s4u::VirtualMachine::on_migration_end_cb(const std::function<void(VirtualMachine const&)> &cb)

Add a callback fired when any VM ends a migration

inline void simgrid::s4u::VirtualMachine::on_this_migration_end_cb(const std::function<void(VirtualMachine const&)> &cb)

Add a callback fired when this specific VM ends a migration

static inline void simgrid