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.

Currently (v3.21), S4U is definitely the way to go for long-term projects. It is feature complete, but may still evolve slightly in the future releases. It can already be used to do everything that can be done in SimGrid, but you may have to adapt your code 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. If you want an API that will never ever evolve in the future, you should use the deprecated MSG API instead.

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 Storages. 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 rendez-vous 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 itself 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 simgrid::s4u::this_actor namespace provides many helper functions to simplify the code of actors.

S4U Examples

SimGrid comes with an extensive set of examples, documented on this page. Most of them only demonstrate one single feature, with some larger examplars listed below.

Each of these examples can be found in a subdirectory under examples/s4u in the archive. It contains the source code (also listed from this page), and the so-called tesh file containing how to call the binary obtained by compiling this example and also the expected output. Tesh files are used to turn each of our examples into an integration test. Some examples also contain other files, on need.

A good way to bootstrap your own project is to copy and combine some of the provided examples to constitute the skeleton of what you plan to simulate.

Actors: the Active Entities

Starting and Stoping Actors

Inter-Actors Interactions

Traces Replay as a Workload

This section details how to run trace-driven simulations. It is very handy when you want to test an algorithm or protocol that only react to external events. For example, many P2P protocols react to user requests, but do nothing if there is no such event.

In such situations, you should write your protocol in C++, and separate the workload that you want to play onto your protocol in a separate text file. Declare a function handling each type of the events in your trace, register them using xbt_replay_action_register() in your main, and then run the simulation.

Then, you can either have one trace file containing all your events, or a file per simulated process: the former may be easier to work with, but the second is more efficient on very large traces. Check also the tesh files in the example directories for details.

Activities: what Actors do

Communications on the Network

Todo

add the ready example here

Executions on the CPU

I/O on Disks and Files

SimGrid provides two levels of abstraction to interact with the simulated storages. At the simplest level, you simply create read and write actions on the storage resources.

The FileSystem plugin provides a more detailed view, with the classical operations over files: open, move, unlink, and of course read and write. The file and disk sizes are also dealt with and can result in short reads and short write, as in reality.

Classical synchronization objects

Interacting with the Platform

Energy Simulation

Tracing and Visualizing

Tracing can be activated by various configuration options which are illustrated in these example. See also the full list of options related to tracing.

It is interesting to run the process-create example with the following options to see the task executions:

  • Platform Tracing: This program is a toy example just loading the platform, so that you can play with the platform visualization. Recommanded options: --cfg=tracing:yes --cfg=tracing/categorized:yes
    examples/s4u/trace-platform/s4u-trace-platform.cpp

Larger SimGrid Examplars

This section contains application examples that are somewhat larger than the previous examples.

Data diffusion

Distributed Hash Tables (DHT)

Todo

document here the examples about plugins

Activities

Activities represent the actions that consume a resource, such as a s4u::Comm that consumes the transmiting power of s4u::Link resources.

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 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().

Todo

wait_for and wait_until are currently not implemented for Exec and Io activities.

Every kind of activities can be asynchronous:

The following example shows how to have several concurrent communications ongoing. First, you have to declare a vector in which we will store the ongoing communications. It is also useful to have a vector of mailboxes.

/* Vector in which we store all ongoing communications */
std::vector<simgrid::s4u::CommPtr> pending_comms;

/* Make a vector of the mailboxes to use */
std::vector<simgrid::s4u::MailboxPtr> mboxes;
for (int i = 0; i < receivers_count; i++)
  mboxes.push_back(simgrid::s4u::Mailbox::by_name(std::string("receiver-") + std::to_string(i)));

Then, you start all the communications that should occur concurrently with s4u::Mailbox::put_async(). Finally, the actor waits for the completion of all of them at once with s4u::Comm::wait_all().

for (int i = 0; i < receivers_count; i++) {
  XBT_INFO("Send 'finalize' to 'receiver-%d'", i);
  simgrid::s4u::CommPtr comm = mboxes[i]->put_async(new std::string("finalize"), 0);
  pending_comms.push_back(comm);
}
XBT_INFO("Done dispatching all messages");

/* Now that all message exchanges were initiated, wait for their completion in one single call */
simgrid::s4u::Comm::wait_all(&pending_comms);

Activities Life cycle

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

Todo

write this section

Memory Management

For sake of simplicity, we use RAII everywhere 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 explicitely 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

API Reference

s4u::Activity

class Activity

Activities.

This class is the ancestor of every activities that an actor can undertake. That is, activities are all the things that do take time to the actor in the simulated world.

They are somewhat linked but not identical to simgrid::kernel::resource::Action, that are stuff occurring on a resource:

  • A sequential execution activity encompasses 2 actions: one for the exec itself, and a time-limited sleep used as timeout detector.
  • A point-to-point communication activity encompasses 3 actions: one for the comm itself (which spans on all links of the path), and one infinite sleep used as failure detector on both sender and receiver hosts.
  • Synchronization activities may possibly be connected to no action.

