X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/dc1369e2055686dde3d178efb2001dbad8972d54..327a1abc2a482ea0b5d7eab53b28f85d4eb1922e:/include/simgrid/s4u/Actor.hpp diff --git a/include/simgrid/s4u/Actor.hpp b/include/simgrid/s4u/Actor.hpp index 8e48a17218..e3a606e979 100644 --- a/include/simgrid/s4u/Actor.hpp +++ b/include/simgrid/s4u/Actor.hpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2006-2019. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2006-2022. The SimGrid Team. All rights reserved. */ /* 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. */ @@ -6,175 +6,280 @@ #ifndef SIMGRID_S4U_ACTOR_HPP #define SIMGRID_S4U_ACTOR_HPP -#include -#include // deprecated wrappers +#include + #include -#include #include -#include #include #include +#include +#include + namespace simgrid { + +extern template class XBT_PUBLIC xbt::Extendable; + namespace s4u { +/** @ingroup s4u_api + * @brief Static methods working on the current actor (see @ref s4u::Actor) */ +namespace this_actor { + +XBT_PUBLIC bool is_maestro(); + +/** Block the current actor sleeping for that amount of seconds */ +XBT_PUBLIC void sleep_for(double duration); +/** Block the current actor sleeping until the specified timestamp */ +XBT_PUBLIC void sleep_until(double wakeup_time); + +template inline void sleep_for(std::chrono::duration duration) +{ + auto seconds = std::chrono::duration_cast(duration); + this_actor::sleep_for(seconds.count()); +} + +template inline void sleep_until(const SimulationTimePoint& wakeup_time) +{ + auto timeout_native = std::chrono::time_point_cast(wakeup_time); + this_actor::sleep_until(timeout_native.time_since_epoch().count()); +} + +/** Block the current actor, computing the given amount of flops */ +XBT_PUBLIC void execute(double flop); + +/** 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. */ +XBT_PUBLIC void execute(double flop, double priority); + /** + * @example examples/cpp/exec-ptask/s4u-exec-ptask.cpp + */ + +/** Block the current actor until the built parallel execution terminates * - * 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. + * @beginrst + * .. _API_s4u_parallel_execute: * - * 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. + * **Example of use:** `examples/cpp/exec-ptask/s4u-exec-ptask.cpp + * `_ * - * @section s4u_actor_def Defining the skeleton of an Actor + * 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. * - * As in the C++11 - * standard, you can declare the code of your actor either as a - * pure function or as an object. It is very simple with functions: + * 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. * - * @code{.cpp} - * #include + * 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. * - * // Declare the code of your worker - * void worker() { - * printf("Hello s4u"); - * simgrid::s4u::this_actor::execute(5*1024*1024); // Get the worker executing a task of 5 MFlops - * }; + * 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 your main or from another actor, create your actor on the host Jupiter - * // The following line actually creates a new actor, even if there is no "new". - * Actor("Alice", simgrid::s4u::Host::by_name("Jupiter"), worker); - * @endcode + * - from host0: [ to host0: 0 bytes; to host1: 1 byte ] * - * But some people prefer to encapsulate their actors in classes and - * objects to save the actor state in a cleanly dedicated location. - * The syntax is slightly more complicated, but not much. + * - from host1: [ to host0: 2 bytes; to host1: 3 bytes ] * - * @code{.cpp} - * #include + * Or, in other words: * - * // Declare the class representing your actors - * class Worker { - * public: - * void operator()() { // Two pairs of () because this defines the method called () - * printf("Hello s4u"); - * simgrid::s4u::this_actor::execute(5*1024*1024); // Get the worker executing a task of 5 MFlops - * } - * }; + * - From host0 to host0: 0 bytes are exchanged * - * // From your main or from another actor, create your actor. Note the () after Worker - * Actor("Bob", simgrid::s4u::Host::by_name("Jupiter"), Worker()); - * @endcode + * - From host0 to host1: 1 byte is exchanged * - * @section s4u_actor_flesh Fleshing your actor + * - From host1 to host0: 2 bytes are exchanged * - * The body of your actor can use the functions of the - * simgrid::s4u::this_actor namespace to interact with the world. - * This namespace contains the methods to start new activities - * (executions, communications, etc), and to get informations about - * the currently running thread (its location, etc). + * - From host1 to host1: 3 bytes are exchanged * - * Please refer to the @link simgrid::s4u::this_actor full API @endlink. + * 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 :ref:`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. * - * @section s4u_actor_deploy Using a deployment file + * @endrst + */ +/** Block the current actor until the built parallel execution completes */ +XBT_PUBLIC void parallel_execute(const std::vector& hosts, const std::vector& flops_amounts, + const std::vector& bytes_amounts); + +/** Initialize a sequential execution that must then be started manually */ +XBT_PUBLIC ExecPtr exec_init(double flops_amounts); +/** Initialize a parallel execution that must then be started manually */ +XBT_PUBLIC ExecPtr exec_init(const std::vector& hosts, const std::vector& flops_amounts, + const std::vector& bytes_amounts); + +XBT_PUBLIC ExecPtr exec_async(double flops_amounts); + +/** @brief Returns the actor ID of the current actor. */ +XBT_PUBLIC aid_t get_pid(); + +/** @brief Returns the ancestor's actor ID of the current actor. */ +XBT_PUBLIC aid_t get_ppid(); + +/** @brief Returns the name of the current actor. */ +XBT_PUBLIC std::string get_name(); +/** @brief Returns the name of the current actor as a C string. */ +XBT_PUBLIC const char* get_cname(); + +/** @brief Returns the name of the host on which the current actor is running. */ +XBT_PUBLIC Host* get_host(); + +/** @brief Suspend the current actor, that is blocked until resume()ed by another actor. */ +XBT_PUBLIC void suspend(); + +/** @brief Yield the current actor. */ +XBT_PUBLIC void yield(); + +/** @brief kill the current actor. */ +XBT_ATTRIB_NORETURN XBT_PUBLIC void exit(); + +/** @brief Add a function to the list of "on_exit" functions of the current actor. * - * @warning This is currently not working with S4U. Sorry about that. + * 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. * - * The best practice is to use an external deployment file as - * follows, because it makes it easier to test your application in - * differing settings. Load this file with - * s4u::Engine::loadDeployment() before the simulation starts. - * Refer to the @ref deployment section for more information. + * 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. * - * @code{.xml} - * - * - * + * 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. + */ + +XBT_PUBLIC void on_exit(const std::function& fun); + +/** @brief Migrate the current actor to a new host. */ +XBT_PUBLIC void set_host(Host* new_host); +} // namespace this_actor + +/** An actor is an independent stream of execution in your distributed application. * - * - * - * - * - * - * - * - * + * @beginrst + * It is located on a (simulated) :cpp:class:`host `, but can interact + * with the whole simulated platform. * - * - *