NS-3: unblock the number of communications + detect when several flows are simultaneously finishing
See merge request simgrid/simgrid!17
- Actor::on_destruction is now called in the destructor
Actor::on_termination new signal called when the actor terminates
its code.
+ - Global signals are now part of the Engine:
+ - on_platform_creation: after config settings, before the XML parsing
+ - on_platform_created: right after the XML parsing
+ - on_time_advance: each time the clock advances
+ - on_simulation_end: after simulation, before cleanups
+ - on_deadlock: as the name implies.
+ - C bindings:
+ - sg_{actor,host,link}_{data,data_set}() now all exist.
+ Use them to attach user data to the object and retrieve it.
MSG:
- convert a new set of functions to the S4U C interface and move the old MSG
- FG#28: add sg_actor_self (and other wrappers on this_actor methods)
- FG#29 and FG#33: provide a new C API to mutexes and condition variables
- FG#30: convert MSG_process_{un}ref to sg_actor_{un}ref
+ - FG#31: per-actor data
- FG#34: SG_BARRIER_SERIAL_THREAD?
- FG#35: model-checker does not like buster-produced binaries
- Example: src/kernel/activity/Activity.cpp
include/simgrid/activity/Activity.hpp
C
+ - Field getters are named sg_object_field() eg sg_link_name()
+ Field setters are named sg_object_field_set() eg sg_link_data_set()
- variables and functions are in snake_case()
- typedefs do not hide the pointers, ie * must be explicit
char * sg_host_get_name(sg_host_t * host);
Of course, this is only one possible way to model these things. YMMV ;)
+.. _understanding_lv08
+Understanding the default TCP model
+*****************************
+When simulating a data transfer between two hosts, you may be surprised
+by the obtained simulation time. Lets consider the following platform:
+
+.. code-block:: xml
+
+ <host id="A" speed="1Gf"/>
+ <host id="B" speed="1Gf"/>
+
+ <link id="link1" latency="10ms" bandwidth="1Mbps"/>
+
+ <route src="A" dst="B>
+ <link_ctn id="link1/>
+ </route>
+
+If host `A` sends `100kB` (a hundred kilobytes) to host `B`, one could expect
+that this communication would take `0.81` seconds to complete according to a
+simple latency-plus-size-divided-by-bandwidth model (0.01 + 8e5/1e6 = 0.81).
+However, the default TCP model of SimGrid is a bit more complex than that. It
+accounts for three phenomena that directly impact the simulation time even
+on such a simple example:
+ - The size of a message at the application level (i.e., 100kB in this
+ example) is not the size that will actually be transferred over the
+ network. To mimic the fact that TCP and IP headers are added to each packet of
+ the original payload, the TCP model of SimGrid empirically considers that
+ `only 97% of the nominal bandwidth` are available. In other words, the
+ size of your message is increased by a few percents, whatever this size be.
+
+ - In the real world, the TCP protocol is not able to fully exploit the
+ bandwidth of a link from the emission of the first packet. To reflect this
+ `slow start` phenomenon, the latency declared in the platform file is
+ multiplied by `a factor of 13.01`. Here again, this is an empirically
+ determined value that may not correspond to every TCP implementations on
+ every networks. It can be tuned when more realistic simulated times for
+ short messages are needed though.
+
+ - When data is transferred from A to B, some TCP ACK messages travel in the
+ opposite direction. To reflect the impact of this `cross-traffic`, SimGrid
+ simulates a flow from B to A that represents an additional bandwidth
+ consumption of `0.05`. The route from B to A is implicity declared in the
+ platfrom file and uses the same link `link1` as if the two hosts were
+ connected through a communication bus. The bandwidth share allocated to the
+ flow from A to B is then the available bandwidth of `link1` (i.e., 97% of
+ the nominal bandwidth of 1Mb/s) divided by 1.05 (i.e., the total consumption).
+ This feature, activated by default, can be disabled by adding the
+ `--cfg=network/crosstraffic:0` flag to command line.
+
+As a consequence, the time to transfer 100kB from A to B as simulated by the
+default TCP model of SimGrid is not 0.81 seconds but
+
+.. code-block:: python
+
+ 0.01 * 13.01 + 800000 / ((0.97 * 1e6) / 1.05) = 0.996079 seconds.
static double sg_host_get_available_at(sg_host_t host)
{
- HostAttribute attr = (HostAttribute) sg_host_user(host);
+ HostAttribute attr = (HostAttribute)sg_host_data(host);
return attr->available_at;
}
static void sg_host_set_available_at(sg_host_t host, double time)
{
- HostAttribute attr = (HostAttribute) sg_host_user(host);
+ HostAttribute attr = (HostAttribute)sg_host_data(host);
attr->available_at = time;
- sg_host_user_set(host, attr);
+ sg_host_data_set(host, attr);
}
static SD_task_t sg_host_get_last_scheduled_task( sg_host_t host){
- HostAttribute attr = (HostAttribute) sg_host_user(host);
+ HostAttribute attr = (HostAttribute)sg_host_data(host);
return attr->last_scheduled_task;
}
static void sg_host_set_last_scheduled_task(sg_host_t host, SD_task_t task){
- HostAttribute attr = (HostAttribute) sg_host_user(host);
+ HostAttribute attr = (HostAttribute)sg_host_data(host);
attr->last_scheduled_task=task;
- sg_host_user_set(host, attr);
+ sg_host_data_set(host, attr);
}
static xbt_dynar_t get_ready_tasks(xbt_dynar_t dax)
SD_create_environment(argv[1]);
/* Allocating the host attribute */
- int total_nhosts = sg_host_count();
+ unsigned int total_nhosts = sg_host_count();
sg_host_t *hosts = sg_host_list();
for (cursor = 0; cursor < total_nhosts; cursor++)
- sg_host_user_set(hosts[cursor], xbt_new0(struct _HostAttribute, 1));
+ sg_host_data_set(hosts[cursor], xbt_new0(struct _HostAttribute, 1));
/* load the DAX file */
xbt_dynar_t dax = SD_daxload(argv[2]);
xbt_dynar_free_container(&dax);
for (cursor = 0; cursor < total_nhosts; cursor++) {
- free(sg_host_user(hosts[cursor]));
- sg_host_user_set(hosts[cursor], NULL);
+ free(sg_host_data(hosts[cursor]));
+ sg_host_data_set(hosts[cursor], NULL);
}
xbt_free(hosts);
XBT_PUBLIC void sg_actor_self_execute(double flops);
XBT_PUBLIC void sg_actor_ref(sg_actor_t actor);
XBT_PUBLIC void sg_actor_unref(sg_actor_t actor);
+XBT_PUBLIC void* sg_actor_data(sg_actor_t actor);
+XBT_PUBLIC void sg_actor_data_set(sg_actor_t actor, void* userdata);
SG_END_DECL()
// ========== User Data ==============
/** @brief Return the user data of a #sg_host_t.
*
- * This functions returns the user data associated to @a host if it is possible.
+ * This functions returns the user data associated to @a host if any.
*/
-XBT_PUBLIC void* sg_host_user(sg_host_t host);
+XBT_PUBLIC void* sg_host_data(sg_host_t host);
+XBT_ATTRIB_DEPRECATED_v327("Please use sg_host_data()") XBT_PUBLIC void* sg_host_user(sg_host_t host);
/** @brief Set the user data of a #sg_host_t.
*
- * This functions attach @a data to @a host if it is possible.
+ * This functions attach @a data to @a host.
*/
-XBT_PUBLIC void sg_host_user_set(sg_host_t host, void* userdata);
-XBT_PUBLIC void sg_host_user_destroy(sg_host_t host);
+XBT_PUBLIC void sg_host_data_set(sg_host_t host, void* userdata);
+XBT_ATTRIB_DEPRECATED_v327("Please use sg_host_data_set()") XBT_PUBLIC
+ void sg_host_user_set(sg_host_t host, void* userdata);
+XBT_ATTRIB_DEPRECATED_v327("Please use sg_host_data_set(h, NULL)") XBT_PUBLIC void sg_host_user_destroy(sg_host_t host);
// ========= storage related functions ============
/** @brief Return the list of mount point names on an host.
*/
void set_config(const std::string& str);
-private:
- kernel::EngineImpl* const pimpl;
- static Engine* instance_;
-};
+ /** Callback fired when the platform is created (ie, the xml file parsed),
+ * right before the actual simulation starts. */
+ static xbt::signal<void()> on_platform_created;
-/** Callback fired when the platform is created (ie, the xml file parsed),
- * right before the actual simulation starts. */
-extern XBT_PUBLIC xbt::signal<void()> on_platform_created;
+ /** Callback fired when the platform is about to be created
+ * (ie, after any configuration change and just before the resource creation) */
+ static xbt::signal<void()> on_platform_creation;
-/** Callback fired when the platform is about to be created
- * (ie, after any configuration change and just before the resource creation) */
-extern XBT_PUBLIC xbt::signal<void()> on_platform_creation;
+ /** Callback fired when the main simulation loop ends, just before the end of Engine::run() */
+ static xbt::signal<void()> on_simulation_end;
-/** Callback fired when the main simulation loop ends, just before the end of Engine::run() */
-extern XBT_PUBLIC xbt::signal<void()> on_simulation_end;
+ /** Callback fired when the time jumps into the future */
+ static xbt::signal<void(double)> on_time_advance;
-/** Callback fired when the time jumps into the future */
-extern XBT_PUBLIC xbt::signal<void(double)> on_time_advance;
+ /** Callback fired when the time cannot advance because of inter-actors deadlock */
+ static xbt::signal<void(void)> on_deadlock;
-/** Callback fired when the time cannot advance because of inter-actors deadlock */
-extern XBT_PUBLIC xbt::signal<void(void)> on_deadlock;
+private:
+ kernel::EngineImpl* const pimpl;
+ static Engine* instance_;
+};
#ifndef DOXYGEN /* Internal use only, no need to expose it */
template <class T> XBT_PRIVATE void get_filtered_netzones_recursive(s4u::NetZone* current, std::vector<T*>* whereto)
} // namespace s4u
} // namespace simgrid
-extern int USER_HOST_LEVEL;
-
#endif /* SIMGRID_S4U_HOST_HPP */
bool is_on() const;
void turn_off();
- void* get_data(); /** Should be used only from the C interface. Prefer extensions in C++ */
- void set_data(void* d);
-
#ifndef DOXYGEN
XBT_ATTRIB_DEPRECATED_v325("Please use Link::set_state_profile()") void set_state_trace(
kernel::profile::Profile* profile)
const char* get_property(const std::string& key) const;
void set_property(const std::string&, const std::string& value);
- void set_data(void* data) { userdata_ = data; }
- void* get_data() { return userdata_; }
-
IoPtr io_init(sg_size_t size, s4u::Io::OpType type);
IoPtr read_async(sg_size_t size);
Host* attached_to_ = nullptr;
kernel::resource::StorageImpl* const pimpl_;
std::string name_;
- void* userdata_ = nullptr;
};
} // namespace s4u
public:
static size_t extension_create(void (*deleter)(void*))
{
+ if (deleters_.empty()) { // Save space for void* user data
+ deleters_.push_back(nullptr);
+ }
deleters_.push_back(deleter);
return deleters_.size() - 1;
}
{
return Extension<T, U>(extension_create([](void* p) { delete static_cast<U*>(p); }));
}
- Extendable() : extensions_(deleters_.size(), nullptr) {}
+ Extendable() : extensions_((deleters_.size() > 0 ? deleters_.size() : 1), nullptr) {}
Extendable(const Extendable&) = delete;
Extendable& operator=(const Extendable&) = delete;
~Extendable()
* an extension A, the subsystem of B might depend on the subsystem on A and
* an extension of B might need to have the extension of A around when executing
* its cleanup function/destructor. */
- for (std::size_t i = extensions_.size(); i > 0; --i)
+ for (std::size_t i = extensions_.size(); i > 1; --i) // rank=0 is the spot of user's void*
if (extensions_[i - 1] != nullptr && deleters_[i - 1] != nullptr)
deleters_[i - 1](extensions_[i - 1]);
}
{
extension_set(rank.id(), value, use_dtor);
}
-
+ // void* version, for C users and nostalgics
+ void set_data(void* data){
+ extensions_[0]=data;
+ }
+ void* get_data(){
+ return extensions_[0];
+ }
// Convenience extension access when the type has a associated EXTENSION ID:
template <class U> U* extension() const { return extension<U>(U::EXTENSION_ID); }
template<class U> void extension_set(U* p) { extension_set<U>(U::EXTENSION_ID, p); }
int console_open(lua_State*)
{
sg_platf_init();
- simgrid::s4u::on_platform_creation();
+ simgrid::s4u::Engine::on_platform_creation();
return 0;
}
int console_close(lua_State*)
{
- simgrid::s4u::on_platform_created();
+ simgrid::s4u::Engine::on_platform_created();
sg_platf_exit();
return 0;
}
6);
/* Connect callbacks */
- simgrid::s4u::on_platform_creation.connect(TRACE_start);
- simgrid::s4u::on_deadlock.connect(TRACE_end);
- simgrid::s4u::on_simulation_end.connect(TRACE_end);
+ simgrid::s4u::Engine::on_platform_creation.connect(TRACE_start);
+ simgrid::s4u::Engine::on_deadlock.connect(TRACE_end);
+ simgrid::s4u::Engine::on_simulation_end.connect(TRACE_end);
}
static void print_line(const char* option, const char* desc, const char* longdesc)
// always need the callbacks to zones (we need only the root zone), to create the rootContainer and the rootType
// properly
if (TRACE_needs_platform()) {
- simgrid::s4u::on_platform_created.connect(instr_on_platform_created);
+ simgrid::s4u::Engine::on_platform_created.connect(instr_on_platform_created);
simgrid::s4u::Host::on_creation.connect(instr_host_on_creation);
simgrid::s4u::Host::on_speed_change.connect(instr_host_on_speed_change);
simgrid::s4u::Link::on_creation.connect(instr_link_on_creation);
int get_refcount() { return refcount_; }
friend void intrusive_ptr_add_ref(ActorImpl* actor)
{
- // std::memory_order_relaxed ought to be enough here instead of std::memory_order_seq_cst
- // But then, we have a threading issue when an actor commits a suicide:
- // it seems that in this case, the worker thread kills the last occurrence of the actor
- // while usually, the maestro does so. FIXME: we should change how actors suicide
- actor->refcount_.fetch_add(1, std::memory_order_seq_cst);
+ // This whole memory consistency semantic drives me nuts.
+ // std::memory_order_relaxed proves to not be enough: There is a threading issue when actors commit suicide.
+ // My guess is that the maestro context wants to propagate changes to the actor's fields after the
+ // actor context frees that memory area or something. But I'm not 100% certain of what's going on.
+ // std::memory_order_seq_cst works but that's rather demanding.
+ // AFAIK, std::memory_order_acq_rel works on all tested platforms, so let's stick to it.
+ // Reducing the requirements to _relaxed would require to fix our suicide procedure, which is a messy piece of code.
+ actor->refcount_.fetch_add(1, std::memory_order_acq_rel);
}
friend void intrusive_ptr_release(ActorImpl* actor)
{
mc_model_checker->visited_states++;
if (stack_.size() <= (std::size_t)_sg_mc_max_depth)
- req = MC_state_get_request(cur_state);
+ req = MC_state_choose_request(cur_state);
else
req = nullptr;
}
}
- smx_simcall_t req = MC_state_get_request(current_pair->graph_state.get());
+ smx_simcall_t req = MC_state_choose_request(current_pair->graph_state.get());
int req_num = current_pair->graph_state->transition_.argument_;
if (dot_output != nullptr) {
// Search an enabled transition in the current state; backtrack if the interleave set is empty
// get_request also sets state.transition to be the one corresponding to the returned req
- smx_simcall_t req = MC_state_get_request(state);
+ smx_simcall_t req = MC_state_choose_request(state);
// req is now the transition of the process that was selected to be executed
if (req == nullptr) {
* Things can get muddled with the WAITANY and TESTANY simcalls, that are rewritten on the fly to a bunch of WAIT
* (resp TEST) transitions using the transition.argument field to remember what was the last returned sub-transition.
*/
-static inline smx_simcall_t MC_state_get_request_for_process(simgrid::mc::State* state, smx_actor_t actor)
+static inline smx_simcall_t MC_state_choose_request_for_process(simgrid::mc::State* state, smx_actor_t actor)
{
/* reset the outgoing transition */
simgrid::mc::ActorState* procstate = &state->actor_states_[actor->get_pid()];
return req;
}
-smx_simcall_t MC_state_get_request(simgrid::mc::State* state)
+smx_simcall_t MC_state_choose_request(simgrid::mc::State* state)
{
for (auto& actor : mc_model_checker->process().actors()) {
/* Only consider the actors that were marked as interleaving by the checker algorithm */
if (not state->actor_states_[actor.copy.get_buffer()->get_pid()].is_todo())
continue;
- smx_simcall_t res = MC_state_get_request_for_process(state, actor.copy.get_buffer());
+ smx_simcall_t res = MC_state_choose_request_for_process(state, actor.copy.get_buffer());
if (res)
return res;
}
}
}
-XBT_PRIVATE smx_simcall_t MC_state_get_request(simgrid::mc::State* state);
+XBT_PRIVATE smx_simcall_t MC_state_choose_request(simgrid::mc::State* state);
#endif
}
void* MSG_host_get_data(sg_host_t host)
{
- return sg_host_user(host);
+ return sg_host_data(host);
}
void MSG_host_set_data(sg_host_t host, void* data)
{
- return sg_host_user_set(host, data);
+ return sg_host_data_set(host, data);
}
xbt_dict_t MSG_host_get_mounted_storage_list(sg_host_t host)
{
simgrid::s4u::Host::on_state_change.connect(&on_host_change);
simgrid::s4u::Host::on_speed_change.connect(&on_host_change);
simgrid::s4u::Host::on_destruction.connect(&on_host_destruction);
- simgrid::s4u::on_simulation_end.connect(&on_simulation_end);
+ simgrid::s4u::Engine::on_simulation_end.connect(&on_simulation_end);
simgrid::kernel::resource::CpuAction::on_state_change.connect(&on_action_state_change);
// We may only have one actor on a node. If that actor executes something like
// compute -> recv -> compute
*/
void sg_link_energy_plugin_init()
{
-
if (LinkEnergy::EXTENSION_ID.valid())
return;
LinkEnergy::EXTENSION_ID = simgrid::s4u::Link::extension_create<LinkEnergy>();
});
simgrid::s4u::Link::on_communicate.connect(&on_communicate);
- simgrid::s4u::on_simulation_end.connect(&on_simulation_end);
+ simgrid::s4u::Engine::on_simulation_end.connect(&on_simulation_end);
}
/** @ingroup plugin_energy
{
intrusive_ptr_release(actor);
}
+
+/** @brief Return the user data of a #sg_actor_t */
+void* sg_actor_data(sg_actor_t actor)
+{
+ return actor->get_data();
+}
+/** @brief Set the user data of a #sg_actor_t */
+void sg_actor_data_set(sg_actor_t actor, void* userdata)
+{
+ actor->set_data(userdata);
+}
namespace simgrid {
namespace s4u {
-xbt::signal<void()> on_platform_creation;
-xbt::signal<void()> on_platform_created;
-xbt::signal<void()> on_simulation_end;
-xbt::signal<void(double)> on_time_advance;
-xbt::signal<void(void)> on_deadlock;
+xbt::signal<void()> Engine::on_platform_creation;
+xbt::signal<void()> Engine::on_platform_created;
+xbt::signal<void()> Engine::on_simulation_end;
+xbt::signal<void(double)> Engine::on_time_advance;
+xbt::signal<void(void)> Engine::on_deadlock;
Engine* Engine::instance_ = nullptr; /* That singleton is awful, but I don't see no other solution right now. */
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_host, s4u, "Logging specific to the S4U hosts");
XBT_LOG_EXTERNAL_CATEGORY(surf_route);
-int USER_HOST_LEVEL = -1;
-
namespace simgrid {
namespace xbt {
template class Extendable<s4u::Host>;
// ========= Layering madness ==============*
// ========== User data Layer ==========
-void* sg_host_user(sg_host_t host)
+void* sg_host_data(sg_host_t host)
+{
+ return host->get_data();
+}
+void sg_host_data_set(sg_host_t host, void* userdata)
+{
+ host->set_data(userdata);
+}
+void* sg_host_user(sg_host_t host) // deprecated
{
- return host->extension(USER_HOST_LEVEL);
+ return host->get_data();
}
-void sg_host_user_set(sg_host_t host, void* userdata)
+void sg_host_user_set(sg_host_t host, void* userdata) // deprecated
{
- host->extension_set(USER_HOST_LEVEL, userdata);
+ host->set_data(userdata);
}
-void sg_host_user_destroy(sg_host_t host)
+void sg_host_user_destroy(sg_host_t host) // deprecated
{
- host->extension_set(USER_HOST_LEVEL, nullptr);
+ host->set_data(nullptr);
}
// ========= storage related functions ============
return this->pimpl_->is_on();
}
-void* Link::get_data()
-{
- return this->pimpl_->get_data();
-}
-void Link::set_data(void* d)
-{
- simgrid::kernel::actor::simcall([this, d]() { this->pimpl_->set_data(d); });
-}
-
void Link::set_state_profile(kernel::profile::Profile* profile)
{
simgrid::kernel::actor::simcall([this, profile]() { this->pimpl_->set_state_profile(profile); });
#endif
/* register a function to be called by SURF after the environment creation */
sg_platf_init();
- simgrid::s4u::on_platform_created.connect(surf_presolve);
+ simgrid::s4u::Engine::on_platform_created.connect(surf_presolve);
simgrid::s4u::Storage::on_creation.connect([](simgrid::s4u::Storage const& storage) {
sg_storage_t s = simgrid::s4u::Storage::by_name(storage.get_name());
XBT_CRITICAL("Oops! Deadlock or code not perfectly clean.");
}
SIMIX_display_process_status();
- simgrid::s4u::on_deadlock();
+ simgrid::s4u::Engine::on_deadlock();
xbt_abort();
}
- simgrid::s4u::on_simulation_end();
+ simgrid::s4u::Engine::on_simulation_end();
}
double SIMIX_timer_next()
papi_counter_t papi_counter_data_;
#endif
public:
+ static simgrid::xbt::Extension<simgrid::s4u::Actor, ActorExt> EXTENSION_ID;
+
explicit ActorExt(s4u::ActorPtr actor);
ActorExt(const ActorExt&) = delete;
ActorExt& operator=(const ActorExt&) = delete;
namespace simgrid {
namespace smpi {
+simgrid::xbt::Extension<simgrid::s4u::Actor, ActorExt> ActorExt::EXTENSION_ID;
ActorExt::ActorExt(s4u::ActorPtr actor) : actor_(actor)
{
+ if (not simgrid::smpi::ActorExt::EXTENSION_ID.valid())
+ simgrid::smpi::ActorExt::EXTENSION_ID = simgrid::s4u::Actor::extension_create<simgrid::smpi::ActorExt>();
+
mailbox_ = s4u::Mailbox::by_name("SMPI-" + std::to_string(actor_->get_pid()));
mailbox_small_ = s4u::Mailbox::by_name("small-" + std::to_string(actor_->get_pid()));
mailboxes_mutex_ = s4u::Mutex::create();
if (code != nullptr) // When started with smpirun, we will not execute a function
simgrid::s4u::Engine::get_instance()->register_function(name, code);
- static bool already_called = false;
- if (not already_called) {
- already_called = true;
- for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts())
- host->extension_set(new simgrid::smpi::Host(host));
- }
-
Instance instance(std::string(name), num_processes, MPI_COMM_NULL);
smpi_instances.insert(std::pair<std::string, Instance>(name, instance));
std::unordered_map<std::string, double> location2speedup;
-static std::map</*process_id*/ simgrid::s4u::Actor const*, simgrid::smpi::ActorExt*> process_data;
static int smpi_exit_status = 0;
extern double smpi_total_benched_time;
xbt_os_timer_t global_timer;
if (me == nullptr) // This happens sometimes (eg, when linking against NS3 because it pulls openMPI...)
return nullptr;
- return process_data.at(me.get());
+ return me->extension<simgrid::smpi::ActorExt>();
}
simgrid::smpi::ActorExt* smpi_process_remote(simgrid::s4u::ActorPtr actor)
{
if (actor.get() == nullptr)
return nullptr;
- return process_data.at(actor.get());
+ return actor->extension<simgrid::smpi::ActorExt>();
}
MPI_Comm smpi_process_comm_self(){
TRACE_global_init();
SIMIX_global_init(&argc, argv);
+ auto engine = simgrid::s4u::Engine::get_instance();
SMPI_switch_data_segment = &smpi_switch_data_segment;
sg_storage_file_system_init();
// parse the platform file: get the host list
- simgrid::s4u::Engine::get_instance()->load_platform(argv[1]);
+ engine->load_platform(argv[1]);
SIMIX_comm_set_copy_data_callback(smpi_comm_copy_buffer_callback);
smpi_init_options();
smpi_init_privatization_no_dlopen(executable);
SMPI_init();
- simgrid::s4u::Engine::get_instance()->load_deployment(argv[2]);
- SMPI_app_instance_register(smpi_default_instance_name.c_str(), nullptr,
- process_data.size()); // This call has a side effect on process_count...
+
+ /* This is a ... heavy way to count the MPI ranks */
+ int rank_counts = 0;
+ simgrid::s4u::Actor::on_creation.connect([&rank_counts](simgrid::s4u::Actor& actor) {
+ if (not actor.is_daemon())
+ rank_counts++;
+ });
+ engine->load_deployment(argv[2]);
+
+ SMPI_app_instance_register(smpi_default_instance_name.c_str(), nullptr, rank_counts);
MPI_COMM_WORLD = *smpi_deployment_comm_world(smpi_default_instance_name);
/* Clean IO before the run */
// Called either directly from the user code, or from the code called by smpirun
void SMPI_init(){
simgrid::s4u::Actor::on_creation.connect([](simgrid::s4u::Actor& actor) {
- if (not actor.is_daemon()) {
- process_data.insert({&actor, new simgrid::smpi::ActorExt(&actor)});
- }
- });
- simgrid::s4u::Actor::on_destruction.connect([](simgrid::s4u::Actor const& actor) {
- XBT_DEBUG("Delete the extension of actor %s", actor.get_cname());
- auto it = process_data.find(&actor);
- if (it != process_data.end()) {
- delete it->second;
- process_data.erase(it);
- }
+ if (not actor.is_daemon())
+ actor.extension_set<simgrid::smpi::ActorExt>(new simgrid::smpi::ActorExt(&actor));
});
simgrid::s4u::Host::on_creation.connect(
[](simgrid::s4u::Host& host) { host.extension_set(new simgrid::smpi::Host(&host)); });
+ for (auto const& host : simgrid::s4u::Engine::get_instance()->get_all_hosts())
+ host->extension_set(new simgrid::smpi::Host(host));
smpi_init_options();
if (not MC_is_active()) {
*/
class LinkImpl : public Resource, public surf::PropertyHolder {
bool currently_destroying_ = false;
- void* userdata_ = nullptr;
protected:
LinkImpl(NetworkModel* model, const std::string& name, lmm::Constraint* constraint);
public:
void destroy(); // Must be called instead of the destructor
- void* get_data() { return userdata_; }
- void set_data(void* d) { userdata_ = d; }
/** @brief Public interface */
s4u::Link piface_;
});
surf::on_cluster.connect(&clusterCreation_cb);
- s4u::on_platform_created.connect(&postparse_cb);
+ s4u::Engine::on_platform_created.connect(&postparse_cb);
s4u::NetZone::on_route_creation.connect(&routeCreation_cb);
}
/** Module management function: creates all internal data structures */
void sg_platf_init()
{
- simgrid::s4u::on_platform_created.connect(check_disk_attachment);
+ simgrid::s4u::Engine::on_platform_created.connect(check_disk_attachment);
}
/** Module management function: frees all internal data structures */
void sg_platf_exit() {
simgrid::surf::on_cluster.disconnect_slots();
- simgrid::s4u::on_platform_created.disconnect_slots();
+ simgrid::s4u::Engine::on_platform_created.disconnect_slots();
/* make sure that we will reinit the models while loading the platf once reinited */
surf_parse_models_setup_already_called = 0;
simgrid::kernel::routing::NetZoneImpl* sg_platf_new_Zone_begin(simgrid::kernel::routing::ZoneCreationArgs* zone)
{
if (not surf_parse_models_setup_already_called) {
- simgrid::s4u::on_platform_creation();
+ simgrid::s4u::Engine::on_platform_creation();
/* Initialize the surf models. That must be done after we got all config, and before we need the models.
* That is, after the last <config> tag, if any, and before the first of cluster|peer|zone|trace|trace_connect
for (auto const& model : all_existing_models)
model->update_actions_state(NOW, time_delta);
- simgrid::s4u::on_time_advance(time_delta);
+ simgrid::s4u::Engine::on_time_advance(time_delta);
TRACE_paje_dump_buffer(false);
#include "src/simgrid/version.h"
#include "src/surf/HostImpl.hpp"
#include "src/surf/xml/platf.hpp"
+#include "src/xbt_modinter.h" /* whether initialization was already done */
#include "surf/surf.hpp"
#include "xbt/module.h"
void surf_init(int *argc, char **argv)
{
- if (USER_HOST_LEVEL != -1) // Already initialized
+ if (xbt_initialized > 0)
return;
- XBT_DEBUG("Create all Libs");
- USER_HOST_LEVEL = simgrid::s4u::Host::extension_create(nullptr);
-
xbt_init(argc, argv);
sg_config_init(argc, argv);
surf_parsed_filename.c_str(), version);
}
void ETag_surfxml_platform(){
- simgrid::s4u::on_platform_created();
+ simgrid::s4u::Engine::on_platform_created();
}
void STag_surfxml_host(){
void xbt_throw_impossible(const char* file, int line, const char* func)
{
std::stringstream ss;
- ss << file << ":" << line << ":" << func << ": The Impossible Did Happen (yet again). Please report this bug.";
+ ss << file << ":" << line << ":" << func
+ << ": The Impossible Did Happen (yet again). Please report this bug (after reading https://xkcd.com/2200 :)";
throw simgrid::xbt::ImpossibleError(ss.str());
}
void xbt_throw_unimplemented(const char* file, int line, const char* func)
/** @brief Initialize the xbt mechanisms. */
void xbt_init(int *argc, char **argv)
{
- simgrid::xbt::install_exception_handler();
-
xbt_initialized++;
if (xbt_initialized > 1) {
XBT_DEBUG("XBT has been initialized %d times.", xbt_initialized);
return;
}
+ simgrid::xbt::install_exception_handler();
+
xbt_binary_name = argv[0];
xbt_cmdline = xbt_dynar_new(sizeof(char*), NULL);
for (int i = 0; i < *argc; i++)
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this msg example");
const int FAIL_ON_ERROR = 0;
-const int flop_amount = 100000000;
+const int flop_amount = 100000000; // 100Mf, so that computing this on a 1Gf core takes exactly 0.1s
int failed_test = 0;
double energy = 0;
if(enable_compile_warnings AND enable_debug)
set(warnCFLAGS "${warnCFLAGS} -Werror")
set(warnCXXFLAGS "${warnCXXFLAGS} -Werror")
+ if(CMAKE_Fortran_COMPILER_ID MATCHES "GCC")
+ set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Werror -Werror=format-security")
+ endif()
endif()
# Activate the warnings on #if FOOBAR when FOOBAR has no value
#generate sloccount report
sloccount --duplicates --wide --details $WORKSPACE | grep -v -e '.git' -e 'mpich3-test' -e 'sloccount.sc' -e 'isp/umpire' -e 'build/' -e 'xml_coverage.xml' -e 'CTestResults_memcheck.xml' -e 'DynamicAnalysis.xml' > $WORKSPACE/sloccount.sc
- #upload files to codacy. CODACY_PROJECT_TOKEN must be setup !
- if ! [ -z $CODACY_PROJECT_TOKEN ]
- then
- for report in $BUILDFOLDER/java_cov*
- do
- if [ ! -e "$report" ]; then continue; fi
- java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar report -l Java -r $report --partial
- done
- java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar final
-
- java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar report -l Python -r $BUILDFOLDER/python_coverage.xml
- java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar report -l C -f -r $BUILDFOLDER/xml_coverage.xml
- java -jar /home/ci/codacy-coverage-reporter-*-assembly.jar report -l CPP -f -r $BUILDFOLDER/xml_coverage.xml
- fi
fi || exit 42