Subclassed by simgrid::s4u::Comm, simgrid::s4u::Exec, simgrid::s4u::Io

Public Types

enum State

Values:

INITED = 0
STARTED
CANCELED
ERRORED
FINISHED

Public Functions

virtual Activity *start() = 0

Starts a previously created activity.

This function is optional: you can call wait() even if you didn’t call start()

virtual Activity *wait() = 0

Tests whether the given activity is terminated yet. This is a pure function. Blocks until the activity is terminated

virtual Activity *wait_for(double timeout) = 0

Blocks until the activity is terminated, or until the timeout is elapsed Raises: timeout exception.

void wait_until(double time_limit)

Blocks until the activity is terminated, or until the time limit is reached Raises: timeout exception.

virtual Activity *cancel() = 0

Cancel that activity

Activity::State get_state()

Retrieve the current state of the activity

virtual bool test() = 0

Returns whether this activity is completed

virtual double get_remaining()

Get the remaining amount of work that this Activity entails. When it’s 0, it’s done.

Activity *set_remaining(double remains)

Set the [remaining] amount of work that this Activity will entail

It is forbidden to change the amount of work once the Activity is started

Activity *set_user_data(void *data)

Put some user data onto the Activity

void *get_user_data()

Retrieve the user data of the Activity

Protected Functions

Activity()
virtual ~Activity()

s4u::Actor

typedef boost::intrusive_ptr<Actor> simgrid::s4u::ActorPtr

Smart pointer to a simgrid::s4u::Actor

class Actor : public simgrid::xbt::Extendable<Actor>

Simulation Agent.

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

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.

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

The s4u::Actor API is strongly inspired from the C++11 threads. The documentation of this standard may help to understand the philosophy of the S4U Actors.

Public Functions

Actor(Actor const&)
Actor &operator=(Actor const&)
void daemonize()

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

bool is_daemon() const

Returns whether or not this actor has been daemonized or not

const simgrid::xbt::string &get_name() const

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

const char *get_cname() const

Retrieves the name of that actor as a C string

s4u::Host *get_host()

Retrieves the host on which that actor is running

aid_t get_pid() const

Retrieves the PID of that actor

aid_t is an alias for long

aid_t get_ppid() const

Retrieves the PPID of that actor

aid_t is an alias for long

void suspend()

Suspend an actor by suspending the task on which it was waiting for the completion.

void resume()

Resume a suspended actor by resuming the task on which it was waiting for the completion.

void yield()
bool is_suspended()

Returns true if the actor is suspended.

void set_auto_restart(bool autorestart)

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

void on_exit(std::function<void(int, void *)> fun, void *data, )

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.

void set_kill_time(double time)

Sets the time at which that actor should be killed

double get_kill_time()

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

void migrate(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).

void 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.

SimGrid still have sometimes issues when you kill actors that are currently communicating and such. Still. Please report any bug that you may encounter with a minimal working example.

void join()

Wait for the actor to finish.

This blocks the calling actor until the actor on which we call join() is terminated

void join(double timeout)
Actor *restart()
kernel::actor::ActorImpl *get_impl()

Returns the internal implementation of this actor

std::unordered_map<std::string, std::string> *get_properties()

Retrieve the property value (or nullptr if not set)

const char *get_property(std::string key)
void set_property(std::string key, std::string value)

Public Static Functions

static ActorPtr self()

Retrieve a reference to myself

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

Create an actor from a std::function<void()>

If the actor is restarted, the actor has a fresh copy of the function.

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

Create an actor from a std::function

If the actor is restarted, the actor has a fresh copy of the function.

