XBT_ATTRIB_DEPRECATED_v322(m)= \
XBT_ATTRIB_DEPRECATED_v323(m)= \
XBT_ATTRIB_DEPRECATED_v324(m)=
- """
+
+ """
}
# For cross-ref generation
:maxdepth: 1
:caption: Basic Use Cases:
- Simulating Algorithms <usecase_algorithms.rst>
+ Simulating Algorithms <tuto_s4u.rst>
Simulating MPI Apps <usecase_mpi.rst>
.. toctree::
..........
Let's start with the code of the worker. It is represented by the
-*master* function below. This simple function takes 4 parameters,
-given as a vector of strings:
-
- - the number of workers managed by the master.
- - the number of tasks to dispatch
- - the computational size (in flops to compute) of each task
- - the communication size (in bytes to exchange) of each task
+*master* function below. This simple function takes at least 3
+parameters (the amount of tasks to dispatch, their computational size
+in flops to compute and their communication size in bytes to
+exchange). Every parameter after the third one must be the name of an
+host on which a worker is waiting for something to compute.
Then, the tasks are sent one after the other, each on a mailbox named
-"worker-XXX" where XXX is the number of an existing worker. On the
-other side, a given worker (which code is given below) wait for
-incoming tasks on its own mailbox. Notice how this mailbox mechanism
-allow the actors to find each other without having all information:
-the master don't have to know the actors nor even where they are, it
-simply pushes the messages on mailbox which name is predetermined.
+after the worker's hosts. On the other side, a given worker (which
+code is given below) wait for incoming tasks on its own
+mailbox.
+
+
At the end, once all tasks are dispatched, the master dispatches
another task per worker, but this time with a negative amount of flops
:start-after: master-begin
:end-before: master-end
-Here comes the code of the worker actors. This function expects only one
-parameter from its vector of strings: its identifier so that it knows
-on which mailbox its incoming tasks will arrive. Its code is very
-simple: as long as it gets valid computation requests (whose
-compute_amount is positive), it compute this task and waits for the
-next one.
+Here comes the code of the worker actors. This function expects no
+parameter from its vector of strings. Its code is very simple: it
+expects messages on the mailbox that is named after its own host. As long as it gets valid
+computation requests (whose compute_amount is positive), it compute
+this task and waits for the next one.
+
+The worker retrieves its own host with
+:cpp:func:`simgrid::s4u::this_actor::get_host`. The
+:ref:`simgrid::s4u::this_actor <namespace_simgrid__s4u__this_actor>`
+namespace contains many such helping functions.
.. literalinclude:: ../../examples/s4u/app-masterworkers/s4u-app-masterworkers-fun.cpp
:language: c++
.......................
And this is it. In only a few lines, we defined the algorithm of our
-master/workers examples. Well, this is true, but an algorithm alone is
-not enough to define a simulation.
+master/workers examples.
-First, SimGrid is a library, not a program. So you need to define your
-own `main()` function, as follows. This function is in charge of
+That being said, an algorithm alone is not enough to define a
+simulation: SimGrid is a library, not a program. So you need to define
+your own ``main()`` function as follows. This function is in charge of
creating a SimGrid simulation engine (on line 3), register the actor
functions to the engine (on lines 7 and 8), load the virtual platform
from its description file (on line 11), map actors onto that platform
:end-before: main-end
:linenos:
-After that, the missing pieces are the platform and deployment
-files.
+As you can see, this also requires a platform file and a deployment
+file.
Platform File
.............
only an excerpts of the full ``examples/platforms/small_platform.xml``
file. For example, most routing information are missing, and only the
route between the hosts Tremblay and Fafard is given. This path
-traverses 6 links (4, 3, 2, 0, 1 and 8). The full file, along with
-other examples, can be found in the archive under
-``examples/platforms``.
+traverses 6 links (named 4, 3, 2, 0, 1 and 8). There are several
+examples of platforms in the archive under ``examples/platforms``.
.. |api_s4u_NetZone| image:: /images/extlink.png
:align: middle
.. literalinclude:: ../../examples/platforms/small_platform.xml
:language: xml
- :lines: 1-10,12-20,56-63,192-
+ :lines: 1-10,12-20,56-62,192-
:caption: (excerpts of the small_platform.xml file)
Deployment File
**SimGrid was invented to answer such questions.** Do not believe the
fools saying that all you need to study such settings is a simple
discrete event simulator. Do you really want to reinvent the wheel,
-debug your own tool, optimize it and validate its models against real
+debug and optimize your own tool, and validate its models against real
settings for ages, or do you prefer to sit on the shoulders of a
giant? With SimGrid, you can focus on your algorithm. The whole
simulation mechanism is already working.
Exercise 1: Simplifying the deployment file
...........................................
-In the provided example, the deployment file is tightly connected to
-the platform file ``small_platform.xml`` and adding more workers
-quickly becomes a pain: You need to start them (at the bottom of the
-file), add to inform the master that they are available by increasing
-the right parameter.
-
-Instead, modify the simulator ``master-workers.c`` into
-``master-workers-exo1.c`` so that the master launches a worker process
-on `all` the other machines at startup. The new deployment file should
-be as simple as:
-
-.. code-block:: xml
-
- <?xml version='1.0'?>
- <!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd">
- <platform version="4.1">
- <actor host="Tremblay" function="master">
- <argument value="20"/> <!-- Number of tasks -->
- <argument value="50000000"/> <!-- Computation size of tasks -->
- <argument value="1000000"/> <!-- Communication size of tasks -->
- </actor>
- </platform>
+In the provided example, adding more workers quickly becomes a pain:
+You need to start them (at the bottom of the file), and to inform the
+master of its availability with an extra parameter. This is mandatory
+if you want to inform the master of where the workers are running. But
+actually, the master does not need to have this information.
+
+We could leverage the mailbox mechanism flexibility, and use a sort of
+yellow page system: Instead of sending data to the worker running on
+Fafard, the master could send data to the third worker. Ie, instead of
+using the worker location (which should be filled in two locations),
+we could use their ID (which should be filled in one location
+only).
+
+This could be done with the following deployment file. It's clearly
+not shorter than the previous one, but it's still simpler because the
+information is only written once. It thus follows the `DRY
+<https://en.wikipedia.org/wiki/Don't_repeat_yourself>`_ `SPOT
+<http://wiki.c2.com/?SinglePointOfTruth>`_ design principle.
+
+.. literalinclude:: tuto_s4u/deployment1.xml
+ :language: xml
+
+
+Copy your ``master-workers.cpp`` into ``master-workers-exo1.cpp`` and
+add a new executable into ``CMakeLists.txt``. Then modify your worker
+function so that it gets its mailbox name not from the name of its
+host, but from the string passed as ``args[1]``. The master will send
+messages to all workers based on their number, for example as follows:
+
+.. code-block:: cpp
+
+ for (int i = 0; i < tasks_count; i++) {
+ std::string worker_rank = std::to_string(i % workers_count);
+ std::string mailbox_name = std::string("worker-") + worker_rank;
+ simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name);
+
+ mailbox->put(...);
+
+ ...
+ }
+
+
+Wrap up
+^^^^^^^
+
+The mailboxes are a very powerful mechanism in SimGrid, allowing many
+interesting application settings. They may feel surprising if you are
+used to BSD sockets or other classical systems, but you will soon
+appreciate their power. They are only used to match the
+communications, but have no impact on the communication
+timing. ``put()`` and ``get()`` are matched regardless of their
+initiators' location and then the real communication occures between
+the involved parties.
+
+Please refer to the full `API of Mailboxes
+<api/classsimgrid_1_1s4u_1_1Mailbox.html#class-documentation>`_
+|api_s4u_Mailbox|_ for more details.
+
+
+Exercise 2: Using the whole platform
+....................................
+
+It is now easier to add a new worker, but you still has to do it
+manually. It would be much easier if the master could start the
+workers on its own, one per available host in the platform. The new
+deployment file should be as simple as:
+
+.. literalinclude:: tuto_s4u/deployment2.xml
+ :language: xml
+
Creating the workers from the master
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In this exercise, we reduced the amount of configuration that our
simulator requests. This is both a good idea, and a dangerous
-trend. This simplification is an application of the good old DRY/SPOT
-programming principle (Don't Repeat Yourself / Single Point Of Truth
--- `more on wikipedia
+trend. This simplification is another application of the good old DRY/SPOT
+programming principle (`Don't Repeat Yourself / Single Point Of Truth
<https://en.wikipedia.org/wiki/Don%27t_repeat_yourself>`_), and you
really want your programming artefacts to follow these software
engineering principles.
--- /dev/null
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd">
+<platform version="4.1">
+ <!-- The master actor (with some arguments) -->
+ <actor host="Tremblay" function="master">
+ <argument value="5"/> <!-- Workers count -->
+ <argument value="20"/> <!-- Tasks count -->
+ <argument value="50000000"/> <!-- Computation size of tasks -->
+ <argument value="1000000"/> <!-- Communication size of tasks -->
+ </actor>
+ <!-- The worker processes (with no argument) -->
+ <actor host="Tremblay" function="worker">
+ <argument value="0" /> <!-- the ID of this worker -->
+ </actor>
+ <actor host="Jupiter" function="worker">
+ <argument value="1" /> <!-- the ID of this worker -->
+ </actor>
+ <actor host="Fafard" function="worker">
+ <argument value="2" /> <!-- the ID of this worker -->
+ </actor>
+ <actor host="Ginette" function="worker">
+ <argument value="3" /> <!-- the ID of this worker -->
+ </actor>
+ <actor host="Bourassa" function="worker">
+ <argument value="4" /> <!-- the ID of this worker -->
+ </actor>
+</platform>
--- /dev/null
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd">
+<platform version="4.1">
+ <!-- The master actor (with some arguments) -->
+ <actor host="Tremblay" function="master">
+ <argument value="20"/> <!-- Tasks count -->
+ <argument value="50000000"/> <!-- Computation size of tasks -->
+ <argument value="1000000"/> <!-- Communication size of tasks -->
+ </actor>
+</platform>
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
+/* ************************************************************************* */
+/* Take this tutorial online: https://simgrid.frama.io/simgrid/tuto_s4u.html */
+/* ************************************************************************* */
+
#include <simgrid/s4u.hpp>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_app_masterworker, "Messages specific for this s4u example");
long tasks_count = 0;
double compute_cost = 0;
double communicate_cost = 0;
- long workers_count = 0;
- simgrid::s4u::MailboxPtr mailbox = nullptr;
+ std::vector<simgrid::s4u::MailboxPtr> workers;
public:
explicit Master(std::vector<std::string> args)
{
- xbt_assert(args.size() == 5, "The master actor expects 4 arguments from the XML deployment file");
+ xbt_assert(args.size() > 4, "The master function expects 3 arguments plus the workers' names");
- workers_count = std::stol(args[1]);
- tasks_count = std::stol(args[2]);
- compute_cost = std::stod(args[3]);
- communicate_cost = std::stod(args[4]);
+ tasks_count = std::stol(args[1]);
+ compute_cost = std::stod(args[2]);
+ communicate_cost = std::stod(args[3]);
+ for (unsigned int i = 4; i < args.size(); i++)
+ workers.push_back(simgrid::s4u::Mailbox::by_name(args[i]));
- XBT_INFO("Got %ld workers and %ld tasks to process", workers_count, tasks_count);
+ XBT_INFO("Got %zu workers and %ld tasks to process", workers.size(), tasks_count);
}
void operator()()
{
for (int i = 0; i < tasks_count; i++) { /* For each task to be executed: */
/* - Select a worker in a round-robin way */
- mailbox = simgrid::s4u::Mailbox::by_name(std::string("worker-") + std::to_string(i % workers_count));
+ simgrid::s4u::MailboxPtr mailbox = workers[i % workers.size()];
/* - Send the computation amount to the worker */
if (tasks_count < 10000 || (tasks_count < 100000 && i % 10000 == 0) || i % 100000 == 0)
}
XBT_INFO("All tasks have been dispatched. Request all workers to stop.");
- for (int i = 0; i < workers_count; i++) {
+ for (unsigned int i = 0; i < workers.size(); i++) {
/* The workers stop when receiving a negative compute_cost */
- mailbox = simgrid::s4u::Mailbox::by_name(std::string("worker-") + std::to_string(i));
+ simgrid::s4u::MailboxPtr mailbox = workers[i % workers.size()];
mailbox->put(new double(-1.0), 0);
}
}
};
class Worker {
- long id = -1;
simgrid::s4u::MailboxPtr mailbox = nullptr;
public:
explicit Worker(std::vector<std::string> args)
{
- xbt_assert(args.size() == 2, "The worker expects a single argument from the XML deployment file: "
- "its worker ID (its numerical rank)");
- id = std::stol(args[1]);
- mailbox = simgrid::s4u::Mailbox::by_name(std::string("worker-") + std::to_string(id));
+ xbt_assert(args.size() == 1, "The worker expects to not get any argument");
+
+ mailbox = simgrid::s4u::Mailbox::by_name(simgrid::s4u::this_actor::get_host()->get_name());
}
void operator()()
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
+/* ************************************************************************* */
+/* Take this tutorial online: https://simgrid.frama.io/simgrid/tuto_s4u.html */
+/* ************************************************************************* */
+
#include <simgrid/s4u.hpp>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_app_masterworker, "Messages specific for this example");
// master-begin
static void master(std::vector<std::string> args)
{
- xbt_assert(args.size() == 5, "The master function expects 4 arguments");
+ xbt_assert(args.size() > 4, "The master function expects at least 3 arguments");
- long workers_count = std::stol(args[1]);
- long tasks_count = std::stol(args[2]);
- double compute_cost = std::stod(args[3]);
- double communication_cost = std::stod(args[4]);
+ long tasks_count = std::stol(args[1]);
+ double compute_cost = std::stod(args[2]);
+ double communication_cost = std::stod(args[3]);
+ std::vector<simgrid::s4u::MailboxPtr> workers;
+ for (unsigned int i = 4; i < args.size(); i++)
+ workers.push_back(simgrid::s4u::Mailbox::by_name(args[i]));
- XBT_INFO("Got %ld workers and %ld tasks to process", workers_count, tasks_count);
+ XBT_INFO("Got %zu workers and %ld tasks to process", workers.size(), tasks_count);
for (int i = 0; i < tasks_count; i++) { /* For each task to be executed: */
/* - Select a worker in a round-robin way */
- std::string worker_rank = std::to_string(i % workers_count);
- std::string mailbox_name = std::string("worker-") + worker_rank;
- simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name);
+ simgrid::s4u::MailboxPtr mailbox = workers[i % workers.size()];
/* - Send the computation cost to that worker */
XBT_INFO("Sending task %d of %ld to mailbox '%s'", i, tasks_count, mailbox->get_cname());
}
XBT_INFO("All tasks have been dispatched. Request all workers to stop.");
- for (int i = 0; i < workers_count; i++) {
+ for (unsigned int i = 0; i < workers.size(); i++) {
/* The workers stop when receiving a negative compute_cost */
- std::string mailbox_name = std::string("worker-") + std::to_string(i);
- simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name);
+ simgrid::s4u::MailboxPtr mailbox = workers[i % workers.size()];
mailbox->put(new double(-1.0), 0);
}
// worker-begin
static void worker(std::vector<std::string> args)
{
- xbt_assert(args.size() == 2, "The worker expects a single argument");
- long id = std::stol(args[1]);
+ xbt_assert(args.size() == 1, "The worker expects no argument");
- const std::string mailbox_name = std::string("worker-") + std::to_string(id);
- simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::by_name(mailbox_name);
+ simgrid::s4u::Host* my_host = simgrid::s4u::this_actor::get_host();
+ simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::by_name(my_host->get_name());
double compute_cost;
do {
! output sort 19
$ $SG_TEST_EXENV ${bindir:=.}/s4u-app-masterworkers-class$EXEEXT ${platfdir}/small_platform.xml s4u-app-masterworkers_d.xml --trace "--log=root.fmt:[%10.6r]%e(%P@%h)%e%m%n"
> [ 0.000000] (master@Tremblay) Got 5 workers and 20 tasks to process
-> [ 0.000000] (master@Tremblay) Sending task 0 of 20 to mailbox 'worker-0'
-> [ 0.002265] (master@Tremblay) Sending task 1 of 20 to mailbox 'worker-1'
-> [ 0.171420] (master@Tremblay) Sending task 2 of 20 to mailbox 'worker-2'
-> [ 0.329817] (master@Tremblay) Sending task 3 of 20 to mailbox 'worker-3'
-> [ 0.453549] (master@Tremblay) Sending task 4 of 20 to mailbox 'worker-4'
-> [ 0.586168] (master@Tremblay) Sending task 5 of 20 to mailbox 'worker-0'
-> [ 0.588433] (master@Tremblay) Sending task 6 of 20 to mailbox 'worker-1'
-> [ 0.995917] (master@Tremblay) Sending task 7 of 20 to mailbox 'worker-2'
-> [ 1.154314] (master@Tremblay) Sending task 8 of 20 to mailbox 'worker-3'
-> [ 1.608379] (master@Tremblay) Sending task 9 of 20 to mailbox 'worker-4'
-> [ 1.749885] (master@Tremblay) Sending task 10 of 20 to mailbox 'worker-0'
-> [ 1.752150] (master@Tremblay) Sending task 11 of 20 to mailbox 'worker-1'
-> [ 1.921304] (master@Tremblay) Sending task 12 of 20 to mailbox 'worker-2'
-> [ 2.079701] (master@Tremblay) Sending task 13 of 20 to mailbox 'worker-3'
-> [ 2.763209] (master@Tremblay) Sending task 14 of 20 to mailbox 'worker-4'
-> [ 2.913601] (master@Tremblay) Sending task 15 of 20 to mailbox 'worker-0'
-> [ 2.915867] (master@Tremblay) Sending task 16 of 20 to mailbox 'worker-1'
-> [ 3.085021] (master@Tremblay) Sending task 17 of 20 to mailbox 'worker-2'
-> [ 3.243418] (master@Tremblay) Sending task 18 of 20 to mailbox 'worker-3'
-> [ 3.918038] (master@Tremblay) Sending task 19 of 20 to mailbox 'worker-4'
+> [ 0.000000] (master@Tremblay) Sending task 0 of 20 to mailbox 'Tremblay'
+> [ 0.002265] (master@Tremblay) Sending task 1 of 20 to mailbox 'Jupiter'
+> [ 0.171420] (master@Tremblay) Sending task 2 of 20 to mailbox 'Fafard'
+> [ 0.329817] (master@Tremblay) Sending task 3 of 20 to mailbox 'Ginette'
+> [ 0.453549] (master@Tremblay) Sending task 4 of 20 to mailbox 'Bourassa'
+> [ 0.586168] (master@Tremblay) Sending task 5 of 20 to mailbox 'Tremblay'
+> [ 0.588433] (master@Tremblay) Sending task 6 of 20 to mailbox 'Jupiter'
+> [ 0.995917] (master@Tremblay) Sending task 7 of 20 to mailbox 'Fafard'
+> [ 1.154314] (master@Tremblay) Sending task 8 of 20 to mailbox 'Ginette'
+> [ 1.608379] (master@Tremblay) Sending task 9 of 20 to mailbox 'Bourassa'
+> [ 1.749885] (master@Tremblay) Sending task 10 of 20 to mailbox 'Tremblay'
+> [ 1.752150] (master@Tremblay) Sending task 11 of 20 to mailbox 'Jupiter'
+> [ 1.921304] (master@Tremblay) Sending task 12 of 20 to mailbox 'Fafard'
+> [ 2.079701] (master@Tremblay) Sending task 13 of 20 to mailbox 'Ginette'
+> [ 2.763209] (master@Tremblay) Sending task 14 of 20 to mailbox 'Bourassa'
+> [ 2.913601] (master@Tremblay) Sending task 15 of 20 to mailbox 'Tremblay'
+> [ 2.915867] (master@Tremblay) Sending task 16 of 20 to mailbox 'Jupiter'
+> [ 3.085021] (master@Tremblay) Sending task 17 of 20 to mailbox 'Fafard'
+> [ 3.243418] (master@Tremblay) Sending task 18 of 20 to mailbox 'Ginette'
+> [ 3.918038] (master@Tremblay) Sending task 19 of 20 to mailbox 'Bourassa'
> [ 4.077318] (master@Tremblay) All tasks have been dispatched. Request all workers to stop.
> [ 4.077513] (worker@Tremblay) Exiting now.
> [ 4.096528] (worker@Jupiter) Exiting now.
! output sort 19
$ $SG_TEST_EXENV ${bindir:=.}/s4u-app-masterworkers-fun$EXEEXT ${platfdir}/small_platform.xml s4u-app-masterworkers_d.xml --trace "--log=root.fmt:[%10.6r]%e(%P@%h)%e%m%n"
> [ 0.000000] (master@Tremblay) Got 5 workers and 20 tasks to process
-> [ 0.000000] (master@Tremblay) Sending task 0 of 20 to mailbox 'worker-0'
-> [ 0.002265] (master@Tremblay) Sending task 1 of 20 to mailbox 'worker-1'
-> [ 0.171420] (master@Tremblay) Sending task 2 of 20 to mailbox 'worker-2'
-> [ 0.329817] (master@Tremblay) Sending task 3 of 20 to mailbox 'worker-3'
-> [ 0.453549] (master@Tremblay) Sending task 4 of 20 to mailbox 'worker-4'
-> [ 0.586168] (master@Tremblay) Sending task 5 of 20 to mailbox 'worker-0'
-> [ 0.588433] (master@Tremblay) Sending task 6 of 20 to mailbox 'worker-1'
-> [ 0.995917] (master@Tremblay) Sending task 7 of 20 to mailbox 'worker-2'
-> [ 1.154314] (master@Tremblay) Sending task 8 of 20 to mailbox 'worker-3'
-> [ 1.608379] (master@Tremblay) Sending task 9 of 20 to mailbox 'worker-4'
-> [ 1.749885] (master@Tremblay) Sending task 10 of 20 to mailbox 'worker-0'
-> [ 1.752150] (master@Tremblay) Sending task 11 of 20 to mailbox 'worker-1'
-> [ 1.921304] (master@Tremblay) Sending task 12 of 20 to mailbox 'worker-2'
-> [ 2.079701] (master@Tremblay) Sending task 13 of 20 to mailbox 'worker-3'
-> [ 2.763209] (master@Tremblay) Sending task 14 of 20 to mailbox 'worker-4'
-> [ 2.913601] (master@Tremblay) Sending task 15 of 20 to mailbox 'worker-0'
-> [ 2.915867] (master@Tremblay) Sending task 16 of 20 to mailbox 'worker-1'
-> [ 3.085021] (master@Tremblay) Sending task 17 of 20 to mailbox 'worker-2'
-> [ 3.243418] (master@Tremblay) Sending task 18 of 20 to mailbox 'worker-3'
-> [ 3.918038] (master@Tremblay) Sending task 19 of 20 to mailbox 'worker-4'
+> [ 0.000000] (master@Tremblay) Sending task 0 of 20 to mailbox 'Tremblay'
+> [ 0.002265] (master@Tremblay) Sending task 1 of 20 to mailbox 'Jupiter'
+> [ 0.171420] (master@Tremblay) Sending task 2 of 20 to mailbox 'Fafard'
+> [ 0.329817] (master@Tremblay) Sending task 3 of 20 to mailbox 'Ginette'
+> [ 0.453549] (master@Tremblay) Sending task 4 of 20 to mailbox 'Bourassa'
+> [ 0.586168] (master@Tremblay) Sending task 5 of 20 to mailbox 'Tremblay'
+> [ 0.588433] (master@Tremblay) Sending task 6 of 20 to mailbox 'Jupiter'
+> [ 0.995917] (master@Tremblay) Sending task 7 of 20 to mailbox 'Fafard'
+> [ 1.154314] (master@Tremblay) Sending task 8 of 20 to mailbox 'Ginette'
+> [ 1.608379] (master@Tremblay) Sending task 9 of 20 to mailbox 'Bourassa'
+> [ 1.749885] (master@Tremblay) Sending task 10 of 20 to mailbox 'Tremblay'
+> [ 1.752150] (master@Tremblay) Sending task 11 of 20 to mailbox 'Jupiter'
+> [ 1.921304] (master@Tremblay) Sending task 12 of 20 to mailbox 'Fafard'
+> [ 2.079701] (master@Tremblay) Sending task 13 of 20 to mailbox 'Ginette'
+> [ 2.763209] (master@Tremblay) Sending task 14 of 20 to mailbox 'Bourassa'
+> [ 2.913601] (master@Tremblay) Sending task 15 of 20 to mailbox 'Tremblay'
+> [ 2.915867] (master@Tremblay) Sending task 16 of 20 to mailbox 'Jupiter'
+> [ 3.085021] (master@Tremblay) Sending task 17 of 20 to mailbox 'Fafard'
+> [ 3.243418] (master@Tremblay) Sending task 18 of 20 to mailbox 'Ginette'
+> [ 3.918038] (master@Tremblay) Sending task 19 of 20 to mailbox 'Bourassa'
> [ 4.077318] (master@Tremblay) All tasks have been dispatched. Request all workers to stop.
> [ 4.077513] (worker@Tremblay) Exiting now.
> [ 4.096528] (worker@Jupiter) Exiting now.
<platform version="4.1">
<!-- The master actor (with some arguments) -->
<actor host="Tremblay" function="master">
- <argument value="5"/> <!-- Number of workers -->
<argument value="20"/> <!-- Number of tasks -->
<argument value="50000000"/> <!-- Computation size of tasks -->
<argument value="1000000"/> <!-- Communication size of tasks -->
+ <!-- name of hosts on which the workers are running -->
+ <argument value="Tremblay"/>
+ <argument value="Jupiter" />
+ <argument value="Fafard" />
+ <argument value="Ginette" />
+ <argument value="Bourassa" />
</actor>
- <!-- The worker processes (with mailbox to listen on as argument) -->
- <actor host="Tremblay" function="worker">
- <argument value="0"/>
- </actor>
- <actor host="Jupiter" function="worker">
- <argument value="1"/>
- </actor>
- <actor host="Fafard" function="worker">
- <argument value="2"/>
- </actor>
- <actor host="Ginette" function="worker">
- <argument value="3"/>
- </actor>
- <actor host="Bourassa" function="worker">
- <argument value="4"/>
- </actor>
+ <!-- The worker processes (with no argument) -->
+ <actor host="Tremblay" function="worker" />
+ <actor host="Jupiter" function="worker" />
+ <actor host="Fafard" function="worker" />
+ <actor host="Ginette" function="worker" />
+ <actor host="Bourassa" function="worker" />
</platform>
/** @brief kill the actor. */
XBT_PUBLIC void exit();
-#ifndef DOXYGEN
-/** @deprecated Please use std::function<void(int, void*)> for first parameter */
-XBT_ATTRIB_DEPRECATED_v323("Please use std::function<void(int, void*)> for first parameter.") XBT_PUBLIC
- void on_exit(int_f_pvoid_pvoid_t fun, void* data);
/** @brief Add a function to the list of "on_exit" functions. */
XBT_PUBLIC void on_exit(std::function<void(int, void*)> fun, void* data);
/** @brief Migrate the actor to a new host. */
XBT_PUBLIC void migrate(Host* new_host);
+/** @} */
+
+#ifndef DOXYGEN
+/** @deprecated Please use std::function<void(int, void*)> for first parameter */
+XBT_ATTRIB_DEPRECATED_v323("Please use std::function<void(int, void*)> for first parameter.") XBT_PUBLIC
+ void on_exit(int_f_pvoid_pvoid_t fun, void* data);
/** @deprecated See this_actor::get_name() */
XBT_ATTRIB_DEPRECATED_v323("Please use this_actor::get_name()") XBT_PUBLIC std::string getName();
/** @deprecated See this_actor::get_cname() */
#endif
}
-/** @} */
}} // namespace simgrid::s4u
namespace s4u {
/** @brief Mailboxes: Network rendez-vous points.
- * @ingroup s4u_api
*
- * @tableofcontents
- *
- * @section s4u_mb_what What are mailboxes
+ * <b>What are mailboxes?</b>
*
* Rendez-vous point for network communications, similar to URLs on
* which you could post and retrieve data. Actually, the mailboxes are
* 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.
+ * 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 usually, 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
+ * 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 @i 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 dialling this number.
+ * once you start the communication by dialing this number.
*
- * @section s4u_mb_howto How to use mailboxes?
+ * <b>How to use mailboxes?</b>
*
* Any existing mailbox can be retrieve from its name (which are
* unique strings, just like with twitter tags). This results in a
*
* 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 prefectly realistic
+ * 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.
* the first relevant actor that can deal with the request will handle
* it.
*
- * @section s4u_mb_matching How are sends and receives matched?
+ * <b>How are sends and receives matched?</b>
*
* 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 incomming
+ * 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.
*
- * @section s4u_mb_receiver Declaring a receiving actor
+ * <b>Declaring a receiving actor</b>
*
* 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
* start as soon as possible, and the data will already be there on
* the receiver host when the receiver actor posts its receive().
*
- * @section s4u_mb_api The API
+ * <b>The API</b>
+ *
*/
class XBT_PUBLIC Mailbox {
#ifndef DOXYGEN
*
* 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.
+ * 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.
*/
void set_receiver(ActorPtr actor);
arg->properties.get(), nullptr);
if (arg->kill_time >= 0)
simcall_process_set_kill_time(actor, arg->kill_time);
+ if (arg->auto_restart)
+ actor->auto_restart_ = arg->auto_restart;
if (arg->daemon_)
actor->daemonize();
}