template <class F, class... Args, typename = typename std::result_of<F(Args...)>::type>
static ActorPtr create(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

static ActorPtr create(std::string name, s4u::Host *host, std::string function, std::vector<std::string> args)
static void kill(aid_t pid)

Kill an actor from its ID

static ActorPtr by_pid(aid_t pid)

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

static void kill_all()

Ask kindly to all actors to die. Only the issuer will survive.

Public Static Attributes

simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_creation

Signal to others that a new actor has been created

simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_suspend

Signal to others that an actor has been suspended

simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_resume

Signal to others that an actor has been resumed

simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_sleep

Signal to others that an actor is sleeping

simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_wake_up

Signal to others that an actor wakes up for a sleep

simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_migration_start

Signal to others that an actor is going to migrated to another host

simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_migration_end

Signal to others that an actor is has been migrated to another host

simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_destruction

Signal indicating that an actor is about to disappear. This signal is fired for any dying actor, which is mostly useful when designing plugins and extensions. If you want to register to the termination of a given actor, use this_actor::on_exit() instead.

Friends

void intrusive_ptr_add_ref(Actor *actor)
void intrusive_ptr_release(Actor *actor)

s4u::Barrier

typedef boost::intrusive_ptr<Barrier> simgrid::s4u::BarrierPtr

Smart pointer to a simgrid::s4u::Barrier

class Barrier

Public Functions

Barrier(unsigned int count)
~Barrier()
Barrier(Barrier const&)
Barrier &operator=(Barrier const&)
int wait()

Public Static Functions

static BarrierPtr create(unsigned int expected_processes)

Constructs a new barrier

Friends

void intrusive_ptr_add_ref(Barrier *barrier)
void intrusive_ptr_release(Barrier *barrier)

s4u::Comm

typedef boost::intrusive_ptr<Comm> simgrid::s4u::CommPtr

Smart pointer to a simgrid::s4u::Comm

class Comm : public simgrid::s4u::Activity

Communication async.

Represents all asynchronous communications, that you can test or wait onto.

Public Functions

virtual ~Comm()
Comm *start()

Starts a previously created activity.

This function is optional: you can call wait() even if you didn’t call start()

Comm *wait()

Tests whether the given activity is terminated yet. This is a pure function. Blocks until the activity is terminated

Comm *wait_for(double timeout)

Blocks until the activity is terminated, or until the timeout is elapsed Raises: timeout exception.

bool test()

Returns whether this activity is completed

Comm *detach()

Start the comm, and ignore its result. It can be completely forgotten after that.

Comm *detach(void (*clean_function)(void *))

Start the comm, and ignore its result. It can be completely forgotten after that.

Comm *set_rate(double rate)

Sets the maximal communication rate (in byte/sec). Must be done before start

Comm *set_src_data(void *buff)

Specify the data to send.

This is way will get actually copied over to the receiver. That’s completely unrelated from the simulated size (given with Activity::set_remaining()): you can send a short buffer in your simulator, that represents a very large message in the simulated world, or the opposite.

Comm *set_src_data_size(size_t size)

Specify the size of the data to send. Not to be mixed with Activity::set_remaining()

That’s the size of the data to actually copy in the simulator (ie, the data passed with Activity::set_src_data()). That’s completely unrelated from the simulated size (given with Activity::set_remaining()): you can send a short buffer in your simulator, that represents a very large message in the simulated world, or the opposite.

Comm *set_src_data(void *buff, size_t size)

Specify the data to send and its size. Don’t mix the size with Activity::set_remaining()

This is way will get actually copied over to the receiver. That’s completely unrelated from the simulated size (given with Activity::set_remaining()): you can send a short buffer in your simulator, that represents a very large message in the simulated world, or the opposite.

Comm *set_dst_data(void **buff)

Specify where to receive the data.

That’s a buffer where the sent data will be copied

Comm *set_dst_data(void **buff, size_t size)

Specify the buffer in which the data should be received

That’s a buffer where the sent data will be copied

size_t get_dst_data_size()

Retrieve the size of the received data. Not to be mixed with Activity::set_remaining()

Comm *cancel()

Cancel that activity

MailboxPtr get_mailbox()

Retrieve the mailbox on which this comm acts

Public Static Functions

static int wait_any(std::vector<CommPtr> *comms)

take a vector s4u::CommPtr and return when one of them is finished. The return value is the rank of the first finished CommPtr.

static int wait_any_for(std::vector<CommPtr> *comms_in, double timeout)

Same as wait_any, but with a timeout. If the timeout occurs, parameter last is returned.

static void wait_all(std::vector<CommPtr> *comms)

take a vector s4u::CommPtr and return when all of them is finished.

static int test_any(std::vector<CommPtr> *comms)

take a vector s4u::CommPtr and return the rank of the first finished one (or -1 if none is done).

Public Static Attributes

simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_sender_start
simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_receiver_start
simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_completion

Friends

void intrusive_ptr_release(simgrid::s4u::Comm *c)
void intrusive_ptr_add_ref(simgrid::s4u::Comm *c)

s4u::ConditionVariable

typedef boost::intrusive_ptr<ConditionVariable> simgrid::s4u::ConditionVariablePtr

Smart pointer to a simgrid::s4u::ConditionVariable

class ConditionVariable

A condition variable

This is a drop-in replacement of std::condition_variable and should respect the same semantic. But we currently use (only) double for both durations and timestamp timeouts.

Public Functions

ConditionVariable(ConditionVariable const&)
ConditionVariable &operator=(ConditionVariable const&)
ConditionVariablePtr createConditionVariable()

void wait(MutexPtr lock)
void wait(std::unique_lock<Mutex> &lock)
template <class P>
void wait(std::unique_lock<Mutex> &lock, P pred)
std::cv_status wait_until(std::unique_lock<Mutex> &lock, double timeout_time)
std::cv_status wait_for(std::unique_lock<Mutex> &lock, double duration)
template <class P>
bool wait_until(std::unique_lock<Mutex> &lock, double timeout_time, P pred)
template <class P>
bool wait_for(std::unique_lock<Mutex> &lock, double duration, P pred)
template <class Rep, class Period, class P>
bool wait_for(std::unique_lock<Mutex> &lock, std::chrono::duration<Rep, Period> duration, P pred)
template <class Rep, class Period>
std::cv_status wait_for(std::unique_lock<Mutex> &lock, std::chrono::duration<Rep, Period> duration)
template <class Duration>
std::cv_status wait_until(std::unique_lock<Mutex> &lock, const SimulationTimePoint<Duration> &timeout_time)
template <class Duration, class P>
bool wait_until(std::unique_lock<Mutex> &lock, const SimulationTimePoint<Duration> &timeout_time, P pred)
void notify_one()
void notify_all()

Public Static Functions

static ConditionVariablePtr create()

Friends

void intrusive_ptr_add_ref(ConditionVariable *cond)
void intrusive_ptr_release(ConditionVariable *cond)

s4u::Engine

class Engine

Simulation engine.

This class is an interface to the simulation engine.

Public Functions

Engine(int *argc, char **argv)

Constructor, taking the command line parameters of your main function

Engine(const Engine&)

Currently, only one instance is allowed to exist. This is why you can’t copy or move it

Engine(Engine&&)
~Engine()
void run()

Run the simulation.

void load_platform(std::string platf)

Load a platform file describing the environment.

The environment is either a XML file following the simgrid.dtd formalism, or a lua file. Some examples can be found in the directory examples/platforms.

void register_function(std::string name, int (*code)(int, char **))

Registers the main function of an actor that will be launched from the deployment file

void register_function(std::string name, void (*code)(std::vector<std::string>))

Registers the main function of an actor that will be launched from the deployment file

void register_default(int (*code)(int, char **))

Registers a function as the default main function of actors

It will be used as fallback when the function requested from the deployment file was not registered. It is used for trace-based simulations (see examples/s4u/replay-comms and similar).

template <class F>
void register_actor(std::string name)
template <class F>
void register_actor(std::string name, F code)
void load_deployment(std::string deploy)

Load a deployment file and launch the actors that it contains.

size_t get_host_count()
std::vector<Host *> get_all_hosts()

Returns the list of all hosts found in the platform.

std::vector<Host *> get_filtered_hosts(std::function<bool(Host *)> filter)
simgrid::s4u::Host *host_by_name(std::string name)
simgrid::s4u::Host *host_by_name_or_null(std::string name)
std::vector<Link *> get_all_links()
std::vector<Link *> get_filtered_links(std::function<bool(Link *)> filter)
size_t get_actor_count()
std::vector<ActorPtr> get_all_actors()
std::vector<ActorPtr> get_filtered_actors(std::function<bool(ActorPtr)> filter)
size_t get_storage_count()
std::vector<Storage *> get_all_storages()
simgrid::s4u::Storage *storage_by_name(std::string name)
simgrid::s4u::Storage *storage_by_name_or_null(std::string name)
std::vector<simgrid::kernel::routing::NetPoint *> get_all_netpoints()
simgrid::kernel::routing::NetPoint *netpoint_by_name_or_null(std::string name)
simgrid::s4u::NetZone *get_netzone_root()
void set_netzone_root(s4u::NetZone *netzone)
simgrid::s4u::NetZone *netzone_by_name_or_null(std::string name)
template <class T>
std::vector<T *> get_filtered_netzones()

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

void set_config(std::string str)

set a configuration variable

Do help on any simgrid binary to see the list of currently existing configuration variables (see also options).

Example: e->set_config(“host/model:ptask_L07”);

void loadPlatform(std::string platf)

void registerFunction(std::string name, int (*code)(int, char **))

void registerDefault(int (*code)(int, char **))

template <class F>
void registerFunction(std::string name)

template <class F>
void registerFunction(std::string name, F code)

void loadDeployment(std::string deploy)

simgrid::s4u::Host *hostByName(std::string name)

simgrid::s4u::Host *hostByNameOrNull(std::string name)

simgrid::s4u::Storage *storageByName(std::string name)

simgrid::s4u::Storage *storageByNameOrNull(std::string name)

size_t getHostCount()

void getHostList(std::vector<Host *> *whereTo)

std::vector<Host *> getAllHosts()

size_t getLinkCount()

void getLinkList(std::vector<Link *> *list)

std::vector<Link *> getAllLinks()

std::vector<Storage *> getAllStorages()

void getNetpointList(std::vector<simgrid::kernel::routing::NetPoint *> *list)

simgrid::kernel::routing::NetPoint *getNetpointByNameOrNull(std::string name)

simgrid::s4u::NetZone *getNetRoot()

simgrid::s4u::NetZone *getNetzoneByNameOrNull(std::string name)

template <class T>
void getNetzoneByType(std::vector<T *> *whereto)

void setConfig(std::string str)

Public Static Functions

static void shutdown()

Finalize the default engine and all its dependencies

static double get_clock()

Retrieve the simulation time.

static s4u::Engine *get_instance()

Retrieve the engine singleton.

static bool is_initialized()

Returns whether SimGrid was initialized yet mostly for internal use

static double getClock()

static s4u::Engine *getInstance()

static bool isInitialized()

s4u::Exec

typedef boost::intrusive_ptr<Exec> simgrid::s4u::ExecPtr

Smart pointer to a simgrid::s4u::Exec

class Exec : public simgrid::s4u::Activity

Computation #Activity, representing the asynchronous disk access.

They are generated from simgrid::s4u::this_actor::exec_init() or simgrid::s4u::Host::execute().

Public Functions

~Exec()
Exec *start()

Starts a previously created activity.

This function is optional: you can call wait() even if you didn’t call start()

Exec *wait()

Tests whether the given activity is terminated yet. This is a pure function. Blocks until the activity is terminated

Exec *wait_for(double timeout)

Blocks until the activity is terminated, or until the timeout is elapsed Raises: timeout exception.

Exec *cancel()

Cancel that activity

bool test()

Returns whether this activity is completed

ExecPtr set_priority(double priority)
ExecPtr set_bound(double bound)
ExecPtr set_host(Host *host)
ExecPtr set_name(std::string name)
ExecPtr set_tracing_category(std::string category)
Host *get_host()
double get_remaining()

Get the remaining amount of work that this Activity entails. When it’s 0, it’s done.

double get_remaining_ratio()

Public Static Attributes

simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_start
simgrid::xbt::signal<void(simgrid::s4u::ActorPtr)> on_completion

Friends

void intrusive_ptr_release(simgrid::s4u::Exec *e)
void intrusive_ptr_add_ref(simgrid::s4u::Exec *e)
ExecPtr exec_init(double flops_amount)

s4u::Host

class Host : public simgrid::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

Public Functions

Host(std::string name)
virtual void destroy()
Host(Host const&)
Host &operator=(Host const&)
simgrid::xbt::string const &get_name() const

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

const char *get_cname() const

Retrieves the name of that host as a C string

int get_actor_count()
std::vector<ActorPtr> get_all_actors()
void turn_on()

Turns that host on if it was previously off

All actors on that host which were marked autorestart will be restarted automatically. This call does nothing if the host is already on.

void turn_off()

Turns that host off. All actors are forcefully stopped.

bool is_on() const

Returns if that host is currently up and running

bool is_off() const

Returns if that host is currently down and offline

const char *get_property(std::string key) const
void set_property(std::string key, std::string value)
std::unordered_map<std::string, std::string> *get_properties()
double get_speed() const
double get_available_speed() const
int get_core_count() const
double get_load() const
double get_pstate_speed(int pstate_index) const
int get_pstate_count() const
void set_pstate(int pstate_index)
int get_pstate() const
std::vector<const char *> get_attached_storages() const
void getAttachedStorages(std::vector<const char *> *storages)
std::unordered_map<std::string, Storage *> const &get_mounted_storages()

Get an associative list [mount point]->[Storage] of all local mount points.

This is defined in the platform file, and cannot be modified programatically (yet).

std::unordered_map<std::string, Storage *> const &getMountedStorages()

void route_to(Host *dest, std::vector<Link *> &links, double *latency)
void route_to(Host *dest, std::vector<kernel::resource::LinkImpl *> &links, double *latency)
void execute(double flops)

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.

ExecPtr exec_async(double flops_amounts)

Start an asynchronous computation on that host (possibly remote)

void execute(double flops, double priority)

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

Public Members

surf::Cpu *pimpl_cpu = nullptr

DO NOT USE DIRECTLY (

surf::HostImpl *pimpl_ = nullptr
kernel::routing::NetPoint *pimpl_netpoint = nullptr

DO NOT USE DIRECTLY (

Public Static Functions

static Host *by_name_or_null(std::string name)

Retrieves an host from its name, or return nullptr

static s4u::Host *by_name(std::string name)

Retrieves an host from its name, or die

static s4u::Host *current()

Retrieves the host on which the current actor is running

Public Static Attributes

simgrid::xbt::signal<void(Host&)> on_creation
simgrid::xbt::signal<void(Host&)> on_destruction
simgrid::xbt::signal<void(Host&)> on_state_change
simgrid::xbt::signal<void(Host&)> on_speed_change

Protected Functions

virtual ~Host()

Host destruction logic

s4u::Io

typedef boost::intrusive_ptr<Io> simgrid::s4u::IoPtr

Smart pointer to a simgrid::s4u::Io

class Io : public simgrid::s4u::Activity

I/O Activity, representing the asynchronous disk access.

They are generated from simgrid::s4u::Storage::read() and simgrid::s4u::Storage::write().

Public Types

enum OpType

Values:

READ
WRITE

Public Functions

~Io()
Io *start()

Starts a previously created activity.

This function is optional: you can call wait() even if you didn’t call start()

Io *wait()

Tests whether the given activity is terminated yet. This is a pure function. Blocks until the activity is terminated

Io *wait_for(double timeout)

Blocks until the activity is terminated, or until the timeout is elapsed Raises: timeout exception.

Io *cancel()

Cancel that activity

bool test()

Returns whether this activity is completed

double get_remaining()

Get the remaining amount of work that this Activity entails. When it’s 0, it’s done.

sg_size_t get_performed_ioops()

Friends

void intrusive_ptr_release(simgrid::s4u::Io *i)
void intrusive_ptr_add_ref(simgrid::s4u::Io *i)

s4u::Mailbox

typedef boost::intrusive_ptr<Mailbox> simgrid::s4u::MailboxPtr

Smart pointer to a simgrid::s4u::Mailbox

class Mailbox

Mailboxes: Network rendez-vous points.

What are mailboxes?

Rendez-vous point 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.

Here are some mechanisms similar to the mailbox in other communication systems: The phone number, which allows the caller to find the receiver. The twitter hashtag, which help senders and receivers to find each others. In TCP, the pair {host name, host port} to which you can connect to find your interlocutor. In HTTP, URLs through which the clients can connect to the servers. In ZeroMQ and other queuing systems, 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. This is a big difference to the socket ports for example, that are definitely exclusive in receiving.

Mailboxes can optionally have a receiver with simgrid::s4u::Mailbox::set_receiver(). It means that the data exchange starts as soon as the sender has done the put(), even before the corresponding get() (usually, it starts as soon as both put() and get() are posted). This is closer to the BSD semantic and can thus help to improve the timing accuracy, but this is not mandatory at all.

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 coming 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 Comm::wait_any() to get the first message on any of the mailbox you are subscribed onto.

The mailboxes are not located on the network, and you can access them without any latency. The network delay 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?

Any existing mailbox can be retrieve from its name (which are unique strings, just like with twitter tags). This results in a versatile mechanism that can be used to build many different situations.

For something close to classical socket communications, use “hostname:port” as mailbox names, and make sure that only one actor reads into that mailbox. It’s hard to build a perfectly realistic model of the TCP sockets, but most of the time, this system is too cumbersome for your simulations anyway. You probably want something simpler, that turns our 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 relevant actor that can deal with the request will handle it.

How are sends and receives matched?

The matching algorithm is as simple as a 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 declared while in real systems (such as TCP or MPI), the data starts to flow as soon as the sender posts it, even if the receiver did not post its recv() yet. This can obviously lead to bad simulation timings, as the simulated communications do not start at the exact same time than the real ones.

If the simulation timings are very important to you, you can declare a specific receiver to a given mailbox (with the function setReceiver()). That way, any send() 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 receive().

The API

Public Functions

kernel::activity::MailboxImpl *get_impl()

private function, do not use. FIXME: make me protected

const simgrid::xbt::string &get_name() const

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

const char *get_cname() const

Retrieves the name of that mailbox as a C string.

bool empty()

Returns whether the mailbox contains queued communications

bool listen()

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

bool ready()

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

smx_activity_t front()

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

void 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 he does a recv(). 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.

ActorPtr get_receiver()

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

CommPtr put_init()

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

CommPtr put_init(void *data, uint64_t simulated_size_in_bytes)

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

CommPtr put_async(void *data, uint64_t simulated_size_in_bytes)

Creates and start a data emission to that mailbox

void put(void *payload, uint64_t simulated_size_in_bytes)

Blocking data emission

void put(void *payload, uint64_t simulated_size_in_bytes, double timeout)

Blocking data emission with timeout

CommPtr get_init()

Creates (but don’t start) a data reception onto that mailbox

CommPtr get_async(void **data)

Creates and start an async data reception to that mailbox

void *get()

Blocking data reception

void *get(double timeout)

Blocking data reception with timeout

void setReceiver(ActorPtr actor)

ActorPtr getReceiver()

const simgrid::xbt::string &getName() const

const char *getCname() const

kernel::activity::MailboxImpl *getImpl()

Public Static Functions

static MailboxPtr by_name(std::string name)

Retrieve the mailbox associated to the given name

static MailboxPtr byName(const char *name)

static MailboxPtr byName(std::string name)

s4u::Mutex

typedef boost::intrusive_ptr<Mutex> simgrid::s4u::MutexPtr

Smart pointer to a simgrid::s4u::Mutex

class Mutex

A classical mutex, but blocking in the simulation world

It is strictly impossible to use a real mutex, such as std::mutex or pthread_mutex_t, because it would block the whole simulation. Instead, you should use the present class, that is a drop-in replacement of <a href=”http://en.cppreference.com/w/cpp/thread/mutex>std::mutex.

As for any S4U object, Mutexes are using the RAII idiom for memory management. Use create() to get a simgrid::s4u::MutexPtr to a newly created mutex and only manipulate simgrid::s4u::MutexPtr.

Public Functions

Mutex(Mutex const&)

You cannot create a new mutex by copying an existing one. Use MutexPtr instead

Mutex &operator=(Mutex const&)

You cannot create a new mutex by value assignment either. Use MutexPtr instead

void lock()
void unlock()
bool try_lock()

Public Static Functions

static MutexPtr create()

Constructs a new mutex

static MutexPtr createMutex()

s4u::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).

Public Functions

const std::string &get_name() const

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

const char *get_cname() const

Retrieves the name of that netzone as a C string.

NetZone *get_father()
std::vector<Host *> get_all_hosts()
int get_host_count()
kernel::routing::NetZoneImpl *get_impl()
std::unordered_map<std::string, std::string> *get_properties()

Get the properties assigned to a netzone

std::vector<NetZone *> get_children()
const char *get_property(std::string key)

Retrieve the property value (or nullptr if not set)

void set_property(std::string key, std::string value)
int add_component(kernel::routing::NetPoint *elm)
void add_route(kernel::routing::NetPoint *src, kernel::routing::NetPoint *dst, kernel::routing::NetPoint *gw_src, kernel::routing::NetPoint *gw_dst, std::vector<kernel::resource::LinkImpl *> &link_list, bool symmetrical)
void add_bypass_route(kernel::routing::NetPoint *src, kernel::routing::NetPoint *dst, kernel::routing::NetPoint *gw_src, kernel::routing::NetPoint *gw_dst, std::vector<kernel::resource::LinkImpl *> &link_list, bool symmetrical)
NetZone *getFather()

const std::string &getName() const

const char *getCname() const

void addRoute(kernel::routing::NetPoint *src, kernel::routing::NetPoint *dst, kernel::routing::NetPoint *gw_src, kernel::routing::NetPoint *gw_dst, std::vector<simgrid::kernel::resource::LinkImpl *> &link_list, bool symmetrical)

void addBypassRoute(kernel::routing::NetPoint *src, kernel::routing::NetPoint *dst, kernel::routing::NetPoint *gw_src, kernel::routing::NetPoint *gw_dst, std::vector<simgrid::kernel::resource::LinkImpl *> &link_list, bool symmetrical)

std::unordered_map<std::string, std::string> *getProperties()

const char *getProperty(const char *key)

void setProperty(const char *key, const char *value)

int addComponent(kernel::routing::NetPoint *elm)

std::vector<kernel::routing::NetPoint *> getVertices()

int getHostCount()

void getHosts(std::vector<s4u::Host *> *whereto)

std::vector<NetZone *> *getChildren()

Public Static Attributes

simgrid::xbt::signal<void(bool symmetrical, kernel::routing::NetPoint *src, kernel::routing::NetPoint *dst, kernel::routing::NetPoint *gw_src, kernel::routing::NetPoint *gw_dst, std::vector<kernel::resource::LinkImpl *> &link_list)> on_route_creation
simgrid::xbt::signal<void(NetZone&)> on_creation
simgrid::xbt::signal<void(NetZone&)> on_seal

Protected Functions

NetZone(kernel::routing::NetZoneImpl *impl)
~NetZone()

s4u::Semaphore

typedef boost::intrusive_ptr<Semaphore> simgrid::s4u::SemaphorePtr

Smart pointer to a simgrid::s4u::Semaphore

class Semaphore

A classical semaphore, but blocking in the simulation world

It is strictly impossible to use a real semaphore, such as sem_init, because it would block the whole simulation. Instead, you should use the present class, that offers a very similar interface.

As for any S4U object, Semaphores are using the RAII idiom for memory management. Use create() to get a simgrid::s4u::SemaphorePtr to a newly created semaphore and only manipulate simgrid::s4u::SemaphorePtr.

Public Functions

Semaphore(Semaphore const&)

You cannot create a new semaphore by copying an existing one. Use SemaphorePtr instead

Semaphore &operator=(Semaphore const&)

You cannot create a new semaphore by value assignment either. Use SemaphorePtr instead

void acquire()
void release()

Public Static Functions

static SemaphorePtr create(unsigned int initial_capacity)

Constructs a new semaphore

s4u::Storage

class Storage : public simgrid::xbt::Extendable<Storage>

Storage represent the disk resources, usually associated to a given 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.

Public Functions

Storage(std::string name, surf::StorageImpl *pimpl)
std::string const &get_name() const

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

const char *get_cname() const

Retrieves the name of that storage as a C string.

const char *get_type()
Host *get_host()
void set_host(Host *host)
std::unordered_map<std::string, std::string> *get_properties()
const char *get_property(std::string key)
void set_property(std::string, std::string value)
void set_data(void *data)
void *get_data()
IoPtr io_init(sg_size_t size, s4u::Io::OpType type)
IoPtr read_async(sg_size_t size)
sg_size_t read(sg_size_t size)
IoPtr write_async(sg_size_t size)
sg_size_t write(sg_size_t size)
surf::StorageImpl *get_impl()
Storage *byName(std::string name)

std::string const &getName() const

const char *getCname() const

const char *getType()

Host *getHost()

std::map<std::string, std::string> *getProperties()

const char *getProperty(const char *key)

void setProperty(std::string key, std::string value)

void setUserdata(void *data)

void *getUserdata()

Public Static Functions

static Storage *by_name(std::string name)

Retrieve a Storage by its name. It must exist in the platform file

static Storage *by_name_or_null(std::string name)

Public Static Attributes

simgrid::xbt::signal<void(s4u::Storage&)> on_creation

Callback signal fired when a new Storage is created.

simgrid::xbt::signal<void(s4u::Storage&)> on_destruction

Callback signal fired when a Storage is destroyed.

simgrid::xbt::signal<void(s4u::Storage&)> on_state_change

Callback signal fired when a Storage’s state changes.

Protected Functions

virtual ~Storage()

s4u::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.

Public Types

enum state

Values:

CREATED

created, but not yet started

RUNNING
SUSPENDED

Suspend/resume does not involve disk I/O, so we assume there is no transition states.

DESTROYED

Public Functions

VirtualMachine(std::string name, s4u::Host *physical_host, int core_amount)
VirtualMachine(std::string name, s4u::Host *physical_host, int core_amount, size_t ramsize)
VirtualMachine(VirtualMachine const&)
VirtualMachine &operator=(VirtualMachine const&)
simgrid::vm::VirtualMachineImpl *get_impl()
void start()
void suspend()
void resume()
void shutdown()
void destroy()
simgrid::s4u::Host *get_pm()
void set_pm(simgrid::s4u::Host *pm)
size_t get_ramsize()
void set_ramsize(size_t ramsize)
void set_bound(double bound)
VirtualMachine::state get_state()
VirtualMachine::state getState()

simgrid::vm::VirtualMachineImpl *getImpl()

simgrid::s4u::Host *getPm()

void setPm(simgrid::s4u::Host *pm)

size_t getRamsize()

void setRamsize(size_t ramsize)

void setBound(double bound)

Public Static Attributes

simgrid::xbt::signal<void(VirtualMachine&)> on_start
simgrid::xbt::signal<void(VirtualMachine&)> on_started
simgrid::xbt::signal<void(VirtualMachine&)> on_shutdown
simgrid::xbt::signal<void(VirtualMachine&)> on_suspend
simgrid::xbt::signal<void(VirtualMachine&)> on_resume
simgrid::xbt::signal<void(VirtualMachine&)> on_migration_start
simgrid::xbt::signal<void(VirtualMachine&)> on_migration_end

namespace s4u::this_actor

namespace this_actor

Static methods working on the current actor (see s4u::Actor)

Functions

bool is_maestro()
void sleep_for(double duration)

Block the actor sleeping for that amount of seconds (may throws hostFailure)

void sleep_until(double timeout)
template <class Rep, class Period>
void sleep_for(std::chrono::duration<Rep, Period> duration)
template <class Duration>
void sleep_until(const SimulationTimePoint<Duration> &timeout_time)
void execute(double flop)

Block the actor, computing the given amount of flops

void execute(double flop, double priority)

Block the 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 parallel_execute(int host_nb, sg_host_t *host_list, double *flops_amount, double *bytes_amount)
void parallel_execute(int host_nb, sg_host_t *host_list, double *flops_amount, double *bytes_amount, double timeout)
ExecPtr exec_init(double flops_amounts)
ExecPtr exec_async(double flops_amounts)
aid_t get_pid()

Returns the actor ID of the current actor).

aid_t get_ppid()

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

std::string get_name()

Returns the name of the current actor.

const char *get_cname()

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

Host *get_host()

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

void suspend()

Suspend the actor.

void yield()

yield the actor.

void resume()

Resume the actor.

bool is_suspended()
void exit()

kill the actor.

void on_exit(std::function<void(int, void *)> fun, void *data, )

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

void migrate(Host *new_host)

Migrate the actor to a new host.