# We need pybind11. SimGrid will pick it automatically if the subdir is here
- cmd: git clone --branch stable --depth=1 https://github.com/pybind/pybind11.git
+before_build:
+ - cmd: if not exist C:\"Program Files"\Eigen\include\eigen3\Eigen\Core (
+ curl -LO https://gitlab.com/libeigen/eigen/-/archive/3.4.0/eigen-3.4.0.tar.gz &&
+ cmake -E tar zxf eigen-3.4.0.tar.gz &&
+ cd eigen-3.4.0 &&
+ mkdir build &&
+ cd build &&
+ cmake -G "MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=C:\projects .. &&
+ cmake --build . --target install &&
+ cd ..\..
+ ) else (echo Using cached Eigen3)
+
build_script:
- cmake -G "MinGW Makefiles" -Denable_documentation=OFF -Denable_java=ON -Denable_msg=ON -Denable_smpi=OFF -Denable_mallocators=OFF -Denable_lto=OFF .
- mingw32-make.exe VERBOSE=1 java-all python-bindings # Only the Java and Python parts
Toufik Boubehziz <toufik.boubehziz@gmail.com>
Toufik Boubehziz <toufik.boubehziz@gmail.com> <boubehtoufik@hotmail.fr>
Toufik Boubehziz <toufik.boubehziz@gmail.com> <toufik.boubehziz@inria.fr>
+Jean-Edouard Boulanger <jean.edouard.boulanger@gmail.com>
Paul Bédaride <paul.bedaride@gmail.com>
Paul Bédaride <paul.bedaride@gmail.com> <bedaride@beowulf.loria.fr>
Paul Bédaride <paul.bedaride@gmail.com> <paul.bedaride@ptitpoulpe.fr>
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads)
+### Check for Eigen library
+find_package (Eigen3 3.3 REQUIRED NO_MODULE)
+message(STATUS "Found Eigen3: ${EIGEN3_INCLUDE_DIR}")
+include_directories(${EIGEN3_INCLUDE_DIR})
+
### Setup Options
include(${CMAKE_HOME_DIRECTORY}/tools/cmake/Option.cmake)
MC:
- Rework the internals, for simpler and modern code. This shall unlock many future improvements.
- - You can now define plugins onto SafetyChecker (a simple DFS explorer), using the declared signals.
- See CommunicationDeterminism for an example.
+ - You can now define plugins onto the DFS explorer (previously called SafetyChecker), using the
+ declared signals. See CommunicationDeterminism for an example.
- Support mutex, semaphore and barrier in DPOR reduction
- Seems to work on Arm64 architectures too.
- Display a nice error message when ptrace is not usable.
S4U:
- New signal: Engine::on_simulation_start_cb()
+ - Introduce a new execution mode with this_actor::thread_execute(). This simulate
+ the execution of a certain amount of flops by multiple threads ran by a host. Each
+ thread executes the same number of flops, given as argument. An example of this new
+ function can be found in examples/cpp/exec-threads.
- Reimplementation of barriers natively.
Previously, they were implemented on top of s4u::Mutex and s4u::ConditionVariable.
The new version should be faster (and can be used in the model-checker).
+ - Actor::get_restart_count(): Returns the number of reboots that this actor did.
MSG:
- MSG_barrier_destroy now expects a non-const msg_barrier parameter.
- Along with the new simgrid-monkey script, it tests whether your simulation
resists resource failures at any possible timestamp in your simulation.
- It is mostly intended to test the simgrid core in extreme conditions,
- but users may find it interesting too.
+ but some users may find it interesting too.
+
+Models:
+ - New model for parallel task: ptask_BMF.
+ - More realistic sharing of heterogeneous resources compared to ptask_L07.
+ - Implement the BMF (Bottleneck max fairness) fairness.
+ - Improved resource sharing for parallel tasks with sub-flows (parallel
+ communications between same source and destination inside the ptask).
+ - Parameters:
+ - "--cfg=host/model:ptask_BMF": enable the model.
+ - "--cfg=bmf/max-iterations: <N>" - maximum number of iterations performed
+ by BMF solver (default: 1000).
+ - "--cfg=bmf/selective-update:<true/false>" - enable/disable the
+ selective-update optimization. Only invalidates and recomputes modified
+ parts of inequations system. May speed up simulation if sparse resource
+ utilization (default: false).
+ - ATTENTION: this model requires Eigen3 library. If you install SimGrid
+ from source, please see the "Installing from source" section:
+ https://simgrid.org/doc/latest/Installing_SimGrid.html#installing-from-the-source.
+ No action is required if you use pre-compiled packages.
XBT:
- Drop xbt_dynar_shrink().
include examples/cpp/comm-failure/s4u-comm-failure.tesh
include examples/cpp/comm-host2host/s4u-comm-host2host.cpp
include examples/cpp/comm-host2host/s4u-comm-host2host.tesh
+include examples/cpp/comm-pingpong/debug-breakpoint.tesh
include examples/cpp/comm-pingpong/s4u-comm-pingpong.cpp
include examples/cpp/comm-pingpong/s4u-comm-pingpong.tesh
-include examples/cpp/comm-pingpong/simix-breakpoint.tesh
include examples/cpp/comm-ready/s4u-comm-ready.cpp
include examples/cpp/comm-ready/s4u-comm-ready.tesh
include examples/cpp/comm-serialize/s4u-comm-serialize.cpp
include examples/cpp/exec-ptask/s4u-exec-ptask.tesh
include examples/cpp/exec-remote/s4u-exec-remote.cpp
include examples/cpp/exec-remote/s4u-exec-remote.tesh
+include examples/cpp/exec-threads/s4u-exec-threads.cpp
+include examples/cpp/exec-threads/s4u-exec-threads.tesh
include examples/cpp/exec-unassigned/s4u-exec-unassigned.cpp
include examples/cpp/exec-unassigned/s4u-exec-unassigned.tesh
include examples/cpp/exec-waitany/s4u-exec-waitany.cpp
include examples/python/comm-waitall/comm-waitall.tesh
include examples/python/comm-waitany/comm-waitany.py
include examples/python/comm-waitany/comm-waitany.tesh
+include examples/python/comm-waitfor/comm-waitfor.py
+include examples/python/comm-waitfor/comm-waitfor.tesh
include examples/python/exec-async/exec-async.py
include examples/python/exec-async/exec-async.tesh
include examples/python/exec-basic/exec-basic.py
include teshsuite/models/cloud-sharing/cloud-sharing.tesh
include teshsuite/models/cm02-set-lat-bw/cm02-set-lat-bw.cpp
include teshsuite/models/cm02-set-lat-bw/cm02-set-lat-bw.tesh
+include teshsuite/models/ptask-subflows/ptask-subflows.cpp
+include teshsuite/models/ptask-subflows/ptask-subflows.tesh
include teshsuite/models/ptask_L07_usage/ptask_L07_usage.cpp
include teshsuite/models/ptask_L07_usage/ptask_L07_usage.tesh
include teshsuite/models/wifi_usage/wifi_usage.cpp
include teshsuite/smpi/MBI/CollMatchingGenerator.py
include teshsuite/smpi/MBI/MBI.py
include teshsuite/smpi/MBI/MBIutils.py
+include teshsuite/smpi/MBI/ResleakGenerator.py
include teshsuite/smpi/MBI/generator_utils.py
include teshsuite/smpi/MBI/simgrid.py
include teshsuite/smpi/auto-shared/auto-shared.c
include src/kernel/actor/ActorImpl.hpp
include src/kernel/actor/CommObserver.cpp
include src/kernel/actor/CommObserver.hpp
+include src/kernel/actor/Simcall.cpp
+include src/kernel/actor/Simcall.hpp
include src/kernel/actor/SimcallObserver.cpp
include src/kernel/actor/SimcallObserver.hpp
include src/kernel/actor/SynchroObserver.cpp
include src/kernel/context/ContextThread.hpp
include src/kernel/context/ContextUnix.cpp
include src/kernel/context/ContextUnix.hpp
+include src/kernel/lmm/bmf.cpp
+include src/kernel/lmm/bmf.hpp
+include src/kernel/lmm/bmf_test.cpp
include src/kernel/lmm/fair_bottleneck.cpp
include src/kernel/lmm/maxmin.cpp
include src/kernel/lmm/maxmin.hpp
include src/mc/api/State.hpp
include src/mc/compare.cpp
include src/mc/explo/CommunicationDeterminismChecker.cpp
+include src/mc/explo/DFSExplorer.cpp
+include src/mc/explo/DFSExplorer.hpp
include src/mc/explo/Exploration.hpp
include src/mc/explo/LivenessChecker.cpp
include src/mc/explo/LivenessChecker.hpp
-include src/mc/explo/SafetyChecker.cpp
-include src/mc/explo/SafetyChecker.hpp
include src/mc/explo/UdporChecker.cpp
include src/mc/explo/UdporChecker.hpp
include src/mc/explo/simgrid_mc.cpp
include src/simgrid/sg_version.cpp
include src/simgrid/util.hpp
include src/simix/libsmx.cpp
-include src/simix/popping.cpp
-include src/simix/popping_private.hpp
include src/simix/smx_context.cpp
include src/smpi/bindings/smpi_f77.cpp
include src/smpi/bindings/smpi_f77_coll.cpp
- **ptask_L07:** Host model somehow similar to Cas01+CM02 but
allowing "parallel tasks", that are intended to model the moldable
tasks of the grid scheduling literature.
+ - **ptask_BMF:** More realistic model for heterogeneous resource sharing.
+ Implements BMF (Bottleneck max fairness) fairness. To be used with
+ parallel tasks instead of ptask_L07.
- ``storage/model``: specify the used storage model. Only one model is
provided so far.
the execution and get a backtrace with a debugger.
It is also possible to set the breakpoint from inside the debugger, by
-writing in global variable simgrid::simix::breakpoint. For example,
+writing in global variable simgrid::kernel::cfg_breakpoint. For example,
with gdb:
.. code-block:: none
- set variable simgrid::simix::breakpoint = 3.1416
+ set variable simgrid::kernel::cfg_breakpoint = 3.1416
.. _cfg=debug/verbose-exit:
configuration options (e.g., if your Python installation is not standard).
boost (at least v1.48, v1.59 recommended)
- On Debian / Ubuntu: ``apt install libboost-dev libboost-context-dev``
+ - On CentOS / Fedora: ``yum install boost-devel``
- On macOS with homebrew: ``brew install boost``
+Eigen3
+ - On Debian / Ubuntu: ``apt install libeigen3-dev``
+ - On CentOS / Fedora: ``yum install eigen3-devel``
+ - On macOS with homebrew: ``brew install eigen``
Java (optional):
- Debian / Ubuntu: ``apt install default-jdk libgcj18-dev`` (or
any version of libgcj)
A formal verification with Mc SimGrid implies two processes: a verified application that is an almost regular SimGrid simulation, and a checker that
is an external process guiding the verified application to ensure that it explores every possible execution scenario. When formal verification was
-initially introduced in SimGrid 15 years ago, both processes were intertwined in the same system process but the mandated system tricks made it
-impossible to use classical debugging tools such as gdb or valgrind on that Frankenstein process. Having more than one heap in your process is not
-usually supported.
+initially introduced in SimGrid 15 years ago, both processes were intertwined in the same system process, but the mandated system tricks made it
+impossible to use gdb or valgrind on that Frankenstein process. Having more than one heap in your process is not usually supported.
-The design was simplified in v3.12 (2015) by splitting the application and the checker in separate system process. But both processes remained tightly
+The design was simplified in v3.12 (2015) by splitting the application and the checker in separate system processes. But both processes remained tightly
coupled: when the checker needed some information (for example the mailbox implied in a send operation to compute whether this operation `commutes
with another one <https://en.wikipedia.org/wiki/Partial_order_reduction>`_), the checker was directly reading the memory of the other system process.
This was efficient and nice in C, but it prevented us from using C++ features such as opaque ``std::function`` data types. As such, it hindered the
clear, but the checker code is now much easier to work with as the formal logic is not spoiled with system-level tricks to retrieve the needed information.
This cleaned design allowed us to finally implement the support for mutexes, semaphores and barriers in the model-checker. In particular, this should
-enable the verification of RMA primitives with Mc SimGrid, as their implementation in SMPI is based on mutexes and barriers.
+enable the verification of RMA primitives with Mc SimGrid, as their implementation in SMPI is based on mutexes and barriers. Simix, a central element of
+the SimGrid 3 design, was also finally removed: the last bits are deprecated and will be removed in 3.35. We also replaced the old, non-free ISP test suite
+by the one from the `MPI Bug Initiative <https://hal.archives-ouvertes.fr/hal-03474762>`_, but not all tests are activated yet. This should eventually
+help improving the robustness of Mc SimGrid.
-Future work on the model checker include: support for condition variables (that are still not handled), implementation of another exploration algorithm based on UDPOR
-(`The Anh Pham's thesis <https://tel.archives-ouvertes.fr/tel-02462074/document>`_ was defended in 2019), and robustness improvement using the `MPI Bug
-Initiative <https://hal.archives-ouvertes.fr/hal-03474762>`_ tests. Many things that were long dreamed of now become technically possible in this code base.
+Future work on the model checker include: support for condition variables (that are still not handled), implementation of another exploration algorithm
+based on event unfoldings (`The Anh Pham's thesis <https://tel.archives-ouvertes.fr/tel-02462074/document>`_ was defended in 2019), and the exploration
+of scenarios where the actors get killed and communications timeout. Many things that were long dreamed of now become technically possible in this code base.
+
+On the model front, we added BMF...
.. |br| raw:: html
.. doxygenfunction:: simgrid::s4u::Actor::join() const
.. doxygenfunction:: simgrid::s4u::Actor::join(double timeout) const
.. doxygenfunction:: simgrid::s4u::Actor::set_auto_restart(bool autorestart)
+ .. doxygenfunction:: simgrid::s4u::Actor::get_restart_count()
.. group-tab:: Python
.. doxygenfunction:: simgrid::s4u::Mailbox::get(double timeout)
.. doxygenfunction:: simgrid::s4u::Mailbox::get_async(T **data)
.. doxygenfunction:: simgrid::s4u::Mailbox::get_init()
- .. doxygenfunction:: simgrid::s4u::Mailbox::iprobe(int type, bool(*match_fun)(void *, void *, kernel::activity::CommImpl *), void *data)
+ .. doxygenfunction:: simgrid::s4u::Mailbox::iprobe(int type, const std::function<bool(void *, void *, kernel::activity::CommImpl *)>& match_fun, void *data)
.. doxygenfunction:: simgrid::s4u::Mailbox::listen
.. doxygenfunction:: simgrid::s4u::Mailbox::ready
#include <simgrid/comm.h>
.. doxygentypedef:: sg_comm_t
- .. doxygentypedef:: const_sg_comm_t
Querying info
-------------
.. doxygenfunction:: simgrid::s4u::Comm::set_dst_data(void **buff)
.. doxygenfunction:: simgrid::s4u::Comm::set_dst_data(void **buff, size_t size)
.. doxygenfunction:: simgrid::s4u::Comm::detach()
- .. doxygenfunction:: simgrid::s4u::Comm::detach(void(*clean_function)(void *))
+ .. doxygenfunction:: simgrid::s4u::Comm::detach(const std::function<void(void*)>& clean_function)
.. doxygenfunction:: simgrid::s4u::Comm::set_payload_size(uint64_t bytes)
.. doxygenfunction:: simgrid::s4u::Comm::set_rate(double rate)
.. doxygenfunction:: simgrid::s4u::Comm::set_src_data(void *buff)
#include <simgrid/barrier.hpp>
.. doxygentypedef:: sg_bar_t
- .. doxygentypedef:: const_sg_bar_t
.. doxygenfunction:: sg_barrier_init(unsigned int count)
- .. doxygenfunction:: sg_barrier_destroy(const_sg_bar_t bar)
+ .. doxygenfunction:: sg_barrier_destroy(sg_bar_t bar)
.. doxygenfunction:: sg_barrier_wait(sg_bar_t bar)
gfortran \
libboost-dev \
libboost-all-dev \
+ libeigen3-dev \
cmake \
dpkg-dev \
# misc tools
gfortran \
libboost-dev \
libboost-all-dev \
+ libeigen3-dev \
cmake \
dpkg-dev \
# misc tools
! output sort 19
$ ${bindir:=.}/c-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/../../cpp/platform-failures/s4u-platform-failures_d.xml --cfg=path:${srcdir} --cfg=network/crosstraffic:0 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose
> [ 0.000000] (0:maestro@) Cannot launch actor 'worker' on failed host 'Fafard'
-> [ 0.000000] (0:maestro@) Deployment includes some initially turned off Hosts ... nevermind.
+> [ 0.000000] (0:maestro@) Starting actor worker(Fafard) failed because its host is turned off.
> [ 0.000000] (1:master@Tremblay) Got 5 workers and 20 tasks to process
> [ 0.000000] (1:master@Tremblay) Send a message to worker-0
> [ 0.010309] (1:master@Tremblay) Send to worker-0 completed
! output sort 19
$ ${bindir:=.}/c-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/../../cpp/platform-failures/s4u-platform-failures_d.xml --cfg=path:${srcdir} "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose
> [ 0.000000] (0:maestro@) Cannot launch actor 'worker' on failed host 'Fafard'
-> [ 0.000000] (0:maestro@) Deployment includes some initially turned off Hosts ... nevermind.
+> [ 0.000000] (0:maestro@) Starting actor worker(Fafard) failed because its host is turned off.
> [ 0.000000] (1:master@Tremblay) Got 5 workers and 20 tasks to process
> [ 0.000000] (1:master@Tremblay) Send a message to worker-0
> [ 0.000000] (2:worker@Tremblay) Waiting a message on worker-0
energy-exec energy-boot energy-link energy-vm energy-exec-ptask energy-wifi
engine-filtering engine-run-partial
exec-async exec-basic exec-dvfs exec-remote exec-waitany exec-waitfor exec-dependent exec-unassigned
- exec-ptask-multicore exec-ptask-multicore-latency exec-cpu-nonlinear exec-cpu-factors exec-failure
+ exec-ptask-multicore exec-ptask-multicore-latency exec-cpu-nonlinear exec-cpu-factors exec-failure exec-threads
maestro-set
mc-bugged1 mc-bugged1-liveness mc-bugged2 mc-bugged2-liveness mc-centralized-mutex mc-electric-fence mc-failing-assert
network-ns3 network-ns3-wifi network-wifi
endforeach()
if (NOT enable_memcheck AND NOT WIN32)
- ADD_TESH(simix-breakpoint --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/comm-pingpong
+ ADD_TESH(debug-breakpoint --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/comm-pingpong
--setenv platfdir=${CMAKE_HOME_DIRECTORY}/examples/platforms
- ${CMAKE_CURRENT_SOURCE_DIR}/comm-pingpong/simix-breakpoint.tesh)
+ ${CMAKE_CURRENT_SOURCE_DIR}/comm-pingpong/debug-breakpoint.tesh)
endif()
# Add all extra files to the archive
####################################
set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness.cpp PARENT_SCOPE)
-set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/comm-pingpong/simix-breakpoint.tesh
+set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/comm-pingpong/debug-breakpoint.tesh
${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness.tesh
${CMAKE_CURRENT_SOURCE_DIR}/mc-bugged1-liveness/s4u-mc-bugged1-liveness-visited.tesh PARENT_SCOPE)
set(xml_files ${xml_files} ${CMAKE_CURRENT_SOURCE_DIR}/actor-create/s4u-actor-create_d.xml
-/* Copyright (c) 2012-2022. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2012-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. */
#include "s4u-tracker.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_bt_peer, "Messages specific for the peers");
+namespace sg4 = simgrid::s4u;
/*
* User parameters for transferred file data. For the test, the default values are :
xbt_assert(args.size() == 3 || args.size() == 4, "Wrong number of arguments");
try {
id = std::stoi(args[1]);
- mailbox_ = simgrid::s4u::Mailbox::by_name(std::to_string(id));
+ mailbox_ = sg4::Mailbox::by_name(std::to_string(id));
} catch (const std::invalid_argument&) {
throw std::invalid_argument("Invalid ID:" + args[1]);
}
// Getting peer data from the tracker.
if (getPeersFromTracker()) {
XBT_DEBUG("Got %zu peers from the tracker. Current status is: %s", connected_peers.size(), getStatus().c_str());
- begin_receive_time = simgrid::s4u::Engine::get_clock();
- mailbox_->set_receiver(simgrid::s4u::Actor::self());
+ begin_receive_time = sg4::Engine::get_clock();
+ mailbox_->set_receiver(sg4::Actor::self());
if (hasFinished()) {
sendHandshakeToAllPeers();
} else {
bool Peer::getPeersFromTracker()
{
- simgrid::s4u::Mailbox* tracker_mailbox = simgrid::s4u::Mailbox::by_name(TRACKER_MAILBOX);
+ sg4::Mailbox* tracker_mailbox = sg4::Mailbox::by_name(TRACKER_MAILBOX);
// Build the task to send to the tracker
auto* peer_request = new TrackerQuery(id, mailbox_);
try {
}
}
-void Peer::sendMessage(simgrid::s4u::Mailbox* mailbox, MessageType type, uint64_t size)
+void Peer::sendMessage(sg4::Mailbox* mailbox, MessageType type, uint64_t size)
{
XBT_DEBUG("Sending %s to %s", message_name(type), mailbox->get_cname());
mailbox->put_init(new Message(type, id, bitfield_, mailbox_), size)->detach();
}
-void Peer::sendBitfield(simgrid::s4u::Mailbox* mailbox)
+void Peer::sendBitfield(sg4::Mailbox* mailbox)
{
XBT_DEBUG("Sending a BITFIELD to %s", mailbox->get_cname());
mailbox
->detach();
}
-void Peer::sendPiece(simgrid::s4u::Mailbox* mailbox, unsigned int piece, int block_index, int block_length)
+void Peer::sendPiece(sg4::Mailbox* mailbox, unsigned int piece, int block_index, int block_length)
{
xbt_assert(not hasNotPiece(piece), "Tried to send a unavailable piece.");
XBT_DEBUG("Sending the PIECE %u (%d,%d) to %s", piece, block_index, block_length, mailbox->get_cname());
void Peer::leech()
{
- double next_choked_update = simgrid::s4u::Engine::get_clock() + UPDATE_CHOKED_INTERVAL;
+ double next_choked_update = sg4::Engine::get_clock() + UPDATE_CHOKED_INTERVAL;
XBT_DEBUG("Start downloading.");
/* Send a "handshake" message to all the peers it got (since it couldn't have gotten more than 50 peers) */
sendHandshakeToAllPeers();
XBT_DEBUG("Starting main leech loop listening on mailbox: %s", mailbox_->get_cname());
- while (simgrid::s4u::Engine::get_clock() < deadline && countPieces(bitfield_) < FILE_PIECES) {
+ while (sg4::Engine::get_clock() < deadline && countPieces(bitfield_) < FILE_PIECES) {
if (comm_received == nullptr) {
comm_received = mailbox_->get_async<Message>(&message);
}
comm_received = nullptr;
} else {
// We don't execute the choke algorithm if we don't already have a piece
- if (simgrid::s4u::Engine::get_clock() >= next_choked_update && countPieces(bitfield_) > 0) {
+ if (sg4::Engine::get_clock() >= next_choked_update && countPieces(bitfield_) > 0) {
updateChokedPeers();
next_choked_update += UPDATE_CHOKED_INTERVAL;
} else {
- simgrid::s4u::this_actor::sleep_for(SLEEP_DURATION);
+ sg4::this_actor::sleep_for(SLEEP_DURATION);
}
}
}
void Peer::seed()
{
- double next_choked_update = simgrid::s4u::Engine::get_clock() + UPDATE_CHOKED_INTERVAL;
+ double next_choked_update = sg4::Engine::get_clock() + UPDATE_CHOKED_INTERVAL;
XBT_DEBUG("Start seeding.");
// start the main seed loop
- while (simgrid::s4u::Engine::get_clock() < deadline) {
+ while (sg4::Engine::get_clock() < deadline) {
if (comm_received == nullptr) {
comm_received = mailbox_->get_async<Message>(&message);
}
delete message;
comm_received = nullptr;
} else {
- if (simgrid::s4u::Engine::get_clock() >= next_choked_update) {
+ if (sg4::Engine::get_clock() >= next_choked_update) {
updateChokedPeers();
// TODO: Change the choked peer algorithm when seeding.
next_choked_update += UPDATE_CHOKED_INTERVAL;
} else {
- simgrid::s4u::this_actor::sleep_for(SLEEP_DURATION);
+ sg4::this_actor::sleep_for(SLEEP_DURATION);
}
}
}
}
// Update the peer speed.
if (remote_peer) {
- remote_peer->addSpeedValue(1.0 / (simgrid::s4u::Engine::get_clock() - begin_receive_time));
+ remote_peer->addSpeedValue(1.0 / (sg4::Engine::get_clock() - begin_receive_time));
}
- begin_receive_time = simgrid::s4u::Engine::get_clock();
+ begin_receive_time = sg4::Engine::get_clock();
}
/** Selects the appropriate piece to download and requests it to the remote_peer */
/**If we are currently seeding, we unchoke the peer which has been unchoked the last time.*/
if (hasFinished()) {
- double unchoke_time = simgrid::s4u::Engine::get_clock() + 1;
+ double unchoke_time = sg4::Engine::get_clock() + 1;
for (auto& kv : connected_peers) {
Connection& remote_peer = kv.second;
if (remote_peer.last_unchoke < unchoke_time && remote_peer.interested && remote_peer.choked_upload) {
xbt_assert((chosen_peer->choked_upload), "Tries to unchoked an unchoked peer");
chosen_peer->choked_upload = false;
active_peers.insert(chosen_peer);
- chosen_peer->last_unchoke = simgrid::s4u::Engine::get_clock();
+ chosen_peer->last_unchoke = sg4::Engine::get_clock();
XBT_DEBUG("(%d) Sending a UNCHOKE to %d", id, chosen_peer->id);
updateActivePeersSet(chosen_peer);
sendMessage(chosen_peer->mailbox_, MessageType::UNCHOKE, message_size(MessageType::UNCHOKE));
-/* Copyright (c) 2012-2022. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2012-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. */
#include <algorithm>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_bt_tracker, "Messages specific for the tracker");
+namespace sg4 = simgrid::s4u;
Tracker::Tracker(std::vector<std::string> args)
{
}
xbt_assert(deadline > 0, "Wrong deadline supplied");
- mailbox = simgrid::s4u::Mailbox::by_name(TRACKER_MAILBOX);
+ mailbox = sg4::Mailbox::by_name(TRACKER_MAILBOX);
XBT_INFO("Tracker launched.");
}
void Tracker::operator()()
{
- simgrid::s4u::CommPtr comm = nullptr;
+ sg4::CommPtr comm = nullptr;
TrackerQuery* query = nullptr;
- while (simgrid::s4u::Engine::get_clock() < deadline) {
+ while (sg4::Engine::get_clock() < deadline) {
if (comm == nullptr)
comm = mailbox->get_async<TrackerQuery>(&query);
if (comm->test()) {
delete query;
comm = nullptr;
} else {
- simgrid::s4u::this_actor::sleep_for(1);
+ sg4::this_actor::sleep_for(1);
}
}
XBT_INFO("Tracker is leaving");
constexpr unsigned MESSAGE_SEND_DATA_HEADER_SIZE = 1;
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_chainsend, "Messages specific for chainsend");
+namespace sg4 = simgrid::s4u;
class ChainMessage {
public:
- simgrid::s4u::Mailbox* prev_ = nullptr;
- simgrid::s4u::Mailbox* next_ = nullptr;
+ sg4::Mailbox* prev_ = nullptr;
+ sg4::Mailbox* next_ = nullptr;
unsigned int num_pieces = 0;
- explicit ChainMessage(simgrid::s4u::Mailbox* prev, simgrid::s4u::Mailbox* next, const unsigned int num_pieces)
+ explicit ChainMessage(sg4::Mailbox* prev, sg4::Mailbox* next, const unsigned int num_pieces)
: prev_(prev), next_(next), num_pieces(num_pieces)
{
}
class Peer {
public:
- simgrid::s4u::Mailbox* prev = nullptr;
- simgrid::s4u::Mailbox* next = nullptr;
- simgrid::s4u::Mailbox* me = nullptr;
- std::vector<simgrid::s4u::CommPtr> pending_recvs;
- std::vector<simgrid::s4u::CommPtr> pending_sends;
+ sg4::Mailbox* prev = nullptr;
+ sg4::Mailbox* next = nullptr;
+ sg4::Mailbox* me = nullptr;
+ std::vector<sg4::CommPtr> pending_recvs;
+ std::vector<sg4::CommPtr> pending_sends;
unsigned long long received_bytes = 0;
unsigned int received_pieces = 0;
unsigned int total_pieces = 0;
- Peer() { me = simgrid::s4u::Mailbox::by_name(simgrid::s4u::Host::current()->get_cname()); }
+ Peer() { me = sg4::Mailbox::by_name(sg4::Host::current()->get_cname()); }
void joinChain()
{
bool done = false;
while (not done) {
- simgrid::s4u::CommPtr comm = me->get_async<FilePiece>(&received);
+ sg4::CommPtr comm = me->get_async<FilePiece>(&received);
pending_recvs.push_back(comm);
- ssize_t idx = simgrid::s4u::Comm::wait_any(pending_recvs);
+ ssize_t idx = sg4::Comm::wait_any(pending_recvs);
if (idx != -1) {
comm = pending_recvs.at(idx);
XBT_DEBUG("Peer %s got a 'SEND_DATA' message", me->get_cname());
pending_recvs.erase(pending_recvs.begin() + idx);
if (next != nullptr) {
XBT_DEBUG("Sending (asynchronously) from %s to %s", me->get_cname(), next->get_cname());
- simgrid::s4u::CommPtr send = next->put_async(received, MESSAGE_SEND_DATA_HEADER_SIZE + PIECE_SIZE);
+ sg4::CommPtr send = next->put_async(received, MESSAGE_SEND_DATA_HEADER_SIZE + PIECE_SIZE);
pending_sends.push_back(send);
} else
delete received;
class Broadcaster {
public:
- simgrid::s4u::Mailbox* first = nullptr;
- std::vector<simgrid::s4u::Mailbox*> mailboxes;
+ sg4::Mailbox* first = nullptr;
+ std::vector<sg4::Mailbox*> mailboxes;
unsigned int piece_count;
void buildChain()
first = mailboxes.front();
for (unsigned i = 0; i < mailboxes.size(); i++) {
- simgrid::s4u::Mailbox* prev = i > 0 ? mailboxes[i - 1] : nullptr;
- simgrid::s4u::Mailbox* next = i < mailboxes.size() - 1 ? mailboxes[i + 1] : nullptr;
+ sg4::Mailbox* prev = i > 0 ? mailboxes[i - 1] : nullptr;
+ sg4::Mailbox* next = i < mailboxes.size() - 1 ? mailboxes[i + 1] : nullptr;
XBT_DEBUG("Building chain--broadcaster:\"%s\" dest:\"%s\" prev:\"%s\" next:\"%s\"",
- simgrid::s4u::Host::current()->get_cname(), mailboxes[i]->get_cname(),
- prev ? prev->get_cname() : nullptr, next ? next->get_cname() : nullptr);
+ sg4::Host::current()->get_cname(), mailboxes[i]->get_cname(), prev ? prev->get_cname() : nullptr,
+ next ? next->get_cname() : nullptr);
/* Send message to current peer */
mailboxes[i]->put(new ChainMessage(prev, next, piece_count), MESSAGE_BUILD_CHAIN_SIZE);
}
void sendFile()
{
- std::vector<simgrid::s4u::CommPtr> pending_sends;
+ std::vector<sg4::CommPtr> pending_sends;
for (unsigned int current_piece = 0; current_piece < piece_count; current_piece++) {
- XBT_DEBUG("Sending (send) piece %u from %s into mailbox %s", current_piece,
- simgrid::s4u::Host::current()->get_cname(), first->get_cname());
- simgrid::s4u::CommPtr comm = first->put_async(new FilePiece(), MESSAGE_SEND_DATA_HEADER_SIZE + PIECE_SIZE);
+ XBT_DEBUG("Sending (send) piece %u from %s into mailbox %s", current_piece, sg4::Host::current()->get_cname(),
+ first->get_cname());
+ sg4::CommPtr comm = first->put_async(new FilePiece(), MESSAGE_SEND_DATA_HEADER_SIZE + PIECE_SIZE);
pending_sends.push_back(comm);
}
- simgrid::s4u::Comm::wait_all(pending_sends);
+ sg4::Comm::wait_all(pending_sends);
}
Broadcaster(int hostcount, unsigned int piece_count) : piece_count(piece_count)
for (int i = 1; i <= hostcount; i++) {
std::string name = std::string("node-") + std::to_string(i) + ".simgrid.org";
XBT_DEBUG("%s", name.c_str());
- mailboxes.push_back(simgrid::s4u::Mailbox::by_name(name));
+ mailboxes.push_back(sg4::Mailbox::by_name(name));
}
}
};
Peer p;
- double start_time = simgrid::s4u::Engine::get_clock();
+ double start_time = sg4::Engine::get_clock();
p.joinChain();
p.forwardFile();
- simgrid::s4u::Comm::wait_all(p.pending_sends);
- double end_time = simgrid::s4u::Engine::get_clock();
+ sg4::Comm::wait_all(p.pending_sends);
+ double end_time = sg4::Engine::get_clock();
XBT_INFO("### %f %llu bytes (Avg %f MB/s); copy finished (simulated).", end_time - start_time, p.received_bytes,
p.received_bytes / 1024.0 / 1024.0 / (end_time - start_time));
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("broadcaster", e.host_by_name("node-0.simgrid.org"), broadcaster, 8, 256);
+ sg4::Actor::create("broadcaster", e.host_by_name("node-0.simgrid.org"), broadcaster, 8, 256);
- simgrid::s4u::Actor::create("peer", e.host_by_name("node-1.simgrid.org"), peer);
- simgrid::s4u::Actor::create("peer", e.host_by_name("node-2.simgrid.org"), peer);
- simgrid::s4u::Actor::create("peer", e.host_by_name("node-3.simgrid.org"), peer);
- simgrid::s4u::Actor::create("peer", e.host_by_name("node-4.simgrid.org"), peer);
- simgrid::s4u::Actor::create("peer", e.host_by_name("node-5.simgrid.org"), peer);
- simgrid::s4u::Actor::create("peer", e.host_by_name("node-6.simgrid.org"), peer);
- simgrid::s4u::Actor::create("peer", e.host_by_name("node-7.simgrid.org"), peer);
- simgrid::s4u::Actor::create("peer", e.host_by_name("node-8.simgrid.org"), peer);
+ sg4::Actor::create("peer", e.host_by_name("node-1.simgrid.org"), peer);
+ sg4::Actor::create("peer", e.host_by_name("node-2.simgrid.org"), peer);
+ sg4::Actor::create("peer", e.host_by_name("node-3.simgrid.org"), peer);
+ sg4::Actor::create("peer", e.host_by_name("node-4.simgrid.org"), peer);
+ sg4::Actor::create("peer", e.host_by_name("node-5.simgrid.org"), peer);
+ sg4::Actor::create("peer", e.host_by_name("node-6.simgrid.org"), peer);
+ sg4::Actor::create("peer", e.host_by_name("node-7.simgrid.org"), peer);
+ sg4::Actor::create("peer", e.host_by_name("node-8.simgrid.org"), peer);
e.run();
- XBT_INFO("Total simulation time: %e", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Total simulation time: %e", sg4::Engine::get_clock());
return 0;
}
#include <simgrid/s4u.hpp>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_app_masterworker, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
class Master {
long tasks_count = 0;
double compute_cost = 0;
long communicate_cost = 0;
- std::vector<simgrid::s4u::Mailbox*> workers;
+ std::vector<sg4::Mailbox*> workers;
public:
explicit Master(std::vector<std::string> args)
compute_cost = std::stod(args[2]);
communicate_cost = std::stol(args[3]);
for (unsigned int i = 4; i < args.size(); i++)
- workers.push_back(simgrid::s4u::Mailbox::by_name(args[i]));
+ workers.push_back(sg4::Mailbox::by_name(args[i]));
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 */
- simgrid::s4u::Mailbox* mailbox = workers[i % workers.size()];
+ sg4::Mailbox* 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 (unsigned int i = 0; i < workers.size(); i++) {
/* The workers stop when receiving a negative compute_cost */
- simgrid::s4u::Mailbox* mailbox = workers[i % workers.size()];
+ sg4::Mailbox* mailbox = workers[i % workers.size()];
mailbox->put(new double(-1.0), 0);
}
}
};
class Worker {
- simgrid::s4u::Mailbox* mailbox = nullptr;
+ sg4::Mailbox* mailbox = nullptr;
public:
explicit Worker(std::vector<std::string> args)
{
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());
+ mailbox = sg4::Mailbox::by_name(sg4::this_actor::get_host()->get_name());
}
void operator()()
compute_cost = *msg;
if (compute_cost > 0) /* If compute_cost is valid, execute a computation of that cost */
- simgrid::s4u::this_actor::execute(compute_cost);
+ sg4::this_actor::execute(compute_cost);
} while (compute_cost > 0); /* Stop when receiving an invalid compute_cost */
XBT_INFO("Exiting now.");
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 2, "Usage: %s platform_file deployment_file\n", argv[0]);
/* Register the classes representing the actors */
/* ************************************************************************* */
#include <simgrid/s4u.hpp>
+namespace sg4 = simgrid::s4u;
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_app_masterworker, "Messages specific for this example");
long tasks_count = std::stol(args[1]);
double compute_cost = std::stod(args[2]);
long communication_cost = std::stol(args[3]);
- std::vector<simgrid::s4u::Mailbox*> workers;
+ std::vector<sg4::Mailbox*> workers;
for (unsigned int i = 4; i < args.size(); i++)
- workers.push_back(simgrid::s4u::Mailbox::by_name(args[i]));
+ workers.push_back(sg4::Mailbox::by_name(args[i]));
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 */
- simgrid::s4u::Mailbox* mailbox = workers[i % workers.size()];
+ sg4::Mailbox* 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 (unsigned int i = 0; i < workers.size(); i++) {
/* The workers stop when receiving a negative compute_cost */
- simgrid::s4u::Mailbox* mailbox = workers[i % workers.size()];
+ sg4::Mailbox* mailbox = workers[i % workers.size()];
mailbox->put(new double(-1.0), 0);
}
{
xbt_assert(args.size() == 1, "The worker expects no argument");
- const simgrid::s4u::Host* my_host = simgrid::s4u::this_actor::get_host();
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(my_host->get_name());
+ const sg4::Host* my_host = sg4::this_actor::get_host();
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(my_host->get_name());
double compute_cost;
do {
compute_cost = *msg;
if (compute_cost > 0) /* If compute_cost is valid, execute a computation of that cost */
- simgrid::s4u::this_actor::execute(compute_cost);
+ sg4::this_actor::execute(compute_cost);
} while (compute_cost > 0); /* Stop when receiving an invalid compute_cost */
XBT_INFO("Exiting now.");
// main-begin
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 2, "Usage: %s platform_file deployment_file\n", argv[0]);
/* Register the functions representing the actors */
#include <vector>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_app_token_ring, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
class RelayRunner {
public:
void operator()() const
{
size_t token_size = 1000000; /* The token is 1MB long*/
- simgrid::s4u::Mailbox* my_mailbox;
- simgrid::s4u::Mailbox* neighbor_mailbox;
+ sg4::Mailbox* my_mailbox;
+ sg4::Mailbox* neighbor_mailbox;
unsigned int rank = 0;
try {
- rank = std::stoi(simgrid::s4u::this_actor::get_name());
+ rank = std::stoi(sg4::this_actor::get_name());
} catch (const std::invalid_argument& ia) {
throw std::invalid_argument(std::string("Actors of this example must have a numerical name, not ") + ia.what());
}
- my_mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(rank));
- if (rank + 1 == simgrid::s4u::Engine::get_instance()->get_host_count())
+ my_mailbox = sg4::Mailbox::by_name(std::to_string(rank));
+ if (rank + 1 == sg4::Engine::get_instance()->get_host_count())
/* The last actor sends the token back to rank 0 */
- neighbor_mailbox = simgrid::s4u::Mailbox::by_name("0");
+ neighbor_mailbox = sg4::Mailbox::by_name("0");
else
/* The others actors send to their right neighbor (rank+1) */
- neighbor_mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(rank + 1));
+ neighbor_mailbox = sg4::Mailbox::by_name(std::to_string(rank + 1));
if (rank == 0) {
/* The root actor (rank 0) first sends the token then waits to receive it back */
int main(int argc, char** argv)
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 1, "Usage: %s platform.xml\n", argv[0]);
e.load_platform(argv[1]);
XBT_INFO("Number of hosts '%zu'", e.get_host_count());
int id = 0;
- std::vector<simgrid::s4u::Host*> list = e.get_all_hosts();
+ std::vector<sg4::Host*> list = e.get_all_hosts();
for (auto const& host : list) {
/* - Give a unique rank to each host and create a @ref relay_runner actor on each */
- simgrid::s4u::Actor::create((std::to_string(id)).c_str(), host, RelayRunner());
+ sg4::Actor::create((std::to_string(id)).c_str(), host, RelayRunner());
id++;
}
e.run();
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
#include "simgrid/s4u/VirtualMachine.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void worker(double computation_amount, bool use_bound, double bound)
{
- double clock_start = simgrid::s4u::Engine::get_clock();
+ double clock_start = sg4::Engine::get_clock();
- simgrid::s4u::ExecPtr exec = simgrid::s4u::this_actor::exec_init(computation_amount);
+ sg4::ExecPtr exec = sg4::this_actor::exec_init(computation_amount);
if (use_bound) {
if (bound < 1e-12) /* close enough to 0 without any floating precision surprise */
}
exec->start();
exec->wait();
- double clock_end = simgrid::s4u::Engine::get_clock();
+ double clock_end = sg4::Engine::get_clock();
double duration = clock_end - clock_start;
double flops_per_sec = computation_amount / duration;
static void worker_busy_loop(const char* name, double speed)
{
double exec_remain_prev = 1e11;
- simgrid::s4u::ExecPtr exec = simgrid::s4u::this_actor::exec_async(exec_remain_prev);
+ sg4::ExecPtr exec = sg4::this_actor::exec_async(exec_remain_prev);
for (int i = 0; i < 10; i++) {
if (speed > 0) {
double new_bound = (speed / 10) * i;
XBT_INFO("set bound of VM1 to %f", new_bound);
- static_cast<simgrid::s4u::VirtualMachine*>(simgrid::s4u::this_actor::get_host())->set_bound(new_bound);
+ static_cast<sg4::VirtualMachine*>(sg4::this_actor::get_host())->set_bound(new_bound);
}
- simgrid::s4u::this_actor::sleep_for(100);
+ sg4::this_actor::sleep_for(100);
double exec_remain_now = exec->get_remaining();
double flops_per_sec = exec_remain_prev - exec_remain_now;
- XBT_INFO("%s@%s: %.0f flops/s", name, simgrid::s4u::this_actor::get_host()->get_cname(), flops_per_sec / 100);
+ XBT_INFO("%s@%s: %.0f flops/s", name, sg4::this_actor::get_host()->get_cname(), flops_per_sec / 100);
exec_remain_prev = exec_remain_now;
- simgrid::s4u::this_actor::sleep_for(1);
+ sg4::this_actor::sleep_for(1);
}
exec->wait();
}
static void test_dynamic_change()
{
- simgrid::s4u::Host* pm0 = simgrid::s4u::Host::by_name("Fafard");
+ sg4::Host* pm0 = sg4::Host::by_name("Fafard");
auto* vm0 = pm0->create_vm("VM0", 1);
auto* vm1 = pm0->create_vm("VM1", 1);
vm0->start();
vm1->start();
- simgrid::s4u::Actor::create("worker0", vm0, worker_busy_loop, "Task0", -1);
- simgrid::s4u::Actor::create("worker1", vm1, worker_busy_loop, "Task1", pm0->get_speed());
+ sg4::Actor::create("worker0", vm0, worker_busy_loop, "Task0", -1);
+ sg4::Actor::create("worker1", vm1, worker_busy_loop, "Task1", pm0->get_speed());
- simgrid::s4u::this_actor::sleep_for(3000); // let the activities end
+ sg4::this_actor::sleep_for(3000); // let the activities end
vm0->destroy();
vm1->destroy();
}
-static void test_one_activity(simgrid::s4u::Host* host)
+static void test_one_activity(sg4::Host* host)
{
const double cpu_speed = host->get_speed();
const double computation_amount = cpu_speed * 10;
XBT_INFO("### Test: with/without activity set_bound");
XBT_INFO("### Test: no bound for Task1@%s", host->get_cname());
- simgrid::s4u::Actor::create("worker0", host, worker, computation_amount, false, 0);
+ sg4::Actor::create("worker0", host, worker, computation_amount, false, 0);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::this_actor::sleep_for(1000);
XBT_INFO("### Test: 50%% for Task1@%s", host->get_cname());
- simgrid::s4u::Actor::create("worker0", host, worker, computation_amount, true, cpu_speed / 2);
+ sg4::Actor::create("worker0", host, worker, computation_amount, true, cpu_speed / 2);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::this_actor::sleep_for(1000);
XBT_INFO("### Test: 33%% for Task1@%s", host->get_cname());
- simgrid::s4u::Actor::create("worker0", host, worker, computation_amount, true, cpu_speed / 3);
+ sg4::Actor::create("worker0", host, worker, computation_amount, true, cpu_speed / 3);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::this_actor::sleep_for(1000);
XBT_INFO("### Test: zero for Task1@%s (i.e., unlimited)", host->get_cname());
- simgrid::s4u::Actor::create("worker0", host, worker, computation_amount, true, 0);
+ sg4::Actor::create("worker0", host, worker, computation_amount, true, 0);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::this_actor::sleep_for(1000);
XBT_INFO("### Test: 200%% for Task1@%s (i.e., meaningless)", host->get_cname());
- simgrid::s4u::Actor::create("worker0", host, worker, computation_amount, true, cpu_speed * 2);
+ sg4::Actor::create("worker0", host, worker, computation_amount, true, cpu_speed * 2);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::this_actor::sleep_for(1000);
}
-static void test_two_activities(simgrid::s4u::Host* hostA, simgrid::s4u::Host* hostB)
+static void test_two_activities(sg4::Host* hostA, sg4::Host* hostB)
{
const double cpu_speed = hostA->get_speed();
xbt_assert(cpu_speed == hostB->get_speed());
const char* hostB_name = hostB->get_cname();
XBT_INFO("### Test: no bound for Task1@%s, no bound for Task2@%s", hostA_name, hostB_name);
- simgrid::s4u::Actor::create("worker0", hostA, worker, computation_amount, false, 0);
- simgrid::s4u::Actor::create("worker1", hostB, worker, computation_amount, false, 0);
+ sg4::Actor::create("worker0", hostA, worker, computation_amount, false, 0);
+ sg4::Actor::create("worker1", hostB, worker, computation_amount, false, 0);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::this_actor::sleep_for(1000);
XBT_INFO("### Test: 0 for Task1@%s, 0 for Task2@%s (i.e., unlimited)", hostA_name, hostB_name);
- simgrid::s4u::Actor::create("worker0", hostA, worker, computation_amount, true, 0);
- simgrid::s4u::Actor::create("worker1", hostB, worker, computation_amount, true, 0);
+ sg4::Actor::create("worker0", hostA, worker, computation_amount, true, 0);
+ sg4::Actor::create("worker1", hostB, worker, computation_amount, true, 0);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::this_actor::sleep_for(1000);
XBT_INFO("### Test: 50%% for Task1@%s, 50%% for Task2@%s", hostA_name, hostB_name);
- simgrid::s4u::Actor::create("worker0", hostA, worker, computation_amount, true, cpu_speed / 2);
- simgrid::s4u::Actor::create("worker1", hostB, worker, computation_amount, true, cpu_speed / 2);
+ sg4::Actor::create("worker0", hostA, worker, computation_amount, true, cpu_speed / 2);
+ sg4::Actor::create("worker1", hostB, worker, computation_amount, true, cpu_speed / 2);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::this_actor::sleep_for(1000);
XBT_INFO("### Test: 25%% for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name);
- simgrid::s4u::Actor::create("worker0", hostA, worker, computation_amount, true, cpu_speed / 4);
- simgrid::s4u::Actor::create("worker1", hostB, worker, computation_amount, true, cpu_speed / 4);
+ sg4::Actor::create("worker0", hostA, worker, computation_amount, true, cpu_speed / 4);
+ sg4::Actor::create("worker1", hostB, worker, computation_amount, true, cpu_speed / 4);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::this_actor::sleep_for(1000);
XBT_INFO("### Test: 75%% for Task1@%s, 100%% for Task2@%s", hostA_name, hostB_name);
- simgrid::s4u::Actor::create("worker0", hostA, worker, computation_amount, true, cpu_speed * 0.75);
- simgrid::s4u::Actor::create("worker1", hostB, worker, computation_amount, true, cpu_speed);
+ sg4::Actor::create("worker0", hostA, worker, computation_amount, true, cpu_speed * 0.75);
+ sg4::Actor::create("worker1", hostB, worker, computation_amount, true, cpu_speed);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::this_actor::sleep_for(1000);
XBT_INFO("### Test: no bound for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name);
- simgrid::s4u::Actor::create("worker0", hostA, worker, computation_amount, false, 0);
- simgrid::s4u::Actor::create("worker1", hostB, worker, computation_amount, true, cpu_speed / 4);
+ sg4::Actor::create("worker0", hostA, worker, computation_amount, false, 0);
+ sg4::Actor::create("worker1", hostB, worker, computation_amount, true, cpu_speed / 4);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::this_actor::sleep_for(1000);
XBT_INFO("### Test: 75%% for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name);
- simgrid::s4u::Actor::create("worker0", hostA, worker, computation_amount, true, cpu_speed * 0.75);
- simgrid::s4u::Actor::create("worker1", hostB, worker, computation_amount, true, cpu_speed / 4);
+ sg4::Actor::create("worker0", hostA, worker, computation_amount, true, cpu_speed * 0.75);
+ sg4::Actor::create("worker1", hostB, worker, computation_amount, true, cpu_speed / 4);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::this_actor::sleep_for(1000);
}
static void master_main()
{
- simgrid::s4u::Host* pm0 = simgrid::s4u::Host::by_name("Fafard");
+ sg4::Host* pm0 = sg4::Host::by_name("Fafard");
XBT_INFO("# 1. Put a single activity on a PM.");
test_one_activity(pm0);
const double computation_amount = cpu_speed * 10;
XBT_INFO("# 10. (a) Put an activity on a VM without any bound.");
- simgrid::s4u::Actor::create("worker0", vm0, worker, computation_amount, false, 0);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::Actor::create("worker0", vm0, worker, computation_amount, false, 0);
+ sg4::this_actor::sleep_for(1000);
XBT_INFO(".");
XBT_INFO("# 10. (b) set 10%% bound to the VM, and then put an activity on the VM.");
vm0->set_bound(cpu_speed / 10);
- simgrid::s4u::Actor::create("worker0", vm0, worker, computation_amount, false, 0);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::Actor::create("worker0", vm0, worker, computation_amount, false, 0);
+ sg4::this_actor::sleep_for(1000);
XBT_INFO(".");
XBT_INFO("# 10. (c) migrate");
- simgrid::s4u::Host* pm1 = simgrid::s4u::Host::by_name("Fafard");
+ sg4::Host* pm1 = sg4::Host::by_name("Fafard");
sg_vm_migrate(vm0, pm1);
XBT_INFO(".");
XBT_INFO("# 10. (d) Put an activity again on the VM.");
- simgrid::s4u::Actor::create("worker0", vm0, worker, computation_amount, false, 0);
- simgrid::s4u::this_actor::sleep_for(1000);
+ sg4::Actor::create("worker0", vm0, worker, computation_amount, false, 0);
+ sg4::this_actor::sleep_for(1000);
XBT_INFO(".");
vm0->destroy();
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
sg_vm_live_migration_plugin_init();
/* load the platform file */
xbt_assert(argc == 2, "Usage: %s platform_file\n\tExample: %s ../platforms/small_platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("master_", e.host_by_name("Fafard"), master_main);
+ sg4::Actor::create("master_", e.host_by_name("Fafard"), master_main);
e.run();
- XBT_INFO("Bye (simulation time %g)", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Bye (simulation time %g)", sg4::Engine::get_clock());
return 0;
}
#include "simgrid/s4u/VirtualMachine.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_cloud_migration, "Messages specific for this example");
+namespace sg4 = simgrid::s4u;
-static void vm_migrate(simgrid::s4u::VirtualMachine* vm, simgrid::s4u::Host* dst_pm)
+static void vm_migrate(sg4::VirtualMachine* vm, sg4::Host* dst_pm)
{
- const simgrid::s4u::Host* src_pm = vm->get_pm();
- double mig_sta = simgrid::s4u::Engine::get_clock();
+ const sg4::Host* src_pm = vm->get_pm();
+ double mig_sta = sg4::Engine::get_clock();
sg_vm_migrate(vm, dst_pm);
- double mig_end = simgrid::s4u::Engine::get_clock();
+ double mig_end = sg4::Engine::get_clock();
XBT_INFO("%s migrated: %s->%s in %g s", vm->get_cname(), src_pm->get_cname(), dst_pm->get_cname(), mig_end - mig_sta);
}
-static void vm_migrate_async(simgrid::s4u::VirtualMachine* vm, simgrid::s4u::Host* dst_pm)
+static void vm_migrate_async(sg4::VirtualMachine* vm, sg4::Host* dst_pm)
{
- simgrid::s4u::Actor::create("mig_wrk", simgrid::s4u::Host::current(), vm_migrate, vm, dst_pm);
+ sg4::Actor::create("mig_wrk", sg4::Host::current(), vm_migrate, vm, dst_pm);
}
static void master_main()
{
- simgrid::s4u::Host* pm0 = simgrid::s4u::Host::by_name("Fafard");
- simgrid::s4u::Host* pm1 = simgrid::s4u::Host::by_name("Tremblay");
- simgrid::s4u::Host* pm2 = simgrid::s4u::Host::by_name("Bourassa");
+ sg4::Host* pm0 = sg4::Host::by_name("Fafard");
+ sg4::Host* pm1 = sg4::Host::by_name("Tremblay");
+ sg4::Host* pm2 = sg4::Host::by_name("Bourassa");
auto* vm0 = pm0->create_vm("VM0", 1);
vm0->set_ramsize(1e9); // 1Gbytes
XBT_INFO("Test: Migrate two VMs at once from PM0 to PM1");
vm_migrate_async(vm0, pm1);
vm_migrate_async(vm1, pm1);
- simgrid::s4u::this_actor::sleep_for(10000);
+ sg4::this_actor::sleep_for(10000);
vm0->destroy();
vm1->destroy();
XBT_INFO("Test: Migrate two VMs at once to different PMs");
vm_migrate_async(vm0, pm1);
vm_migrate_async(vm1, pm2);
- simgrid::s4u::this_actor::sleep_for(10000);
+ sg4::this_actor::sleep_for(10000);
vm0->destroy();
vm1->destroy();
int main(int argc, char* argv[])
{
/* Get the arguments */
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
sg_vm_live_migration_plugin_init();
/* load the platform file */
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("master_", simgrid::s4u::Host::by_name("Fafard"), master_main);
+ sg4::Actor::create("master_", sg4::Host::by_name("Fafard"), master_main);
e.run();
- XBT_INFO("Bye (simulation time %g)", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Bye (simulation time %g)", sg4::Engine::get_clock());
return 0;
}
#include "simgrid/s4u/VirtualMachine.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void computation_fun()
{
- double clock_sta = simgrid::s4u::Engine::get_clock();
- simgrid::s4u::this_actor::execute(1000000);
- double clock_end = simgrid::s4u::Engine::get_clock();
+ double clock_sta = sg4::Engine::get_clock();
+ sg4::this_actor::execute(1000000);
+ double clock_end = sg4::Engine::get_clock();
- XBT_INFO("%s:%s executed %g", simgrid::s4u::this_actor::get_host()->get_cname(),
- simgrid::s4u::this_actor::get_cname(), clock_end - clock_sta);
+ XBT_INFO("%s:%s executed %g", sg4::this_actor::get_host()->get_cname(), sg4::this_actor::get_cname(),
+ clock_end - clock_sta);
}
static void launch_computation_worker(s4u_Host* host)
{
- simgrid::s4u::Actor::create("compute", host, computation_fun);
+ sg4::Actor::create("compute", host, computation_fun);
}
struct s_payload {
static void communication_tx_fun(std::vector<std::string> args)
{
- simgrid::s4u::Mailbox* mbox = simgrid::s4u::Mailbox::by_name(args.at(0));
+ sg4::Mailbox* mbox = sg4::Mailbox::by_name(args.at(0));
auto* payload = new s_payload;
- payload->tx_actor_name = simgrid::s4u::Actor::self()->get_cname();
- payload->tx_host = simgrid::s4u::this_actor::get_host();
- payload->clock_sta = simgrid::s4u::Engine::get_clock();
+ payload->tx_actor_name = sg4::Actor::self()->get_cname();
+ payload->tx_host = sg4::this_actor::get_host();
+ payload->clock_sta = sg4::Engine::get_clock();
mbox->put(payload, 1000000);
}
static void communication_rx_fun(std::vector<std::string> args)
{
- const char* actor_name = simgrid::s4u::Actor::self()->get_cname();
- const char* host_name = simgrid::s4u::this_actor::get_host()->get_cname();
- simgrid::s4u::Mailbox* mbox = simgrid::s4u::Mailbox::by_name(args.at(0));
+ const char* actor_name = sg4::Actor::self()->get_cname();
+ const char* host_name = sg4::this_actor::get_host()->get_cname();
+ sg4::Mailbox* mbox = sg4::Mailbox::by_name(args.at(0));
auto payload = mbox->get_unique<struct s_payload>();
- double clock_end = simgrid::s4u::Engine::get_clock();
+ double clock_end = sg4::Engine::get_clock();
XBT_INFO("%s:%s to %s:%s => %g sec", payload->tx_host->get_cname(), payload->tx_actor_name, host_name, actor_name,
clock_end - payload->clock_sta);
std::vector<std::string> args;
args.push_back(mbox_name);
- simgrid::s4u::Actor::create("comm_tx", tx_host, communication_tx_fun, args);
+ sg4::Actor::create("comm_tx", tx_host, communication_tx_fun, args);
- simgrid::s4u::Actor::create("comm_rx", rx_host, communication_rx_fun, args);
+ sg4::Actor::create("comm_rx", rx_host, communication_rx_fun, args);
}
static void master_main()
{
- s4u_Host* pm0 = simgrid::s4u::Host::by_name("Fafard");
- s4u_Host* pm1 = simgrid::s4u::Host::by_name("Tremblay");
- s4u_Host* pm2 = simgrid::s4u::Host::by_name("Bourassa");
+ s4u_Host* pm0 = sg4::Host::by_name("Fafard");
+ s4u_Host* pm1 = sg4::Host::by_name("Tremblay");
+ s4u_Host* pm2 = sg4::Host::by_name("Bourassa");
XBT_INFO("## Test 1 (started): check computation on normal PMs");
XBT_INFO("### Put an activity on a PM");
launch_computation_worker(pm0);
- simgrid::s4u::this_actor::sleep_for(2);
+ sg4::this_actor::sleep_for(2);
XBT_INFO("### Put two activities on a PM");
launch_computation_worker(pm0);
launch_computation_worker(pm0);
- simgrid::s4u::this_actor::sleep_for(2);
+ sg4::this_actor::sleep_for(2);
XBT_INFO("### Put an activity on each PM");
launch_computation_worker(pm0);
launch_computation_worker(pm1);
- simgrid::s4u::this_actor::sleep_for(2);
+ sg4::this_actor::sleep_for(2);
XBT_INFO("## Test 1 (ended)");
auto* vm0 = pm0->create_vm("VM0", 1);
vm0->start();
launch_computation_worker(vm0);
- simgrid::s4u::this_actor::sleep_for(2);
+ sg4::this_actor::sleep_for(2);
vm0->destroy();
XBT_INFO("## Test 2 (ended)");
vm0 = pm0->create_vm("VM0", 1);
vm0->start();
launch_computation_worker(pm0);
- simgrid::s4u::this_actor::sleep_for(2);
+ sg4::this_actor::sleep_for(2);
vm0->destroy();
XBT_INFO("## Test 3 (ended)");
auto* vm1 = pm0->create_vm("VM1", 1);
launch_computation_worker(vm0);
launch_computation_worker(vm1);
- simgrid::s4u::this_actor::sleep_for(2);
+ sg4::this_actor::sleep_for(2);
vm0->destroy();
vm1->destroy();
vm1->start();
launch_computation_worker(vm0);
launch_computation_worker(vm1);
- simgrid::s4u::this_actor::sleep_for(2);
+ sg4::this_actor::sleep_for(2);
vm0->destroy();
vm1->destroy();
XBT_INFO("## Test 4 (ended)");
XBT_INFO("## Test 5 (started): Analyse network impact");
XBT_INFO("### Make a connection between PM0 and PM1");
launch_communication_worker(pm0, pm1);
- simgrid::s4u::this_actor::sleep_for(5);
+ sg4::this_actor::sleep_for(5);
XBT_INFO("### Make two connection between PM0 and PM1");
launch_communication_worker(pm0, pm1);
launch_communication_worker(pm0, pm1);
- simgrid::s4u::this_actor::sleep_for(5);
+ sg4::this_actor::sleep_for(5);
XBT_INFO("### Make a connection between PM0 and VM0@PM0");
vm0 = pm0->create_vm("VM0", 1);
vm0->start();
launch_communication_worker(pm0, vm0);
- simgrid::s4u::this_actor::sleep_for(5);
+ sg4::this_actor::sleep_for(5);
vm0->destroy();
XBT_INFO("### Make a connection between PM0 and VM0@PM1");
vm0 = pm1->create_vm("VM0", 1);
launch_communication_worker(pm0, vm0);
- simgrid::s4u::this_actor::sleep_for(5);
+ sg4::this_actor::sleep_for(5);
vm0->destroy();
XBT_INFO("### Make two connections between PM0 and VM0@PM1");
vm0->start();
launch_communication_worker(pm0, vm0);
launch_communication_worker(pm0, vm0);
- simgrid::s4u::this_actor::sleep_for(5);
+ sg4::this_actor::sleep_for(5);
vm0->destroy();
XBT_INFO("### Make a connection between PM0 and VM0@PM1, and also make a connection between PM0 and PM1");
vm0->start();
launch_communication_worker(pm0, vm0);
launch_communication_worker(pm0, pm1);
- simgrid::s4u::this_actor::sleep_for(5);
+ sg4::this_actor::sleep_for(5);
vm0->destroy();
XBT_INFO("### Make a connection between VM0@PM0 and PM1@PM1, and also make a connection between VM0@PM0 and VM1@PM1");
vm1->start();
launch_communication_worker(vm0, vm1);
launch_communication_worker(vm0, vm1);
- simgrid::s4u::this_actor::sleep_for(5);
+ sg4::this_actor::sleep_for(5);
vm0->destroy();
vm1->destroy();
vm0->start();
launch_communication_worker(vm0, pm2);
- simgrid::s4u::this_actor::sleep_for(0.01);
+ sg4::this_actor::sleep_for(0.01);
sg_vm_migrate(vm0, pm1);
- simgrid::s4u::this_actor::sleep_for(0.01);
+ sg4::this_actor::sleep_for(0.01);
sg_vm_migrate(vm0, pm0);
- simgrid::s4u::this_actor::sleep_for(5);
+ sg4::this_actor::sleep_for(5);
vm0->destroy();
XBT_INFO("## Test 6 (ended)");
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
sg_vm_live_migration_plugin_init();
e.load_platform(argv[1]); /* - Load the platform description */
- simgrid::s4u::Actor::create("master_", e.host_by_name("Fafard"), master_main);
+ sg4::Actor::create("master_", e.host_by_name("Fafard"), master_main);
e.run();
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
}
XBT_INFO("Wait for remaining comm, just to be nice");
pending_comms.erase(pending_comms.begin());
- simgrid::s4u::Comm::wait_any(pending_comms);
+ sg4::Comm::wait_any(pending_comms);
}
};
#include <vector>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
sg_storage_file_system_init();
e.load_platform(argv[1]);
auto jupiter = e.host_by_name("Jupiter");
// Display the details on vetoed activities
- simgrid::s4u::Activity::on_veto_cb([](const simgrid::s4u::Activity& a) {
+ sg4::Activity::on_veto_cb([](const sg4::Activity& a) {
XBT_INFO("Activity '%s' vetoed. Dependencies: %s; Ressources: %s", a.get_cname(),
(a.dependencies_solved() ? "solved" : "NOT solved"), (a.is_assigned() ? "assigned" : "NOT assigned"));
});
- simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
- const auto* exec = dynamic_cast<simgrid::s4u::Exec const*>(&activity);
+ sg4::Activity::on_completion_cb([](sg4::Activity const& activity) {
+ const auto* exec = dynamic_cast<sg4::Exec const*>(&activity);
if (exec != nullptr)
XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(),
exec->get_finish_time());
- const auto* comm = dynamic_cast<simgrid::s4u::Comm const*>(&activity);
+ const auto* comm = dynamic_cast<sg4::Comm const*>(&activity);
if (comm != nullptr)
XBT_INFO("Activity '%s' is complete", comm->get_cname());
});
// Create a small DAG: parent->transfert->child
- simgrid::s4u::ExecPtr parent = simgrid::s4u::Exec::init();
- simgrid::s4u::CommPtr transfert = simgrid::s4u::Comm::sendto_init();
- simgrid::s4u::ExecPtr child = simgrid::s4u::Exec::init();
+ sg4::ExecPtr parent = sg4::Exec::init();
+ sg4::CommPtr transfert = sg4::Comm::sendto_init();
+ sg4::ExecPtr child = sg4::Exec::init();
parent->add_successor(transfert);
transfert->add_successor(child);
e.run();
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
auto* faulty = e.host_by_name("Faulty Host");
auto* safe = e.host_by_name("Safe Host");
sg4::Activity::on_completion_cb([](sg4::Activity const& activity) {
- const auto* exec = dynamic_cast<simgrid::s4u::Exec const*>(&activity);
+ const auto* exec = dynamic_cast<sg4::Exec const*>(&activity);
if (exec == nullptr) // Only Execs are concerned here
return;
if (exec->get_state() == sg4::Activity::State::FINISHED)
/* simple test trying to load a DAX file. */
-/* Copyright (c) 2009-2022. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2009-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. */
#include <string.h>
XBT_LOG_NEW_DEFAULT_CATEGORY(dag_from_dax, "Logging specific to this example");
+namespace sg4 = simgrid::s4u;
int main(int argc, char** argv)
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- std::vector<simgrid::s4u::ActivityPtr> dag = simgrid::s4u::create_DAG_from_DAX(argv[2]);
+ std::vector<sg4::ActivityPtr> dag = sg4::create_DAG_from_DAX(argv[2]);
if (dag.empty()) {
XBT_ERROR("A problem occurred during DAX parsing (cycle or syntax). Do not continue this test");
for (const auto& a : dag) {
std::string type = "an Exec";
std::string task = "flops to execute";
- if (dynamic_cast<simgrid::s4u::Comm*>(a.get()) != nullptr) {
+ if (dynamic_cast<sg4::Comm*>(a.get()) != nullptr) {
type = "a Comm";
task = "bytes to transfer";
}
auto count = e.get_host_count();
int cursor = 0;
// Schedule end first
- static_cast<simgrid::s4u::Exec*>(dag.back().get())->set_host(hosts[0]);
+ static_cast<sg4::Exec*>(dag.back().get())->set_host(hosts[0]);
for (const auto& a : dag) {
- auto* exec = dynamic_cast<simgrid::s4u::Exec*>(a.get());
+ auto* exec = dynamic_cast<sg4::Exec*>(a.get());
if (exec != nullptr && exec->get_name() != "end") {
exec->set_host(hosts[cursor % count]);
cursor++;
}
- auto* comm = dynamic_cast<simgrid::s4u::Comm*>(a.get());
+ auto* comm = dynamic_cast<sg4::Comm*>(a.get());
if (comm != nullptr) {
- auto pred = dynamic_cast<simgrid::s4u::Exec*>((*comm->get_dependencies().begin()).get());
- auto succ = dynamic_cast<simgrid::s4u::Exec*>(comm->get_successors().front().get());
+ auto pred = dynamic_cast<sg4::Exec*>((*comm->get_dependencies().begin()).get());
+ auto succ = dynamic_cast<sg4::Exec*>(comm->get_successors().front().get());
comm->set_source(pred->get_host())->set_destination(succ->get_host());
}
}
XBT_INFO("-------------- Summary of executed schedule ------------------");
for (const auto& a : dag) {
- const auto* exec = dynamic_cast<simgrid::s4u::Exec*>(a.get());
+ const auto* exec = dynamic_cast<sg4::Exec*>(a.get());
if (exec != nullptr) {
XBT_INFO("[%f->%f] '%s' executed on %s", exec->get_start_time(), exec->get_finish_time(), exec->get_cname(),
exec->get_host()->get_cname());
}
- const auto* comm = dynamic_cast<simgrid::s4u::Comm*>(a.get());
+ const auto* comm = dynamic_cast<sg4::Comm*>(a.get());
if (comm != nullptr) {
XBT_INFO("[%f->%f] '%s' transferred from %s to %s", comm->get_start_time(), comm->get_finish_time(),
comm->get_cname(), comm->get_source()->get_cname(), comm->get_destination()->get_cname());
/* simple test trying to load a DOT file. */
-/* Copyright (c) 2010-2022. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2010-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. */
#include <stdio.h>
XBT_LOG_NEW_DEFAULT_CATEGORY(dag_from_dot, "Logging specific to this example");
+namespace sg4 = simgrid::s4u;
int main(int argc, char** argv)
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- std::vector<simgrid::s4u::ActivityPtr> dag = simgrid::s4u::create_DAG_from_dot(argv[2]);
+ std::vector<sg4::ActivityPtr> dag = sg4::create_DAG_from_dot(argv[2]);
if (dag.empty()) {
XBT_CRITICAL("No dot loaded. Do you have a cycle in your graph?");
for (const auto& a : dag) {
std::string type = "an Exec";
std::string task = "flops to execute";
- if (dynamic_cast<simgrid::s4u::Comm*>(a.get()) != nullptr) {
+ if (dynamic_cast<sg4::Comm*>(a.get()) != nullptr) {
type = "a Comm";
task = "bytes to transfer";
}
auto count = e.get_host_count();
int cursor = 0;
// Schedule end first
- static_cast<simgrid::s4u::Exec*>(dag.back().get())->set_host(hosts[0]);
+ static_cast<sg4::Exec*>(dag.back().get())->set_host(hosts[0]);
for (const auto& a : dag) {
- auto* exec = dynamic_cast<simgrid::s4u::Exec*>(a.get());
+ auto* exec = dynamic_cast<sg4::Exec*>(a.get());
if (exec != nullptr && exec->get_name() != "end") {
exec->set_host(hosts[cursor % count]);
cursor++;
}
- auto* comm = dynamic_cast<simgrid::s4u::Comm*>(a.get());
+ auto* comm = dynamic_cast<sg4::Comm*>(a.get());
if (comm != nullptr) {
- auto pred = dynamic_cast<simgrid::s4u::Exec*>((*comm->get_dependencies().begin()).get());
- auto succ = dynamic_cast<simgrid::s4u::Exec*>(comm->get_successors().front().get());
+ auto pred = dynamic_cast<sg4::Exec*>((*comm->get_dependencies().begin()).get());
+ auto succ = dynamic_cast<sg4::Exec*>(comm->get_successors().front().get());
comm->set_source(pred->get_host())->set_destination(succ->get_host());
}
}
XBT_INFO("-------------- Summary of executed schedule ------------------");
for (const auto& a : dag) {
- const auto* exec = dynamic_cast<simgrid::s4u::Exec*>(a.get());
+ const auto* exec = dynamic_cast<sg4::Exec*>(a.get());
if (exec != nullptr) {
XBT_INFO("[%f->%f] '%s' executed on %s", exec->get_start_time(), exec->get_finish_time(), exec->get_cname(),
exec->get_host()->get_cname());
}
- const auto* comm = dynamic_cast<simgrid::s4u::Comm*>(a.get());
+ const auto* comm = dynamic_cast<sg4::Comm*>(a.get());
if (comm != nullptr) {
XBT_INFO("[%f->%f] '%s' transferred from %s to %s", comm->get_start_time(), comm->get_finish_time(),
comm->get_cname(), comm->get_source()->get_cname(), comm->get_destination()->get_cname());
#include <vector>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
sg_storage_file_system_init();
e.load_platform(argv[1]);
auto carl = e.host_by_name("carl");
// Display the details on vetoed activities
- simgrid::s4u::Activity::on_veto_cb([](const simgrid::s4u::Activity& a) {
+ sg4::Activity::on_veto_cb([](const sg4::Activity& a) {
XBT_INFO("Activity '%s' vetoed. Dependencies: %s; Ressources: %s", a.get_cname(),
(a.dependencies_solved() ? "solved" : "NOT solved"), (a.is_assigned() ? "assigned" : "NOT assigned"));
});
- simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
- const auto* exec = dynamic_cast<simgrid::s4u::Exec const*>(&activity);
+ sg4::Activity::on_completion_cb([](sg4::Activity const& activity) {
+ const auto* exec = dynamic_cast<sg4::Exec const*>(&activity);
if (exec == nullptr) // Only Execs are concerned here
return;
XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(),
});
// Create a small DAG: parent->write_output->read_input->child
- simgrid::s4u::ExecPtr parent = simgrid::s4u::Exec::init();
- simgrid::s4u::IoPtr write_output = simgrid::s4u::Io::init();
- simgrid::s4u::IoPtr read_input = simgrid::s4u::Io::init();
- simgrid::s4u::ExecPtr child = simgrid::s4u::Exec::init();
+ sg4::ExecPtr parent = sg4::Exec::init();
+ sg4::IoPtr write_output = sg4::Io::init();
+ sg4::IoPtr read_input = sg4::Io::init();
+ sg4::ExecPtr child = sg4::Exec::init();
parent->add_successor(write_output);
write_output->add_successor(read_input);
read_input->add_successor(child);
// Set the parameters (the name is for logging purposes only)
// + parent and chile end after 1 second
parent->set_name("parent")->set_flops_amount(bob->get_speed());
- write_output->set_name("write")->set_size(1e9)->set_op_type(simgrid::s4u::Io::OpType::WRITE);
- read_input->set_name("read")->set_size(1e9)->set_op_type(simgrid::s4u::Io::OpType::READ);
+ write_output->set_name("write")->set_size(1e9)->set_op_type(sg4::Io::OpType::WRITE);
+ read_input->set_name("read")->set_size(1e9)->set_op_type(sg4::Io::OpType::READ);
child->set_name("child")->set_flops_amount(carl->get_speed());
// Schedule and try to start the different activities
e.run();
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
-/* Copyright (c) 2009-2022. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2009-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. */
#include <string.h>
XBT_LOG_NEW_DEFAULT_CATEGORY(dag_scheduling, "Logging specific to this example");
+namespace sg4 = simgrid::s4u;
struct HostAttribute {
/* Earliest time at which a host is ready to execute a task */
double available_at = 0.0;
- simgrid::s4u::Exec* last_scheduled_task = nullptr;
+ sg4::Exec* last_scheduled_task = nullptr;
};
-static double sg_host_get_available_at(const simgrid::s4u::Host* host)
+static double sg_host_get_available_at(const sg4::Host* host)
{
return host->get_data<HostAttribute>()->available_at;
}
-static void sg_host_set_available_at(const simgrid::s4u::Host* host, double time)
+static void sg_host_set_available_at(const sg4::Host* host, double time)
{
host->get_data<HostAttribute>()->available_at = time;
}
-static simgrid::s4u::Exec* sg_host_get_last_scheduled_task(const simgrid::s4u::Host* host)
+static sg4::Exec* sg_host_get_last_scheduled_task(const sg4::Host* host)
{
return host->get_data<HostAttribute>()->last_scheduled_task;
}
-static void sg_host_set_last_scheduled_task(const simgrid::s4u::Host* host, simgrid::s4u::ExecPtr task)
+static void sg_host_set_last_scheduled_task(const sg4::Host* host, sg4::ExecPtr task)
{
host->get_data<HostAttribute>()->last_scheduled_task = task.get();
}
-static bool dependency_exists(const simgrid::s4u::Exec* src, simgrid::s4u::Exec* dst)
+static bool dependency_exists(const sg4::Exec* src, sg4::Exec* dst)
{
const auto& dependencies = src->get_dependencies();
const auto& successors = src->get_successors();
dependencies.find(dst) != dependencies.end());
}
-static std::vector<simgrid::s4u::Exec*> get_ready_tasks(const std::vector<simgrid::s4u::ActivityPtr>& dax)
+static std::vector<sg4::Exec*> get_ready_tasks(const std::vector<sg4::ActivityPtr>& dax)
{
- std::vector<simgrid::s4u::Exec*> ready_tasks;
- std::map<simgrid::s4u::Exec*, unsigned int> candidate_execs;
+ std::vector<sg4::Exec*> ready_tasks;
+ std::map<sg4::Exec*, unsigned int> candidate_execs;
for (auto& a : dax) {
// Only loot at activity that have their dependencies solved but are not assigned
if (a->dependencies_solved() && not a->is_assigned()) {
// if it is an exec, it's ready
- auto* exec = dynamic_cast<simgrid::s4u::Exec*>(a.get());
+ auto* exec = dynamic_cast<sg4::Exec*>(a.get());
if (exec != nullptr)
ready_tasks.push_back(exec);
// if it a comm, we consider its successor as a candidate. If a candidate solves all its dependencies,
// i.e., get all its input data, it's ready
- const auto* comm = dynamic_cast<simgrid::s4u::Comm*>(a.get());
+ const auto* comm = dynamic_cast<sg4::Comm*>(a.get());
if (comm != nullptr) {
- auto* next_exec = static_cast<simgrid::s4u::Exec*>(comm->get_successors().front().get());
+ auto* next_exec = static_cast<sg4::Exec*>(comm->get_successors().front().get());
candidate_execs[next_exec]++;
if (next_exec->get_dependencies().size() == candidate_execs[next_exec])
ready_tasks.push_back(next_exec);
return ready_tasks;
}
-static double finish_on_at(const simgrid::s4u::ExecPtr task, const simgrid::s4u::Host* host)
+static double finish_on_at(const sg4::ExecPtr task, const sg4::Host* host)
{
double result;
last_data_available = -1.0;
for (const auto& parent : parents) {
/* normal case */
- const auto* comm = dynamic_cast<simgrid::s4u::Comm*>(parent.get());
+ const auto* comm = dynamic_cast<sg4::Comm*>(parent.get());
if (comm != nullptr) {
auto source = comm->get_source();
XBT_DEBUG("transfer from %s to %s", source->get_cname(), host->get_cname());
data_available = *comm->get_data<double>() + redist_time;
}
- const auto* exec = dynamic_cast<simgrid::s4u::Exec*>(parent.get());
+ const auto* exec = dynamic_cast<sg4::Exec*>(parent.get());
/* no transfer, control dependency */
if (exec != nullptr) {
data_available = exec->get_finish_time();
return result;
}
-static simgrid::s4u::Host* get_best_host(const simgrid::s4u::ExecPtr exec)
+static sg4::Host* get_best_host(const sg4::ExecPtr exec)
{
- std::vector<simgrid::s4u::Host*> hosts = simgrid::s4u::Engine::get_instance()->get_all_hosts();
+ std::vector<sg4::Host*> hosts = sg4::Engine::get_instance()->get_all_hosts();
auto best_host = hosts.front();
double min_EFT = finish_on_at(exec, best_host);
return best_host;
}
-static void schedule_on(simgrid::s4u::ExecPtr exec, simgrid::s4u::Host* host)
+static void schedule_on(sg4::ExecPtr exec, sg4::Host* host)
{
exec->set_host(host);
// we can also set the destination of all the input comms of this exec
for (const auto& pred : exec->get_dependencies()) {
- auto* comm = dynamic_cast<simgrid::s4u::Comm*>(pred.get());
+ auto* comm = dynamic_cast<sg4::Comm*>(pred.get());
if (comm != nullptr) {
comm->set_destination(host);
delete comm->get_data<double>();
}
// we can also set the source of all the output comms of this exec
for (const auto& succ : exec->get_successors()) {
- auto* comm = dynamic_cast<simgrid::s4u::Comm*>(succ.get());
+ auto* comm = dynamic_cast<sg4::Comm*>(succ.get());
if (comm != nullptr)
comm->set_source(host);
}
int main(int argc, char** argv)
{
- simgrid::s4u::Engine e(&argc, argv);
- std::set<simgrid::s4u::Activity*> vetoed;
+ sg4::Engine e(&argc, argv);
+ std::set<sg4::Activity*> vetoed;
e.track_vetoed_activities(&vetoed);
- simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
+ sg4::Activity::on_completion_cb([](sg4::Activity const& activity) {
// when an Exec completes, we need to set the potential start time of all its ouput comms
- const auto* exec = dynamic_cast<simgrid::s4u::Exec const*>(&activity);
+ const auto* exec = dynamic_cast<sg4::Exec const*>(&activity);
if (exec == nullptr) // Only Execs are concerned here
return;
for (const auto& succ : exec->get_successors()) {
- auto* comm = dynamic_cast<simgrid::s4u::Comm*>(succ.get());
+ auto* comm = dynamic_cast<sg4::Comm*>(succ.get());
if (comm != nullptr) {
auto* finish_time = new double(exec->get_finish_time());
// We use the user data field to store the finish time of the predecessor of the comm, i.e., its potential start
hosts[i]->set_data(&host_attributes[i]);
/* load the DAX file */
- auto dax = simgrid::s4u::create_DAG_from_DAX(argv[2]);
+ auto dax = sg4::create_DAG_from_DAX(argv[2]);
/* Schedule the root first */
- auto* root = static_cast<simgrid::s4u::Exec*>(dax.front().get());
+ auto* root = static_cast<sg4::Exec*>(dax.front().get());
auto host = get_best_host(root);
schedule_on(root, host);
* select the task that has the minimum completion time on its best host.
*/
double min_finish_time = -1.0;
- simgrid::s4u::Exec* selected_task = nullptr;
- simgrid::s4u::Host* selected_host = nullptr;
+ sg4::Exec* selected_task = nullptr;
+ sg4::Host* selected_host = nullptr;
for (auto task : ready_tasks) {
XBT_DEBUG("%s is ready", task->get_cname());
*/
auto last_scheduled_task = sg_host_get_last_scheduled_task(selected_host);
- if (last_scheduled_task && (last_scheduled_task->get_state() != simgrid::s4u::Activity::State::FINISHED) &&
- (last_scheduled_task->get_state() != simgrid::s4u::Activity::State::FAILED) &&
+ if (last_scheduled_task && (last_scheduled_task->get_state() != sg4::Activity::State::FINISHED) &&
+ (last_scheduled_task->get_state() != sg4::Activity::State::FAILED) &&
not dependency_exists(sg_host_get_last_scheduled_task(selected_host), selected_task))
last_scheduled_task->add_successor(selected_task);
#include <vector>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- std::set<simgrid::s4u::Activity*> vetoed;
+ std::set<sg4::Activity*> vetoed;
e.track_vetoed_activities(&vetoed);
auto fafard = e.host_by_name("Fafard");
// Display the details on vetoed activities
- simgrid::s4u::Activity::on_veto_cb([](const simgrid::s4u::Activity& a) {
- const auto& exec = static_cast<const simgrid::s4u::Exec&>(a); // all activities are execs in this example
+ sg4::Activity::on_veto_cb([](const sg4::Activity& a) {
+ const auto& exec = static_cast<const sg4::Exec&>(a); // all activities are execs in this example
XBT_INFO("Activity '%s' vetoed. Dependencies: %s; Ressources: %s", exec.get_cname(),
(exec.dependencies_solved() ? "solved" : "NOT solved"),
(exec.is_assigned() ? "assigned" : "NOT assigned"));
});
- simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
- const auto* exec = dynamic_cast<simgrid::s4u::Exec const*>(&activity);
+ sg4::Activity::on_completion_cb([](sg4::Activity const& activity) {
+ const auto* exec = dynamic_cast<sg4::Exec const*>(&activity);
if (exec == nullptr) // Only Execs are concerned here
return;
XBT_INFO("Activity '%s' is complete (start time: %f, finish time: %f)", exec->get_cname(), exec->get_start_time(),
double computation_amount = fafard->get_speed();
// Create a small DAG: Two parents and a child
- simgrid::s4u::ExecPtr first_parent = simgrid::s4u::Exec::init();
- simgrid::s4u::ExecPtr second_parent = simgrid::s4u::Exec::init();
- simgrid::s4u::ExecPtr child = simgrid::s4u::Exec::init();
+ sg4::ExecPtr first_parent = sg4::Exec::init();
+ sg4::ExecPtr second_parent = sg4::Exec::init();
+ sg4::ExecPtr child = sg4::Exec::init();
first_parent->add_successor(child);
second_parent->add_successor(child);
second_parent->vetoable_start();
child->vetoable_start();
- while (child->get_state() != simgrid::s4u::Activity::State::FINISHED) {
+ while (child->get_state() != sg4::Activity::State::FINISHED) {
e.run();
for (auto* a : vetoed) {
- auto* exec = static_cast<simgrid::s4u::Exec*>(a);
+ auto* exec = static_cast<sg4::Exec*>(a);
// In this simple case, we just assign the child task to a resource when its dependencies are solved
if (exec->dependencies_solved() && not exec->is_assigned()) {
vetoed.clear(); // DON'T FORGET TO CLEAR this set between two calls to run
}
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
#include "s4u-dht-chord.hpp"
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(s4u_chord);
+namespace sg4 = simgrid::s4u;
/* Returns whether an id belongs to the interval [start, end].
*
id_ = std::stoi(args[1]);
XBT_DEBUG("Initialize node with id: %d", id_);
random.set_seed(id_);
- mailbox_ = simgrid::s4u::Mailbox::by_name(std::to_string(id_));
+ mailbox_ = sg4::Mailbox::by_name(std::to_string(id_));
next_finger_to_fix = 0;
fingers_.resize(nb_bits, id_);
if (args.size() == 3) { // first ring
deadline_ = std::stod(args[2]);
- start_time_ = simgrid::s4u::Engine::get_clock();
+ start_time_ = sg4::Engine::get_clock();
XBT_DEBUG("Create a new Chord ring...");
} else {
known_id_ = std::stoi(args[2]);
XBT_DEBUG("Sending a 'PREDECESSOR_LEAVING' to my successor %d", fingers_[0]);
try {
- simgrid::s4u::Mailbox::by_name(std::to_string(fingers_[0]))->put(pred_msg, 10, timeout);
+ sg4::Mailbox::by_name(std::to_string(fingers_[0]))->put(pred_msg, 10, timeout);
} catch (const simgrid::TimeoutException&) {
XBT_DEBUG("Timeout expired when sending a 'PREDECESSOR_LEAVING' to my successor %d", fingers_[0]);
delete pred_msg;
XBT_DEBUG("Sending a 'SUCCESSOR_LEAVING' to my predecessor %d", pred_id_);
try {
- simgrid::s4u::Mailbox::by_name(std::to_string(pred_id_))->put(succ_msg, 10, timeout);
+ sg4::Mailbox::by_name(std::to_string(pred_id_))->put(succ_msg, 10, timeout);
} catch (const simgrid::TimeoutException&) {
XBT_DEBUG("Timeout expired when sending a 'SUCCESSOR_LEAVING' to my predecessor %d", pred_id_);
delete succ_msg;
if (pred_id_ == -1)
return;
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(pred_id_));
- simgrid::s4u::Mailbox* return_mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id_) + "_is_alive");
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(pred_id_));
+ sg4::Mailbox* return_mailbox = sg4::Mailbox::by_name(std::to_string(id_) + "_is_alive");
auto* message = new ChordMessage(MessageType::PREDECESSOR_ALIVE);
message->request_id = pred_id_;
XBT_DEBUG("Sent 'Predecessor Alive' request to %d, waiting for the answer on my mailbox '%s'", pred_id_,
message->answer_to->get_cname());
ChordMessage* answer = nullptr;
- simgrid::s4u::CommPtr comm = return_mailbox->get_async<ChordMessage>(&answer);
+ sg4::CommPtr comm = return_mailbox->get_async<ChordMessage>(&answer);
try {
comm->wait_for(timeout);
int Node::remoteGetPredecessor(int ask_to)
{
int predecessor_id = -1;
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(ask_to));
- simgrid::s4u::Mailbox* return_mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id_) + "_pred");
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(ask_to));
+ sg4::Mailbox* return_mailbox = sg4::Mailbox::by_name(std::to_string(id_) + "_pred");
auto* message = new ChordMessage(MessageType::GET_PREDECESSOR);
message->request_id = id_;
XBT_DEBUG("Sent 'Get Predecessor' request to %d, waiting for the answer on my mailbox '%s'", ask_to,
message->answer_to->get_cname());
ChordMessage* answer = nullptr;
- simgrid::s4u::CommPtr comm = return_mailbox->get_async<ChordMessage>(&answer);
+ sg4::CommPtr comm = return_mailbox->get_async<ChordMessage>(&answer);
try {
comm->wait_for(timeout);
int Node::remoteFindSuccessor(int ask_to, int id)
{
int successor = -1;
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(ask_to));
- simgrid::s4u::Mailbox* return_mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id_) + "_succ");
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(ask_to));
+ sg4::Mailbox* return_mailbox = sg4::Mailbox::by_name(std::to_string(id_) + "_succ");
auto* message = new ChordMessage(MessageType::FIND_SUCCESSOR);
message->request_id = id_;
// receive the answer
XBT_DEBUG("Sent a 'Find Successor' request to %d for key %d, waiting for the answer", ask_to, id);
ChordMessage* answer = nullptr;
- simgrid::s4u::CommPtr comm = return_mailbox->get_async<ChordMessage>(&answer);
+ sg4::CommPtr comm = return_mailbox->get_async<ChordMessage>(&answer);
try {
comm->wait_for(timeout);
// send a "Notify" request to notify_id
XBT_DEBUG("Sending a 'Notify' request to %d", notify_id);
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(notify_id));
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(notify_id));
mailbox->put_init(message, 10)->detach(ChordMessage::destroy);
}
int closest = closestPrecedingFinger(message->request_id);
XBT_DEBUG("Forwarding the 'Find Successor' request for id %d to my closest preceding finger %d",
message->request_id, closest);
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(closest));
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(closest));
mailbox->put_init(message, 10)->detach(ChordMessage::destroy);
}
break;
void Node::operator()()
{
- simgrid::s4u::this_actor::sleep_for(start_time_);
+ sg4::this_actor::sleep_for(start_time_);
if (known_id_ == -1) {
setPredecessor(-1); // -1 means that I have no predecessor
printFingerTable();
if (not joined)
return;
ChordMessage* message = nullptr;
- double now = simgrid::s4u::Engine::get_clock();
+ double now = sg4::Engine::get_clock();
double next_stabilize_date = start_time_ + PERIODIC_STABILIZE_DELAY;
double next_fix_fingers_date = start_time_ + PERIODIC_FIX_FINGERS_DELAY;
double next_check_predecessor_date = start_time_ + PERIODIC_CHECK_PREDECESSOR_DELAY;
double next_lookup_date = start_time_ + PERIODIC_LOOKUP_DELAY;
- simgrid::s4u::CommPtr comm_receive = nullptr;
+ sg4::CommPtr comm_receive = nullptr;
while (now < std::min(start_time_ + deadline_, MAX_SIMULATION_TIME)) {
if (comm_receive == nullptr)
comm_receive = mailbox_->get_async<ChordMessage>(&message);
// no task was received: make some periodic calls
if (now >= next_stabilize_date) {
stabilize();
- next_stabilize_date = simgrid::s4u::Engine::get_clock() + PERIODIC_STABILIZE_DELAY;
+ next_stabilize_date = sg4::Engine::get_clock() + PERIODIC_STABILIZE_DELAY;
} else if (now >= next_fix_fingers_date) {
fixFingers();
- next_fix_fingers_date = simgrid::s4u::Engine::get_clock() + PERIODIC_FIX_FINGERS_DELAY;
+ next_fix_fingers_date = sg4::Engine::get_clock() + PERIODIC_FIX_FINGERS_DELAY;
} else if (now >= next_check_predecessor_date) {
checkPredecessor();
- next_check_predecessor_date = simgrid::s4u::Engine::get_clock() + PERIODIC_CHECK_PREDECESSOR_DELAY;
+ next_check_predecessor_date = sg4::Engine::get_clock() + PERIODIC_CHECK_PREDECESSOR_DELAY;
} else if (now >= next_lookup_date) {
randomLookup();
- next_lookup_date = simgrid::s4u::Engine::get_clock() + PERIODIC_LOOKUP_DELAY;
+ next_lookup_date = sg4::Engine::get_clock() + PERIODIC_LOOKUP_DELAY;
} else {
// nothing to do: sleep for a while
- simgrid::s4u::this_actor::sleep_for(SLEEP_DELAY);
+ sg4::this_actor::sleep_for(SLEEP_DELAY);
}
}
- now = simgrid::s4u::Engine::get_clock();
+ now = sg4::Engine::get_clock();
}
if (comm_receive != nullptr) {
try {
#include <xbt/random.hpp>
#include <xbt/str.h>
+namespace sg4 = simgrid::s4u;
+
constexpr double MAX_SIMULATION_TIME = 1000;
constexpr double PERIODIC_STABILIZE_DELAY = 20;
constexpr double PERIODIC_FIX_FINGERS_DELAY = 120;
class ChordMessage {
public:
MessageType type; // type of message
- std::string issuer_host_name = simgrid::s4u::this_actor::get_host()->get_name(); // used for logging
+ std::string issuer_host_name = sg4::this_actor::get_host()->get_name(); // used for logging
int request_id = -1; // id (used by some types of messages)
int request_finger = 1; // finger parameter (used by some types of messages)
int answer_id = -1; // answer (used by some types of messages)
- simgrid::s4u::Mailbox* answer_to = nullptr; // mailbox to send an answer to (if any)
+ sg4::Mailbox* answer_to = nullptr; // mailbox to send an answer to (if any)
explicit ChordMessage(MessageType type) : type(type) {}
int id_; // my id
int pred_id_ = -1; // predecessor id
simgrid::xbt::random::XbtRandom random; // random number generator for this node
- simgrid::s4u::Mailbox* mailbox_; // my mailbox
+ sg4::Mailbox* mailbox_; // my mailbox
std::vector<int> fingers_; // finger table,(fingers[0] is my successor)
int next_finger_to_fix; // index of the next finger to fix in fix_fingers()
#include "routing_table.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(kademlia_node, "Messages specific for this example");
+namespace sg4 = simgrid::s4u;
namespace kademlia {
static void destroy(void* message)
/**
* Try to asynchronously get a new message from given mailbox. Return null if none available.
*/
-Message* Node::receive(simgrid::s4u::Mailbox* mailbox)
+Message* Node::receive(sg4::Mailbox* mailbox)
{
if (receive_comm == nullptr)
receive_comm = mailbox->get_async<kademlia::Message>(&received_msg);
/* First step: Send a "FIND_NODE" request to the node we know */
sendFindNode(known_id, id_);
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id_));
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(id_));
do {
if (Message* msg = receive(mailbox)) {
XBT_DEBUG("Received an answer from the node I know.");
}
delete msg;
} else
- simgrid::s4u::this_actor::sleep_for(1);
+ sg4::this_actor::sleep_for(1);
} while (not got_answer);
/* Second step: Send a FIND_NODE to a random node in buckets */
void Node::sendFindNode(unsigned int id, unsigned int destination) const
{
/* Gets the mailbox to send to */
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id));
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(id));
/* Build the task */
- auto* msg = new Message(id_, destination, simgrid::s4u::Mailbox::by_name(std::to_string(id_)),
- simgrid::s4u::Host::current()->get_cname());
+ auto* msg =
+ new Message(id_, destination, sg4::Mailbox::by_name(std::to_string(id_)), sg4::Host::current()->get_cname());
/* Send the task */
mailbox->put_init(msg, 1)->detach(kademlia::destroy);
unsigned int answers;
bool destination_found = false;
unsigned int nodes_added = 0;
- double global_timeout = simgrid::s4u::Engine::get_clock() + FIND_NODE_GLOBAL_TIMEOUT;
+ double global_timeout = sg4::Engine::get_clock() + FIND_NODE_GLOBAL_TIMEOUT;
unsigned int steps = 0;
/* First we build a list of who we already know */
answers = 0;
queries = sendFindNodeToBest(node_list.get());
nodes_added = 0;
- double timeout = simgrid::s4u::Engine::get_clock() + FIND_NODE_TIMEOUT;
+ double timeout = sg4::Engine::get_clock() + FIND_NODE_TIMEOUT;
steps++;
- double time_beginreceive = simgrid::s4u::Engine::get_clock();
+ double time_beginreceive = sg4::Engine::get_clock();
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id_));
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(id_));
do {
if (Message* msg = receive(mailbox)) {
// Check if what we have received is what we are looking for.
handleFindNode(msg);
}
// Update the timeout if we didn't have our answer
- timeout += simgrid::s4u::Engine::get_clock() - time_beginreceive;
- time_beginreceive = simgrid::s4u::Engine::get_clock();
+ timeout += sg4::Engine::get_clock() - time_beginreceive;
+ time_beginreceive = sg4::Engine::get_clock();
}
delete msg;
} else {
- simgrid::s4u::this_actor::sleep_for(1);
+ sg4::this_actor::sleep_for(1);
}
- } while (simgrid::s4u::Engine::get_clock() < timeout && answers < queries);
+ } while (sg4::Engine::get_clock() < timeout && answers < queries);
destination_found = node_list->destinationFound();
- } while (not destination_found && (nodes_added > 0 || answers == 0) &&
- simgrid::s4u::Engine::get_clock() < global_timeout && steps < MAX_STEPS);
+ } while (not destination_found && (nodes_added > 0 || answers == 0) && sg4::Engine::get_clock() < global_timeout &&
+ steps < MAX_STEPS);
if (destination_found) {
if (count_in_stats)
XBT_VERB("Received a FIND_NODE from %s (%s), he's trying to find %08x", msg->answer_to_->get_cname(),
msg->issuer_host_name_.c_str(), msg->destination_id_);
// Building the answer to the request
- auto* answer =
- new Message(id_, msg->destination_id_, findClosest(msg->destination_id_),
- simgrid::s4u::Mailbox::by_name(std::to_string(id_)), simgrid::s4u::Host::current()->get_cname());
+ auto* answer = new Message(id_, msg->destination_id_, findClosest(msg->destination_id_),
+ sg4::Mailbox::by_name(std::to_string(id_)), sg4::Host::current()->get_cname());
// Sending the answer
msg->answer_to_->put_init(answer, 1)->detach(kademlia::destroy);
}
-/* Copyright (c) 2012-2022. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2012-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. */
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(kademlia, "Messages specific for this example");
+namespace sg4 = simgrid::s4u;
/** @brief Node function
* @param my node ID
if (join_success) {
XBT_VERB("Ok, I'm joining the network with id %u", node.getId());
// We start the main loop
- double next_lookup_time = simgrid::s4u::Engine::get_clock() + RANDOM_LOOKUP_INTERVAL;
+ double next_lookup_time = sg4::Engine::get_clock() + RANDOM_LOOKUP_INTERVAL;
XBT_VERB("Main loop start");
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(node.getId()));
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::to_string(node.getId()));
- while (simgrid::s4u::Engine::get_clock() < deadline) {
+ while (sg4::Engine::get_clock() < deadline) {
if (kademlia::Message* msg = node.receive(mailbox)) {
// There has been a message, we need to handle it !
node.handleFindNode(msg);
delete msg;
} else {
/* We search for a pseudo random node */
- if (simgrid::s4u::Engine::get_clock() >= next_lookup_time) {
+ if (sg4::Engine::get_clock() >= next_lookup_time) {
node.randomLookup();
next_lookup_time += RANDOM_LOOKUP_INTERVAL;
} else {
// Didn't get a message: sleep for a while...
- simgrid::s4u::this_actor::sleep_for(1);
+ sg4::this_actor::sleep_for(1);
}
}
}
/** @brief Main function */
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
/* Check the arguments */
xbt_assert(argc > 2,
e.run();
- XBT_INFO("Simulated time: %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulated time: %g", sg4::Engine::get_clock());
return 0;
}
#include "simgrid/plugins/energy.h"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this example");
+namespace sg4 = simgrid::s4u;
-static void simulate_bootup(simgrid::s4u::Host* host)
+static void simulate_bootup(sg4::Host* host)
{
unsigned long previous_pstate = host->get_pstate();
host->turn_on();
XBT_INFO("Wait 150s to simulate the boot time.");
- simgrid::s4u::this_actor::sleep_for(150);
+ sg4::this_actor::sleep_for(150);
XBT_INFO("The host is now up and running. Switch back to previous pstate %lu", previous_pstate);
host->set_pstate(previous_pstate);
}
-static void simulate_shutdown(simgrid::s4u::Host* host)
+static void simulate_shutdown(sg4::Host* host)
{
unsigned long previous_pstate = host->get_pstate();
host->set_pstate(4);
XBT_INFO("Wait 7 seconds to simulate the shutdown time.");
- simgrid::s4u::this_actor::sleep_for(7);
+ sg4::this_actor::sleep_for(7);
XBT_INFO("Switch back to previous pstate %lu, that will be used on reboot.", previous_pstate);
host->set_pstate(previous_pstate);
static void monitor()
{
- simgrid::s4u::Host* host1 = simgrid::s4u::Host::by_name("MyHost1");
+ sg4::Host* host1 = sg4::Host::by_name("MyHost1");
XBT_INFO("Initial pstate: %lu; Energy dissipated so far:%.0E J", host1->get_pstate(),
sg_host_get_consumed_energy(host1));
XBT_INFO("Sleep for 10 seconds");
- simgrid::s4u::this_actor::sleep_for(10);
+ sg4::this_actor::sleep_for(10);
XBT_INFO("Done sleeping. Current pstate: %lu; Energy dissipated so far: %.2f J", host1->get_pstate(),
sg_host_get_consumed_energy(host1));
sg_host_get_consumed_energy(host1));
XBT_INFO("Sleep for 10 seconds");
- simgrid::s4u::this_actor::sleep_for(10);
+ sg4::this_actor::sleep_for(10);
XBT_INFO("Done sleeping. Current pstate: %lu; Energy dissipated so far: %.2f J", host1->get_pstate(),
sg_host_get_consumed_energy(host1));
int main(int argc, char* argv[])
{
sg_host_energy_plugin_init();
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc == 2, "Usage: %s platform_file\n\tExample: %s platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("Boot Monitor", e.host_by_name("MyHost2"), monitor);
+ sg4::Actor::create("Boot Monitor", e.host_by_name("MyHost2"), monitor);
e.run();
#include "simgrid/plugins/energy.h"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void runner()
{
- simgrid::s4u::Host* host1 = simgrid::s4u::Host::by_name("MyHost1");
- simgrid::s4u::Host* host2 = simgrid::s4u::Host::by_name("MyHost2");
- std::vector<simgrid::s4u::Host*> hosts{host1, host2};
+ sg4::Host* host1 = sg4::Host::by_name("MyHost1");
+ sg4::Host* host2 = sg4::Host::by_name("MyHost2");
+ std::vector<sg4::Host*> hosts{host1, host2};
double old_energy_host1 = sg_host_get_consumed_energy(host1);
double old_energy_host2 = sg_host_get_consumed_energy(host2);
XBT_INFO("[%s] Initial peak speed=%.0E flop/s; Total energy dissipated =%.0E J", host2->get_cname(), host2->get_speed(),
old_energy_host2);
- double start = simgrid::s4u::Engine::get_clock();
+ double start = sg4::Engine::get_clock();
XBT_INFO("Sleep for 10 seconds");
- simgrid::s4u::this_actor::sleep_for(10);
+ sg4::this_actor::sleep_for(10);
double new_energy_host1 = sg_host_get_consumed_energy(host1);
double new_energy_host2 = sg_host_get_consumed_energy(host2);
XBT_INFO("Done sleeping (duration: %.2f s).\n"
"[%s] Current peak speed=%.0E; Energy dissipated during this step=%.2f J; Total energy dissipated=%.2f J\n"
"[%s] Current peak speed=%.0E; Energy dissipated during this step=%.2f J; Total energy dissipated=%.2f J\n",
- simgrid::s4u::Engine::get_clock() - start,
- host1->get_cname(), host1->get_speed(), (new_energy_host1 - old_energy_host1), sg_host_get_consumed_energy(host1),
- host2->get_cname(), host2->get_speed(), (new_energy_host2 - old_energy_host2), sg_host_get_consumed_energy(host2));
+ sg4::Engine::get_clock() - start, host1->get_cname(), host1->get_speed(),
+ (new_energy_host1 - old_energy_host1), sg_host_get_consumed_energy(host1), host2->get_cname(),
+ host2->get_speed(), (new_energy_host2 - old_energy_host2), sg_host_get_consumed_energy(host2));
old_energy_host1 = new_energy_host1;
old_energy_host2 = new_energy_host2;
// ========= Execute something =========
- start = simgrid::s4u::Engine::get_clock();
+ start = sg4::Engine::get_clock();
double flopAmount = 1E9;
std::vector<double> cpu_amounts{flopAmount, flopAmount};
std::vector<double> com_amounts{0, 0, 0, 0};
XBT_INFO("Run a task of %.0E flops on two hosts", flopAmount);
- simgrid::s4u::this_actor::parallel_execute(hosts, cpu_amounts, com_amounts);
+ sg4::this_actor::parallel_execute(hosts, cpu_amounts, com_amounts);
new_energy_host1 = sg_host_get_consumed_energy(host1);
new_energy_host2 = sg_host_get_consumed_energy(host2);
- XBT_INFO("Task done (duration: %.2f s).\n"
- "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n"
- "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n",
- simgrid::s4u::Engine::get_clock() - start,
- host1->get_cname(), host1->get_speed(), (new_energy_host1 - old_energy_host1), sg_host_get_consumed_energy(host1),
- host2->get_cname(), host2->get_speed(), (new_energy_host2 - old_energy_host2), sg_host_get_consumed_energy(host2));
+ XBT_INFO(
+ "Task done (duration: %.2f s).\n"
+ "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n"
+ "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f "
+ "J\n",
+ sg4::Engine::get_clock() - start, host1->get_cname(), host1->get_speed(), (new_energy_host1 - old_energy_host1),
+ sg_host_get_consumed_energy(host1), host2->get_cname(), host2->get_speed(), (new_energy_host2 - old_energy_host2),
+ sg_host_get_consumed_energy(host2));
old_energy_host1 = new_energy_host1;
old_energy_host2 = new_energy_host2;
// ========= Run another ptask =========
- start = simgrid::s4u::Engine::get_clock();
+ start = sg4::Engine::get_clock();
std::vector<double> cpu_amounts2{flopAmount, flopAmount};
std::vector<double> com_amounts2{0, 0, 0, 0};
XBT_INFO("Run a task of %.0E flops on %s and %.0E flops on %s.", flopAmount, host1->get_cname(), flopAmount, host2->get_cname());
- simgrid::s4u::this_actor::parallel_execute(hosts, cpu_amounts2, com_amounts2);
+ sg4::this_actor::parallel_execute(hosts, cpu_amounts2, com_amounts2);
new_energy_host1 = sg_host_get_consumed_energy(host1);
new_energy_host2 = sg_host_get_consumed_energy(host2);
- XBT_INFO("Task done (duration: %.2f s).\n"
- "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n"
- "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n",
- simgrid::s4u::Engine::get_clock() - start,
- host1->get_cname(), host1->get_speed(), (new_energy_host1 - old_energy_host1), sg_host_get_consumed_energy(host1),
- host2->get_cname(), host2->get_speed(), (new_energy_host2 - old_energy_host2), sg_host_get_consumed_energy(host2));
+ XBT_INFO(
+ "Task done (duration: %.2f s).\n"
+ "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n"
+ "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f "
+ "J\n",
+ sg4::Engine::get_clock() - start, host1->get_cname(), host1->get_speed(), (new_energy_host1 - old_energy_host1),
+ sg_host_get_consumed_energy(host1), host2->get_cname(), host2->get_speed(), (new_energy_host2 - old_energy_host2),
+ sg_host_get_consumed_energy(host2));
old_energy_host1 = new_energy_host1;
old_energy_host2 = new_energy_host2;
// ========= A new ptask with computation and communication =========
- start = simgrid::s4u::Engine::get_clock();
+ start = sg4::Engine::get_clock();
double comAmount = 1E7;
std::vector<double> cpu_amounts3{flopAmount, flopAmount};
std::vector<double> com_amounts3{0, comAmount, comAmount, 0};
XBT_INFO("Run a task with computation and communication on two hosts.");
- simgrid::s4u::this_actor::parallel_execute(hosts, cpu_amounts3, com_amounts3);
+ sg4::this_actor::parallel_execute(hosts, cpu_amounts3, com_amounts3);
new_energy_host1 = sg_host_get_consumed_energy(host1);
new_energy_host2 = sg_host_get_consumed_energy(host2);
- XBT_INFO("Task done (duration: %.2f s).\n"
- "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n"
- "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n",
- simgrid::s4u::Engine::get_clock() - start,
- host1->get_cname(), host1->get_speed(), (new_energy_host1 - old_energy_host1), sg_host_get_consumed_energy(host1),
- host2->get_cname(), host2->get_speed(), (new_energy_host2 - old_energy_host2), sg_host_get_consumed_energy(host2));
+ XBT_INFO(
+ "Task done (duration: %.2f s).\n"
+ "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n"
+ "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f "
+ "J\n",
+ sg4::Engine::get_clock() - start, host1->get_cname(), host1->get_speed(), (new_energy_host1 - old_energy_host1),
+ sg_host_get_consumed_energy(host1), host2->get_cname(), host2->get_speed(), (new_energy_host2 - old_energy_host2),
+ sg_host_get_consumed_energy(host2));
old_energy_host1 = new_energy_host1;
old_energy_host2 = new_energy_host2;
// ========= A new ptask with communication only =========
- start = simgrid::s4u::Engine::get_clock();
+ start = sg4::Engine::get_clock();
std::vector<double> cpu_amounts4{0, 0};
std::vector<double> com_amounts4{0, comAmount, comAmount, 0};
XBT_INFO("Run a task with only communication on two hosts.");
- simgrid::s4u::this_actor::parallel_execute(hosts, cpu_amounts4, com_amounts4);
+ sg4::this_actor::parallel_execute(hosts, cpu_amounts4, com_amounts4);
new_energy_host1 = sg_host_get_consumed_energy(host1);
new_energy_host2 = sg_host_get_consumed_energy(host2);
- XBT_INFO("Task done (duration: %.2f s).\n"
- "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n"
- "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n",
- simgrid::s4u::Engine::get_clock() - start,
- host1->get_cname(), host1->get_speed(), (new_energy_host1 - old_energy_host1), sg_host_get_consumed_energy(host1),
- host2->get_cname(), host2->get_speed(), (new_energy_host2 - old_energy_host2), sg_host_get_consumed_energy(host2));
+ XBT_INFO(
+ "Task done (duration: %.2f s).\n"
+ "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n"
+ "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f "
+ "J\n",
+ sg4::Engine::get_clock() - start, host1->get_cname(), host1->get_speed(), (new_energy_host1 - old_energy_host1),
+ sg_host_get_consumed_energy(host1), host2->get_cname(), host2->get_speed(), (new_energy_host2 - old_energy_host2),
+ sg_host_get_consumed_energy(host2));
old_energy_host1 = new_energy_host1;
old_energy_host2 = new_energy_host2;
// ========= A new ptask with computation and a timeout =========
- start = simgrid::s4u::Engine::get_clock();
+ start = sg4::Engine::get_clock();
std::vector<double> cpu_amounts5{flopAmount, flopAmount};
std::vector<double> com_amounts5{0, 0, 0, 0};
XBT_INFO("Run a task with computation on two hosts and a timeout of 20s.");
try {
- simgrid::s4u::this_actor::exec_init(hosts, cpu_amounts5, com_amounts5)->wait_for(20);
+ sg4::this_actor::exec_init(hosts, cpu_amounts5, com_amounts5)->wait_for(20);
} catch (const simgrid::TimeoutException &){
XBT_INFO("Finished WITH timeout");
}
new_energy_host1 = sg_host_get_consumed_energy(host1);
new_energy_host2 = sg_host_get_consumed_energy(host2);
- XBT_INFO("Task ended (duration: %.2f s).\n"
- "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n"
- "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n",
- simgrid::s4u::Engine::get_clock() - start,
- host1->get_cname(), host1->get_speed(), (new_energy_host1 - old_energy_host1), sg_host_get_consumed_energy(host1),
- host2->get_cname(), host2->get_speed(), (new_energy_host2 - old_energy_host2), sg_host_get_consumed_energy(host2));
+ XBT_INFO(
+ "Task ended (duration: %.2f s).\n"
+ "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f J\n"
+ "[%s] Current peak speed=%.0E flop/s; Energy dissipated during this step=%.2f J; Total energy dissipated=%.0f "
+ "J\n",
+ sg4::Engine::get_clock() - start, host1->get_cname(), host1->get_speed(), (new_energy_host1 - old_energy_host1),
+ sg_host_get_consumed_energy(host1), host2->get_cname(), host2->get_speed(), (new_energy_host2 - old_energy_host2),
+ sg_host_get_consumed_energy(host2));
XBT_INFO("Now is time to quit!");
}
int main(int argc, char* argv[])
{
sg_host_energy_plugin_init();
- simgrid::s4u::Engine e(&argc, argv);
- simgrid::s4u::Engine::set_config("host/model:ptask_L07");
+ sg4::Engine e(&argc, argv);
+ sg4::Engine::set_config("host/model:ptask_L07");
xbt_assert(argc == 2, "Usage: %s platform_file\n\tExample: %s ../platforms/energy_platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("energy_ptask_test", e.host_by_name("MyHost1"), runner);
+ sg4::Actor::create("energy_ptask_test", e.host_by_name("MyHost1"), runner);
e.run();
XBT_INFO("End of simulation.");
#include "simgrid/plugins/energy.h"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void dvfs()
{
- simgrid::s4u::Host* host1 = simgrid::s4u::Host::by_name("MyHost1");
- simgrid::s4u::Host* host2 = simgrid::s4u::Host::by_name("MyHost2");
+ sg4::Host* host1 = sg4::Host::by_name("MyHost1");
+ sg4::Host* host2 = sg4::Host::by_name("MyHost2");
XBT_INFO("Energetic profile: %s", host1->get_property("wattage_per_state"));
XBT_INFO("Initial peak speed=%.0E flop/s; Energy dissipated =%.0E J", host1->get_speed(),
sg_host_get_consumed_energy(host1));
- double start = simgrid::s4u::Engine::get_clock();
+ double start = sg4::Engine::get_clock();
XBT_INFO("Sleep for 10 seconds");
- simgrid::s4u::this_actor::sleep_for(10);
+ sg4::this_actor::sleep_for(10);
XBT_INFO("Done sleeping (duration: %.2f s). Current peak speed=%.0E; Energy dissipated=%.2f J",
- simgrid::s4u::Engine::get_clock() - start, host1->get_speed(), sg_host_get_consumed_energy(host1));
+ sg4::Engine::get_clock() - start, host1->get_speed(), sg_host_get_consumed_energy(host1));
// Execute something
- start = simgrid::s4u::Engine::get_clock();
+ start = sg4::Engine::get_clock();
double flopAmount = 100E6;
XBT_INFO("Run a computation of %.0E flops", flopAmount);
- simgrid::s4u::this_actor::execute(flopAmount);
+ sg4::this_actor::execute(flopAmount);
XBT_INFO(
"Computation done (duration: %.2f s). Current peak speed=%.0E flop/s; Current consumption: from %.0fW to %.0fW"
" depending on load; Energy dissipated=%.0f J",
- simgrid::s4u::Engine::get_clock() - start, host1->get_speed(), sg_host_get_wattmin_at(host1, host1->get_pstate()),
+ sg4::Engine::get_clock() - start, host1->get_speed(), sg_host_get_wattmin_at(host1, host1->get_pstate()),
sg_host_get_wattmax_at(host1, host1->get_pstate()), sg_host_get_consumed_energy(host1));
// ========= Change power peak =========
host1->get_pstate_speed(pstate), host1->get_speed());
// Run another computation
- start = simgrid::s4u::Engine::get_clock();
+ start = sg4::Engine::get_clock();
XBT_INFO("Run a computation of %.0E flops", flopAmount);
- simgrid::s4u::this_actor::execute(flopAmount);
+ sg4::this_actor::execute(flopAmount);
XBT_INFO("Computation done (duration: %.2f s). Current peak speed=%.0E flop/s; Energy dissipated=%.0f J",
- simgrid::s4u::Engine::get_clock() - start, host1->get_speed(), sg_host_get_consumed_energy(host1));
+ sg4::Engine::get_clock() - start, host1->get_speed(), sg_host_get_consumed_energy(host1));
- start = simgrid::s4u::Engine::get_clock();
+ start = sg4::Engine::get_clock();
XBT_INFO("Sleep for 4 seconds");
- simgrid::s4u::this_actor::sleep_for(4);
+ sg4::this_actor::sleep_for(4);
XBT_INFO("Done sleeping (duration: %.2f s). Current peak speed=%.0E flop/s; Energy dissipated=%.0f J",
- simgrid::s4u::Engine::get_clock() - start, host1->get_speed(), sg_host_get_consumed_energy(host1));
+ sg4::Engine::get_clock() - start, host1->get_speed(), sg_host_get_consumed_energy(host1));
// =========== Turn the other host off ==========
XBT_INFO("Turning MyHost2 off, and sleeping another 10 seconds. MyHost2 dissipated %.0f J so far.",
sg_host_get_consumed_energy(host2));
host2->turn_off();
- start = simgrid::s4u::Engine::get_clock();
- simgrid::s4u::this_actor::sleep_for(10);
+ start = sg4::Engine::get_clock();
+ sg4::this_actor::sleep_for(10);
XBT_INFO("Done sleeping (duration: %.2f s). Current peak speed=%.0E flop/s; Energy dissipated=%.0f J",
- simgrid::s4u::Engine::get_clock() - start, host1->get_speed(), sg_host_get_consumed_energy(host1));
+ sg4::Engine::get_clock() - start, host1->get_speed(), sg_host_get_consumed_energy(host1));
}
int main(int argc, char* argv[])
{
sg_host_energy_plugin_init();
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc == 2, "Usage: %s platform_file\n\tExample: %s ../platforms/energy_platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("dvfs_test", e.host_by_name("MyHost1"), dvfs);
+ sg4::Actor::create("dvfs_test", e.host_by_name("MyHost1"), dvfs);
e.run();
static const int max_size = 1e9;
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_app_energyconsumption, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void sender(std::vector<std::string> args)
{
long comm_size = std::stol(args.at(1));
XBT_INFO("Send %ld bytes, in %d flows", comm_size, flow_amount);
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::string("message"));
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::string("message"));
/* Sleep a while before starting the example */
- simgrid::s4u::this_actor::sleep_for(10);
+ sg4::this_actor::sleep_for(10);
if (flow_amount == 1) {
/* - Send the task to the @ref worker */
mailbox->put(payload, comm_size);
} else {
// Start all comms in parallel, and wait for all completions in one shot
- std::vector<simgrid::s4u::CommPtr> comms;
+ std::vector<sg4::CommPtr> comms;
for (int i = 0; i < flow_amount; i++)
comms.push_back(mailbox->put_async(bprintf("%d", i), comm_size));
- simgrid::s4u::Comm::wait_all(comms);
+ sg4::Comm::wait_all(comms);
}
XBT_INFO("sender done.");
}
XBT_INFO("Receiving %d flows ...", flow_amount);
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name(std::string("message"));
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name(std::string("message"));
if (flow_amount == 1) {
char* res = mailbox->get<char>();
std::vector<char*> data(flow_amount);
// Start all comms in parallel, and wait for their completion in one shot
- std::vector<simgrid::s4u::CommPtr> comms;
+ std::vector<sg4::CommPtr> comms;
for (int i = 0; i < flow_amount; i++)
comms.push_back(mailbox->get_async<char>(&data[i]));
- simgrid::s4u::Comm::wait_all(comms);
+ sg4::Comm::wait_all(comms);
for (int i = 0; i < flow_amount; i++)
xbt_free(data[i]);
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
XBT_INFO("Activating the SimGrid link energy plugin");
sg_link_energy_plugin_init();
} else { // No parameter at all? Then use the default value
argSender.emplace_back("25000");
}
- simgrid::s4u::Actor::create("sender", e.host_by_name("MyHost1"), sender, argSender);
- simgrid::s4u::Actor::create("receiver", e.host_by_name("MyHost2"), receiver, argReceiver);
+ sg4::Actor::create("sender", e.host_by_name("MyHost1"), sender, argSender);
+ sg4::Actor::create("receiver", e.host_by_name("MyHost2"), receiver, argReceiver);
/* And now, launch the simulation */
e.run();
#include "simgrid/s4u/VirtualMachine.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(energy_vm, "Messages of this example");
+namespace sg4 = simgrid::s4u;
static void executor()
{
- simgrid::s4u::this_actor::execute(300E6);
+ sg4::this_actor::execute(300E6);
XBT_INFO("This worker is done.");
}
static void dvfs()
{
- simgrid::s4u::Host* host1 = simgrid::s4u::Host::by_name("MyHost1");
- simgrid::s4u::Host* host2 = simgrid::s4u::Host::by_name("MyHost2");
- simgrid::s4u::Host* host3 = simgrid::s4u::Host::by_name("MyHost3");
+ sg4::Host* host1 = sg4::Host::by_name("MyHost1");
+ sg4::Host* host2 = sg4::Host::by_name("MyHost2");
+ sg4::Host* host3 = sg4::Host::by_name("MyHost3");
/* Host 1 */
XBT_INFO("Creating and starting two VMs");
vm_host2->start();
XBT_INFO("Create two activities on Host1: both inside a VM");
- simgrid::s4u::Actor::create("p11", vm_host1, executor);
- simgrid::s4u::Actor::create("p12", vm_host1, executor);
+ sg4::Actor::create("p11", vm_host1, executor);
+ sg4::Actor::create("p12", vm_host1, executor);
XBT_INFO("Create two activities on Host2: one inside a VM, the other directly on the host");
- simgrid::s4u::Actor::create("p21", vm_host2, executor);
- simgrid::s4u::Actor::create("p22", host2, executor);
+ sg4::Actor::create("p21", vm_host2, executor);
+ sg4::Actor::create("p22", host2, executor);
XBT_INFO("Create two activities on Host3: both directly on the host");
- simgrid::s4u::Actor::create("p31", host3, executor);
- simgrid::s4u::Actor::create("p32", host3, executor);
+ sg4::Actor::create("p31", host3, executor);
+ sg4::Actor::create("p32", host3, executor);
XBT_INFO("Wait 5 seconds. The activities are still running (they run for 3 seconds, but 2 activities are co-located, "
"so they run for 6 seconds)");
- simgrid::s4u::this_actor::sleep_for(5);
+ sg4::this_actor::sleep_for(5);
XBT_INFO("Wait another 5 seconds. The activities stop at some point in between");
- simgrid::s4u::this_actor::sleep_for(5);
+ sg4::this_actor::sleep_for(5);
vm_host1->destroy();
vm_host2->destroy();
int main(int argc, char* argv[])
{
sg_host_energy_plugin_init();
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 1, "Usage: %s platform_file\n\tExample: %s ../platforms/energy_platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("dvfs", e.host_by_name("MyHost1"), dvfs);
+ sg4::Actor::create("dvfs", e.host_by_name("MyHost1"), dvfs);
e.run();
XBT_INFO("Total simulation time: %.2f; Host2 and Host3 must have the exact same energy consumption; Host1 is "
"multi-core and will differ.",
- simgrid::s4u::Engine::get_clock());
+ sg4::Engine::get_clock());
return 0;
}
#include "simgrid/s4u/Mailbox.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(test_wifi, "Wifi energy demo");
+namespace sg4 = simgrid::s4u;
static void sender()
{
// start sending after 5 seconds
- simgrid::s4u::this_actor::sleep_until(5);
+ sg4::this_actor::sleep_until(5);
std::string mbName = "MailBoxRCV";
- simgrid::s4u::Mailbox *dst = simgrid::s4u::Mailbox::by_name(mbName);
+ sg4::Mailbox* dst = sg4::Mailbox::by_name(mbName);
int size = 6750000;
{
std::string mbName = "MailBoxRCV";
XBT_INFO("RECEIVING on mb %s", mbName.c_str());
- simgrid::s4u::Mailbox *myBox = simgrid::s4u::Mailbox::by_name(mbName);
+ sg4::Mailbox* myBox = sg4::Mailbox::by_name(mbName);
myBox->get<std::string>();
XBT_INFO("received all messages");
int main(int argc, char** argv)
{
- simgrid::s4u::Engine engine(&argc, argv);
+ sg4::Engine engine(&argc, argv);
sg_wifi_energy_plugin_init();
engine.load_platform(argv[1]);
l->set_host_wifi_rate(engine.host_by_name("Station 2"), 0);
// create the two actors for the test
- simgrid::s4u::Actor::create("act0", engine.host_by_name("Station 1"), sender);
- simgrid::s4u::Actor::create("act1", engine.host_by_name("Station 2"), receiver);
+ sg4::Actor::create("act0", engine.host_by_name("Station 1"), sender);
+ sg4::Actor::create("act1", engine.host_by_name("Station 2"), receiver);
engine.run();
#include <simgrid/s4u.hpp>
-/* This example shows how to use simgrid::s4u::Engine::get_filtered_hosts() to retrieve
+/* This example shows how to use sg4::Engine::get_filtered_hosts() to retrieve
* all hosts that match a given criteria. This criteria can be specified either with:
* - an inlined callback
* - a boolean function, such as filter_speed_more_than_50Mf() below
*/
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_engine_filtering, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
namespace filter {
/* First example of thing that we can use as a filtering criteria: a simple boolean function */
-static bool filter_speed_more_than_50Mf(const simgrid::s4u::Host* host)
+static bool filter_speed_more_than_50Mf(const sg4::Host* host)
{
return host->get_speed() > 50E6;
}
*/
class SingleCore {
public:
- bool operator()(const simgrid::s4u::Host* host) const { return host->get_core_count() == 1; }
+ bool operator()(const sg4::Host* host) const { return host->get_core_count() == 1; }
};
/* This functor is a bit more complex, as it saves the current state when created.
* Then, it allows one to easily retrieve the hosts which frequency changed since the functor creation.
*/
class FrequencyChanged {
- std::map<simgrid::s4u::Host*, unsigned long> host_list;
+ std::map<sg4::Host*, unsigned long> host_list;
public:
- explicit FrequencyChanged(const simgrid::s4u::Engine& e)
+ explicit FrequencyChanged(const sg4::Engine& e)
{
- std::vector<simgrid::s4u::Host*> list = e.get_all_hosts();
+ std::vector<sg4::Host*> list = e.get_all_hosts();
for (auto& host : list) {
host_list.insert({host, host->get_pstate()});
}
}
- bool operator()(simgrid::s4u::Host* host) { return host->get_pstate() != host_list.at(host); }
+ bool operator()(sg4::Host* host) { return host->get_pstate() != host_list.at(host); }
- unsigned long get_old_speed_state(simgrid::s4u::Host* host) { return host_list.at(host); }
+ unsigned long get_old_speed_state(sg4::Host* host) { return host_list.at(host); }
};
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
/* Use a lambda function to filter hosts: We only want multicore hosts */
XBT_INFO("Hosts currently registered with this engine: %zu", e.get_host_count());
- std::vector<simgrid::s4u::Host*> list =
- e.get_filtered_hosts([](const simgrid::s4u::Host* host) { return host->get_core_count() > 1; });
+ std::vector<sg4::Host*> list = e.get_filtered_hosts([](const sg4::Host* host) { return host->get_core_count() > 1; });
for (auto& host : list)
XBT_INFO("The following hosts have more than one core: %s", host->get_cname());
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
/* This actor simply executes and waits the activity it got as a parameter. */
-static void runner(simgrid::s4u::ExecPtr activity)
+static void runner(sg4::ExecPtr activity)
{
activity->start();
activity->wait();
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- simgrid::s4u::Host* fafard = e.host_by_name("Fafard");
+ sg4::Host* fafard = e.host_by_name("Fafard");
- simgrid::s4u::ExecPtr activity = simgrid::s4u::this_actor::exec_init(fafard->get_speed() * 10.)->set_host(fafard);
- simgrid::s4u::Actor::create("runner", fafard, runner, activity);
+ sg4::ExecPtr activity = sg4::this_actor::exec_init(fafard->get_speed() * 10.)->set_host(fafard);
+ sg4::Actor::create("runner", fafard, runner, activity);
while (activity->get_remaining() > 0) {
XBT_INFO("Remaining amount of flops: %g (%.0f%%)", activity->get_remaining(),
100 * activity->get_remaining_ratio());
- e.run_until(simgrid::s4u::Engine::get_clock() + 1);
+ e.run_until(sg4::Engine::get_clock() + 1);
}
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
/* This actor simply waits for its activity completion after starting it.
* That's exactly equivalent to synchronous execution. */
static void waiter()
{
- double computation_amount = simgrid::s4u::this_actor::get_host()->get_speed();
+ double computation_amount = sg4::this_actor::get_host()->get_speed();
XBT_INFO("Execute %g flops, should take 1 second.", computation_amount);
- simgrid::s4u::ExecPtr activity = simgrid::s4u::this_actor::exec_init(computation_amount);
+ sg4::ExecPtr activity = sg4::this_actor::exec_init(computation_amount);
activity->start();
activity->wait();
/* This actor tests the ongoing execution until its completion, and don't wait before it's terminated. */
static void monitor()
{
- double computation_amount = simgrid::s4u::this_actor::get_host()->get_speed();
+ double computation_amount = sg4::this_actor::get_host()->get_speed();
XBT_INFO("Execute %g flops, should take 1 second.", computation_amount);
- simgrid::s4u::ExecPtr activity = simgrid::s4u::this_actor::exec_init(computation_amount);
+ sg4::ExecPtr activity = sg4::this_actor::exec_init(computation_amount);
activity->start();
while (not activity->test()) {
XBT_INFO("Remaining amount of flops: %g (%.0f%%)", activity->get_remaining(),
100 * activity->get_remaining_ratio());
- simgrid::s4u::this_actor::sleep_for(0.3);
+ sg4::this_actor::sleep_for(0.3);
}
XBT_INFO("Goodbye now!");
/* This actor cancels the ongoing execution after a while. */
static void canceller()
{
- double computation_amount = simgrid::s4u::this_actor::get_host()->get_speed();
+ double computation_amount = sg4::this_actor::get_host()->get_speed();
XBT_INFO("Execute %g flops, should take 1 second.", computation_amount);
- simgrid::s4u::ExecPtr activity = simgrid::s4u::this_actor::exec_async(computation_amount);
- simgrid::s4u::this_actor::sleep_for(0.5);
+ sg4::ExecPtr activity = sg4::this_actor::exec_async(computation_amount);
+ sg4::this_actor::sleep_for(0.5);
XBT_INFO("I changed my mind, cancel!");
activity->cancel();
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- simgrid::s4u::Host* fafard = e.host_by_name("Fafard");
- simgrid::s4u::Host* ginette = e.host_by_name("Ginette");
- simgrid::s4u::Host* boivin = e.host_by_name("Boivin");
+ sg4::Host* fafard = e.host_by_name("Fafard");
+ sg4::Host* ginette = e.host_by_name("Ginette");
+ sg4::Host* boivin = e.host_by_name("Boivin");
- simgrid::s4u::Actor::create("wait", fafard, waiter);
- simgrid::s4u::Actor::create("monitor", ginette, monitor);
- simgrid::s4u::Actor::create("cancel", boivin, canceller);
+ sg4::Actor::create("wait", fafard, waiter);
+ sg4::Actor::create("monitor", ginette, monitor);
+ sg4::Actor::create("cancel", boivin, canceller);
e.run();
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void executor()
{
/* this_actor::execute() tells SimGrid to pause the calling actor
* until its host has computed the amount of flops passed as a parameter */
- simgrid::s4u::this_actor::execute(98095);
+ sg4::this_actor::execute(98095);
XBT_INFO("Done.");
/* This simple example does not do anything beyond that */
* Since the priority is 2, it computes twice as fast as a regular one.
*
* So instead of a half/half sharing between the two executions, we get a 1/3 vs 2/3 sharing. */
- simgrid::s4u::this_actor::execute(98095, 2);
+ sg4::this_actor::execute(98095, 2);
XBT_INFO("Done.");
/* Note that the timings printed when running this example are a bit misleading, because the uneven sharing only last
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 1, "Usage: %s platform_file\n\tExample: %s platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("executor", e.host_by_name("Tremblay"), executor);
- simgrid::s4u::Actor::create("privileged", e.host_by_name("Tremblay"), privileged);
+ sg4::Actor::create("executor", e.host_by_name("Tremblay"), executor);
+ sg4::Actor::create("privileged", e.host_by_name("Tremblay"), privileged);
e.run();
#include <vector>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void worker()
{
// Define an amount of work that should take 1 second to execute.
- double computation_amount = simgrid::s4u::this_actor::get_host()->get_speed();
+ double computation_amount = sg4::this_actor::get_host()->get_speed();
- std::vector<simgrid::s4u::ExecPtr> pending_execs;
+ std::vector<sg4::ExecPtr> pending_execs;
// Create a small DAG
// + Two parents and a child
// + First parent ends after 1 second and the Second parent after 2 seconds.
- simgrid::s4u::ExecPtr first_parent = simgrid::s4u::this_actor::exec_init(computation_amount);
+ sg4::ExecPtr first_parent = sg4::this_actor::exec_init(computation_amount);
pending_execs.push_back(first_parent);
- simgrid::s4u::ExecPtr second_parent = simgrid::s4u::this_actor::exec_init(2 * computation_amount);
+ sg4::ExecPtr second_parent = sg4::this_actor::exec_init(2 * computation_amount);
pending_execs.push_back(second_parent);
- simgrid::s4u::ExecPtr child = simgrid::s4u::Exec::init()->set_flops_amount(computation_amount);
+ sg4::ExecPtr child = sg4::Exec::init()->set_flops_amount(computation_amount);
pending_execs.push_back(child);
// Name the activities (for logging purposes only)
// wait for the completion of all activities
while (not pending_execs.empty()) {
- ssize_t changed_pos = simgrid::s4u::Exec::wait_any_for(pending_execs, -1);
+ ssize_t changed_pos = sg4::Exec::wait_any_for(pending_execs, -1);
XBT_INFO("Exec '%s' is complete", pending_execs[changed_pos]->get_cname());
pending_execs.erase(pending_execs.begin() + changed_pos);
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Fafard"), worker);
+ sg4::Actor::create("worker", e.host_by_name("Fafard"), worker);
- simgrid::s4u::Activity::on_veto_cb([&e](simgrid::s4u::Activity& a) {
- auto& exec = static_cast<simgrid::s4u::Exec&>(a);
+ sg4::Activity::on_veto_cb([&e](sg4::Activity& a) {
+ auto& exec = static_cast<sg4::Exec&>(a);
// First display the situation
XBT_INFO("Activity '%s' vetoed. Dependencies: %s; Ressources: %s", exec.get_cname(),
e.run();
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(test, "Pstate properties test");
+namespace sg4 = simgrid::s4u;
static int dvfs()
{
double workload = 100E6;
- simgrid::s4u::Host* host = simgrid::s4u::this_actor::get_host();
+ sg4::Host* host = sg4::this_actor::get_host();
unsigned long nb = host->get_pstate_count();
XBT_INFO("Count of Processor states=%lu", nb);
XBT_INFO("Current power peak=%f", host->get_speed());
// Run a Computation
- simgrid::s4u::this_actor::execute(workload);
+ sg4::this_actor::execute(workload);
- double exec_time = simgrid::s4u::Engine::get_clock();
+ double exec_time = sg4::Engine::get_clock();
XBT_INFO("Computation1 duration: %.2f", exec_time);
// Change power peak
XBT_INFO("Current power peak=%f", host->get_speed());
// Run a second Computation
- simgrid::s4u::this_actor::execute(workload);
+ sg4::this_actor::execute(workload);
- exec_time = simgrid::s4u::Engine::get_clock() - exec_time;
+ exec_time = sg4::Engine::get_clock() - exec_time;
XBT_INFO("Computation2 duration: %.2f", exec_time);
// Verify that the default pstate is set to 0
- host = simgrid::s4u::Host::by_name_or_null("MyHost2");
+ host = sg4::Host::by_name_or_null("MyHost2");
XBT_INFO("Count of Processor states=%lu", host->get_pstate_count());
XBT_INFO("Current power peak=%f", host->get_speed());
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc == 2, "Usage: %s platform_file\n\tExample: %s ../platforms/energy_platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("dvfs_test", e.host_by_name("MyHost1"), dvfs);
- simgrid::s4u::Actor::create("dvfs_test", e.host_by_name("MyHost2"), dvfs);
+ sg4::Actor::create("dvfs_test", e.host_by_name("MyHost1"), dvfs);
+ sg4::Actor::create("dvfs_test", e.host_by_name("MyHost2"), dvfs);
e.run();
- XBT_INFO("Total simulation time: %e", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Total simulation time: %e", sg4::Engine::get_clock());
return 0;
}
}
pending_execs.pop_back();
XBT_INFO("Wait for remaining exec, just to be nice");
- simgrid::s4u::Exec::wait_any(pending_execs);
+ sg4::Exec::wait_any(pending_execs);
XBT_INFO("Dispatcher ends");
}
#include <simgrid/s4u.hpp>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_ptask_multicore, "Messages specific for this s4u example");
-
namespace sg4 = simgrid::s4u;
static void runner()
// Add a background task and change ptask on the fly
auto MyHost1 = e->host_by_name("MyHost1");
- simgrid::s4u::ExecPtr background_task = MyHost1->exec_async(5e9);
+ sg4::ExecPtr background_task = MyHost1->exec_async(5e9);
XBT_INFO("Start a 1-core background task on the 4-core host.");
start_time = sg4::Engine::get_clock();
#include <simgrid/s4u.hpp>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_ptask, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void runner()
{
/* Retrieve the list of all hosts as an array of hosts */
- auto hosts = simgrid::s4u::Engine::get_instance()->get_all_hosts();
+ auto hosts = sg4::Engine::get_instance()->get_all_hosts();
size_t hosts_count = hosts.size();
std::vector<double> computation_amounts;
for (size_t j = i + 1; j < hosts_count; j++)
communication_amounts[i * hosts_count + j] = 1e7; // 10 MB
- simgrid::s4u::this_actor::parallel_execute(hosts, computation_amounts, communication_amounts);
+ sg4::this_actor::parallel_execute(hosts, computation_amounts, communication_amounts);
/* ------[ test 2 ]----------------- */
XBT_INFO("We can do the same with a timeout of 10 seconds enabled.");
for (size_t j = i + 1; j < hosts_count; j++)
communication_amounts[i * hosts_count + j] = 1e7; // 10 MB
- simgrid::s4u::ExecPtr activity =
- simgrid::s4u::this_actor::exec_init(hosts, computation_amounts, communication_amounts);
+ sg4::ExecPtr activity = sg4::this_actor::exec_init(hosts, computation_amounts, communication_amounts);
try {
activity->wait_for(10.0 /* timeout (in seconds)*/);
xbt_die("Woops, this did not timeout as expected... Please report that bug.");
XBT_INFO("Then, build a parallel activity involving only computations (of different amounts) and no communication");
computation_amounts = {3e8, 6e8, 1e9}; // 300Mflop, 600Mflop, 1Gflop
communication_amounts.clear(); // no comm
- simgrid::s4u::this_actor::parallel_execute(hosts, computation_amounts, communication_amounts);
+ sg4::this_actor::parallel_execute(hosts, computation_amounts, communication_amounts);
/* ------[ test 4 ]----------------- */
XBT_INFO("Then, build a parallel activity with no computation nor communication (synchro only)");
computation_amounts.clear();
communication_amounts.clear();
- simgrid::s4u::this_actor::parallel_execute(hosts, computation_amounts, communication_amounts);
+ sg4::this_actor::parallel_execute(hosts, computation_amounts, communication_amounts);
/* ------[ test 5 ]----------------- */
XBT_INFO("Then, Monitor the execution of a parallel activity");
computation_amounts.assign(hosts_count, 1e6 /*1Mflop*/);
communication_amounts = {0, 1e6, 0, 0, 0, 1e6, 1e6, 0, 0};
- activity = simgrid::s4u::this_actor::exec_init(hosts, computation_amounts, communication_amounts);
+ activity = sg4::this_actor::exec_init(hosts, computation_amounts, communication_amounts);
activity->start();
while (not activity->test()) {
XBT_INFO("Remaining flop ratio: %.0f%%", 100 * activity->get_remaining_ratio());
- simgrid::s4u::this_actor::sleep_for(5);
+ sg4::this_actor::sleep_for(5);
}
activity->wait();
XBT_INFO(" - Start a regular parallel execution, with both comm and computation");
computation_amounts.assign(hosts_count, 1e6 /*1Mflop*/);
communication_amounts = {0, 1e6, 0, 0, 1e6, 0, 1e6, 0, 0};
- activity = simgrid::s4u::this_actor::exec_init(hosts, computation_amounts, communication_amounts);
+ activity = sg4::this_actor::exec_init(hosts, computation_amounts, communication_amounts);
activity->start();
- simgrid::s4u::this_actor::sleep_for(10);
+ sg4::this_actor::sleep_for(10);
double remaining_ratio = activity->get_remaining_ratio();
XBT_INFO(" - After 10 seconds, %.2f%% remains to be done. Change it from 3 hosts to 2 hosts only.",
remaining_ratio * 100);
XBT_INFO(" - Now, simulate the reconfiguration (modeled as a comm from the removed host to the remaining ones).");
std::vector<double> rescheduling_comp{0, 0, 0};
std::vector<double> rescheduling_comm{0, 0, 0, 0, 0, 0, 25000, 25000, 0};
- simgrid::s4u::this_actor::parallel_execute(hosts, rescheduling_comp, rescheduling_comm);
+ sg4::this_actor::parallel_execute(hosts, rescheduling_comp, rescheduling_comm);
XBT_INFO(" - Now, let's cancel the old task and create a new task with modified comm and computation vectors:");
XBT_INFO(" What was already done is removed, and the load of the removed host is shared between remaining ones.");
communication_amounts = {0, remaining_comm, remaining_comm, 0}; // Resizing a linearized matrix is hairly
activity->cancel();
- activity = simgrid::s4u::this_actor::exec_init(hosts, computation_amounts, communication_amounts);
+ activity = sg4::this_actor::exec_init(hosts, computation_amounts, communication_amounts);
XBT_INFO(" - Done, let's wait for the task completion");
activity->wait();
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc == 2, "Usage: %s <platform file>", argv[0]);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("test", e.host_by_name("MyHost1"), runner);
+ sg4::Actor::create("test", e.host_by_name("MyHost1"), runner);
e.run();
XBT_INFO("Simulation done.");
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void wizard()
{
- const simgrid::s4u::Host* fafard = simgrid::s4u::Host::by_name("Fafard");
- simgrid::s4u::Host* ginette = simgrid::s4u::Host::by_name("Ginette");
- simgrid::s4u::Host* boivin = simgrid::s4u::Host::by_name("Boivin");
+ const sg4::Host* fafard = sg4::Host::by_name("Fafard");
+ sg4::Host* ginette = sg4::Host::by_name("Ginette");
+ sg4::Host* boivin = sg4::Host::by_name("Boivin");
XBT_INFO("I'm a wizard! I can run an activity on the Ginette host from the Fafard one! Look!");
- simgrid::s4u::ExecPtr exec = simgrid::s4u::this_actor::exec_init(48.492e6);
+ sg4::ExecPtr exec = sg4::this_actor::exec_init(48.492e6);
exec->set_host(ginette);
exec->start();
XBT_INFO("It started. Running 48.492Mf takes exactly one second on Ginette (but not on Fafard).");
- simgrid::s4u::this_actor::sleep_for(0.1);
+ sg4::this_actor::sleep_for(0.1);
XBT_INFO("Loads in flops/s: Boivin=%.0f; Fafard=%.0f; Ginette=%.0f", boivin->get_load(), fafard->get_load(),
ginette->get_load());
XBT_INFO("Done!");
XBT_INFO("And now, harder. Start a remote activity on Ginette and move it to Boivin after 0.5 sec");
- exec = simgrid::s4u::this_actor::exec_init(73293500)->set_host(ginette);
+ exec = sg4::this_actor::exec_init(73293500)->set_host(ginette);
exec->start();
- simgrid::s4u::this_actor::sleep_for(0.5);
+ sg4::this_actor::sleep_for(0.5);
XBT_INFO("Loads before the move: Boivin=%.0f; Fafard=%.0f; Ginette=%.0f", boivin->get_load(), fafard->get_load(),
ginette->get_load());
exec->set_host(boivin);
- simgrid::s4u::this_actor::sleep_for(0.1);
+ sg4::this_actor::sleep_for(0.1);
XBT_INFO("Loads after the move: Boivin=%.0f; Fafard=%.0f; Ginette=%.0f", boivin->get_load(), fafard->get_load(),
ginette->get_load());
XBT_INFO("Done!");
XBT_INFO("And now, even harder. Start a remote activity on Ginette and turn off the host after 0.5 sec");
- exec = simgrid::s4u::this_actor::exec_init(48.492e6)->set_host(ginette);
+ exec = sg4::this_actor::exec_init(48.492e6)->set_host(ginette);
exec->start();
- simgrid::s4u::this_actor::sleep_for(0.5);
+ sg4::this_actor::sleep_for(0.5);
ginette->turn_off();
try {
exec->wait();
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("test", e.host_by_name("Fafard"), wizard);
+ sg4::Actor::create("test", e.host_by_name("Fafard"), wizard);
e.run();
--- /dev/null
+/* Copyright (c) 2017-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. */
+
+#include <simgrid/s4u.hpp>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_exec_thread, "Messages specific for this s4u example");
+
+namespace sg4 = simgrid::s4u;
+
+static void runner()
+{
+ auto e = sg4::Engine::get_instance();
+ sg4::Host* multicore_host = e->host_by_name("MyHost1");
+ // First test with less than, same number as, and more threads than cores
+ double start_time = sg4::Engine::get_clock();
+ sg4::this_actor::thread_execute(multicore_host, 1e9, 2);
+ XBT_INFO("Computed 2-thread activity on a 4-core host. Took %g s", e->get_clock() - start_time);
+
+ start_time = sg4::Engine::get_clock();
+ sg4::this_actor::thread_execute(multicore_host, 1e9, 4);
+ XBT_INFO("Computed 4-thread activity on a 4-core host. Took %g s", e->get_clock() - start_time);
+
+ start_time = sg4::Engine::get_clock();
+ sg4::this_actor::thread_execute(multicore_host, 1e9, 6);
+ XBT_INFO("Computed 6-thread activity on a 4-core host. Took %g s", e->get_clock() - start_time);
+
+ auto MyHost1 = e->host_by_name("MyHost1");
+ simgrid::s4u::ExecPtr background_task = MyHost1->exec_async(2.5e9);
+ XBT_INFO("Start a 1-core background task on the 4-core host.");
+
+ start_time = sg4::Engine::get_clock();
+ sg4::this_actor::thread_execute(multicore_host, 1e9, 2);
+ XBT_INFO("Computed 2-thread activity on a 4-core host. Took %g s", e->get_clock() - start_time);
+
+ start_time = sg4::Engine::get_clock();
+ sg4::this_actor::thread_execute(multicore_host, 1e9, 4);
+ XBT_INFO("Computed 4-thread activity on a 4-core host. Took %g s", e->get_clock() - start_time);
+
+ background_task->wait();
+ XBT_INFO("The background task has ended.");
+}
+
+int main(int argc, char* argv[])
+{
+ sg4::Engine e(&argc, argv);
+
+ xbt_assert(argc == 2, "Usage: %s <platform file>", argv[0]);
+
+ e.load_platform(argv[1]);
+ sg4::Actor::create("test", e.host_by_name("MyHost1"), runner);
+
+ e.run();
+ XBT_INFO("Simulation done.");
+ return 0;
+}
--- /dev/null
+#!/usr/bin/env tesh
+
+$ ${bindir:=.}/s4u-exec-threads ${platfdir}/energy_platform.xml "--log=root.fmt:[%10.6r]%e%m%n"
+> [ 10.000000] Computed 2-thread activity on a 4-core host. Took 10 s
+> [ 20.000000] Computed 4-thread activity on a 4-core host. Took 10 s
+> [ 35.000000] Computed 6-thread activity on a 4-core host. Took 15 s
+> [ 35.000000] Start a 1-core background task on the 4-core host.
+> [ 45.000000] Computed 2-thread activity on a 4-core host. Took 10 s
+> [ 57.500000] Computed 4-thread activity on a 4-core host. Took 12.5 s
+> [ 62.500000] The background task has ended.
+> [ 62.500000] Simulation done.
\ No newline at end of file
#include <vector>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void worker()
{
// Define an amount of work that should take 1 second to execute.
- double computation_amount = simgrid::s4u::this_actor::get_host()->get_speed();
+ double computation_amount = sg4::this_actor::get_host()->get_speed();
// Create an unassigned activity and start it
- simgrid::s4u::ExecPtr exec =
- simgrid::s4u::Exec::init()->set_flops_amount(computation_amount)->set_name("exec")->vetoable_start();
+ sg4::ExecPtr exec = sg4::Exec::init()->set_flops_amount(computation_amount)->set_name("exec")->vetoable_start();
// Wait for a while
- simgrid::s4u::this_actor::sleep_for(10);
+ sg4::this_actor::sleep_for(10);
// Assign the activity to the current host. This triggers its start, then waits for it completion.
- exec->set_host(simgrid::s4u::Host::current())->wait();
+ exec->set_host(sg4::Host::current())->wait();
XBT_INFO("Exec '%s' is complete", exec->get_cname());
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Fafard"), worker);
+ sg4::Actor::create("worker", e.host_by_name("Fafard"), worker);
e.run();
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
#include <string>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_exec_waitany, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void worker(bool with_timeout)
{
/* Vector in which we store all pending executions*/
- std::vector<simgrid::s4u::ExecPtr> pending_executions;
+ std::vector<sg4::ExecPtr> pending_executions;
for (int i = 0; i < 3; i++) {
std::string name = std::string("Exec-") + std::to_string(i);
- double amount = (6 * (i % 2) + i + 1) * simgrid::s4u::this_actor::get_host()->get_speed();
+ double amount = (6 * (i % 2) + i + 1) * sg4::this_actor::get_host()->get_speed();
- simgrid::s4u::ExecPtr exec = simgrid::s4u::this_actor::exec_init(amount)->set_name(name);
+ sg4::ExecPtr exec = sg4::this_actor::exec_init(amount)->set_name(name);
pending_executions.push_back(exec);
exec->start();
XBT_INFO("Activity %s has started for %.0f seconds", name.c_str(),
- amount / simgrid::s4u::this_actor::get_host()->get_speed());
+ amount / sg4::this_actor::get_host()->get_speed());
}
/* Now that executions were initiated, wait for their completion, in order of termination.
while (not pending_executions.empty()) {
ssize_t pos;
if (with_timeout)
- pos = simgrid::s4u::Exec::wait_any_for(pending_executions, 4);
+ pos = sg4::Exec::wait_any_for(pending_executions, 4);
else
- pos = simgrid::s4u::Exec::wait_any(pending_executions);
+ pos = sg4::Exec::wait_any(pending_executions);
if (pos < 0) {
XBT_INFO("Do not wait any longer for an activity");
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Tremblay"), worker, false);
- simgrid::s4u::Actor::create("worker_timeout", e.host_by_name("Tremblay"), worker, true);
+ sg4::Actor::create("worker", e.host_by_name("Tremblay"), worker, false);
+ sg4::Actor::create("worker_timeout", e.host_by_name("Tremblay"), worker, true);
e.run();
return 0;
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_exec_waitfor, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void worker()
{
- simgrid::s4u::ExecPtr exec;
- double amount = 5 * simgrid::s4u::this_actor::get_host()->get_speed();
+ sg4::ExecPtr exec;
+ double amount = 5 * sg4::this_actor::get_host()->get_speed();
XBT_INFO("Create an activity that should run for 5 seconds");
- exec = simgrid::s4u::this_actor::exec_async(amount);
+ exec = sg4::this_actor::exec_async(amount);
/* Now that execution is started, wait for 3 seconds. */
XBT_INFO("But let it end after 3 seconds");
/* do it again, but this time with a timeout greater than the duration of the execution */
XBT_INFO("Create another activity that should run for 5 seconds and wait for it for 6 seconds");
- exec = simgrid::s4u::this_actor::exec_async(amount);
+ exec = sg4::this_actor::exec_async(amount);
try {
exec->wait_for(6);
XBT_INFO("Execution complete");
}
XBT_INFO("Finally test with a parallel execution");
- auto hosts = simgrid::s4u::Engine::get_instance()->get_all_hosts();
+ auto hosts = sg4::Engine::get_instance()->get_all_hosts();
size_t hosts_count = hosts.size();
std::vector<double> computation_amounts;
std::vector<double> communication_amounts;
for (size_t j = i + 1; j < hosts_count; j++)
communication_amounts[i * hosts_count + j] = 1e7; // 10 MB
- exec = simgrid::s4u::this_actor::exec_init(hosts, computation_amounts, communication_amounts);
+ exec = sg4::this_actor::exec_init(hosts, computation_amounts, communication_amounts);
try {
exec->wait_for(2);
XBT_INFO("Parallel Execution complete");
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Tremblay"), worker);
+ sg4::Actor::create("worker", e.host_by_name("Tremblay"), worker);
e.run();
return 0;
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void test(sg_size_t size)
{
- const simgrid::s4u::Disk* disk = simgrid::s4u::Host::current()->get_disks().front();
+ const sg4::Disk* disk = sg4::Host::current()->get_disks().front();
XBT_INFO("Hello! read %llu bytes from %s", size, disk->get_cname());
- simgrid::s4u::IoPtr activity = disk->io_init(size, simgrid::s4u::Io::OpType::READ);
+ sg4::IoPtr activity = disk->io_init(size, sg4::Io::OpType::READ);
activity->start();
activity->wait();
static void test_waitfor(sg_size_t size)
{
- const simgrid::s4u::Disk* disk = simgrid::s4u::Host::current()->get_disks().front();
+ const sg4::Disk* disk = sg4::Host::current()->get_disks().front();
XBT_INFO("Hello! write %llu bytes from %s", size, disk->get_cname());
- simgrid::s4u::IoPtr activity = disk->write_async(size);
+ sg4::IoPtr activity = disk->write_async(size);
try {
activity->wait_for(0.5);
} catch (const simgrid::TimeoutException&) {
static void test_cancel(sg_size_t size)
{
- const simgrid::s4u::Disk* disk = simgrid::s4u::Host::current()->get_disks().front();
- simgrid::s4u::this_actor::sleep_for(0.5);
+ const sg4::Disk* disk = sg4::Host::current()->get_disks().front();
+ sg4::this_actor::sleep_for(0.5);
XBT_INFO("Hello! write %llu bytes from %s", size, disk->get_cname());
- simgrid::s4u::IoPtr activity = disk->write_async(size);
- simgrid::s4u::this_actor::sleep_for(0.5);
+ sg4::IoPtr activity = disk->write_async(size);
+ sg4::this_actor::sleep_for(0.5);
XBT_INFO("I changed my mind, cancel!");
activity->cancel();
static void test_monitor(sg_size_t size)
{
- const simgrid::s4u::Disk* disk = simgrid::s4u::Host::current()->get_disks().front();
- simgrid::s4u::this_actor::sleep_for(1);
- simgrid::s4u::IoPtr activity = disk->write_async(size);
+ const sg4::Disk* disk = sg4::Host::current()->get_disks().front();
+ sg4::this_actor::sleep_for(1);
+ sg4::IoPtr activity = disk->write_async(size);
while (not activity->test()) {
XBT_INFO("Remaining amount of bytes to write: %g", activity->get_remaining());
- simgrid::s4u::this_actor::sleep_for(0.2);
+ sg4::this_actor::sleep_for(0.2);
}
activity->wait();
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("test", e.host_by_name("bob"), test, 2e7);
- simgrid::s4u::Actor::create("test_waitfor", e.host_by_name("alice"), test_waitfor, 5e7);
- simgrid::s4u::Actor::create("test_cancel", e.host_by_name("alice"), test_cancel, 5e7);
- simgrid::s4u::Actor::create("test_monitor", e.host_by_name("alice"), test_monitor, 5e7);
+ sg4::Actor::create("test", e.host_by_name("bob"), test, 2e7);
+ sg4::Actor::create("test_waitfor", e.host_by_name("alice"), test_waitfor, 5e7);
+ sg4::Actor::create("test_cancel", e.host_by_name("alice"), test_cancel, 5e7);
+ sg4::Actor::create("test_monitor", e.host_by_name("alice"), test_monitor, 5e7);
e.run();
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
#include <simgrid/s4u.hpp>
-namespace sg4 = simgrid::s4u;
-
XBT_LOG_NEW_DEFAULT_CATEGORY(disk_test, "Messages specific for this simulation");
+namespace sg4 = simgrid::s4u;
/** @brief Calculates the bandwidth for disk doing async operations */
static void estimate_bw(const sg4::Disk* disk, int n_flows, bool read)
create_sata_disk(bob, "Griffon (SATA II)");
zone->seal();
- simgrid::s4u::Actor::create("", bob, host);
+ sg4::Actor::create("", bob, host);
e.run();
- XBT_INFO("Simulated time: %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulated time: %g", sg4::Engine::get_clock());
return 0;
}
#include <vector>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void test()
{
- std::vector<simgrid::s4u::ActivityPtr> pending_activities;
+ std::vector<sg4::ActivityPtr> pending_activities;
- simgrid::s4u::ExecPtr bob_compute = simgrid::s4u::this_actor::exec_init(1e9);
- pending_activities.push_back(boost::dynamic_pointer_cast<simgrid::s4u::Activity>(bob_compute));
- simgrid::s4u::IoPtr bob_write =
- simgrid::s4u::Host::current()->get_disks().front()->io_init(4000000, simgrid::s4u::Io::OpType::WRITE);
- pending_activities.push_back(boost::dynamic_pointer_cast<simgrid::s4u::Activity>(bob_write));
- simgrid::s4u::IoPtr carl_read =
- simgrid::s4u::Host::by_name("carl")->get_disks().front()->io_init(4000000, simgrid::s4u::Io::OpType::READ);
- pending_activities.push_back(boost::dynamic_pointer_cast<simgrid::s4u::Activity>(carl_read));
- simgrid::s4u::ExecPtr carl_compute = simgrid::s4u::Host::by_name("carl")->exec_init(1e9);
- pending_activities.push_back(boost::dynamic_pointer_cast<simgrid::s4u::Activity>(carl_compute));
+ sg4::ExecPtr bob_compute = sg4::this_actor::exec_init(1e9);
+ pending_activities.push_back(boost::dynamic_pointer_cast<sg4::Activity>(bob_compute));
+ sg4::IoPtr bob_write = sg4::Host::current()->get_disks().front()->io_init(4000000, sg4::Io::OpType::WRITE);
+ pending_activities.push_back(boost::dynamic_pointer_cast<sg4::Activity>(bob_write));
+ sg4::IoPtr carl_read = sg4::Host::by_name("carl")->get_disks().front()->io_init(4000000, sg4::Io::OpType::READ);
+ pending_activities.push_back(boost::dynamic_pointer_cast<sg4::Activity>(carl_read));
+ sg4::ExecPtr carl_compute = sg4::Host::by_name("carl")->exec_init(1e9);
+ pending_activities.push_back(boost::dynamic_pointer_cast<sg4::Activity>(carl_compute));
// Name the activities (for logging purposes only)
bob_compute->set_name("bob compute");
// wait for the completion of all activities
while (not pending_activities.empty()) {
- ssize_t changed_pos = simgrid::s4u::Activity::wait_any(pending_activities);
+ ssize_t changed_pos = sg4::Activity::wait_any(pending_activities);
XBT_INFO("Activity '%s' is complete", pending_activities[changed_pos]->get_cname());
pending_activities.erase(pending_activities.begin() + changed_pos);
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
sg_storage_file_system_init();
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("bob", e.host_by_name("bob"), test);
+ sg4::Actor::create("bob", e.host_by_name("bob"), test);
e.run();
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
#include <unordered_map>
XBT_LOG_NEW_DEFAULT_CATEGORY(disk_test, "Messages specific for this simulation");
+namespace sg4 = simgrid::s4u;
static void host()
{
/* -Add an extra disk in a programmatic way */
- simgrid::s4u::Host::current()->create_disk("Disk3", /*read bandwidth*/ 9.6e7, /*write bandwidth*/6.4e7)->seal();
+ sg4::Host::current()->create_disk("Disk3", /*read bandwidth*/ 9.6e7, /*write bandwidth*/ 6.4e7)->seal();
/* - Display information on the disks mounted by the current host */
- XBT_INFO("*** Storage info on %s ***", simgrid::s4u::Host::current()->get_cname());
+ XBT_INFO("*** Storage info on %s ***", sg4::Host::current()->get_cname());
/* - Retrieve all disks from current host */
- std::vector<simgrid::s4u::Disk*> const& disk_list = simgrid::s4u::Host::current()->get_disks();
+ std::vector<sg4::Disk*> const& disk_list = sg4::Host::current()->get_disks();
/* - For each disk mounted on host, display disk name and mount point */
for (auto const& disk : disk_list)
disk->get_write_bandwidth());
/* - Write 400,000 bytes on Disk1 */
- simgrid::s4u::Disk* disk = disk_list.front();
+ sg4::Disk* disk = disk_list.front();
sg_size_t write = disk->write(400000);
XBT_INFO("Wrote %llu bytes on '%s'", write, disk->get_cname());
XBT_INFO("Read %llu bytes on '%s'", read, disk->get_cname());
/* - Write 800,000 bytes on Disk3 */
- const simgrid::s4u::Disk* disk3 = disk_list.back();
+ const sg4::Disk* disk3 = disk_list.back();
sg_size_t write_on_disk3 = disk3->write(800000);
XBT_INFO("Wrote %llu bytes on '%s'", write_on_disk3, disk3->get_cname());
int main(int argc, char** argv)
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
/* - Display Host properties */
XBT_INFO(" %s -> %s", kv.first.c_str(), kv.second.c_str());
}
- simgrid::s4u::Actor::create("", e.host_by_name("bob"), host);
+ sg4::Actor::create("", e.host_by_name("bob"), host);
e.run();
- XBT_INFO("Simulated time: %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulated time: %g", sg4::Engine::get_clock());
return 0;
}
#define INMEGA (1024 * 1024)
XBT_LOG_NEW_DEFAULT_CATEGORY(remote_io, "Messages specific for this io example");
+namespace sg4 = simgrid::s4u;
static void host(std::vector<std::string> args)
{
- simgrid::s4u::File* file = simgrid::s4u::File::open(args[1], nullptr);
+ sg4::File* file = sg4::File::open(args[1], nullptr);
const char* filename = file->get_path();
XBT_INFO("Opened file '%s'", filename);
file->dump();
if (args.size() > 4) {
if (std::stoi(args[4]) != 0) {
- XBT_INFO("Move '%s' (of size %llu) from '%s' to '%s'", filename, file->size(),
- simgrid::s4u::Host::current()->get_cname(), args[2].c_str());
- file->remote_move(simgrid::s4u::Host::by_name(args[2]), args[3]);
+ XBT_INFO("Move '%s' (of size %llu) from '%s' to '%s'", filename, file->size(), sg4::Host::current()->get_cname(),
+ args[2].c_str());
+ file->remote_move(sg4::Host::by_name(args[2]), args[3]);
} else {
- XBT_INFO("Copy '%s' (of size %llu) from '%s' to '%s'", filename, file->size(),
- simgrid::s4u::Host::current()->get_cname(), args[2].c_str());
- file->remote_copy(simgrid::s4u::Host::by_name(args[2]), args[3]);
+ XBT_INFO("Copy '%s' (of size %llu) from '%s' to '%s'", filename, file->size(), sg4::Host::current()->get_cname(),
+ args[2].c_str());
+ file->remote_copy(sg4::Host::by_name(args[2]), args[3]);
}
}
file->close();
int main(int argc, char** argv)
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
sg_storage_file_system_init();
e.load_platform(argv[1]);
e.register_function("host", host);
e.load_deployment(argv[2]);
- std::vector<simgrid::s4u::Host*> all_hosts = e.get_all_hosts();
+ std::vector<sg4::Host*> all_hosts = e.get_all_hosts();
for (auto const& h : all_hosts) {
for (auto const& d : h->get_disks())
sg_disk_get_size_free(d) / INMEGA, d->get_cname(), h->get_cname());
}
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category");
+namespace sg4 = simgrid::s4u;
class MyHost {
public:
- void show_info(std::vector<simgrid::s4u::Disk*> const& disks) const
+ void show_info(std::vector<sg4::Disk*> const& disks) const
{
- XBT_INFO("Storage info on %s:", simgrid::s4u::Host::current()->get_cname());
+ XBT_INFO("Storage info on %s:", sg4::Host::current()->get_cname());
for (auto const& d : disks) {
// Retrieve disk's information
void operator()() const
{
- std::vector<simgrid::s4u::Disk*> const& disks = simgrid::s4u::Host::current()->get_disks();
+ std::vector<sg4::Disk*> const& disks = sg4::Host::current()->get_disks();
show_info(disks);
// Open a non-existing file to create it
std::string filename = "/scratch/tmp/data.txt";
- auto* file = simgrid::s4u::File::open(filename, nullptr);
+ auto* file = sg4::File::open(filename, nullptr);
sg_size_t write = file->write(200000); // Write 200,000 bytes
XBT_INFO("Create a %llu bytes file named '%s' on /scratch", write, filename.c_str());
show_info(disks);
// Reopen the file and then unlink it
- file = simgrid::s4u::File::open("/scratch/tmp/simgrid.readme", nullptr);
+ file = sg4::File::open("/scratch/tmp/simgrid.readme", nullptr);
XBT_INFO("Unlink file: '%s'", file->get_path());
file->unlink();
file->close(); // Unlinking the file on "disk" does not close the file and free the object
int main(int argc, char** argv)
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
sg_storage_file_system_init();
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("host", e.host_by_name("bob"), MyHost());
+ sg4::Actor::create("host", e.host_by_name("bob"), MyHost());
e.run();
return 0;
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void writer()
{
/* - Retrieve all disks from current host */
- std::vector<simgrid::s4u::Disk*> const& disk_list = simgrid::s4u::Host::current()->get_disks();
+ std::vector<sg4::Disk*> const& disk_list = sg4::Host::current()->get_disks();
/* - Write 4,000,000 bytes on Disk1 */
disk_list.front()->write(4000000);
XBT_INFO("First write done.");
static void privileged_writer()
{
/* - Retrieve all disks from current host */
- std::vector<simgrid::s4u::Disk*> const& disk_list = simgrid::s4u::Host::current()->get_disks();
+ std::vector<sg4::Disk*> const& disk_list = sg4::Host::current()->get_disks();
/* - Write 4,000,000 bytes on Disk1 but specifies that this I/O operation gets a larger share of the resource.
*
* quickly. */
/* Resynchronize actors before second write */
- simgrid::s4u::this_actor::sleep_for(0.05);
+ sg4::this_actor::sleep_for(0.05);
/* - Write 4,000,000 bytes on Disk1 again and this time :
* - Start the I/O operation asynchronously to get an IoPtr
* 0.025s to write the last MB.
*/
- simgrid::s4u::IoPtr io = disk_list.front()->write_async(4000000);
- simgrid::s4u::this_actor::sleep_for(0.1);
+ sg4::IoPtr io = disk_list.front()->write_async(4000000);
+ sg4::this_actor::sleep_for(0.1);
XBT_INFO("Increase priority for the priviledged writer (%.0f bytes remaining to write)", io->get_remaining());
io->update_priority(2);
io->wait();
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 1, "Usage: %s platform_file\n\tExample: %s platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("writer", e.host_by_name("bob"), writer);
- simgrid::s4u::Actor::create("privileged_writer", e.host_by_name("bob"), privileged_writer);
+ sg4::Actor::create("writer", e.host_by_name("bob"), writer);
+ sg4::Actor::create("privileged_writer", e.host_by_name("bob"), privileged_writer);
e.run();
/* 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. */
-/** @addtogroup S4U_examples
+/** Switch the system thread hosting our maestro.
*
- * - <b>maestro-set/maestro-set.cpp: Switch the system thread hosting our maestro</b>.
- * That's a very advanced example in which we move the maestro context to another system thread.
- * Not many users need it (maybe only one, actually), but this example is also a regression test.
+ * That's a very advanced example in which we move the maestro context to another system thread.
+ * Not many users need it (maybe only one, actually), but this example is also a regression test.
*
- * This example is in C++ because we use C++11 threads to ensure that the feature is working as
- * expected. You can still use that feature from a C code.
+ * This example is in C++ because we use C++11 threads to ensure that the feature is working as
+ * expected. You can still use that feature from a C code.
*/
#include "simgrid/Exception.hpp"
#include <thread>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
const std::thread::id root_id = std::this_thread::get_id();
{
ensure_root_tid();
auto* payload = new std::string("some message");
- simgrid::s4u::Mailbox::by_name("some mailbox")->put(payload, 10e8);
+ sg4::Mailbox::by_name("some mailbox")->put(payload, 10e8);
}
static void receiver()
{
ensure_other_tid();
- simgrid::s4u::Mailbox::by_name("some mailbox")->get_unique<std::string>();
+ sg4::Mailbox::by_name("some mailbox")->get_unique<std::string>();
XBT_INFO("Task received");
}
static void maestro(void* /* data */)
{
ensure_other_tid();
- simgrid::s4u::Actor::create("receiver", simgrid::s4u::Host::by_name("Jupiter"), receiver);
- simgrid::s4u::Engine::get_instance()->run();
+ sg4::Actor::create("receiver", sg4::Host::by_name("Jupiter"), receiver);
+ sg4::Engine::get_instance()->run();
}
/** Main function */
* actor by the subsequent sg_actor_attach(). This must be done before the creation of the engine. */
simgrid_set_maestro(maestro, nullptr);
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc == 2, "Usage: %s platform_file\n"
"example: %s ../platforms/small_platform.xml\n",
#include <xbt/dynar.h>
XBT_LOG_NEW_DEFAULT_CATEGORY(bugged1_liveness, "my log messages");
+namespace sg4 = simgrid::s4u;
class Message {
public:
enum class Kind { GRANT, REQUEST, RELEASE };
Kind kind = Kind::GRANT;
- simgrid::s4u::Mailbox* return_mailbox = nullptr;
- explicit Message(Message::Kind kind, simgrid::s4u::Mailbox* mbox) : kind(kind), return_mailbox(mbox) {}
+ sg4::Mailbox* return_mailbox = nullptr;
+ explicit Message(Message::Kind kind, sg4::Mailbox* mbox) : kind(kind), return_mailbox(mbox) {}
};
int r = 0;
static void coordinator()
{
bool CS_used = false;
- std::queue<simgrid::s4u::Mailbox*> requests;
+ std::queue<sg4::Mailbox*> requests;
- simgrid::s4u::Mailbox* mbox = simgrid::s4u::Mailbox::by_name("coordinator");
+ sg4::Mailbox* mbox = sg4::Mailbox::by_name("coordinator");
while (true) {
auto m = mbox->get_unique<Message>();
} else {
if (not requests.empty()) {
XBT_INFO("CS release. Grant to queued requests (queue size: %zu)", requests.size());
- simgrid::s4u::Mailbox* req = requests.front();
+ sg4::Mailbox* req = requests.front();
requests.pop();
if (req->get_name() != "1") {
req->put(new Message(Message::Kind::GRANT, mbox), 1000);
static void client(int id)
{
- aid_t my_pid = simgrid::s4u::this_actor::get_pid();
+ aid_t my_pid = sg4::this_actor::get_pid();
- simgrid::s4u::Mailbox* my_mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id));
+ sg4::Mailbox* my_mailbox = sg4::Mailbox::by_name(std::to_string(id));
while (true) {
XBT_INFO("Ask the request");
- simgrid::s4u::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::REQUEST, my_mailbox), 1000);
+ sg4::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::REQUEST, my_mailbox), 1000);
if (id == 1) {
r = 1;
XBT_INFO("%d got the answer. Sleep a bit and release it", id);
- simgrid::s4u::this_actor::sleep_for(1);
+ sg4::this_actor::sleep_for(1);
- simgrid::s4u::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::RELEASE, my_mailbox), 1000);
+ sg4::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::RELEASE, my_mailbox), 1000);
- simgrid::s4u::this_actor::sleep_for(static_cast<double>(my_pid));
+ sg4::this_actor::sleep_for(static_cast<double>(my_pid));
if (id == 1) {
cs = 0;
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
MC_automaton_new_propositional_symbol_pointer("r", &r);
MC_automaton_new_propositional_symbol_pointer("cs", &cs);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("coordinator", e.host_by_name("Tremblay"), coordinator)
+ sg4::Actor::create("coordinator", e.host_by_name("Tremblay"), coordinator)
->set_kill_time(argc > 3 ? std::stod(argv[3]) : -1.0);
if (std::stod(argv[2]) == 0) {
- simgrid::s4u::Actor::create("client", e.host_by_name("Boivin"), raw_client, 1);
- simgrid::s4u::Actor::create("client", e.host_by_name("Fafard"), raw_client, 2);
+ sg4::Actor::create("client", e.host_by_name("Boivin"), raw_client, 1);
+ sg4::Actor::create("client", e.host_by_name("Fafard"), raw_client, 2);
} else { // "Visited" case
- simgrid::s4u::Actor::create("client", e.host_by_name("Boivin"), raw_client, 2);
- simgrid::s4u::Actor::create("client", e.host_by_name("Fafard"), raw_client, 1);
+ sg4::Actor::create("client", e.host_by_name("Boivin"), raw_client, 2);
+ sg4::Actor::create("client", e.host_by_name("Fafard"), raw_client, 1);
}
e.run();
constexpr int N = 3;
XBT_LOG_NEW_DEFAULT_CATEGORY(example, "this example");
+namespace sg4 = simgrid::s4u;
static void server()
{
int count = 0;
while (count < N) {
received.reset();
- received = simgrid::s4u::Mailbox::by_name("mymailbox")->get_unique<int>();
+ received = sg4::Mailbox::by_name("mymailbox")->get_unique<int>();
count++;
}
int value_got = *received;
static void client(int id)
{
auto* payload = new int(id);
- simgrid::s4u::Mailbox::by_name("mymailbox")->put(payload, 10000);
+ sg4::Mailbox::by_name("mymailbox")->put(payload, 10000);
XBT_INFO("Sent!");
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("server", e.host_by_name("HostA"), server);
- simgrid::s4u::Actor::create("client", e.host_by_name("HostB"), client, 1);
- simgrid::s4u::Actor::create("client", e.host_by_name("HostC"), client, 2);
- simgrid::s4u::Actor::create("client", e.host_by_name("HostD"), client, 3);
+ sg4::Actor::create("server", e.host_by_name("HostA"), server);
+ sg4::Actor::create("client", e.host_by_name("HostB"), client, 1);
+ sg4::Actor::create("client", e.host_by_name("HostC"), client, 2);
+ sg4::Actor::create("client", e.host_by_name("HostD"), client, 3);
e.run();
return 0;
#include <simgrid/s4u.hpp>
XBT_LOG_NEW_DEFAULT_CATEGORY(bugged2_liveness, "my log messages");
+namespace sg4 = simgrid::s4u;
class Message {
public:
enum class Kind { GRANT, NOT_GRANT, REQUEST };
Kind kind = Kind::GRANT;
- simgrid::s4u::Mailbox* return_mailbox = nullptr;
- explicit Message(Message::Kind kind, simgrid::s4u::Mailbox* mbox) : kind(kind), return_mailbox(mbox) {}
+ sg4::Mailbox* return_mailbox = nullptr;
+ explicit Message(Message::Kind kind, sg4::Mailbox* mbox) : kind(kind), return_mailbox(mbox) {}
};
int cs = 0;
static void coordinator()
{
bool CS_used = false; // initially the CS is idle
- std::queue<simgrid::s4u::Mailbox*> requests;
+ std::queue<sg4::Mailbox*> requests;
- simgrid::s4u::Mailbox* mbox = simgrid::s4u::Mailbox::by_name("coordinator");
+ sg4::Mailbox* mbox = sg4::Mailbox::by_name("coordinator");
while (true) {
auto m = mbox->get_unique<Message>();
static void client(int id)
{
- aid_t my_pid = simgrid::s4u::this_actor::get_pid();
+ aid_t my_pid = sg4::this_actor::get_pid();
- simgrid::s4u::Mailbox* my_mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(id));
+ sg4::Mailbox* my_mailbox = sg4::Mailbox::by_name(std::to_string(id));
while (true) {
XBT_INFO("Client (%d) asks the request", id);
- simgrid::s4u::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::REQUEST, my_mailbox), 1000);
+ sg4::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::REQUEST, my_mailbox), 1000);
auto grant = my_mailbox->get_unique<Message>();
XBT_INFO("Client (%d) got the answer (not grant). Try again", id);
}
- simgrid::s4u::this_actor::sleep_for(my_pid);
+ sg4::this_actor::sleep_for(my_pid);
}
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
MC_automaton_new_propositional_symbol_pointer("cs", &cs);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("coordinator", e.host_by_name("Tremblay"), coordinator);
- simgrid::s4u::Actor::create("client", e.host_by_name("Fafard"), client, 1);
- simgrid::s4u::Actor::create("client", e.host_by_name("Boivin"), client, 2);
+ sg4::Actor::create("coordinator", e.host_by_name("Tremblay"), coordinator);
+ sg4::Actor::create("client", e.host_by_name("Fafard"), client, 1);
+ sg4::Actor::create("client", e.host_by_name("Boivin"), client, 2);
e.run();
constexpr int CS_PER_PROCESS = 2;
XBT_LOG_NEW_DEFAULT_CATEGORY(centralized, "my log messages");
+namespace sg4 = simgrid::s4u;
class Message {
public:
enum class Kind { GRANT, REQUEST, RELEASE };
Kind kind = Kind::GRANT;
- simgrid::s4u::Mailbox* return_mailbox = nullptr;
- explicit Message(Message::Kind kind, simgrid::s4u::Mailbox* mbox) : kind(kind), return_mailbox(mbox) {}
+ sg4::Mailbox* return_mailbox = nullptr;
+ explicit Message(Message::Kind kind, sg4::Mailbox* mbox) : kind(kind), return_mailbox(mbox) {}
};
static void coordinator()
{
- std::queue<simgrid::s4u::Mailbox*> requests;
- simgrid::s4u::Mailbox* mbox = simgrid::s4u::Mailbox::by_name("coordinator");
+ std::queue<sg4::Mailbox*> requests;
+ sg4::Mailbox* mbox = sg4::Mailbox::by_name("coordinator");
bool CS_used = false; // initially the CS is idle
int todo = AMOUNT_OF_CLIENTS * CS_PER_PROCESS; // amount of releases we are expecting
} else { // that's a release. Check if someone was waiting for the lock
if (not requests.empty()) {
XBT_INFO("CS release. Grant to queued requests (queue size: %zu)", requests.size());
- simgrid::s4u::Mailbox* req = requests.front();
+ sg4::Mailbox* req = requests.front();
requests.pop();
req->put(new Message(Message::Kind::GRANT, mbox), 1000);
todo--;
static void client()
{
- aid_t my_pid = simgrid::s4u::this_actor::get_pid();
+ aid_t my_pid = sg4::this_actor::get_pid();
- simgrid::s4u::Mailbox* my_mailbox = simgrid::s4u::Mailbox::by_name(std::to_string(my_pid));
+ sg4::Mailbox* my_mailbox = sg4::Mailbox::by_name(std::to_string(my_pid));
// request the CS 3 times, sleeping a bit in between
for (int i = 0; i < CS_PER_PROCESS; i++) {
XBT_INFO("Ask the request");
- simgrid::s4u::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::REQUEST, my_mailbox), 1000);
+ sg4::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::REQUEST, my_mailbox), 1000);
// wait for the answer
auto grant = my_mailbox->get_unique<Message>();
XBT_INFO("got the answer. Sleep a bit and release it");
- simgrid::s4u::this_actor::sleep_for(1);
+ sg4::this_actor::sleep_for(1);
- simgrid::s4u::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::RELEASE, my_mailbox), 1000);
- simgrid::s4u::this_actor::sleep_for(static_cast<double>(my_pid));
+ sg4::Mailbox::by_name("coordinator")->put(new Message(Message::Kind::RELEASE, my_mailbox), 1000);
+ sg4::this_actor::sleep_for(static_cast<double>(my_pid));
}
XBT_INFO("Got all the CS I wanted, quit now");
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("coordinator", e.host_by_name("Tremblay"), coordinator);
- simgrid::s4u::Actor::create("client", e.host_by_name("Fafard"), client);
- simgrid::s4u::Actor::create("client", e.host_by_name("Boivin"), client);
- simgrid::s4u::Actor::create("client", e.host_by_name("Jacquelin"), client);
- simgrid::s4u::Actor::create("client", e.host_by_name("Ginette"), client);
+ sg4::Actor::create("coordinator", e.host_by_name("Tremblay"), coordinator);
+ sg4::Actor::create("client", e.host_by_name("Fafard"), client);
+ sg4::Actor::create("client", e.host_by_name("Boivin"), client);
+ sg4::Actor::create("client", e.host_by_name("Jacquelin"), client);
+ sg4::Actor::create("client", e.host_by_name("Ginette"), client);
e.run();
#!/usr/bin/env tesh
$ ${bindir:=.}/../../../bin/simgrid-mc ${bindir:=.}/s4u-mc-electric-fence ${platfdir}/model_checker_platform.xml
-> [0.000000] [mc_safety/INFO] Start a DFS exploration. Reduction is: dpor.
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor.
> [HostB:client:(2) 0.000000] [electric_fence/INFO] Sent!
> [HostA:server:(1) 0.000000] [electric_fence/INFO] OK
> [HostC:client:(3) 0.000000] [electric_fence/INFO] Sent!
> [HostA:server:(1) 0.000000] [electric_fence/INFO] OK
> [HostB:client:(2) 0.000000] [electric_fence/INFO] Sent!
> [HostC:client:(3) 0.000000] [electric_fence/INFO] Sent!
-> [0.000000] [mc_safety/INFO] DFS exploration ended. 15 unique states visited; 5 backtracks (32 transition replays, 13 states visited overall)
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 15 unique states visited; 5 backtracks (32 transition replays, 13 states visited overall)
#include <simgrid/s4u.hpp>
XBT_LOG_NEW_DEFAULT_CATEGORY(mc_assert_example, "Logging channel used in this example");
+namespace sg4 = simgrid::s4u;
static int server(int worker_amount)
{
int value_got = -1;
- simgrid::s4u::Mailbox* mb = simgrid::s4u::Mailbox::by_name("server");
+ sg4::Mailbox* mb = sg4::Mailbox::by_name("server");
for (int count = 0; count < worker_amount; count++) {
auto msg = mb->get_unique<int>();
value_got = *msg;
/* I just send my rank onto the mailbox. It must be passed as a stable memory block (thus the new) so that that
* memory survives even after the end of the client */
- simgrid::s4u::Mailbox* mailbox = simgrid::s4u::Mailbox::by_name("server");
+ sg4::Mailbox* mailbox = sg4::Mailbox::by_name("server");
mailbox->put(new int(rank), 1 /* communication cost is not really relevant in MC mode */);
XBT_INFO("Sent!");
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 1, "Usage: %s platform_file\n", argv[0]);
e.load_platform(argv[1]);
auto hosts = e.get_all_hosts();
xbt_assert(hosts.size() >= 3, "This example requires at least 3 hosts");
- simgrid::s4u::Actor::create("server", hosts[0], &server, 2);
- simgrid::s4u::Actor::create("client1", hosts[1], &client, 1);
- simgrid::s4u::Actor::create("client2", hosts[2], &client, 2);
+ sg4::Actor::create("server", hosts[0], &server, 2);
+ sg4::Actor::create("client1", hosts[1], &client, 1);
+ sg4::Actor::create("client2", hosts[2], &client, 2);
e.run();
return 0;
-/* Copyright (c) 2007-2022. The SimGrid Team. LEVEL_ALL rights reserved. */
+/* Copyright (c) 2007-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. */
#include <iomanip>
XBT_LOG_NEW_DEFAULT_CATEGORY(ns3_wifi_example, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
class Message
{
static void sender(const std::string& mailbox, int msg_size, unsigned sleep_time)
{
- simgrid::s4u::this_actor::sleep_for(sleep_time);
- auto* mbox = simgrid::s4u::Mailbox::by_name(mailbox);
- auto* msg = new Message(simgrid::s4u::this_actor::get_host()->get_name(), msg_size);
+ sg4::this_actor::sleep_for(sleep_time);
+ auto* mbox = sg4::Mailbox::by_name(mailbox);
+ auto* msg = new Message(sg4::this_actor::get_host()->get_name(), msg_size);
mbox->put(msg, msg_size);
}
static void receiver(const std::string& mailbox)
{
- auto* mbox = simgrid::s4u::Mailbox::by_name(mailbox);
+ auto* mbox = sg4::Mailbox::by_name(mailbox);
auto msg = mbox->get_unique<Message>();
- XBT_INFO("[%s] %s received %d bytes from %s",
- mailbox.c_str(),
- simgrid::s4u::this_actor::get_host()->get_name().c_str(),
- msg->size,
- msg->sender.c_str());
+ XBT_INFO("[%s] %s received %d bytes from %s", mailbox.c_str(), sg4::this_actor::get_host()->get_name().c_str(),
+ msg->size, msg->sender.c_str());
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
int msg_size = 1e5;
/* Communication between STA in the same wifi zone */
- simgrid::s4u::Actor::create("sender", e.host_by_name("STA0-0"), sender, "1", msg_size, 10);
- simgrid::s4u::Actor::create("receiver", e.host_by_name("STA0-1"), receiver, "1");
- simgrid::s4u::Actor::create("sender", e.host_by_name("STA0-1"), sender, "2", msg_size, 20);
- simgrid::s4u::Actor::create("receiver", e.host_by_name("STA0-0"), receiver, "2");
- simgrid::s4u::Actor::create("sender", e.host_by_name("STA1-1"), sender, "3", msg_size, 30);
- simgrid::s4u::Actor::create("receiver", e.host_by_name("STA1-2"), receiver, "3");
- simgrid::s4u::Actor::create("sender", e.host_by_name("STA1-2"), sender, "4", msg_size, 40);
- simgrid::s4u::Actor::create("receiver", e.host_by_name("STA1-1"), receiver, "4");
+ sg4::Actor::create("sender", e.host_by_name("STA0-0"), sender, "1", msg_size, 10);
+ sg4::Actor::create("receiver", e.host_by_name("STA0-1"), receiver, "1");
+ sg4::Actor::create("sender", e.host_by_name("STA0-1"), sender, "2", msg_size, 20);
+ sg4::Actor::create("receiver", e.host_by_name("STA0-0"), receiver, "2");
+ sg4::Actor::create("sender", e.host_by_name("STA1-1"), sender, "3", msg_size, 30);
+ sg4::Actor::create("receiver", e.host_by_name("STA1-2"), receiver, "3");
+ sg4::Actor::create("sender", e.host_by_name("STA1-2"), sender, "4", msg_size, 40);
+ sg4::Actor::create("receiver", e.host_by_name("STA1-1"), receiver, "4");
/* Communication between STA of different wifi zones */
- simgrid::s4u::Actor::create("sender", e.host_by_name("STA0-0"), sender, "5", msg_size, 50);
- simgrid::s4u::Actor::create("receiver", e.host_by_name("STA1-0"), receiver, "5");
- simgrid::s4u::Actor::create("sender", e.host_by_name("STA1-0"), sender, "6", msg_size, 60);
- simgrid::s4u::Actor::create("receiver", e.host_by_name("STA0-0"), receiver, "6");
- simgrid::s4u::Actor::create("sender", e.host_by_name("STA0-1"), sender, "7", msg_size, 70);
- simgrid::s4u::Actor::create("receiver", e.host_by_name("STA1-2"), receiver, "7");
- simgrid::s4u::Actor::create("sender", e.host_by_name("STA1-2"), sender, "8", msg_size, 80);
- simgrid::s4u::Actor::create("receiver", e.host_by_name("STA0-1"), receiver, "8");
+ sg4::Actor::create("sender", e.host_by_name("STA0-0"), sender, "5", msg_size, 50);
+ sg4::Actor::create("receiver", e.host_by_name("STA1-0"), receiver, "5");
+ sg4::Actor::create("sender", e.host_by_name("STA1-0"), sender, "6", msg_size, 60);
+ sg4::Actor::create("receiver", e.host_by_name("STA0-0"), receiver, "6");
+ sg4::Actor::create("sender", e.host_by_name("STA0-1"), sender, "7", msg_size, 70);
+ sg4::Actor::create("receiver", e.host_by_name("STA1-2"), receiver, "7");
+ sg4::Actor::create("sender", e.host_by_name("STA1-2"), sender, "8", msg_size, 80);
+ sg4::Actor::create("receiver", e.host_by_name("STA0-1"), receiver, "8");
e.run();
return 0;
#include <unordered_map>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
double start_time;
std::unordered_map<int, std::string> workernames;
/* worker name */
workernames[id] = args[2];
- simgrid::s4u::Mailbox* mbox = simgrid::s4u::Mailbox::by_name(args[3]);
+ sg4::Mailbox* mbox = sg4::Mailbox::by_name(args[3]);
- masternames[id] = simgrid::s4u::Host::current()->get_name();
+ masternames[id] = sg4::Host::current()->get_name();
auto* payload = new double(msg_size);
/* time measurement */
- start_time = simgrid::s4u::Engine::get_clock();
+ start_time = sg4::Engine::get_clock();
mbox->put(payload, static_cast<uint64_t>(msg_size));
XBT_DEBUG("Finished");
xbt_assert(args.size() == 2, "Strange number of arguments expected 1 got %zu", args.size() - 1);
int id = std::stoi(args[1]);
- simgrid::s4u::Mailbox* mbox = simgrid::s4u::Mailbox::by_name(args[1]);
+ sg4::Mailbox* mbox = sg4::Mailbox::by_name(args[1]);
XBT_DEBUG("Worker started");
auto payload = mbox->get_unique<double>();
- double elapsed_time = simgrid::s4u::Engine::get_clock() - start_time;
+ double elapsed_time = sg4::Engine::get_clock() - start_time;
XBT_INFO("FLOW[%d] : Receive %.0f bytes from %s to %s", id, *payload, masternames.at(id).c_str(),
workernames.at(id).c_str());
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 2,
"Usage: %s platform_file deployment_file\n"
"\tExample: %s platform.xml deployment.xml\n",
*/
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_network_wifi, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
-static void sender(simgrid::s4u::Mailbox* mailbox, int data_size)
+static void sender(sg4::Mailbox* mailbox, int data_size)
{
XBT_INFO("Send a message to the other station.");
static std::string message = "message";
mailbox->put(&message, data_size);
XBT_INFO("Done.");
}
-static void receiver(simgrid::s4u::Mailbox* mailbox)
+static void receiver(sg4::Mailbox* mailbox)
{
XBT_INFO("Wait for a message.");
mailbox->get<std::string>();
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 1, "Usage: %s platform_file\n\tExample: %s platform.xml deployment.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
/* Exchange a message between the 2 stations */
- auto mailbox = simgrid::s4u::Mailbox::by_name("mailbox");
+ auto mailbox = sg4::Mailbox::by_name("mailbox");
auto station1 = e.host_by_name("Station 1");
auto station2 = e.host_by_name("Station 2");
- simgrid::s4u::Actor::create("sender", station1, sender, mailbox, 1e7);
- simgrid::s4u::Actor::create("receiver", station2, receiver, mailbox);
+ sg4::Actor::create("sender", station1, sender, mailbox, 1e7);
+ sg4::Actor::create("receiver", station2, receiver, mailbox);
/* Declare that the stations are not at the same distance from their AP */
auto ap = e.link_by_name("AP1");
! output sort 19
$ ${bindir:=.}/s4u-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/s4u-platform-failures_d.xml --cfg=path:${srcdir} --cfg=network/crosstraffic:0 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose
> [ 0.000000] (0:maestro@) Cannot launch actor 'worker' on failed host 'Fafard'
-> [ 0.000000] (0:maestro@) Deployment includes some initially turned off Hosts ... nevermind.
+> [ 0.000000] (0:maestro@) Starting actor worker(Fafard) failed because its host is turned off.
> [ 0.000000] (1:master@Tremblay) Got 5 workers and 20 tasks to process
> [ 0.000000] (1:master@Tremblay) Send a message to worker-0
> [ 0.000000] (7:sleeper@Lilibeth) Start sleeping...
! output sort 19
$ ${bindir:=.}/s4u-platform-failures --log=xbt_cfg.thres:critical --log=no_loc ${platfdir}/small_platform_failures.xml ${srcdir:=.}/s4u-platform-failures_d.xml --cfg=path:${srcdir} "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose
> [ 0.000000] (0:maestro@) Cannot launch actor 'worker' on failed host 'Fafard'
-> [ 0.000000] (0:maestro@) Deployment includes some initially turned off Hosts ... nevermind.
+> [ 0.000000] (0:maestro@) Starting actor worker(Fafard) failed because its host is turned off.
> [ 0.000000] (1:master@Tremblay) Got 5 workers and 20 tasks to process
> [ 0.000000] (1:master@Tremblay) Send a message to worker-0
> [ 0.000000] (2:worker@Tremblay) Waiting a message on worker-0
* speed. The first way to do so is to use a file in the XML, while the second is to use the programmatic interface. */
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_platform_profile, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void watcher()
{
- const auto* jupiter = simgrid::s4u::Host::by_name("Jupiter");
- const auto* fafard = simgrid::s4u::Host::by_name("Fafard");
- const auto* lilibeth = simgrid::s4u::Host::by_name("Lilibeth");
- const auto* link1 = simgrid::s4u::Link::by_name("1");
- const auto* link2 = simgrid::s4u::Link::by_name("2");
+ const auto* jupiter = sg4::Host::by_name("Jupiter");
+ const auto* fafard = sg4::Host::by_name("Fafard");
+ const auto* lilibeth = sg4::Host::by_name("Lilibeth");
+ const auto* link1 = sg4::Link::by_name("1");
+ const auto* link2 = sg4::Link::by_name("2");
- std::vector<simgrid::s4u::Link*> links;
+ std::vector<sg4::Link*> links;
double lat = 0;
jupiter->route_to(fafard, links, &lat);
jupiter->get_speed() * jupiter->get_available_speed() / 1000000,
lilibeth->get_speed() * lilibeth->get_available_speed() / 1000000, link1->get_bandwidth() / 1000,
link1->get_latency() * 1000, link2->get_bandwidth() / 1000, link2->get_latency() * 1000);
- simgrid::s4u::this_actor::sleep_for(1);
+ sg4::this_actor::sleep_for(1);
}
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 1, "Usage: %s platform_file\n\tExample: %s platform.xml\n", argv[0], argv[0]);
->seal();
// Add a watcher of the changes
- simgrid::s4u::Actor::create("watcher", e.host_by_name("Fafard"), watcher);
+ sg4::Actor::create("watcher", e.host_by_name("Fafard"), watcher);
e.run();
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void execute_load_test()
{
- s4u_Host* host = simgrid::s4u::Host::by_name("MyHost1");
+ s4u_Host* host = sg4::Host::by_name("MyHost1");
XBT_INFO("Initial peak speed: %.0E flop/s; number of flops computed so far: %.0E (should be 0) and current average "
"load: %.5f (should be 0)",
host->get_speed(), sg_host_get_computed_flops(host), sg_host_get_avg_load(host));
- double start = simgrid::s4u::Engine::get_clock();
+ double start = sg4::Engine::get_clock();
XBT_INFO("Sleep for 10 seconds");
- simgrid::s4u::this_actor::sleep_for(10);
+ sg4::this_actor::sleep_for(10);
double speed = host->get_speed();
XBT_INFO("Done sleeping %.2fs; peak speed: %.0E flop/s; number of flops computed so far: %.0E (nothing should have "
"changed)",
- simgrid::s4u::Engine::get_clock() - start, host->get_speed(), sg_host_get_computed_flops(host));
+ sg4::Engine::get_clock() - start, host->get_speed(), sg_host_get_computed_flops(host));
// Run an activity
- start = simgrid::s4u::Engine::get_clock();
+ start = sg4::Engine::get_clock();
XBT_INFO("Run an activity of %.0E flops at current speed of %.0E flop/s", 200E6, host->get_speed());
- simgrid::s4u::this_actor::execute(200E6);
+ sg4::this_actor::execute(200E6);
XBT_INFO(
"Done working on my activity; this took %.2fs; current peak speed: %.0E flop/s (when I started the computation, "
"the speed was set to %.0E flop/s); number of flops computed so "
"far: %.2E, average load as reported by the HostLoad plugin: %.5f (should be %.5f)",
- simgrid::s4u::Engine::get_clock() - start, host->get_speed(), speed, sg_host_get_computed_flops(host),
+ sg4::Engine::get_clock() - start, host->get_speed(), speed, sg_host_get_computed_flops(host),
sg_host_get_avg_load(host),
200E6 / (10.5 * speed * host->get_core_count() +
- (simgrid::s4u::Engine::get_clock() - start - 0.5) * host->get_speed() * host->get_core_count()));
+ (sg4::Engine::get_clock() - start - 0.5) * host->get_speed() * host->get_core_count()));
// ========= Change power peak =========
int pstate = 1;
pstate, host->get_pstate_speed(pstate), host->get_speed(), sg_host_get_avg_load(host));
// Run a second activity
- start = simgrid::s4u::Engine::get_clock();
+ start = sg4::Engine::get_clock();
XBT_INFO("Run an activity of %.0E flops", 100E6);
- simgrid::s4u::this_actor::execute(100E6);
+ sg4::this_actor::execute(100E6);
XBT_INFO("Done working on my activity; this took %.2fs; current peak speed: %.0E flop/s; number of flops computed so "
"far: %.2E",
- simgrid::s4u::Engine::get_clock() - start, host->get_speed(), sg_host_get_computed_flops(host));
+ sg4::Engine::get_clock() - start, host->get_speed(), sg_host_get_computed_flops(host));
- start = simgrid::s4u::Engine::get_clock();
+ start = sg4::Engine::get_clock();
XBT_INFO("========= Requesting a reset of the computation and load counters");
sg_host_load_reset(host);
XBT_INFO("After reset: %.0E flops computed; load is %.5f", sg_host_get_computed_flops(host),
sg_host_get_avg_load(host));
XBT_INFO("Sleep for 4 seconds");
- simgrid::s4u::this_actor::sleep_for(4);
+ sg4::this_actor::sleep_for(4);
XBT_INFO("Done sleeping %.2f s; peak speed: %.0E flop/s; number of flops computed so far: %.0E",
- simgrid::s4u::Engine::get_clock() - start, host->get_speed(), sg_host_get_computed_flops(host));
+ sg4::Engine::get_clock() - start, host->get_speed(), sg_host_get_computed_flops(host));
// =========== Turn the other host off ==========
- s4u_Host* host2 = simgrid::s4u::Host::by_name("MyHost2");
+ s4u_Host* host2 = sg4::Host::by_name("MyHost2");
XBT_INFO("Turning MyHost2 off, and sleeping another 10 seconds. MyHost2 computed %.0f flops so far and has an "
"average load of %.5f.",
sg_host_get_computed_flops(host2), sg_host_get_avg_load(host2));
host2->turn_off();
- start = simgrid::s4u::Engine::get_clock();
- simgrid::s4u::this_actor::sleep_for(10);
+ start = sg4::Engine::get_clock();
+ sg4::this_actor::sleep_for(10);
XBT_INFO("Done sleeping %.2f s; peak speed: %.0E flop/s; number of flops computed so far: %.0E",
- simgrid::s4u::Engine::get_clock() - start, host->get_speed(), sg_host_get_computed_flops(host));
+ sg4::Engine::get_clock() - start, host->get_speed(), sg_host_get_computed_flops(host));
}
static void change_speed()
{
- s4u_Host* host = simgrid::s4u::Host::by_name("MyHost1");
- simgrid::s4u::this_actor::sleep_for(10.5);
+ s4u_Host* host = sg4::Host::by_name("MyHost1");
+ sg4::this_actor::sleep_for(10.5);
XBT_INFO("I slept until now, but now I'll change the speed of this host "
"while the other actor is still computing! This should slow the computation down.");
host->set_pstate(2);
int main(int argc, char* argv[])
{
sg_host_load_plugin_init();
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc == 2, "Usage: %s platform_file\n\tExample: %s ../platforms/energy_platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("load_test", e.host_by_name("MyHost1"), execute_load_test);
- simgrid::s4u::Actor::create("change_speed", e.host_by_name("MyHost1"), change_speed);
+ sg4::Actor::create("load_test", e.host_by_name("MyHost1"), execute_load_test);
+ sg4::Actor::create("change_speed", e.host_by_name("MyHost1"), change_speed);
e.run();
- XBT_INFO("Total simulation time: %.2f", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Total simulation time: %.2f", sg4::Engine::get_clock());
return 0;
}
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void sender(const std::string& mailbox, uint64_t msg_size)
{
- auto mbox = simgrid::s4u::Mailbox::by_name(mailbox);
+ auto mbox = sg4::Mailbox::by_name(mailbox);
static int payload = 42;
mbox->put(&payload, msg_size);
}
static void receiver(const std::string& mailbox)
{
- auto mbox = simgrid::s4u::Mailbox::by_name(mailbox);
+ auto mbox = sg4::Mailbox::by_name(mailbox);
mbox->get<int>();
}
-static void run_transfer(simgrid::s4u::Host* src_host, simgrid::s4u::Host* dst_host, const std::string& mailbox,
- unsigned long msg_size)
+static void run_transfer(sg4::Host* src_host, sg4::Host* dst_host, const std::string& mailbox, unsigned long msg_size)
{
XBT_INFO("Launching the transfer of %lu bytes", msg_size);
- simgrid::s4u::Actor::create("sender", src_host, sender, mailbox, msg_size);
- simgrid::s4u::Actor::create("receiver", dst_host, receiver, mailbox);
+ sg4::Actor::create("sender", src_host, sender, mailbox, msg_size);
+ sg4::Actor::create("receiver", dst_host, receiver, mailbox);
}
static void execute_load_test()
{
- auto host0 = simgrid::s4u::Host::by_name("node-0.simgrid.org");
- auto host1 = simgrid::s4u::Host::by_name("node-1.simgrid.org");
+ auto host0 = sg4::Host::by_name("node-0.simgrid.org");
+ auto host1 = sg4::Host::by_name("node-1.simgrid.org");
- simgrid::s4u::this_actor::sleep_for(1);
+ sg4::this_actor::sleep_for(1);
run_transfer(host0, host1, "1", 1000 * 1000 * 1000);
- simgrid::s4u::this_actor::sleep_for(10);
+ sg4::this_actor::sleep_for(10);
run_transfer(host0, host1, "2", 1000 * 1000 * 1000);
- simgrid::s4u::this_actor::sleep_for(3);
+ sg4::this_actor::sleep_for(3);
run_transfer(host0, host1, "3", 1000 * 1000 * 1000);
}
-static void show_link_load(const std::string& link_name, const simgrid::s4u::Link* link)
+static void show_link_load(const std::string& link_name, const sg4::Link* link)
{
XBT_INFO("%s link load (cum, avg, min, max): (%g, %g, %g, %g)", link_name.c_str(), sg_link_get_cum_load(link),
sg_link_get_avg_load(link), sg_link_get_min_instantaneous_load(link),
static void monitor()
{
- auto link_backbone = simgrid::s4u::Link::by_name("cluster0_backbone");
- auto link_host0 = simgrid::s4u::Link::by_name("cluster0_link_0_UP");
- auto link_host1 = simgrid::s4u::Link::by_name("cluster0_link_1_DOWN");
+ auto link_backbone = sg4::Link::by_name("cluster0_backbone");
+ auto link_host0 = sg4::Link::by_name("cluster0_link_0_UP");
+ auto link_host1 = sg4::Link::by_name("cluster0_link_1_DOWN");
XBT_INFO("Tracking desired links");
sg_link_load_track(link_backbone);
sg_link_load_track(link_host1);
show_link_load("Backbone", link_backbone);
- while (simgrid::s4u::Engine::get_clock() < 5) {
- simgrid::s4u::this_actor::sleep_for(1);
+ while (sg4::Engine::get_clock() < 5) {
+ sg4::this_actor::sleep_for(1);
show_link_load("Backbone", link_backbone);
}
XBT_INFO("Now resetting and probing host links each second.");
- while (simgrid::s4u::Engine::get_clock() < 29) {
+ while (sg4::Engine::get_clock() < 29) {
sg_link_load_reset(link_host0);
sg_link_load_reset(link_host1);
- simgrid::s4u::this_actor::sleep_for(1);
+ sg4::this_actor::sleep_for(1);
show_link_load("Host0_UP", link_host0);
show_link_load("Host1_UP", link_host1);
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
sg_link_load_plugin_init();
xbt_assert(argc == 2, "Usage: %s platform_file\n\tExample: %s ../platforms/energy_platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
- simgrid::s4u::Actor::create("load_test", e.host_by_name("node-42.simgrid.org"), execute_load_test);
- simgrid::s4u::Actor::create("monitor", e.host_by_name("node-51.simgrid.org"), monitor);
+ sg4::Actor::create("load_test", e.host_by_name("node-42.simgrid.org"), execute_load_test);
+ sg4::Actor::create("monitor", e.host_by_name("node-51.simgrid.org"), monitor);
e.run();
- XBT_INFO("Total simulation time: %.2f", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Total simulation time: %.2f", sg4::Engine::get_clock());
return 0;
}
#include <string>
XBT_LOG_NEW_DEFAULT_CATEGORY(replay_comm, "Messages specific for this example");
+namespace sg4 = simgrid::s4u;
#define ACT_DEBUG(...) \
if (XBT_LOG_ISENABLED(replay_comm, xbt_log_priority_verbose)) { \
static void compute(simgrid::xbt::ReplayAction& action)
{
double amount = std::stod(action[2]);
- double clock = simgrid::s4u::Engine::get_clock();
+ double clock = sg4::Engine::get_clock();
ACT_DEBUG("Entering %s", NAME.c_str());
- simgrid::s4u::this_actor::execute(amount);
- log_action(action, simgrid::s4u::Engine::get_clock() - clock);
+ sg4::this_actor::execute(amount);
+ log_action(action, sg4::Engine::get_clock() - clock);
}
static void send(simgrid::xbt::ReplayAction& action)
{
auto size = static_cast<uint64_t>(std::stod(action[3]));
auto* payload = new std::string(action[3]);
- double clock = simgrid::s4u::Engine::get_clock();
- simgrid::s4u::Mailbox* to = simgrid::s4u::Mailbox::by_name(simgrid::s4u::this_actor::get_name() + "_" + action[2]);
+ double clock = sg4::Engine::get_clock();
+ sg4::Mailbox* to = sg4::Mailbox::by_name(sg4::this_actor::get_name() + "_" + action[2]);
ACT_DEBUG("Entering Send: %s (size: %" PRIu64 ") -- Actor %s on mailbox %s", NAME.c_str(), size,
- simgrid::s4u::this_actor::get_cname(), to->get_cname());
+ sg4::this_actor::get_cname(), to->get_cname());
to->put(payload, size);
- log_action(action, simgrid::s4u::Engine::get_clock() - clock);
+ log_action(action, sg4::Engine::get_clock() - clock);
}
static void recv(simgrid::xbt::ReplayAction& action)
{
- double clock = simgrid::s4u::Engine::get_clock();
- simgrid::s4u::Mailbox* from =
- simgrid::s4u::Mailbox::by_name(std::string(action[2]) + "_" + simgrid::s4u::this_actor::get_name());
+ double clock = sg4::Engine::get_clock();
+ sg4::Mailbox* from = sg4::Mailbox::by_name(std::string(action[2]) + "_" + sg4::this_actor::get_name());
- ACT_DEBUG("Receiving: %s -- Actor %s on mailbox %s", NAME.c_str(), simgrid::s4u::this_actor::get_cname(),
- from->get_cname());
+ ACT_DEBUG("Receiving: %s -- Actor %s on mailbox %s", NAME.c_str(), sg4::this_actor::get_cname(), from->get_cname());
from->get_unique<std::string>();
- log_action(action, simgrid::s4u::Engine::get_clock() - clock);
+ log_action(action, sg4::Engine::get_clock() - clock);
}
};
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 2,
"Usage: %s platform_file deployment_file [action_files]\n"
e.run();
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
#include <boost/algorithm/string/join.hpp>
XBT_LOG_NEW_DEFAULT_CATEGORY(replay_io, "Messages specific for this example");
+namespace sg4 = simgrid::s4u;
#define ACT_DEBUG(...) \
if (XBT_LOG_ISENABLED(replay_io, xbt_log_priority_verbose)) { \
((void)0)
class Replayer {
- static std::unordered_map<std::string, simgrid::s4u::File> opened_files;
+ static std::unordered_map<std::string, sg4::File> opened_files;
static void log_action(const simgrid::xbt::ReplayAction& action, double date)
{
}
}
- static simgrid::s4u::File* get_file_descriptor(const std::string& file_name)
+ static sg4::File* get_file_descriptor(const std::string& file_name)
{
- std::string full_name = simgrid::s4u::this_actor::get_name() + ":" + file_name;
+ std::string full_name = sg4::this_actor::get_name() + ":" + file_name;
return &opened_files.at(full_name);
}
static void open(simgrid::xbt::ReplayAction& action)
{
std::string file_name = action[2];
- double clock = simgrid::s4u::Engine::get_clock();
- std::string full_name = simgrid::s4u::this_actor::get_name() + ":" + file_name;
+ double clock = sg4::Engine::get_clock();
+ std::string full_name = sg4::this_actor::get_name() + ":" + file_name;
ACT_DEBUG("Entering Open: %s (filename: %s)", NAME.c_str(), file_name.c_str());
opened_files.emplace(std::piecewise_construct, std::forward_as_tuple(full_name),
std::forward_as_tuple(file_name, nullptr));
- log_action(action, simgrid::s4u::Engine::get_clock() - clock);
+ log_action(action, sg4::Engine::get_clock() - clock);
}
static void read(simgrid::xbt::ReplayAction& action)
{
std::string file_name = action[2];
sg_size_t size = std::stoul(action[3]);
- double clock = simgrid::s4u::Engine::get_clock();
+ double clock = sg4::Engine::get_clock();
- simgrid::s4u::File* file = get_file_descriptor(file_name);
+ sg4::File* file = get_file_descriptor(file_name);
ACT_DEBUG("Entering Read: %s (size: %llu)", NAME.c_str(), size);
file->read(size);
- log_action(action, simgrid::s4u::Engine::get_clock() - clock);
+ log_action(action, sg4::Engine::get_clock() - clock);
}
static void close(simgrid::xbt::ReplayAction& action)
{
std::string file_name = action[2];
- std::string full_name = simgrid::s4u::this_actor::get_name() + ":" + file_name;
- double clock = simgrid::s4u::Engine::get_clock();
+ std::string full_name = sg4::this_actor::get_name() + ":" + file_name;
+ double clock = sg4::Engine::get_clock();
ACT_DEBUG("Entering Close: %s (filename: %s)", NAME.c_str(), file_name.c_str());
xbt_assert(opened_files.erase(full_name) == 1, "File not found in opened files: %s", full_name.c_str());
- log_action(action, simgrid::s4u::Engine::get_clock() - clock);
+ log_action(action, sg4::Engine::get_clock() - clock);
}
};
-std::unordered_map<std::string, simgrid::s4u::File> Replayer::opened_files;
+std::unordered_map<std::string, sg4::File> Replayer::opened_files;
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
sg_storage_file_system_init();
xbt_assert(argc > 3,
e.run();
- XBT_INFO("Simulation time %g", simgrid::s4u::Engine::get_clock());
+ XBT_INFO("Simulation time %g", sg4::Engine::get_clock());
return 0;
}
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform(argv[1]);
std::vector<simgrid::kernel::routing::ClusterZone*> clusters =
for (auto c : clusters) {
XBT_INFO("%s", c->get_cname());
- std::vector<simgrid::s4u::Host*> hosts = c->get_all_hosts();
+ std::vector<sg4::Host*> hosts = c->get_all_hosts();
for (auto h : hosts)
XBT_INFO(" %s", h->get_cname());
}
#!/usr/bin/env tesh
-$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_safety.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-barrier 1 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n"
+$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-barrier 1 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n"
> [Checker] Start a DFS exploration. Reduction is: dpor.
> [Checker] Execute 1: BARRIER_LOCK(barrier: 0) (stack depth: 1, state: 1, 0 interleaves)
> [Checker] Execute 1: BARRIER_WAIT(barrier: 0) (stack depth: 2, state: 2, 0 interleaves)
> [Checker] Backtracking from 1;1;0
> [Checker] DFS exploration ended. 3 unique states visited; 1 backtracks (3 transition replays, 0 states visited overall)
-$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_safety.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-barrier 2 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n"
+$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-barrier 2 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n"
> [Checker] Start a DFS exploration. Reduction is: dpor.
> [Checker] Execute 1: BARRIER_LOCK(barrier: 0) (stack depth: 1, state: 1, 0 interleaves)
> [Checker] Execute 2: BARRIER_LOCK(barrier: 0) (stack depth: 2, state: 2, 0 interleaves)
> [Checker] Backtracking from 1;2
> [Checker] DFS exploration ended. 5 unique states visited; 2 backtracks (7 transition replays, 1 states visited overall)
-$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_safety.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-barrier 3 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n"
+$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-barrier 3 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n"
> [Checker] Start a DFS exploration. Reduction is: dpor.
> [Checker] Execute 1: BARRIER_LOCK(barrier: 0) (stack depth: 1, state: 1, 0 interleaves)
> [Checker] Execute 2: BARRIER_LOCK(barrier: 0) (stack depth: 2, state: 2, 0 interleaves)
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category");
+namespace sg4 = simgrid::s4u;
/// Wait on the barrier then leave
-static void worker(simgrid::s4u::BarrierPtr barrier)
+static void worker(sg4::BarrierPtr barrier)
{
XBT_INFO("Waiting on the barrier");
barrier->wait();
/// Spawn actor_count-1 workers and do a barrier with them
static void master(int actor_count)
{
- simgrid::s4u::BarrierPtr barrier = simgrid::s4u::Barrier::create(actor_count);
+ sg4::BarrierPtr barrier = sg4::Barrier::create(actor_count);
XBT_INFO("Spawning %d workers", actor_count - 1);
for (int i = 0; i < actor_count - 1; i++) {
- simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Jupiter"), worker, barrier);
+ sg4::Actor::create("worker", sg4::Host::by_name("Jupiter"), worker, barrier);
}
XBT_INFO("Waiting on the barrier");
int main(int argc, char **argv)
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
// Parameter: Number of actores in the barrier
xbt_assert(argc >= 2, "Usage: %s <actor-count>\n", argv[0]);
xbt_assert(actor_count > 0, "<actor-count> must be greater than 0");
e.load_platform(argc > 2 ? argv[2] : "../../platforms/two_hosts.xml");
- simgrid::s4u::Actor::create("master", e.host_by_name("Tremblay"), master, actor_count);
+ sg4::Actor::create("master", e.host_by_name("Tremblay"), master, actor_count);
e.run();
return 0;
#include <simgrid/s4u.hpp> /* All of S4U */
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category");
+namespace sg4 = simgrid::s4u;
-simgrid::s4u::MutexPtr mtx = nullptr;
-simgrid::s4u::ConditionVariablePtr cv = nullptr;
+sg4::MutexPtr mtx = nullptr;
+sg4::ConditionVariablePtr cv = nullptr;
bool ready = false;
static void competitor(int id)
{
XBT_INFO("Entering the race...");
- std::unique_lock<simgrid::s4u::Mutex> lck(*mtx);
+ std::unique_lock<sg4::Mutex> lck(*mtx);
while (not ready) {
- auto now = simgrid::s4u::Engine::get_clock();
+ auto now = sg4::Engine::get_clock();
if (cv->wait_until(lck, now + (id+1)*0.25) == std::cv_status::timeout) {
XBT_INFO("Out of wait_until (timeout)");
}
static void go()
{
XBT_INFO("Are you ready? ...");
- simgrid::s4u::this_actor::sleep_for(3);
- std::unique_lock<simgrid::s4u::Mutex> lck(*mtx);
+ sg4::this_actor::sleep_for(3);
+ std::unique_lock<sg4::Mutex> lck(*mtx);
XBT_INFO("Go go go!");
ready = true;
cv->notify_all();
static void main_actor()
{
- mtx = simgrid::s4u::Mutex::create();
- cv = simgrid::s4u::ConditionVariable::create();
+ mtx = sg4::Mutex::create();
+ cv = sg4::ConditionVariable::create();
- auto host = simgrid::s4u::this_actor::get_host();
+ auto host = sg4::this_actor::get_host();
for (int i = 0; i < 10; ++i)
- simgrid::s4u::Actor::create("competitor", host, competitor, i);
- simgrid::s4u::Actor::create("go", host, go);
+ sg4::Actor::create("competitor", host, competitor, i);
+ sg4::Actor::create("go", host, go);
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform("../../platforms/small_platform.xml");
- simgrid::s4u::Actor::create("main", e.host_by_name("Tremblay"), main_actor);
+ sg4::Actor::create("main", e.host_by_name("Tremblay"), main_actor);
e.run();
return 0;
#include <simgrid/s4u.hpp> /* All of S4U */
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "a sample log category");
+namespace sg4 = simgrid::s4u;
std::string data;
bool done = false;
-static void worker_fun(simgrid::s4u::ConditionVariablePtr cv, simgrid::s4u::MutexPtr mutex)
+static void worker_fun(sg4::ConditionVariablePtr cv, sg4::MutexPtr mutex)
{
- std::unique_lock<simgrid::s4u::Mutex> lock(*mutex);
+ std::unique_lock<sg4::Mutex> lock(*mutex);
XBT_INFO("Start processing data which is '%s'.", data.c_str());
data += std::string(" after processing");
static void master_fun()
{
- auto mutex = simgrid::s4u::Mutex::create();
- auto cv = simgrid::s4u::ConditionVariable::create();
+ auto mutex = sg4::Mutex::create();
+ auto cv = sg4::ConditionVariable::create();
data = std::string("Example data");
- auto worker = simgrid::s4u::Actor::create("worker", simgrid::s4u::Host::by_name("Jupiter"), worker_fun, cv, mutex);
+ auto worker = sg4::Actor::create("worker", sg4::Host::by_name("Jupiter"), worker_fun, cv, mutex);
// wait for the worker
- cv->wait(std::unique_lock<simgrid::s4u::Mutex>(*mutex), []() { return done; });
+ cv->wait(std::unique_lock<sg4::Mutex>(*mutex), []() { return done; });
XBT_INFO("data is now '%s'.", data.c_str());
worker->join();
int main(int argc, char** argv)
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
e.load_platform("../../platforms/two_hosts.xml");
- simgrid::s4u::Actor::create("main", e.host_by_name("Tremblay"), master_fun);
+ sg4::Actor::create("main", e.host_by_name("Tremblay"), master_fun);
e.run();
return 0;
p This file tests the dependencies between MUTEX transitions
-$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_safety.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:1 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n"
+$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:1 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n"
> [Checker] Start a DFS exploration. Reduction is: dpor.
> [App ] Configuration change: Set 'actors' to '1'
> [Checker] Execute 2: MUTEX_LOCK(mutex: 0, owner:2) (stack depth: 1, state: 1, 0 interleaves)
> [Checker] MUTEX_LOCK(mutex: 0, owner:3) (state=8)
> [Checker] DFS exploration ended. 13 unique states visited; 3 backtracks (18 transition replays, 3 states visited overall)
-$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_safety.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:2 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n"
+$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:2 --log=s4u_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n"
> [Checker] Start a DFS exploration. Reduction is: dpor.
> [App ] Configuration change: Set 'actors' to '2'
> [Checker] Execute 2: MUTEX_LOCK(mutex: 0, owner:2) (stack depth: 1, state: 1, 0 interleaves)
> [Checker] DFS exploration ended. 37 unique states visited; 7 backtracks (76 transition replays, 33 states visited overall)
$ ${bindir:=.}/../../../bin/simgrid-mc -- ${bindir:=.}/s4u-synchro-mutex --cfg=actors:3 --log=s4u_test.thres:critical
-> [0.000000] [mc_safety/INFO] Start a DFS exploration. Reduction is: dpor.
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor.
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'actors' to '3'
-> [0.000000] [mc_safety/INFO] DFS exploration ended. 85 unique states visited; 15 backtracks (240 transition replays, 141 states visited overall)
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 85 unique states visited; 15 backtracks (240 transition replays, 141 states visited overall)
#!/usr/bin/env tesh
-$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_safety.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-semaphore --log=sem_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n"
+$ ${bindir:=.}/../../../bin/simgrid-mc --log=mc_dfs.thres:verbose --log=root.fmt="[Checker]%e%m%n" -- ${bindir:=.}/s4u-synchro-semaphore --log=sem_test.thres:critical --log=root.fmt="[App%e%e%e%e]%e%m%n"
> [Checker] Start a DFS exploration. Reduction is: dpor.
> [Checker] Execute 1: SEM_LOCK(semaphore: 0) (stack depth: 1, state: 1, 0 interleaves)
> [Checker] Execute 1: SEM_WAIT(semaphore: 0, granted: yes) (stack depth: 2, state: 2, 0 interleaves)
#include "simgrid/instr.h"
#include "simgrid/s4u.hpp"
+namespace sg4 = simgrid::s4u;
+
struct Task {
std::string name;
std::string category;
static void master()
{
- auto mbox = simgrid::s4u::Mailbox::by_name("master_mailbox");
+ auto mbox = sg4::Mailbox::by_name("master_mailbox");
for (int i = 0; i < 10; i++) {
Task task;
if (i % 2)
static void worker()
{
- auto mbox = simgrid::s4u::Mailbox::by_name("master_mailbox");
+ auto mbox = sg4::Mailbox::by_name("master_mailbox");
while (true) {
auto task = mbox->get_unique<Task>();
if (task->name == "finalize") {
break;
}
// creating task and setting its category
- simgrid::s4u::this_actor::exec_init(task->flops)
- ->set_name(task->name)
- ->set_tracing_category(task->category)
- ->wait();
+ sg4::this_actor::exec_init(task->flops)->set_name(task->name)->set_tracing_category(task->category)->wait();
}
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 1, "Usage: %s platform_file\n \tExample: %s small_platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
simgrid::instr::declare_tracing_category("data", "0 0 1"); // blue
simgrid::instr::declare_tracing_category("finalize", "0 0 0"); // black
- simgrid::s4u::Actor::create("master", e.host_by_name("Tremblay"), master);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Fafard"), worker);
+ sg4::Actor::create("master", e.host_by_name("Tremblay"), master);
+ sg4::Actor::create("worker", e.host_by_name("Fafard"), worker);
e.run();
return 0;
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void trace_fun()
{
- const auto host = simgrid::s4u::this_actor::get_host()->get_name();
+ const auto host = sg4::this_actor::get_host()->get_name();
// the hostname has an empty HDD with a capacity of 100000 (bytes)
simgrid::instr::set_host_variable(host, "HDD_capacity", 100000);
for (int i = 0; i < 10; i++) {
// create and execute a task just to make the simulated time advance
- simgrid::s4u::this_actor::execute(1e4);
+ sg4::this_actor::execute(1e4);
// ADD: after the execution of this task, the HDD utilization increases by 100 (bytes)
simgrid::instr::add_host_variable(host, "HDD_utilization", 100);
for (int i = 0; i < 10; i++) {
// create and execute a task just to make the simulated time advance
- simgrid::s4u::this_actor::execute(1e4);
+ sg4::this_actor::execute(1e4);
// SUB: after the execution of this task, the HDD utilization decreases by 100 (bytes)
simgrid::instr::sub_host_variable(host, "HDD_utilization", 100);
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 1, "Usage: %s platform_file\n \tExample: %s small_platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
simgrid::instr::declare_host_variable("HDD_capacity");
simgrid::instr::declare_host_variable("HDD_utilization", "1 0 0"); // red color
- simgrid::s4u::Actor::create("master", e.host_by_name("Tremblay"), trace_fun);
+ sg4::Actor::create("master", e.host_by_name("Tremblay"), trace_fun);
e.run();
#include "simgrid/instr.h"
#include "simgrid/s4u.hpp"
+namespace sg4 = simgrid::s4u;
+
static void trace_fun()
{
// set initial values for the link user variables this example only shows for links identified by "6" and "3" in the
// run the simulation, update my variables accordingly
for (int i = 0; i < 10; i++) {
- simgrid::s4u::this_actor::execute(1e6);
+ sg4::this_actor::execute(1e6);
// Add to link user variables
simgrid::instr::add_link_variable("3", "Link_Utilization", 5.6);
}
for (int i = 0; i < 10; i++) {
- simgrid::s4u::this_actor::execute(1e6);
+ sg4::this_actor::execute(1e6);
// Subtract from link user variables
simgrid::instr::sub_link_variable("3", "Link_Utilization", 3.4);
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 1, "Usage: %s platform_file\n \tExample: %s small_platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
simgrid::instr::declare_link_variable("Link_Capacity");
simgrid::instr::declare_link_variable("Link_Utilization", "0.9 0.1 0.1");
- simgrid::s4u::Actor::create("master", e.host_by_name("Tremblay"), trace_fun);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Tremblay"), trace_fun);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Jupiter"), trace_fun);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Fafard"), trace_fun);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Ginette"), trace_fun);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Bourassa"), trace_fun);
+ sg4::Actor::create("master", e.host_by_name("Tremblay"), trace_fun);
+ sg4::Actor::create("worker", e.host_by_name("Tremblay"), trace_fun);
+ sg4::Actor::create("worker", e.host_by_name("Jupiter"), trace_fun);
+ sg4::Actor::create("worker", e.host_by_name("Fafard"), trace_fun);
+ sg4::Actor::create("worker", e.host_by_name("Ginette"), trace_fun);
+ sg4::Actor::create("worker", e.host_by_name("Bourassa"), trace_fun);
e.run();
return 0;
#include <simgrid/s4u.hpp>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_trace_masterworker, "Messages specific for this example");
+namespace sg4 = simgrid::s4u;
struct Task {
std::string name;
double compute_cost = std::stod(args[2]);
long communication_cost = std::stol(args[3]);
size_t workers_count = args.size() - 4;
- const auto& my_host = simgrid::s4u::this_actor::get_host()->get_name();
- auto mailbox = simgrid::s4u::Mailbox::by_name("master_mailbox");
+ const auto& my_host = sg4::this_actor::get_host()->get_name();
+ auto mailbox = sg4::Mailbox::by_name("master_mailbox");
XBT_DEBUG("Got %zu workers and %ld tasks to process", workers_count, tasks_count);
{
xbt_assert(args.size() == 1, "The worker expects no argument");
- const auto& my_host = simgrid::s4u::this_actor::get_host()->get_name();
- auto mailbox = simgrid::s4u::Mailbox::by_name("master_mailbox");
+ const auto& my_host = sg4::this_actor::get_host()->get_name();
+ auto mailbox = sg4::Mailbox::by_name("master_mailbox");
simgrid::instr::set_host_variable(my_host, "is_worker", 1);
simgrid::instr::set_host_variable(my_host, "task_computation", 0);
}
// adding the task's cost to the variable "task_computation"
simgrid::instr::add_host_variable(my_host, "task_computation", task->flops);
- simgrid::s4u::this_actor::exec_init(task->flops)
- ->set_name(task->name)
- ->set_tracing_category(task->category)
- ->wait();
+ sg4::this_actor::exec_init(task->flops)->set_name(task->name)->set_tracing_category(task->category)->wait();
}
XBT_DEBUG("Exiting now.");
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 2, "Usage: %s platform_file deployment_file\n", argv[0]);
e.load_platform(argv[1]);
#include "simgrid/s4u.hpp"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u example");
+namespace sg4 = simgrid::s4u;
static void trace_fun()
{
// run the simulation, update my variables accordingly
for (int i = 0; i < 10; i++) {
- simgrid::s4u::this_actor::execute(1e6);
+ sg4::this_actor::execute(1e6);
// Add to link user variables
simgrid::instr::add_link_variable("Tremblay", "Bourassa", "Link_Utilization", 5.6);
}
for (int i = 0; i < 10; i++) {
- simgrid::s4u::this_actor::execute(1e6);
+ sg4::this_actor::execute(1e6);
// Subtract from link user variables
simgrid::instr::sub_link_variable("Tremblay", "Bourassa", "Link_Utilization", 3.4);
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine e(&argc, argv);
+ sg4::Engine e(&argc, argv);
xbt_assert(argc > 1, "Usage: %s platform_file\n \tExample: %s small_platform.xml\n", argv[0], argv[0]);
e.load_platform(argv[1]);
simgrid::instr::declare_link_variable("Link_Capacity");
simgrid::instr::declare_link_variable("Link_Utilization", "0.9 0.1 0.1");
- simgrid::s4u::Actor::create("master", e.host_by_name("Tremblay"), trace_fun);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Tremblay"), trace_fun);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Jupiter"), trace_fun);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Fafard"), trace_fun);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Ginette"), trace_fun);
- simgrid::s4u::Actor::create("worker", e.host_by_name("Bourassa"), trace_fun);
+ sg4::Actor::create("master", e.host_by_name("Tremblay"), trace_fun);
+ sg4::Actor::create("worker", e.host_by_name("Tremblay"), trace_fun);
+ sg4::Actor::create("worker", e.host_by_name("Jupiter"), trace_fun);
+ sg4::Actor::create("worker", e.host_by_name("Fafard"), trace_fun);
+ sg4::Actor::create("worker", e.host_by_name("Ginette"), trace_fun);
+ sg4::Actor::create("worker", e.host_by_name("Bourassa"), trace_fun);
e.run();
return 0;
! output sort 19
$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/platform-failures.py ${platfdir}/small_platform_failures.xml ${srcdir:=.}/platform-failures_d.xml --log=xbt_cfg.thres:critical --log=no_loc --cfg=path:${srcdir} --cfg=network/crosstraffic:0 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n" --log=res_cpu.t:verbose
> [ 0.000000] (0:maestro@) Cannot launch actor 'worker' on failed host 'Fafard'
-> [ 0.000000] (0:maestro@) Deployment includes some initially turned off Hosts ... nevermind.
+> [ 0.000000] (0:maestro@) Starting actor worker(Fafard) failed because its host is turned off.
> [ 0.000000] (1:master@Tremblay) Got 5 workers and 20 tasks to process
> [ 0.000000] (1:master@Tremblay) Send a message to worker-0
> [ 0.000000] (7:sleeper@Lilibeth) Start sleeping...
! timeout 60
$ ../../../smpi_script/bin/smpirun -wrapper "${bindir:=.}/../../../bin/simgrid-mc" --log=xbt_cfg.thresh:warning -hostfile ${srcdir:=.}/hostfile_only_send_deterministic -platform ${srcdir:=.}/../../platforms/cluster_backbone.xml --cfg=model-check/communications-determinism:1 --cfg=smpi/buffering:zero --cfg=smpi/host-speed:1Gf ./smpi_only_send_deterministic
-> [0.000000] [mc_safety/INFO] Start a DFS exploration. Reduction is: dpor.
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor.
> [0.000000] [mc_comm_determinism/INFO] Check communication determinism
> [0.000000] [mc_comm_determinism/INFO] *******************************************************
> [0.000000] [mc_comm_determinism/INFO] **** Only-send-deterministic communication pattern ****
> [0.000000] [mc_comm_determinism/INFO] The recv communications pattern of the actor 0 is different! Different source for communication #1
> [0.000000] [mc_comm_determinism/INFO] Send-deterministic : Yes
> [0.000000] [mc_comm_determinism/INFO] Recv-deterministic : No
-> [0.000000] [mc_safety/INFO] DFS exploration ended. 36 unique states visited; 13 backtracks (97 transition replays, 49 states visited overall)
\ No newline at end of file
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 36 unique states visited; 13 backtracks (97 transition replays, 49 states visited overall)
\ No newline at end of file
p Testing the permissive model
! timeout 60
$ ../../../smpi_script/bin/smpirun -quiet -wrapper "${bindir:=.}/../../../bin/simgrid-mc" -np 2 -platform ${platfdir:=.}/cluster_backbone.xml --cfg=smpi/buffering:infty --log=xbt_cfg.thresh:warning ./smpi_sendsend
-> [0.000000] [mc_safety/INFO] Start a DFS exploration. Reduction is: dpor.
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor.
> Sent 0 to rank 1
> Sent 1 to rank 0
> rank 0 recv the data
> rank 1 recv the data
> Sent 0 to rank 1
-> [0.000000] [mc_safety/INFO] DFS exploration ended. 7 unique states visited; 2 backtracks (10 transition replays, 2 states visited overall)
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 7 unique states visited; 2 backtracks (10 transition replays, 2 states visited overall)
p Testing the paranoid model
! timeout 60
! expect return 3
$ ../../../smpi_script/bin/smpirun -quiet -wrapper "${bindir:=.}/../../../bin/simgrid-mc" -np 2 -platform ${platfdir:=.}/cluster_backbone.xml --cfg=smpi/buffering:zero --log=xbt_cfg.thresh:warning ./smpi_sendsend
-> [0.000000] [mc_safety/INFO] Start a DFS exploration. Reduction is: dpor.
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor.
> [0.000000] [mc_global/INFO] **************************
> [0.000000] [mc_global/INFO] *** DEADLOCK DETECTED ***
> [0.000000] [mc_global/INFO] **************************
> [0.000000] [mc_global/INFO] 1: iSend(mbox=2)
> [0.000000] [mc_global/INFO] 2: iSend(mbox=0)
> [0.000000] [mc_global/INFO] Path = 1;2
-> [0.000000] [mc_safety/INFO] DFS exploration ended. 3 unique states visited; 1 backtracks (3 transition replays, 0 states visited overall)
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 3 unique states visited; 1 backtracks (3 transition replays, 0 states visited overall)
> Execution failed with code 3.
// Create an ActorCode from the parameters parsed in the XML file (or elsewhere)
using ActorCodeFactory = std::function<ActorCode(std::vector<std::string> args)>;
+class Simcall;
class SimcallObserver;
} // namespace actor
/** Pointer to a SimGrid barrier object */
typedef s4u_Barrier* sg_bar_t;
/** Constant pointer to a SimGrid barrier object */
-typedef const s4u_Barrier* const_sg_bar_t;
+XBT_ATTRIB_DEPRECATED_v335("Please stop using this type alias") typedef const s4u_Barrier* const_sg_bar_t;
typedef s4u_Comm* sg_comm_t;
-typedef const s4u_Comm* const_sg_comm_t;
+XBT_ATTRIB_DEPRECATED_v335("Please stop using this type alias") typedef const s4u_Comm* const_sg_comm_t;
typedef s4u_Exec* sg_exec_t;
typedef const s4u_Exec* const_sg_exec_t;
typedef s4u_ConditionVariable* sg_cond_t;
/** Pointer to a constant actor object */
typedef const s4u_Actor* const_sg_actor_t;
-typedef struct s_smx_simcall* smx_simcall_t;
-
/** @ingroup m_datatypes_management_details
* @brief Type for any simgrid size
*/
#endif
#ifdef __cplusplus
-#include <map>
-#include <simgrid/simix.h>
namespace simgrid {
namespace msg {
class Comm;
XBT_PUBLIC void parallel_execute(const std::vector<s4u::Host*>& hosts, const std::vector<double>& flops_amounts,
const std::vector<double>& bytes_amounts);
+/** Block the current actor until the built multi-thread execution completes */
+XBT_PUBLIC void thread_execute(s4u::Host* host, double flop_amounts, int thread_count);
+
/** 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 */
friend Mailbox;
friend kernel::actor::ActorImpl;
friend kernel::activity::MailboxImpl;
- friend void this_actor::sleep_for(double);
- friend void this_actor::suspend();
+ friend XBT_PUBLIC void this_actor::sleep_for(double);
+ friend XBT_PUBLIC void this_actor::suspend();
kernel::actor::ActorImpl* const pimpl_;
#endif
/** Retrieves the actor ID of that actor's creator */
aid_t get_ppid() const;
- /** Suspend an actor, that is blocked until resumeed by another actor */
+ /** Suspend an actor, that is blocked until resumed by another actor. */
void suspend();
/** Resume an actor that was previously suspended */
/** Returns true if the actor is suspended. */
bool is_suspended() const;
- /** If set to true, the actor will automatically restart when its host reboots */
+ /** If set to true, the actor will automatically restart when its host reboots.
+ *
+ * Some elements of the actor are remembered over reboots: name, host, properties, the on_exit functions, whether it
+ * is daemonized and whether it should automatically restart when its host reboots. Note that the state after reboot
+ * is the one when set_auto_restart() is called.
+ *
+ * If you daemonize your actor after marking it auto_restart, then the new actor after rebooot will not be a daemon.
+ *
+ * The on_exit functions are the one defined when the actor dies, not the ones given when it was marked auto_restart
+ * (sorry for the inconsistency -- speak to us if it's too hard to bear).
+ */
Actor* set_auto_restart(bool autorestart = true);
+ /** Returns the number of reboots that this actor did. Before the first reboot, this function returns 0. */
+ int get_restart_count() const;
/** Add a function to the list of "on_exit" functions for the current actor. The on_exit functions are the functions
* executed when your actor is killed. You should use them to free the data used by your actor.
/* FIXME: expose these elements in the API */
bool detached_ = false;
- bool (*match_fun_)(void*, void*, kernel::activity::CommImpl*) = nullptr;
- void (*clean_fun_)(void*) = nullptr;
- void (*copy_data_function_)(kernel::activity::CommImpl*, void*, size_t) = nullptr;
+ std::function<bool(void*, void*, kernel::activity::CommImpl*)> match_fun_;
+ std::function<void(void*)> clean_fun_;
+ std::function<void(kernel::activity::CommImpl*, void*, size_t)> copy_data_function_;
Comm() = default;
static void on_start_cb(const std::function<void(Comm const&)>& cb) { on_start.connect(cb); }
static void on_completion_cb(const std::function<void(Activity const&)>& cb) { on_completion.connect(cb); }
/* More callbacks */
- CommPtr set_copy_data_callback(void (*callback)(kernel::activity::CommImpl*, void*, size_t));
+ CommPtr set_copy_data_callback(const std::function<void(kernel::activity::CommImpl*, void*, size_t)>& callback);
static void copy_buffer_callback(kernel::activity::CommImpl*, void*, size_t);
static void copy_pointer_callback(kernel::activity::CommImpl*, void*, size_t);
~Comm() override;
+ static void send(kernel::actor::ActorImpl* sender, const Mailbox* mbox, double task_size, double rate, void* src_buff,
+ size_t src_buff_size,
+ const std::function<bool(void*, void*, simgrid::kernel::activity::CommImpl*)>& match_fun,
+ const std::function<void(simgrid::kernel::activity::CommImpl*, void*, size_t)>& copy_data_fun,
+ void* data, double timeout);
+ static void recv(kernel::actor::ActorImpl* receiver, const Mailbox* mbox, void* dst_buff, size_t* dst_buff_size,
+ const std::function<bool(void*, void*, simgrid::kernel::activity::CommImpl*)>& match_fun,
+ const std::function<void(simgrid::kernel::activity::CommImpl*, void*, size_t)>& copy_data_fun,
+ void* data, double timeout, double rate);
+
/* "One-sided" communications. This way of communicating bypasses the mailbox and actors mechanism. It creates a
* communication (vetoabled, asynchronous, or synchronous) directly between two hosts. There is really no limit on
* the hosts involved. In particular, the actor creating such a communication does not have to be on one of the
/** Start the comm, and ignore its result. It can be completely forgotten after that. */
Comm* detach();
/** Start the comm, and ignore its result. It can be completely forgotten after that. */
- Comm* detach(void (*clean_function)(void*))
+ Comm* detach(const std::function<void(void*)>& clean_function)
{
clean_fun_ = clean_function;
return detach();
static void set_config(const std::string& name, double value);
static void set_config(const std::string& name, const std::string& value);
- Engine* set_default_comm_data_copy_callback(void (*callback)(kernel::activity::CommImpl*, void*, size_t));
+ Engine*
+ set_default_comm_data_copy_callback(const std::function<void(kernel::activity::CommImpl*, void*, size_t)>& callback);
/** Add a callback fired when the platform is created (ie, the xml file parsed),
* right before the actual simulation starts. */
ExecPtr set_flops_amounts(const std::vector<double>& flops_amounts);
ExecPtr set_bytes_amounts(const std::vector<double>& bytes_amounts);
+ ExecPtr set_thread_count(int thread_count);
+
ExecPtr set_bound(double bound);
ExecPtr set_priority(double priority);
ExecPtr update_priority(double priority);
*/
CommPtr put_async(void* data, uint64_t simulated_size_in_bytes);
- kernel::activity::ActivityImplPtr iprobe(int type, bool (*match_fun)(void*, void*, kernel::activity::CommImpl*),
- void* data);
+ kernel::activity::ActivityImplPtr
+ iprobe(int type, const std::function<bool(void*, void*, kernel::activity::CommImpl*)>& match_fun, void* data);
/** Blocking data transmission.
*
* Please note that if you send a pointer to some data, you must ensure that your data remains live during the
#define SIMGRID_SIMIX_H
#include <simgrid/forward.h>
-#include <xbt/dynar.h>
-#include <xbt/ex.h>
#include <xbt/parmap.h>
-#ifdef __cplusplus
-#include <functional>
-#include <string>
-#include <unordered_map>
-#include <vector>
+
+#ifndef SIMIX_H_NO_DEPRECATED_WARNING
+#warning simgrid/simix.h is deprecated and will be removed in v3.35.
#endif
/******************************* Networking ***********************************/
void SIMIX_comm_copy_pointer_callback(simgrid::kernel::activity::CommImpl* comm, void* buff, size_t buff_size);
XBT_ATTRIB_DEPRECATED_v333("Please use Comm::copy_pointer_callback()") XBT_PUBLIC
void SIMIX_comm_copy_buffer_callback(simgrid::kernel::activity::CommImpl* comm, void* buff, size_t buff_size);
-#endif
/******************************************************************************/
/* SIMIX simcalls */
/************************** Communication simcalls ****************************/
-#ifdef __cplusplus
-XBT_PUBLIC void simcall_comm_send(smx_actor_t sender, smx_mailbox_t mbox, double task_size, double rate, void* src_buff,
- size_t src_buff_size,
- bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*),
- void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t),
- void* data, double timeout);
-
-XBT_PUBLIC simgrid::kernel::activity::ActivityImplPtr
-simcall_comm_isend(smx_actor_t sender, smx_mailbox_t mbox, double task_size, double rate, void* src_buff,
- size_t src_buff_size, bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*),
- void (*clean_fun)(void*), void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t),
- void* data, bool detached);
-
-XBT_PUBLIC void simcall_comm_recv(smx_actor_t receiver, smx_mailbox_t mbox, void* dst_buff, size_t* dst_buff_size,
- bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*),
- void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t),
- void* data, double timeout, double rate);
-
-XBT_PUBLIC simgrid::kernel::activity::ActivityImplPtr
-simcall_comm_irecv(smx_actor_t receiver, smx_mailbox_t mbox, void* dst_buff, size_t* dst_buff_size,
- bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*),
- void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data, double rate);
+XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::send()") XBT_PUBLIC
+ void simcall_comm_send(smx_actor_t sender, smx_mailbox_t mbox, double task_size, double rate, void* src_buff,
+ size_t src_buff_size, bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*),
+ void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data,
+ double timeout);
+
+XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::isend()") XBT_PUBLIC simgrid::kernel::activity::ActivityImplPtr
+ simcall_comm_isend(smx_actor_t sender, smx_mailbox_t mbox, double task_size, double rate, void* src_buff,
+ size_t src_buff_size, bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*),
+ void (*clean_fun)(void*),
+ void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data,
+ bool detached);
+
+XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::recv()") XBT_PUBLIC
+ void simcall_comm_recv(smx_actor_t receiver, smx_mailbox_t mbox, void* dst_buff, size_t* dst_buff_size,
+ bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*),
+ void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data,
+ double timeout, double rate);
+
+XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::irecv()") XBT_PUBLIC simgrid::kernel::activity::ActivityImplPtr
+ simcall_comm_irecv(smx_actor_t receiver, smx_mailbox_t mbox, void* dst_buff, size_t* dst_buff_size,
+ bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*),
+ void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data,
+ double rate);
XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::wait_any_for()") XBT_PUBLIC ssize_t
simcall_comm_waitany(simgrid::kernel::activity::CommImpl* comms[], size_t count, double timeout);
-XBT_PUBLIC void simcall_comm_wait(simgrid::kernel::activity::ActivityImpl* comm, double timeout);
+XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::wait_for()") XBT_PUBLIC
+ void simcall_comm_wait(simgrid::kernel::activity::ActivityImpl* comm, double timeout);
XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::test()") XBT_PUBLIC
bool simcall_comm_test(simgrid::kernel::activity::ActivityImpl* comm);
XBT_ATTRIB_DEPRECATED_v335("Please use s4u::Comm::test_any()") XBT_PUBLIC ssize_t
#define SIMGRID_SIMIX_HPP
#include <simgrid/s4u/Actor.hpp>
-#include <simgrid/simix.h>
#include <xbt/promise.hpp>
#include <xbt/signal.hpp>
#include "xbt/base.h" // XBT_ATTRIB_DEPRECATED_v334
#include <cstddef>
+#include <functional>
#include <limits>
#include <vector>
template<class T>
class Extendable {
private:
- static std::vector<void(*)(void*)> deleters_;
- std::vector<void*> extensions_{std::max<decltype(deleters_.size())>(1, deleters_.size()), nullptr};
+ static std::vector<std::function<void(void*)>> deleters_;
+ std::vector<void*> extensions_{deleters_.size(), nullptr};
public:
- static size_t extension_create(void (*deleter)(void*))
+ static size_t extension_create(const std::function<void(void*)>& deleter)
{
- if (deleters_.empty()) { // Save space for void* user data
- deleters_.push_back(nullptr);
- }
- deleters_.push_back(deleter);
+ deleters_.emplace_back(deleter);
return deleters_.size() - 1;
}
- template<class U>
- static Extension<T,U> extension_create(void (*deleter)(void*))
+ template <class U> static Extension<T, U> extension_create(const std::function<void(void*)>& deleter)
{
return Extension<T,U>(extension_create(deleter));
}
* 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 > 1; --i) // rank=0 is the spot of user's void*
- if (extensions_[i - 1] != nullptr && deleters_[i - 1] != nullptr)
+ if (extensions_[i - 1] != nullptr && deleters_[i - 1])
deleters_[i - 1](extensions_[i - 1]);
}
template<class U> void extension_set(U* p) { extension_set<U>(U::EXTENSION_ID, p); }
};
-template <class T> std::vector<void (*)(void*)> Extendable<T>::deleters_;
+// Initialized with a first element, to save space for void* user data
+template <class T> std::vector<std::function<void(void*)>> Extendable<T>::deleters_{1};
}
}
# - Python files used to generate either simcalls or deployment files
# - Any java source code (it's deprecated now)
# - MSG (deprecated too)
-sonar.coverage.exclusions=teshsuite/smpi/mpich3-test/**,examples/smpi/mc/**,**/*.xml,src/simix/simcalls.py,**/generate.py,**/*.java,src/bindings/java/**,src/msg/**,include/msg/**,examples/deprecated/**,teshsuite/msg/**
+sonar.coverage.exclusions=teshsuite/smpi/mpich3-test/**,teshsuite/smpi/MBI/**,examples/smpi/mc/**,**/*.xml,**/generate.py,**/*.java,src/bindings/java/**,src/msg/**,include/msg/**,examples/deprecated/**,teshsuite/msg/**
# Encoding of the source files
sonar.sourceEncoding=UTF-8
#include <simgrid/forward.h>
#include <simgrid/modelchecker.h> /* our public interface (and definition of SIMGRID_HAVE_MC) */
-SG_BEGIN_DECL
-
-/********************************* Global *************************************/
-XBT_ATTRIB_NORETURN XBT_PUBLIC void MC_run();
-
-SG_END_DECL
-
#ifdef __cplusplus
XBT_PUBLIC void MC_process_clock_add(const simgrid::kernel::actor::ActorImpl*, double);
XBT_PUBLIC double MC_process_clock_get(const simgrid::kernel::actor::ActorImpl*);
#include "src/instr/instr_smpi.hpp"
#include "src/smpi/include/private.hpp"
#include "src/surf/surf_interface.hpp"
+#include "xbt/ex.h"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(instr_paje_events, instr, "Paje tracing event system (events)");
#include <simgrid/s4u/Host.hpp>
#include <simgrid/sg_config.hpp>
+#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v332)
+#include <simgrid/simix.h>
+
#include "mc/mc.h"
#include "src/kernel/EngineImpl.hpp"
#include "src/kernel/resource/StandardLinkImpl.hpp"
"When non-negative, raise a SIGTRAP after given (simulated) time", -1.0};
config::Flag<bool> cfg_verbose_exit{"debug/verbose-exit", "Display the actor status at exit", true};
-xbt_dynar_t get_actors_addr()
-{
-#if SIMGRID_HAVE_MC
- return EngineImpl::get_instance()->get_actors_vector();
-#else
- xbt_die("This function is intended to be used when compiling with MC");
-#endif
-}
-
constexpr std::initializer_list<std::pair<const char*, context::ContextFactoryInitializer>> context_factories = {
#if HAVE_RAW_CONTEXTS
{"raw", &context::raw_factory},
EngineImpl::instance_ = this;
#if SIMGRID_HAVE_MC
// The communication initialization is done ASAP, as we need to get some init parameters from the MC for different
- // layers. But simix_global needs to be created, as we send the address of some of its fields to the MC that wants to
+ // layers. But instance_ needs to be created, as we send the address of some of its fields to the MC that wants to
// read them directly.
- simgrid::mc::AppSide::initialize();
+ simgrid::mc::AppSide::initialize(actors_vector_);
#endif
if (xbt_initialized == 0) {
void EngineImpl::seal_platform() const
{
+ /* Seal only once */
+ static bool sealed = false;
+ if (sealed)
+ return;
+ sealed = true;
+
/* sealing resources before run: links */
for (auto const& kv : links_)
kv.second->get_iface()->seal();
{
instance_->get_context_factory()->run_all();
+ for (auto const& actor : actors_to_run_)
+ if (actor->context_->to_be_freed())
+ actor->cleanup_from_kernel();
+
actors_to_run_.swap(actors_that_ran_);
actors_to_run_.clear();
}
return nullptr; // Not found, even in the trash
}
-/** Execute all the tasks that are queued, e.g. `.then()` callbacks of futures. */
-bool EngineImpl::execute_tasks()
-{
- if (tasks.empty())
- return false;
-
- std::vector<xbt::Task<void()>> tasksTemp;
- do {
- // We don't want the callbacks to modify the vector we are iterating over:
- tasks.swap(tasksTemp);
-
- // Execute all the queued tasks:
- for (auto& task : tasksTemp)
- task();
-
- tasksTemp.clear();
- } while (not tasks.empty());
-
- return true;
-}
-
void EngineImpl::remove_daemon(actor::ActorImpl* actor)
{
auto it = daemons_.find(actor);
actor->waiting_synchro_->get_cname(), actor->waiting_synchro_->get_state_str());
} else {
XBT_INFO("Actor %ld (%s@%s) simcall %s", actor->get_pid(), actor->get_cname(), actor->get_host()->get_cname(),
- SIMIX_simcall_name(actor->simcall_));
+ actor->simcall_.get_cname());
}
}
}
{
seal_platform();
+ if (MC_is_active()) {
+#if SIMGRID_HAVE_MC
+ mc::AppSide::get()->main_loop();
+#else
+ xbt_die("MC_is_active() is not supposed to return true in non-MC settings");
+#endif
+ THROW_IMPOSSIBLE; // main_loop never returns
+ }
+
if (MC_record_replay_is_active()) {
mc::RecordTrace::replay(MC_record_path());
empty_trash();
#endif
}
- execute_tasks();
-
while (not actors_to_run_.empty()) {
XBT_DEBUG("New Sub-Schedule Round; size(queue)=%zu", actors_to_run_.size());
* and would thus be a pure waste of time.
*/
- for (auto const& actor : actors_that_ran_) {
- if (actor->simcall_.call_ != simix::Simcall::NONE) {
+ for (auto const& actor : actors_that_ran_)
+ if (actor->simcall_.call_ != actor::Simcall::Type::NONE)
actor->simcall_handle(0);
- }
- }
- execute_tasks();
- do {
- wake_all_waiting_actors();
- } while (execute_tasks());
+ wake_all_waiting_actors();
/* If only daemon actors remain, cancel their actions, mark them to die and reschedule them */
if (actor_list_.size() == daemons_.size())
/* FIXME: iterate through the list of failed host and mark each of them */
/* as failed. On each host, signal all the running actors with host_fail */
- // Execute timers and tasks until there isn't anything to be done:
+ // Execute timers until there isn't anything to be done:
bool again = false;
do {
again = timer::Timer::execute_all();
- if (execute_tasks())
- again = true;
wake_all_waiting_actors();
} while (again);
namespace simgrid {
namespace kernel {
-// In MC mode, the application sends these pointers to the MC
-xbt_dynar_t get_actors_addr();
class EngineImpl {
std::map<std::string, s4u::Host*, std::less<>> hosts_;
xbt_dynar_t actors_vector_ = xbt_dynar_new(sizeof(actor::ActorImpl*), nullptr);
#endif
- std::vector<xbt::Task<void()>> tasks;
-
- std::mutex mutex_;
static EngineImpl* instance_;
actor::ActorImpl* maestro_ = nullptr;
context::ContextFactory* context_factory_ = nullptr;
void add_split_duplex_link(const std::string& name, std::unique_ptr<resource::SplitDuplexLinkImpl> link);
#if SIMGRID_HAVE_MC
- xbt_dynar_t get_actors_vector() const { return actors_vector_; }
void reset_actor_dynar() { xbt_dynar_reset(actors_vector_); }
void add_actor_to_dynar(actor::ActorImpl* actor) { xbt_dynar_push_as(actors_vector_, actor::ActorImpl*, actor); }
#endif
const std::vector<actor::ActorImpl*>& get_actors_to_run() const { return actors_to_run_; }
const std::vector<actor::ActorImpl*>& get_actors_that_ran() const { return actors_that_ran_; }
- std::mutex& get_mutex() { return mutex_; }
- bool execute_tasks();
- void add_task(xbt::Task<void()>&& t) { tasks.push_back(std::move(t)); }
void wake_all_waiting_actors() const;
/**
* Garbage collection
XBT_DEBUG("Destroy activity %p", this);
}
-void ActivityImpl::register_simcall(smx_simcall_t simcall)
+void ActivityImpl::register_simcall(actor::Simcall* simcall)
{
simcalls_.push_back(simcall);
simcall->issuer_->waiting_synchro_ = this;
}
-void ActivityImpl::unregister_simcall(smx_simcall_t simcall)
+void ActivityImpl::unregister_simcall(actor::Simcall* simcall)
{
// Remove the first occurrence of simcall:
auto j = boost::range::find(simcalls_, simcall);
state_ = State::CANCELED;
}
-void ActivityImpl::handle_activity_waitany(smx_simcall_t simcall)
+void ActivityImpl::handle_activity_waitany(actor::Simcall* simcall)
{
/* If a waitany simcall is waiting for this synchro to finish, then remove it from the other synchros in the waitany
* list. Afterwards, get the position of the actual synchro in the waitany list and return it as the result of the
public:
virtual ~ActivityImpl();
ActivityImpl() = default;
- std::list<smx_simcall_t> simcalls_; /* List of simcalls waiting for this activity */
+ std::list<actor::Simcall*> simcalls_; /* List of simcalls waiting for this activity */
s4u::Activity* piface_ = nullptr;
resource::Action* surf_action_ = nullptr;
virtual void finish() = 0; // Unlock all simcalls blocked on that activity, either because it was marked as done by
// the model or because it terminated without waiting for the model
- void register_simcall(smx_simcall_t simcall);
- void unregister_simcall(smx_simcall_t simcall);
- void handle_activity_waitany(smx_simcall_t simcall);
+ void register_simcall(actor::Simcall* simcall);
+ void unregister_simcall(actor::Simcall* simcall);
+ void handle_activity_waitany(actor::Simcall* simcall);
void clean_action();
virtual double get_remaining() const;
// Support for the boost::intrusive_ptr<ActivityImpl> datatype
void BarrierAcquisitionImpl::finish()
{
xbt_assert(simcalls_.size() == 1, "Unexpected number of simcalls waiting: %zu", simcalls_.size());
- smx_simcall_t simcall = simcalls_.front();
+ actor::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
simcall->issuer_->waiting_synchro_ = nullptr;
std::atomic_int_fast32_t refcount_{1};
s4u::Barrier piface_;
unsigned int expected_actors_;
- // std::vector<actor::ActorImpl*> arrived_actors_;
std::deque<BarrierAcquisitionImplPtr> ongoing_acquisitions_;
static unsigned next_id_;
unsigned id_ = next_id_++;
friend s4u::Barrier;
public:
- BarrierImpl(int expected_actors) : piface_(this), expected_actors_(expected_actors) {}
+ explicit BarrierImpl(int expected_actors) : piface_(this), expected_actors_(expected_actors) {}
BarrierImpl(BarrierImpl const&) = delete;
BarrierImpl& operator=(BarrierImpl const&) = delete;
#include <simgrid/modelchecker.h>
#include <simgrid/s4u/Host.hpp>
+#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v333)
+#include <simgrid/simix.h>
+
#include "src/kernel/activity/CommImpl.hpp"
#include "src/kernel/activity/MailboxImpl.hpp"
#include "src/kernel/actor/SimcallObserver.hpp"
xbt::signal<void(CommImpl const&)> CommImpl::on_start;
xbt::signal<void(CommImpl const&)> CommImpl::on_completion;
-void (*CommImpl::copy_data_callback_)(CommImpl*, void*, size_t) = &s4u::Comm::copy_pointer_callback;
+std::function<void(CommImpl*, void*, size_t)> CommImpl::copy_data_callback_ = &s4u::Comm::copy_pointer_callback;
-void CommImpl::set_copy_data_callback(void (*callback)(CommImpl*, void*, size_t))
+void CommImpl::set_copy_data_callback(const std::function<void(CommImpl*, void*, size_t)>& callback)
{
copy_data_callback_ = callback;
}
copy_data();
while (not simcalls_.empty()) {
- smx_simcall_t simcall = simcalls_.front();
+ actor::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
/* If a waitany simcall is waiting for this synchro to finish, then remove it from the other synchros in the waitany
* list. Afterwards, get the position of the actual synchro in the waitany list and return it as the result of the
* simcall */
- if (simcall->call_ == simix::Simcall::NONE) // FIXME: maybe a better way to handle this case
- continue; // if actor handling comm is killed
+ if (simcall->call_ == actor::Simcall::Type::NONE) // FIXME: maybe a better way to handle this case
+ continue; // if actor handling comm is killed
handle_activity_waitany(simcall);
~CommImpl() override;
void cleanup_surf();
- static void (*copy_data_callback_)(CommImpl*, void*, size_t);
+ static std::function<void(CommImpl*, void*, size_t)> copy_data_callback_;
- double rate_ = 0.0;
+ double rate_ = -1.0;
double size_ = 0.0;
bool detached_ = false; /* If detached or not */
bool copied_ = false; /* whether the data were already copied */
public:
CommImpl() = default;
- static void set_copy_data_callback(void (*callback)(CommImpl*, void*, size_t));
+ static void set_copy_data_callback(const std::function<void(CommImpl*, void*, size_t)>& callback);
CommImpl& set_type(CommImplType type);
CommImplType get_type() const { return type_; }
void set_exception(actor::ActorImpl* issuer) override;
void finish() override;
- void (*clean_fun)(void*) = nullptr; /* Function to clean the detached src_buf if something goes wrong */
- bool (*match_fun)(void*, void*, CommImpl*) = nullptr; /* Filter function used by the other side. It is used when
+ std::function<void(void*)> clean_fun; /* Function to clean the detached src_buf if something goes wrong */
+ std::function<bool(void*, void*, CommImpl*)> match_fun; /* Filter function used by the other side. It is used when
looking if a given communication matches my needs. For that, myself must match the
expectations of the other side, too. See */
- void (*copy_data_fun)(CommImpl*, void*, size_t) = nullptr;
+ std::function<void(CommImpl*, void*, size_t)> copy_data_fun;
/* Surf action data */
resource::Action* src_timeout_ = nullptr; /* Surf's actions to instrument the timeouts */
proc.waiting_synchro_ = nullptr;
/* Now transform the cond wait simcall into a mutex lock one */
- smx_simcall_t simcall = &proc.simcall_;
+ actor::Simcall* simcall = &proc.simcall_;
const auto* observer = dynamic_cast<kernel::actor::ConditionWaitSimcall*>(simcall->observer_);
xbt_assert(observer != nullptr);
observer->get_mutex()->lock_async(simcall->issuer_)->wait_for(simcall->issuer_, -1);
return *this;
}
+ExecImpl& ExecImpl::set_thread_count(int thread_count)
+{
+ thread_count_ = thread_count;
+
+ return *this;
+}
ExecImpl* ExecImpl::start()
{
set_state(State::RUNNING);
if (not MC_is_active() && not MC_record_replay_is_active()) {
if (hosts_.size() == 1) {
- surf_action_ = hosts_.front()->get_cpu()->execution_start(flops_amounts_.front(), bound_);
- surf_action_->set_sharing_penalty(sharing_penalty_);
+ if (thread_count_ == 1) {
+ surf_action_ = hosts_.front()->get_cpu()->execution_start(flops_amounts_.front(), bound_);
+ surf_action_->set_sharing_penalty(sharing_penalty_);
+ } else {
+ auto host_model = hosts_.front()->get_netpoint()->get_englobing_zone()->get_host_model();
+ surf_action_ = host_model->execute_thread(hosts_.front(), flops_amounts_.front(), thread_count_);
+ }
surf_action_->set_category(get_tracing_category());
} else {
// get the model from first host since we have only 1 by now
{
XBT_DEBUG("ExecImpl::finish() in state %s", get_state_str());
while (not simcalls_.empty()) {
- smx_simcall_t simcall = simcalls_.front();
+ actor::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
- if (simcall->call_ == simix::Simcall::NONE) // FIXME: maybe a better way to handle this case
- continue; // if process handling comm is killed
+ if (simcall->call_ == actor::Simcall::Type::NONE) // FIXME: maybe a better way to handle this case
+ continue; // if process handling comm is killed
handle_activity_waitany(simcall);
std::vector<s4u::Host*> hosts_;
std::vector<double> flops_amounts_;
std::vector<double> bytes_amounts_;
+ int thread_count_ = 1;
int cb_id_ = -1; // callback id from Host::on_state_change.connect()
public:
ExecImpl& set_flops_amounts(const std::vector<double>& flops_amounts);
ExecImpl& set_bytes_amounts(const std::vector<double>& bytes_amounts);
+ ExecImpl& set_thread_count(int thread_count);
ExecImpl& set_hosts(const std::vector<s4u::Host*>& hosts);
unsigned int get_host_number() const { return hosts_.size(); }
{
XBT_DEBUG("IoImpl::finish() in state %s", get_state_str());
while (not simcalls_.empty()) {
- smx_simcall_t simcall = simcalls_.front();
+ actor::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
/* If a waitany simcall is waiting for this synchro to finish, then remove it from the other synchros in the waitany
* list. Afterwards, get the position of the actual synchro in the waitany list and return it as the result of the
* simcall */
- if (simcall->call_ == simix::Simcall::NONE) // FIXME: maybe a better way to handle this case
- continue; // if process handling comm is killed
+ if (simcall->call_ == actor::Simcall::Type::NONE) // FIXME: maybe a better way to handle this case
+ continue; // if process handling comm is killed
handle_activity_waitany(simcall);
}
}
-CommImplPtr MailboxImpl::iprobe(int type, bool (*match_fun)(void*, void*, CommImpl*), void* data)
+CommImplPtr MailboxImpl::iprobe(int type, const std::function<bool(void*, void*, CommImpl*)>& match_fun, void* data)
{
XBT_DEBUG("iprobe from %p %p", this, &comm_queue_);
* @param remove_matching whether or not to clean the found object from the queue
* @return The communication activity if found, nullptr otherwise
*/
-CommImplPtr MailboxImpl::find_matching_comm(CommImplType type, bool (*match_fun)(void*, void*, CommImpl*),
+CommImplPtr MailboxImpl::find_matching_comm(CommImplType type,
+ const std::function<bool(void*, void*, CommImpl*)>& match_fun,
void* this_user_data, const CommImplPtr& my_synchro, bool done,
bool remove_matching)
{
void push_done(CommImplPtr done_comm) { done_comm_queue_.push_back(done_comm); }
void remove(const CommImplPtr& comm);
void clear();
- CommImplPtr iprobe(int type, bool (*match_fun)(void*, void*, CommImpl*), void* data);
- CommImplPtr find_matching_comm(CommImplType type, bool (*match_fun)(void*, void*, CommImpl*), void* this_user_data,
- const CommImplPtr& my_synchro, bool done, bool remove_matching);
+ CommImplPtr iprobe(int type, const std::function<bool(void*, void*, CommImpl*)>& match_fun, void* data);
+ CommImplPtr find_matching_comm(CommImplType type, const std::function<bool(void*, void*, CommImpl*)>& match_fun,
+ void* this_user_data, const CommImplPtr& my_synchro, bool done, bool remove_matching);
bool is_permanent() const { return permanent_receiver_ != nullptr; }
actor::ActorImplPtr get_permanent_receiver() const { return permanent_receiver_; }
bool empty() const { return comm_queue_.empty(); }
void MutexAcquisitionImpl::finish()
{
xbt_assert(simcalls_.size() == 1, "Unexpected number of simcalls waiting: %zu", simcalls_.size());
- smx_simcall_t simcall = simcalls_.front();
+ actor::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
simcall->issuer_->waiting_synchro_ = nullptr;
void SemAcquisitionImpl::finish()
{
xbt_assert(simcalls_.size() == 1, "Unexpected number of simcalls waiting: %zu", simcalls_.size());
- smx_simcall_t simcall = simcalls_.front();
+ actor::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
if (surf_action_ != nullptr) { // A timeout was declared
delete sem;
}
}
- unsigned get_id() { return id_; }
-
+ unsigned get_id() const { return id_; }
s4u::Semaphore& sem() { return piface_; }
};
} // namespace activity
{
XBT_DEBUG("SleepImpl::finish() in state %s", get_state_str());
while (not simcalls_.empty()) {
- const s_smx_simcall* simcall = simcalls_.front();
+ const actor::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
simcall->issuer_->waiting_synchro_ = nullptr;
{
XBT_DEBUG("SynchroImpl::finish() in state %s", get_state_str());
xbt_assert(simcalls_.size() == 1, "Unexpected number of simcalls waiting: %zu", simcalls_.size());
- smx_simcall_t simcall = simcalls_.front();
+ actor::Simcall* simcall = simcalls_.front();
simcalls_.pop_front();
set_exception(simcall->issuer_);
#include <simgrid/s4u/Actor.hpp>
#include <simgrid/s4u/Host.hpp>
+#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v333)
+#include <simgrid/simix.h>
+
#include "src/kernel/EngineImpl.hpp"
#if HAVE_SMPI
#include "src/smpi/include/private.hpp"
auto* context = dynamic_cast<context::AttachContext*>(context::Context::self());
xbt_assert(context != nullptr, "Not a suitable context");
- context->get_actor()->cleanup();
+ context->get_actor()->cleanup_from_self();
context->attach_stop();
}
return context_->is_maestro();
}
-void ActorImpl::cleanup_from_simix()
+void ActorImpl::cleanup_from_kernel()
{
+ xbt_assert(s4u::Actor::is_maestro(), "Cleanup_from_kernel called from '%s' on '%s'", ActorImpl::self()->get_cname(),
+ get_cname());
+
auto* engine = EngineImpl::get_instance();
- const std::lock_guard<std::mutex> lock(engine->get_mutex());
engine->remove_actor(pid_);
if (host_ && host_actor_list_hook.is_linked())
host_->get_impl()->remove_actor(this);
if (not kernel_destroy_list_hook.is_linked())
engine->add_actor_to_destroy_list(*this);
-}
-
-void ActorImpl::cleanup()
-{
- finished_ = true;
if (has_to_auto_restart() && not get_host()->is_on()) {
XBT_DEBUG("Insert host %s to watched_hosts because it's off and %s needs to restart", get_host()->get_cname(),
watched_hosts().insert(get_host()->get_name());
}
+ undaemonize();
+
+ while (not mailboxes.empty())
+ mailboxes.back()->set_receiver(nullptr);
+}
+
+/* Do all the cleanups from the actor context. Warning, the simcall mechanism was not reignited so doing simcalls in
+ * this context is dangerous */
+void ActorImpl::cleanup_from_self()
+{
+ xbt_assert(not ActorImpl::is_maestro(), "Cleanup_from_self called from maestro on '%s'", get_cname());
+ context_->set_to_be_freed();
+
if (on_exit) {
// Execute the termination callbacks
bool failed = context_->wannadie();
(*exit_fun)(failed);
on_exit.reset();
}
- undaemonize();
/* cancel non-blocking activities */
for (auto activity : activities_)
activity->cancel();
activities_.clear();
- while (not mailboxes.empty())
- mailboxes.back()->set_receiver(nullptr);
-
XBT_DEBUG("%s@%s(%ld) should not run anymore", get_cname(), get_host()->get_cname(), get_pid());
- if (EngineImpl::get_instance()->is_maestro(this)) /* Do not cleanup maestro */
- return;
-
- XBT_DEBUG("Cleanup actor %s (%p), waiting synchro %p", get_cname(), this, waiting_synchro_.get());
-
/* Unregister associated timers if any */
if (kill_timer_ != nullptr) {
kill_timer_->remove();
simcall_.timeout_cb_ = nullptr;
}
- cleanup_from_simix();
-
context_->set_wannadie(false); // don't let the simcall's yield() do a Context::stop(), to avoid infinite loops
actor::simcall_answered([this] { s4u::Actor::on_termination(*get_ciface()); });
context_->set_wannadie();
void ActorImpl::exit()
{
context_->set_wannadie();
- suspended_ = false;
- exception_ = nullptr;
+ suspended_ = false;
+ exception_ = nullptr;
/* destroy the blocking synchro if any */
if (auto activity = waiting_synchro_) {
void ActorImpl::kill(ActorImpl* actor) const
{
xbt_assert(not actor->is_maestro(), "Killing maestro is a rather bad idea.");
- if (actor->finished_) {
+ if (actor->context_->wannadie()) {
XBT_DEBUG("Ignoring request to kill actor %s@%s that is already dead", actor->get_cname(),
actor->host_->get_cname());
return;
}
}
#if HAVE_SMPI
- if (not finished_)
+ if (not context_->wannadie())
smpi_switch_data_segment(get_iface());
#endif
}
XBT_DEBUG("Restarting actor %s on %s", get_cname(), host_->get_cname());
// retrieve the arguments of the old actor
- ProcessArg arg(host_, this);
+ ProcessArg args(host_, this);
// kill the old actor
context::Context::self()->get_actor()->kill(this);
// start the new actor
- ActorImplPtr actor = ActorImpl::create(arg.name, arg.code, arg.data, arg.host, nullptr);
- actor->set_properties(arg.properties);
- *actor->on_exit = std::move(*arg.on_exit);
- actor->set_kill_time(arg.kill_time);
- actor->set_auto_restart(arg.auto_restart);
-
- return actor->get_ciface();
+ return create(&args)->get_ciface();
}
void ActorImpl::suspend()
XBT_IN("actor = %p", this);
if (context_->wannadie()) {
- XBT_VERB("Ignoring request to suspend an actor that is currently dying.");
+ XBT_VERB("Ignoring request to resume an actor that is currently dying.");
return;
}
{
auto* engine = EngineImpl::get_instance();
if (not this->is_maestro()) {
- XBT_DEBUG("Answer simcall %s issued by %s (%p)", SIMIX_simcall_name(simcall_), get_cname(), this);
- xbt_assert(simcall_.call_ != simix::Simcall::NONE);
- simcall_.call_ = simix::Simcall::NONE;
+ XBT_DEBUG("Answer simcall %s issued by %s (%p)", simcall_.get_cname(), get_cname(), this);
+ xbt_assert(simcall_.call_ != Simcall::Type::NONE);
+ simcall_.call_ = Simcall::Type::NONE;
const auto& actors_to_run = engine->get_actors_to_run();
xbt_assert(not XBT_LOG_ISENABLED(ker_actor, xbt_log_priority_debug) ||
std::find(begin(actors_to_run), end(actors_to_run), this) == end(actors_to_run),
return actor;
}
+ActorImplPtr ActorImpl::create(ProcessArg* args)
+{
+ ActorImplPtr actor = ActorImpl::create(args->name, args->code, nullptr, args->host, nullptr);
+ actor->restart_count_ = args->restart_count_;
+ actor->set_properties(args->properties);
+ if (args->on_exit)
+ *actor->on_exit = *args->on_exit;
+ if (args->kill_time >= 0)
+ actor->set_kill_time(args->kill_time);
+ if (args->auto_restart)
+ actor->set_auto_restart(args->auto_restart);
+ if (args->daemon_)
+ actor->daemonize();
+ return actor;
+}
void create_maestro(const std::function<void()>& code)
{
#ifndef SIMGRID_KERNEL_ACTOR_ACTORIMPL_HPP
#define SIMGRID_KERNEL_ACTOR_ACTORIMPL_HPP
+#include "Simcall.hpp"
#include "simgrid/kernel/Timer.hpp"
#include "simgrid/s4u/Actor.hpp"
-#include "src/simix/popping_private.hpp"
#include "xbt/PropertyHolder.hpp"
#include <boost/intrusive/list.hpp>
#include <functional>
namespace simgrid {
namespace kernel {
namespace actor {
+class ProcessArg;
-class XBT_PUBLIC ActorImpl : public xbt::PropertyHolder {
+class XBT_PUBLIC ActorRestartingTrait {
+ bool auto_restart_ = false;
+ int restart_count_ = 0;
+
+ friend ActorImpl;
+
+public:
+ bool has_to_auto_restart() const { return auto_restart_; }
+ void set_auto_restart(bool autorestart) { auto_restart_ = autorestart; }
+ int get_restart_count() const { return restart_count_; }
+};
+
+class XBT_PUBLIC ActorImpl : public xbt::PropertyHolder, public ActorRestartingTrait {
s4u::Host* host_ = nullptr; /* the host on which the actor is running */
+ xbt::string name_;
aid_t pid_ = 0;
aid_t ppid_ = -1;
bool daemon_ = false; /* Daemon actors are automatically killed when the last non-daemon leaves */
- bool auto_restart_ = false;
unsigned stacksize_; // set to default value in constructor
std::vector<activity::MailboxImpl*> mailboxes;
friend activity::MailboxImpl;
public:
- xbt::string name_;
ActorImpl(xbt::string name, s4u::Host* host);
ActorImpl(const ActorImpl&) = delete;
ActorImpl& operator=(const ActorImpl&) = delete;
bool is_daemon() const { return daemon_; } /** Whether this actor has been daemonized */
bool is_maestro() const; /** Whether this actor is actually maestro (cheap call but may segfault before actor creation
/ after terminaison) */
- bool has_to_auto_restart() const { return auto_restart_; }
- void set_auto_restart(bool autorestart) { auto_restart_ = autorestart; }
void set_stacksize(unsigned stacksize) { stacksize_ = stacksize; }
unsigned get_stacksize() const { return stacksize_; }
std::unique_ptr<context::Context> context_; /* the context (uctx/raw/thread) that executes the user function */
std::exception_ptr exception_;
- bool finished_ = false;
bool suspended_ = false;
activity::ActivityImplPtr waiting_synchro_ = nullptr; /* the current blocking synchro if any */
std::list<activity::ActivityImplPtr> activities_; /* the current non-blocking synchros */
- s_smx_simcall simcall_;
+ Simcall simcall_;
/* list of functions executed when the actor dies */
std::shared_ptr<std::vector<std::function<void(bool)>>> on_exit =
std::make_shared<std::vector<std::function<void(bool)>>>();
private:
s4u::Actor piface_; // Our interface is part of ourselves
- void cleanup_from_simix();
void undaemonize();
public:
static ActorImplPtr create(const std::string& name, const ActorCode& code, void* data, s4u::Host* host,
const ActorImpl* parent_actor);
+ static ActorImplPtr create(ProcessArg* args);
static ActorImplPtr attach(const std::string& name, void* data, s4u::Host* host);
static void detach();
- void cleanup();
+ void cleanup_from_self();
+ void cleanup_from_kernel();
void exit();
void kill(ActorImpl* actor) const;
void kill_all() const;
double kill_time = 0.0;
const std::unordered_map<std::string, std::string> properties{};
bool auto_restart = false;
- bool daemon_ = false;
+ bool daemon_;
/* list of functions executed when the actor dies */
const std::shared_ptr<std::vector<std::function<void(bool)>>> on_exit;
+ int restart_count_ = 0;
ProcessArg() = delete;
ProcessArg(const ProcessArg&) = delete;
explicit ProcessArg(const std::string& name, const std::function<void()>& code, void* data, s4u::Host* host,
double kill_time, const std::unordered_map<std::string, std::string>& properties,
- bool auto_restart)
+ bool auto_restart, bool daemon, int restart_count)
: name(name)
, code(code)
, data(data)
, kill_time(kill_time)
, properties(properties)
, auto_restart(auto_restart)
+ , daemon_(daemon)
+ , restart_count_(restart_count)
{
}
, auto_restart(actor->has_to_auto_restart())
, daemon_(actor->is_daemon())
, on_exit(actor->on_exit)
+ , restart_count_(actor->get_restart_count() + 1)
{
}
};
activity::CommImpl* comm_;
int tag_;
- bool (*match_fun_)(void*, void*, activity::CommImpl*);
- void (*clean_fun_)(void*); // used to free the synchro in case of problem after a detached send
- void (*copy_data_fun_)(activity::CommImpl*, void*, size_t); // used to copy data if not default one
+ std::function<bool(void*, void*, activity::CommImpl*)> match_fun_;
+ std::function<void(void*)> clean_fun_; // used to free the synchro in case of problem after a detached send
+ std::function<void(activity::CommImpl*, void*, size_t)> copy_data_fun_; // used to copy data if not default one
public:
- CommIsendSimcall(ActorImpl* actor, activity::MailboxImpl* mbox, double payload_size, double rate,
- unsigned char* src_buff, size_t src_buff_size, bool (*match_fun)(void*, void*, activity::CommImpl*),
- void (*clean_fun)(void*), // used to free the synchro in case of problem after a detached send
- void (*copy_data_fun)(activity::CommImpl*, void*, size_t), // used to copy data if not default one
- void* payload, bool detached)
+ CommIsendSimcall(
+ ActorImpl* actor, activity::MailboxImpl* mbox, double payload_size, double rate, unsigned char* src_buff,
+ size_t src_buff_size, const std::function<bool(void*, void*, activity::CommImpl*)>& match_fun,
+ const std::function<void(void*)>& clean_fun, // used to free the synchro in case of problem after a detached send
+ const std::function<void(activity::CommImpl*, void*, size_t)>&
+ copy_data_fun, // used to copy data if not default one
+ void* payload, bool detached)
: SimcallObserver(actor)
, mbox_(mbox)
, payload_size_(payload_size)
void set_comm(activity::CommImpl* comm) { comm_ = comm; }
void set_tag(int tag) { tag_ = tag; }
- auto get_match_fun() const { return match_fun_; }
- auto get_clean_fun() const { return clean_fun_; }
- auto get_copy_data_fun() const { return copy_data_fun_; }
+ auto const& get_match_fun() const { return match_fun_; }
+ auto const& get_clean_fun() const { return clean_fun_; }
+ auto const& get_copy_data_fun() const { return copy_data_fun_; }
};
class CommIrecvSimcall : public SimcallObserver {
int tag_;
activity::CommImpl* comm_;
- bool (*match_fun_)(void*, void*, activity::CommImpl*);
- void (*copy_data_fun_)(activity::CommImpl*, void*, size_t); // used to copy data if not default one
+ std::function<bool(void*, void*, activity::CommImpl*)> match_fun_;
+ std::function<void(activity::CommImpl*, void*, size_t)> copy_data_fun_; // used to copy data if not default one
public:
CommIrecvSimcall(ActorImpl* actor, activity::MailboxImpl* mbox, unsigned char* dst_buff, size_t* dst_buff_size,
- bool (*match_fun)(void*, void*, activity::CommImpl*),
- void (*copy_data_fun)(activity::CommImpl*, void*, size_t), void* payload, double rate)
+ const std::function<bool(void*, void*, activity::CommImpl*)>& match_fun,
+ const std::function<void(activity::CommImpl*, void*, size_t)>& copy_data_fun, void* payload,
+ double rate)
: SimcallObserver(actor)
, mbox_(mbox)
, dst_buff_(dst_buff)
void set_comm(activity::CommImpl* comm) { comm_ = comm; }
void set_tag(int tag) { tag_ = tag; }
- auto get_match_fun() const { return match_fun_; };
- auto get_copy_data_fun() const { return copy_data_fun_; }
+ auto const& get_match_fun() const { return match_fun_; };
+ auto const& get_copy_data_fun() const { return copy_data_fun_; }
};
} // namespace actor
/* 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. */
+#include "Simcall.hpp"
#include "simgrid/s4u/Host.hpp"
#include "src/kernel/actor/ActorImpl.hpp"
#include "src/kernel/actor/SimcallObserver.hpp"
#include "src/kernel/context/Context.hpp"
-#include "src/simix/popping_private.hpp"
#include "xbt/log.h"
-XBT_LOG_NEW_DEFAULT_CATEGORY(simix, "transmuting from user request into kernel handlers");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_simcall, kernel, "transmuting from user request into kernel handlers");
-constexpr std::array<const char*, simgrid::simix::NUM_SIMCALLS> simcall_names{{
- "Simcall::NONE",
- "Simcall::RUN_ANSWERED",
- "Simcall::RUN_BLOCKING",
-}};
+namespace simgrid {
+namespace kernel {
+namespace actor {
/** @private
* @brief (in kernel mode) unpack the simcall and activate the handler
*
*/
-void simgrid::kernel::actor::ActorImpl::simcall_handle(int times_considered)
+void ActorImpl::simcall_handle(int times_considered)
{
- XBT_DEBUG("Handling simcall %p: %s", &simcall_, SIMIX_simcall_name(simcall_));
+ XBT_DEBUG("Handling simcall %p: %s", &simcall_, simcall_.get_cname());
if (simcall_.observer_ != nullptr)
simcall_.observer_->prepare(times_considered);
if (context_->wannadie())
return;
- xbt_assert(simcall_.call_ != simgrid::simix::Simcall::NONE, "Asked to do the noop syscall on %s@%s", get_cname(),
+ xbt_assert(simcall_.call_ != Simcall::Type::NONE, "Asked to do the noop syscall on %s@%s", get_cname(),
get_host()->get_cname());
(*simcall_.code_)();
- if (simcall_.call_ == simgrid::simix::Simcall::RUN_ANSWERED)
+ if (simcall_.call_ == Simcall::Type::RUN_ANSWERED)
simcall_answer();
}
/** @brief returns a printable string representing a simcall */
-const char* SIMIX_simcall_name(const s_smx_simcall& simcall)
+const char* Simcall::get_cname() const
{
- if (simcall.observer_ != nullptr) {
+ if (observer_ != nullptr) {
static std::string name;
- name = boost::core::demangle(typeid(*simcall.observer_).name());
+ name = boost::core::demangle(typeid(*observer_).name());
const char* cname = name.c_str();
if (name.rfind("simgrid::kernel::", 0) == 0)
cname += 17; // strip prefix "simgrid::kernel::"
return cname;
} else {
- return simcall_names.at(static_cast<int>(simcall.call_));
+ return to_c_str(call_);
}
}
+
+} // namespace actor
+} // namespace kernel
+} // namespace simgrid
/* 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. */
-#ifndef SG_POPPING_PRIVATE_HPP
-#define SG_POPPING_PRIVATE_HPP
+#ifndef SIMCALL_HPP
+#define SIMCALL_HPP
#include "simgrid/forward.h"
#include "src/kernel/activity/ActivityImpl.hpp"
-
-#include <array>
-#include <boost/intrusive_ptr.hpp>
+#include "xbt/utility.hpp"
/********************************* Simcalls *********************************/
namespace simgrid {
-namespace simix {
-/** All possible simcalls. */
-enum class Simcall {
- NONE,
- RUN_ANSWERED,
- RUN_BLOCKING,
-};
-constexpr int NUM_SIMCALLS = 3;
-} // namespace simix
-} // namespace simgrid
-
+namespace kernel {
+namespace actor {
/**
* @brief Represents a simcall to the kernel.
*/
-struct s_smx_simcall {
- simgrid::simix::Simcall call_ = simgrid::simix::Simcall::NONE;
+class Simcall {
+public:
+ /** All possible simcalls. */
+ XBT_DECLARE_ENUM_CLASS(Type, NONE, RUN_ANSWERED, RUN_BLOCKING);
+
+ Type call_ = Type::NONE;
smx_actor_t issuer_ = nullptr;
simgrid::kernel::timer::Timer* timeout_cb_ = nullptr; // Callback to timeouts
simgrid::kernel::actor::SimcallObserver* observer_ = nullptr; // makes that simcall observable by the MC
unsigned int mc_max_consider_ =
0; // How many times this simcall should be used. If >1, this will be a fork in the state space.
- std::function<void()> const* code_ = nullptr;
-};
+ std::function<void()> const* code_ = nullptr;
-/******************************** General *************************************/
+ const char* get_cname() const;
+};
-XBT_PRIVATE const char* SIMIX_simcall_name(const s_smx_simcall& simcall);
+} // namespace actor
+} // namespace kernel
+} // namespace simgrid
#endif
void Context::stop()
{
- this->actor_->cleanup();
+ this->actor_->cleanup_from_self();
}
void Context::set_wannadie(bool value)
std::function<void()> code_;
actor::ActorImpl* actor_ = nullptr;
- bool iwannadie_ = false;
+ bool iwannadie_ = false; // True if we need to do some cleanups in actor mode.
+ bool to_be_freed_ = false; // True if cleanups in actor mode done, but cleanups in kernel mode pending
bool is_maestro_;
void declare_context(std::size_t size);
bool wannadie() const { return iwannadie_; }
void set_wannadie(bool value = true);
+ bool to_be_freed() const { return to_be_freed_; }
+ void set_to_be_freed() { to_be_freed_ = true; }
bool is_maestro() const { return is_maestro_; }
void operator()() const { code_(); }
bool has_code() const { return static_cast<bool>(code_); }
--- /dev/null
+/* Copyright (c) 2007-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. */
+
+#include "src/kernel/lmm/bmf.hpp"
+#include <Eigen/LU>
+#include <iostream>
+#include <numeric>
+#include <sstream>
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(ker_bmf, kernel, "Kernel BMF solver");
+
+int sg_bmf_max_iterations = 1000; /* Change this with --cfg=bmf/max-iterations:VALUE */
+
+namespace simgrid {
+namespace kernel {
+namespace lmm {
+
+AllocationGenerator::AllocationGenerator(Eigen::MatrixXd A) : A_(std::move(A)), alloc_(A_.cols(), 0)
+{
+ // got a first valid allocation
+ for (size_t p = 0; p < alloc_.size(); p++) {
+ for (int r = 0; r < A_.rows(); r++) {
+ if (A_(r, p) > 0) {
+ alloc_[p] = r;
+ break;
+ }
+ }
+ }
+}
+
+bool AllocationGenerator::next(std::vector<int>& next_alloc)
+{
+ if (first_) {
+ next_alloc = alloc_;
+ first_ = false;
+ return true;
+ }
+
+ auto n_resources = A_.rows();
+ size_t idx = 0;
+ while (idx < alloc_.size()) {
+ alloc_[idx] = (alloc_[idx] + 1) % n_resources;
+ if (alloc_[idx] == 0) {
+ idx++;
+ continue;
+ } else {
+ idx = 0;
+ }
+ if (A_(alloc_[idx], idx) > 0) {
+ next_alloc = alloc_;
+ return true;
+ }
+ }
+ return false;
+}
+
+/*****************************************************************************/
+
+BmfSolver::BmfSolver(Eigen::MatrixXd A, Eigen::MatrixXd maxA, Eigen::VectorXd C, std::vector<bool> shared,
+ Eigen::VectorXd phi)
+ : A_(std::move(A))
+ , maxA_(std::move(maxA))
+ , C_(std::move(C))
+ , C_shared_(std::move(shared))
+ , phi_(std::move(phi))
+ , gen_(A_)
+{
+ xbt_assert(max_iteration_ > 0,
+ "Invalid number of iterations for BMF solver. Please check your \"bmf/max-iterations\" configuration.");
+ xbt_assert(A_.cols() == maxA_.cols(), "Invalid number of cols in matrix A (%td) or maxA (%td)", A_.cols(),
+ maxA_.cols());
+ xbt_assert(A_.cols() == phi_.size(), "Invalid size of phi vector (%td)", phi_.size());
+ xbt_assert(static_cast<long>(C_shared_.size()) == C_.size(), "Invalid size param shared (%zu)", C_shared_.size());
+}
+
+template <typename T> std::string BmfSolver::debug_eigen(const T& obj) const
+{
+ std::stringstream debug;
+ debug << obj;
+ return debug.str();
+}
+
+template <typename C> std::string BmfSolver::debug_vector(const C& container) const
+{
+ std::stringstream debug;
+ std::copy(container.begin(), container.end(),
+ std::ostream_iterator<typename std::remove_reference<decltype(container)>::type::value_type>(debug, " "));
+ return debug.str();
+}
+
+std::string BmfSolver::debug_alloc(const allocation_map_t& alloc) const
+{
+ std::stringstream debug;
+ for (const auto& e : alloc) {
+ debug << "{" + std::to_string(e.first) + ": [" + debug_vector(e.second) + "]}, ";
+ }
+ return debug.str();
+}
+
+double BmfSolver::get_resource_capacity(int resource, const std::vector<int>& bounded_players) const
+{
+ double capacity = C_[resource];
+ if (not C_shared_[resource])
+ return capacity;
+
+ for (int p : bounded_players) {
+ capacity -= A_(resource, p) * phi_[p];
+ }
+ return std::max(0.0, capacity);
+}
+
+std::vector<int> BmfSolver::alloc_map_to_vector(const allocation_map_t& alloc) const
+{
+ std::vector<int> alloc_by_player(A_.cols(), -1);
+ for (const auto& it : alloc) {
+ for (auto p : it.second) {
+ alloc_by_player[p] = it.first;
+ }
+ }
+ return alloc_by_player;
+}
+
+std::vector<int> BmfSolver::get_bounded_players(const allocation_map_t& alloc) const
+{
+ std::vector<int> bounded_players;
+ for (const auto& e : alloc) {
+ if (e.first == NO_RESOURCE) {
+ bounded_players.insert(bounded_players.end(), e.second.begin(), e.second.end());
+ }
+ }
+ return bounded_players;
+}
+
+Eigen::VectorXd BmfSolver::equilibrium(const allocation_map_t& alloc) const
+{
+ auto n_players = A_.cols();
+ Eigen::MatrixXd A_p = Eigen::MatrixXd::Zero(n_players, n_players); // square matrix with number of players
+ Eigen::VectorXd C_p = Eigen::VectorXd::Zero(n_players);
+
+ int row = 0;
+ auto bounded_players = get_bounded_players(alloc);
+ for (const auto& e : alloc) {
+ // add one row for the resource with A[r,]
+ int cur_resource = e.first;
+ /* bounded players, nothing to do */
+ if (cur_resource == NO_RESOURCE)
+ continue;
+ /* not shared resource, each player can receive the full capacity of the resource */
+ if (not C_shared_[cur_resource]) {
+ for (int i : e.second) {
+ C_p[row] = get_resource_capacity(cur_resource, bounded_players);
+ A_p(row, i) = A_(cur_resource, i);
+ row++;
+ }
+ continue;
+ }
+
+ /* shared resource: fairly share it between players */
+ A_p.row(row) = A_.row(cur_resource);
+ C_p[row] = get_resource_capacity(cur_resource, bounded_players);
+ row++;
+ if (e.second.size() > 1) {
+ // if 2 players have chosen the same resource
+ // they must have a fair sharing of this resource, adjust A_p and C_p accordingly
+ auto it = e.second.begin();
+ int i = *it; // first player
+ /* for each other player sharing this resource */
+ for (++it; it != e.second.end(); ++it) {
+ /* player i and k on this resource j: so maxA_ji*rho_i - maxA_jk*rho_k = 0 */
+ int k = *it;
+ C_p[row] = 0;
+ A_p(row, i) = maxA_(cur_resource, i);
+ A_p(row, k) = -maxA_(cur_resource, k);
+ row++;
+ }
+ }
+ }
+ /* clear players which are externally bounded */
+ for (int p : bounded_players) {
+ A_p.col(p).setZero();
+ }
+
+ XBT_DEBUG("A':\n%s", debug_eigen(A_p).c_str());
+
+ XBT_DEBUG("C':\n%s", debug_eigen(C_p).c_str());
+ /* PartialPivLU is much faster than FullPivLU but requires that the matrix is invertible
+ * FullPivLU however assures that it finds come solution even if the matrix is singular
+ * Ideally we would like to be optimist and try Partial and in case of error, go back
+ * to FullPivLU.
+ * However, this with isNaN doesn't work if compiler uses -Ofastmath. In our case,
+ * the icc compiler raises an error when compiling the code (comparison with NaN always evaluates to false in fast
+ * floating point modes).
+ * Eigen::VectorXd rho = Eigen::PartialPivLU<Eigen::MatrixXd>(A_p).solve(C_p);
+ * if (rho.array().isNaN().any()) {
+ * XBT_DEBUG("rho with nan values, falling back to FullPivLU, rho:\n%s", debug_eigen(rho).c_str());
+ * rho = Eigen::FullPivLU<Eigen::MatrixXd>(A_p).solve(C_p);
+ * }
+ */
+
+ Eigen::VectorXd rho = Eigen::FullPivLU<Eigen::MatrixXd>(A_p).solve(C_p);
+ for (int p : bounded_players) {
+ rho[p] = phi_[p];
+ }
+ return rho;
+}
+
+bool BmfSolver::disturb_allocation(allocation_map_t& alloc, std::vector<int>& alloc_by_player)
+{
+ while (gen_.next(alloc_by_player)) {
+ if (allocations_.find(alloc_by_player) == allocations_.end()) {
+ allocations_.clear();
+ allocations_.insert(alloc_by_player);
+ alloc.clear();
+ for (size_t p = 0; p < alloc_by_player.size(); p++) {
+ alloc[alloc_by_player[p]].insert(p);
+ }
+ return false;
+ }
+ }
+ return true;
+}
+
+bool BmfSolver::get_alloc(const Eigen::VectorXd& fair_sharing, const allocation_map_t& last_alloc,
+ allocation_map_t& alloc, bool initial)
+{
+ alloc.clear();
+ for (int player_idx = 0; player_idx < A_.cols(); player_idx++) {
+ int selected_resource = NO_RESOURCE;
+ double bound = phi_[player_idx];
+ double min_share = (bound <= 0 || initial) ? -1 : bound;
+ for (int cnst_idx = 0; cnst_idx < A_.rows(); cnst_idx++) {
+ if (A_(cnst_idx, player_idx) <= 0.0)
+ continue;
+
+ double share = fair_sharing[cnst_idx] / A_(cnst_idx, player_idx);
+ if (min_share == -1 || share < min_share) {
+ selected_resource = cnst_idx;
+ min_share = share;
+ }
+ }
+ alloc[selected_resource].insert(player_idx);
+ }
+ bool is_stable = (alloc == last_alloc);
+ if (is_stable)
+ return true;
+
+ std::vector<int> alloc_by_player = alloc_map_to_vector(alloc);
+ auto ret = allocations_.insert(alloc_by_player);
+ /* oops, allocation already tried, let's pertube it a bit */
+ if (not ret.second) {
+ XBT_DEBUG("Allocation already tried: %s", debug_alloc(alloc).c_str());
+ return disturb_allocation(alloc, alloc_by_player);
+ }
+ return false;
+}
+
+void BmfSolver::set_fair_sharing(const allocation_map_t& alloc, const Eigen::VectorXd& rho,
+ Eigen::VectorXd& fair_sharing) const
+{
+ std::vector<int> bounded_players = get_bounded_players(alloc);
+
+ for (int r = 0; r < fair_sharing.size(); r++) {
+ auto it = alloc.find(r);
+ if (it != alloc.end()) { // resource selected by some player, fair share depends on rho
+ int player = *(it->second.begin()); // equilibrium assures that every player receives the same, use one of them to
+ // calculate the fair sharing for resource r
+ fair_sharing[r] = A_(r, player) * rho[player];
+ } else { // nobody selects this resource, fair_sharing depends on resource saturation
+ // resource r is saturated (A[r,*] * rho > C), divide it among players
+ double consumption_r = A_.row(r) * rho;
+ double_update(&consumption_r, C_[r], sg_maxmin_precision);
+ if (consumption_r > 0.0) {
+ auto n_players = (A_.row(r).array() > 0).count();
+ fair_sharing[r] = C_[r] / n_players;
+ } else {
+ fair_sharing[r] = get_resource_capacity(r, bounded_players);
+ }
+ }
+ }
+}
+
+bool BmfSolver::is_bmf(const Eigen::VectorXd& rho) const
+{
+ bool bmf = true;
+
+ // 1) the capacity of all resources is respected
+ Eigen::VectorXd shared(C_shared_.size());
+ for (int j = 0; j < shared.size(); j++)
+ shared[j] = C_shared_[j] ? 1.0 : 0.0;
+
+ Eigen::VectorXd remaining = (A_ * rho) - C_;
+ remaining = remaining.array() * shared.array(); // ignore non shared resources
+ bmf = bmf && (not std::any_of(remaining.data(), remaining.data() + remaining.size(),
+ [](double v) { return double_positive(v, sg_maxmin_precision); }));
+
+ // 3) every player receives maximum share in at least 1 saturated resource
+ // due to subflows, compare with the maximum consumption and not the A matrix
+ Eigen::MatrixXd usage =
+ maxA_.array().rowwise() * rho.transpose().array(); // usage_ji: indicates the usage of player i on resource j
+
+ XBT_DEBUG("Usage_ji considering max consumption:\n%s", debug_eigen(usage).c_str());
+ auto max_share = usage.rowwise().maxCoeff(); // max share for each resource j
+
+ // matrix_ji: boolean indicating player p has the maximum share at resource j
+ Eigen::MatrixXi player_max_share =
+ ((usage.array().colwise() - max_share.array()).abs() <= sg_maxmin_precision).cast<int>();
+ // but only saturated resources must be considered
+ Eigen::VectorXi saturated = (remaining.array().abs() <= sg_maxmin_precision).cast<int>();
+ XBT_DEBUG("Saturated_j resources:\n%s", debug_eigen(saturated).c_str());
+ player_max_share.array().colwise() *= saturated.array();
+
+ // just check if it has received at least it's bound
+ for (int p = 0; p < rho.size(); p++) {
+ if (double_equals(rho[p], phi_[p], sg_maxmin_precision)) {
+ player_max_share(0, p) = 1; // it doesn't really matter, just to say that it's a bmf
+ saturated[0] = 1;
+ }
+ }
+
+ // 2) at least 1 resource is saturated
+ bmf = bmf && (saturated.array() == 1).any();
+
+ XBT_DEBUG("Player_ji usage of saturated resources:\n%s", debug_eigen(player_max_share).c_str());
+ // for all columns(players) it has to be the max at least in 1
+ bmf = bmf && (player_max_share.colwise().sum().array() >= 1).all();
+ return bmf;
+}
+
+Eigen::VectorXd BmfSolver::solve()
+{
+ XBT_DEBUG("Starting BMF solver");
+
+ XBT_DEBUG("A:\n%s", debug_eigen(A_).c_str());
+ XBT_DEBUG("maxA:\n%s", debug_eigen(maxA_).c_str());
+ XBT_DEBUG("C:\n%s", debug_eigen(C_).c_str());
+
+ /* no flows to share, just returns */
+ if (A_.cols() == 0)
+ return {};
+
+ int it = 0;
+ auto fair_sharing = C_;
+
+ /* BMF allocation for each player (current and last one) stop when are equal */
+ allocation_map_t last_alloc;
+ allocation_map_t cur_alloc;
+ Eigen::VectorXd rho;
+
+ while (it < max_iteration_ && not get_alloc(fair_sharing, last_alloc, cur_alloc, it == 0)) {
+ last_alloc = cur_alloc;
+ XBT_DEBUG("BMF: iteration %d", it);
+ XBT_DEBUG("B (current allocation): %s", debug_alloc(cur_alloc).c_str());
+
+ // solve inv(A)*rho = C
+ rho = equilibrium(cur_alloc);
+ XBT_DEBUG("rho:\n%s", debug_eigen(rho).c_str());
+
+ // get fair sharing for each resource
+ set_fair_sharing(cur_alloc, rho, fair_sharing);
+ XBT_DEBUG("Fair sharing vector (per resource):\n%s", debug_eigen(fair_sharing).c_str());
+
+ // get new allocation for players
+ it++;
+ }
+
+ /* Not mandatory but a safe check to assure we have a proper solution */
+ if (not is_bmf(rho)) {
+ fprintf(stderr, "Unable to find a BMF allocation for your system.\n"
+ "You may try to increase the maximum number of iterations performed by BMF solver "
+ "(\"--cfg=bmf/max-iterations\").\n"
+ "Additionally, you could decrease numerical precision (\"--cfg=surf/precision\").\n");
+ fprintf(stderr, "Internal states (after %d iterations):\n", it);
+ fprintf(stderr, "A:\n%s\n", debug_eigen(A_).c_str());
+ fprintf(stderr, "maxA:\n%s\n", debug_eigen(maxA_).c_str());
+ fprintf(stderr, "C:\n%s\n", debug_eigen(C_).c_str());
+ fprintf(stderr, "C_shared:\n%s\n", debug_vector(C_shared_).c_str());
+ fprintf(stderr, "phi:\n%s\n", debug_eigen(phi_).c_str());
+ fprintf(stderr, "rho:\n%s\n", debug_eigen(rho).c_str());
+ xbt_abort();
+ }
+
+ XBT_DEBUG("BMF done after %d iterations", it);
+ return rho;
+}
+
+/*****************************************************************************/
+
+void BmfSystem::get_flows_data(Eigen::Index number_cnsts, Eigen::MatrixXd& A, Eigen::MatrixXd& maxA,
+ Eigen::VectorXd& phi)
+{
+ A.resize(number_cnsts, variable_set.size());
+ A.setZero();
+ maxA.resize(number_cnsts, variable_set.size());
+ maxA.setZero();
+ phi.resize(variable_set.size());
+
+ int var_idx = 0;
+ for (Variable& var : variable_set) {
+ if (var.sharing_penalty_ <= 0)
+ continue;
+ bool active = false;
+ bool linked = false; // variable is linked to some constraint (specially for selective_update)
+ for (const Element& elem : var.cnsts_) {
+ const boost::intrusive::list_member_hook<>& cnst_hook = selective_update_active
+ ? elem.constraint->modified_constraint_set_hook_
+ : elem.constraint->active_constraint_set_hook_;
+ if (not cnst_hook.is_linked())
+ continue;
+ /* active and linked variable, lets check its consumption */
+ linked = true;
+ double consumption = elem.consumption_weight;
+ if (consumption > 0) {
+ int cnst_idx = cnst2idx_[elem.constraint];
+ A(cnst_idx, var_idx) += consumption;
+ // a variable with double penalty must receive half share, so it max weight is greater
+ maxA(cnst_idx, var_idx) = std::max(maxA(cnst_idx, var_idx), elem.max_consumption_weight * var.sharing_penalty_);
+ active = true;
+ }
+ }
+ /* skip variables not linked to any modified or active constraint */
+ if (not linked)
+ continue;
+ if (active) {
+ phi[var_idx] = var.get_bound();
+ idx2Var_[var_idx] = &var;
+ var_idx++;
+ } else {
+ var.value_ = 1; // assign something by default for tasks with 0 consumption
+ }
+ }
+ // resize matrix to active variables only
+ A.conservativeResize(Eigen::NoChange_t::NoChange, var_idx);
+ maxA.conservativeResize(Eigen::NoChange_t::NoChange, var_idx);
+ phi.conservativeResize(var_idx);
+}
+
+template <class CnstList>
+void BmfSystem::get_constraint_data(const CnstList& cnst_list, Eigen::VectorXd& C, std::vector<bool>& shared)
+{
+ C.resize(cnst_list.size());
+ shared.resize(cnst_list.size());
+ cnst2idx_.clear();
+ int cnst_idx = 0;
+ for (const Constraint& cnst : cnst_list) {
+ C(cnst_idx) = cnst.bound_;
+ if (cnst.get_sharing_policy() == Constraint::SharingPolicy::NONLINEAR && cnst.dyn_constraint_cb_) {
+ C(cnst_idx) = cnst.dyn_constraint_cb_(cnst.bound_, cnst.concurrency_current_);
+ if (not warned_nonlinear_) {
+ XBT_WARN("You are using dynamic constraint bound with parallel tasks and BMF model."
+ " The BMF solver assumes that all flows (and subflows) are always active and executing."
+ " This is quite pessimist, specially considering parallel tasks with small subflows."
+ " Analyze your results with caution.");
+ warned_nonlinear_ = true;
+ }
+ }
+ cnst2idx_[&cnst] = cnst_idx;
+ // FATPIPE links aren't really shared
+ shared[cnst_idx] = (cnst.sharing_policy_ != Constraint::SharingPolicy::FATPIPE);
+ cnst_idx++;
+ }
+}
+
+void BmfSystem::solve()
+{
+ if (modified_) {
+ if (selective_update_active)
+ bmf_solve(modified_constraint_set);
+ else
+ bmf_solve(active_constraint_set);
+ }
+}
+
+template <class CnstList> void BmfSystem::bmf_solve(const CnstList& cnst_list)
+{
+ /* initialize players' weight and constraint matrices */
+ idx2Var_.clear();
+ cnst2idx_.clear();
+ Eigen::MatrixXd A;
+ Eigen::MatrixXd maxA;
+ Eigen::VectorXd C;
+ Eigen::VectorXd bounds;
+ std::vector<bool> shared;
+ get_constraint_data(cnst_list, C, shared);
+ get_flows_data(C.size(), A, maxA, bounds);
+
+ auto solver = BmfSolver(std::move(A), std::move(maxA), std::move(C), std::move(shared), std::move(bounds));
+ auto rho = solver.solve();
+
+ if (rho.size() == 0)
+ return;
+
+ /* setting rhos */
+ for (int i = 0; i < rho.size(); i++) {
+ idx2Var_[i]->value_ = rho[i];
+ }
+
+ print();
+}
+
+} // namespace lmm
+} // namespace kernel
+} // namespace simgrid
--- /dev/null
+/* Copyright (c) 2004-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. */
+
+#ifndef SURF_BMF_HPP
+#define SURF_BMF_HPP
+
+#include "src/kernel/lmm/maxmin.hpp"
+#include <Eigen/Dense>
+#include <unordered_set>
+
+namespace simgrid {
+namespace kernel {
+namespace lmm {
+
+/** @brief Generate all combinations of valid allocation */
+class XBT_PUBLIC AllocationGenerator {
+public:
+ explicit AllocationGenerator(Eigen::MatrixXd A);
+
+ /**
+ * @brief Get next valid allocation
+ *
+ * @param next_alloc Allocation (OUTPUT)
+ * @return true if there's an allocation not tested yet, false otherwise
+ */
+ bool next(std::vector<int>& next_alloc);
+
+private:
+ Eigen::MatrixXd A_;
+ std::vector<int> alloc_;
+ bool first_ = true;
+};
+
+/**
+ * @beginrst
+ *
+ * Despite the simplicity of BMF fairness definition, it's quite hard to
+ * find a BMF allocation in the general case.
+ *
+ * This solver implements one possible algorithm to find a BMF, as proposed
+ * at: https://hal.archives-ouvertes.fr/hal-01552739.
+ *
+ * The idea of this algorithm is that each player/flow "selects" a resource to
+ * saturate. Then, we calculate the rate each flow would have with this allocation.
+ * If the allocation is a valid BMF and no one needs to move, it's over. Otherwise,
+ * each player selects a new resource to saturate based on the minimim rate possible
+ * between all resources.
+ *
+ * The steps:
+ * 1) Given an initial allocation B_i
+ * 2) Build a matrix A'_ji and C'_ji which assures that the player receives the most
+ * share at selected resources
+ * 3) Solve: A'_ji * rho_i = C'_j
+ * 4) Calculate the minimum fair rate for each resource j: f_j. The f_j represents
+ * the maximum each flow can receive at the resource j.
+ * 5) Builds a new vector B'_i = arg min(f_j/A_ji).
+ * 6) Stop if B == B' (nobody needs to move), go to step 2 otherwise
+ *
+ * Despite the overall good performance of this algorithm, which converges in a few
+ * iterations, we don't have any assurance about its convergence. In the worst case,
+ * it may be needed to test all possible combination of allocations (which is exponential).
+ *
+ * @endrst
+ */
+class XBT_PUBLIC BmfSolver {
+public:
+ /**
+ * @brief Instantiate the BMF solver
+ *
+ * @param A A_ji: consumption of player i on resource j
+ * @param maxA maxA_ji: consumption of larger player i on resource j
+ * @param C Resource capacity
+ * @param shared Is resource shared between player or each player receives the full capacity (FATPIPE links)
+ * @param phi Bound for each player
+ */
+ BmfSolver(Eigen::MatrixXd A, Eigen::MatrixXd maxA, Eigen::VectorXd C, std::vector<bool> shared, Eigen::VectorXd phi);
+ /** @brief Solve equation system to find a fair-sharing of resources */
+ Eigen::VectorXd solve();
+
+private:
+ using allocation_map_t = std::unordered_map<int, std::unordered_set<int>>;
+ /**
+ * @brief Get actual resource capacity considering bounded players
+ *
+ * Calculates the resource capacity considering that some players on it may be bounded by user,
+ * i.e. an explicit limit in speed was configured
+ *
+ * @param resource Internal index of resource in C_ vector
+ * @param bounded_players List of players that are externally bounded
+ * @return Actual resource capacity
+ */
+ double get_resource_capacity(int resource, const std::vector<int>& bounded_players) const;
+ /**
+ * @brief Auxiliary method to get list of bounded player from allocation
+ *
+ * @param alloc Current allocation
+ * @return list of bounded players
+ */
+ std::vector<int> get_bounded_players(const allocation_map_t& alloc) const;
+
+ /**
+ * @brief Given an allocation calculates the speed/rho for each player
+ *
+ * Do the magic!!
+ * Builds 2 auxiliares matrices A' and C' and solves the system: rho_i = inv(A'_ji) * C'_j
+ *
+ * All resources in A' and C' are saturated, i.e., sum(A'_j * rho_i) = C'_j.
+ *
+ * The matrix A' is built as follows:
+ * - For each resource j in alloc: copy row A_j to A'
+ * - If 2 players (i, k) share a same resource, assure fairness by adding a row in A' such as:
+ * - A_ji*rho_i - Ajk*rho_j = 0
+ *
+ * @param alloc for each resource, players that chose to saturate it
+ * @return Vector rho with "players' speed"
+ */
+ Eigen::VectorXd equilibrium(const allocation_map_t& alloc) const;
+
+ /**
+ * @brief Given a fair_sharing vector, gets the allocation
+ *
+ * The allocation for player i is given by: min(bound, f_j/A_ji).
+ * The minimum between all fair-sharing and the external bound (if any)
+ *
+ * The algorithm dictates a random initial allocation. For simplicity, we opt to use the same
+ * logic with the fair_sharing vector.
+ *
+ * @param fair_sharing Fair sharing vector
+ * @param initial Is this the initial allocation?
+ * @return allocation vector
+ */
+ bool get_alloc(const Eigen::VectorXd& fair_sharing, const allocation_map_t& last_alloc, allocation_map_t& alloc,
+ bool initial);
+
+ bool disturb_allocation(allocation_map_t& alloc, std::vector<int>& alloc_by_player);
+ /**
+ * @brief Calculates the fair sharing for each resource
+ *
+ * Basically 3 options:
+ * 1) resource in allocation: A_ji*rho_i since all players who selected this resource have the same share
+ * 2) resource not selected by saturated (fully used): divide it by the number of players C_/n_players
+ * 3) resource not selected and not-saturated: no limitation
+ *
+ * @param alloc Allocation map (resource-> players)
+ * @param rho Speed for each player i
+ * @param fair_sharing Output vector, fair sharing for each resource j
+ */
+ void set_fair_sharing(const allocation_map_t& alloc, const Eigen::VectorXd& rho, Eigen::VectorXd& fair_sharing) const;
+
+ /**
+ * @brief Check if allocation is BMF
+ *
+ * To be a bmf allocation it must:
+ * - respect the capacity of all resources
+ * - saturate at least 1 resource
+ * - every player receives maximum share in at least 1 saturated resource
+ * @param rho Allocation
+ * @return true if BMF false otherwise
+ */
+ bool is_bmf(const Eigen::VectorXd& rho) const;
+ std::vector<int> alloc_map_to_vector(const allocation_map_t& alloc) const;
+
+ /**
+ * @brief Set of debug functions to print the different objects
+ */
+ template <typename T> std::string debug_eigen(const T& obj) const;
+ template <typename C> std::string debug_vector(const C& container) const;
+ std::string debug_alloc(const allocation_map_t& alloc) const;
+
+ Eigen::MatrixXd A_; //!< A_ji: resource usage matrix, each row j represents a resource and col i a flow/player
+ Eigen::MatrixXd maxA_; //!< maxA_ji, similar as A_, but containing the maximum consumption of player i (if player a
+ //!< single flow it's equal to A_)
+ Eigen::VectorXd C_; //!< C_j Capacity of each resource
+ std::vector<bool> C_shared_; //!< shared_j Resource j is shared or not
+ Eigen::VectorXd phi_; //!< phi_i bound for each player
+
+ std::set<std::vector<int>> allocations_; //!< set of already tested allocations, since last identified loop
+ AllocationGenerator gen_;
+ std::vector<int> allocations_age_;
+ static constexpr int NO_RESOURCE = -1; //!< flag to indicate player has selected no resource
+ int max_iteration_ = sg_bmf_max_iterations; //!< number maximum of iterations of BMF algorithm
+};
+
+/**
+ * @beginrst
+ *
+ * A BMF (bottleneck max fairness) solver to resolve inequation systems.
+ *
+ * Usually, SimGrid relies on a *max-min fairness* solver to share the resources.
+ * Max-min is great when sharing homogenous resources, however it cannot be used with heterogeneous resources.
+ *
+ * BMF is a natural alternative to max-min, providing a fair-sharing of heterogeneous resources (CPU, network, disk).
+ * It is specially relevant for the implementation of parallel tasks whose sharing involves different
+ * kinds of resources.
+ *
+ * BMF assures that every flow receives the maximum share possible in at least 1 bottleneck (fully used) resource.
+ *
+ * The BMF is characterized by:
+ * - A_ji: a matrix of requirement for flows/player. For each resource j, and flow i, A_ji represents the utilization
+ * of resource j for 1 unit of the flow i.
+ * - rho_i: the rate allocated for flow i (same among all resources)
+ * - C_j: the capacity of each resource (can be bytes/s, flops/s, etc)
+ *
+ * Therefore, these conditions need to satisfied to an allocation be considered a BMF:
+ * 1) All constraints are respected (flows cannot use more than the resource has available)
+ * - for all resource j and player i: A_ji * rho_i <= C_j
+ * 2) At least 1 resource is fully used (bottleneck).
+ * - for some resource j: A_ji * rho_i = C_j
+ * 3) Each flow (player) receives the maximum share in at least 1 bottleneck.
+ * - for all player i: exist a resource j: A_ji * rho_i >= A_jk * rho_k for all other player k
+ *
+ * Despite the prove of existence of a BMF allocation in the general case, it may not
+ * be unique, which leads to possible different rate for the applications.
+ *
+ * More details about BMF can be found at: https://hal.inria.fr/hal-01243985/document
+ *
+ * @endrst
+ */
+/**
+ * @brief Bottleneck max-fair system
+ */
+class XBT_PUBLIC BmfSystem : public System {
+public:
+ using System::System;
+ /** @brief Implements the solve method to calculate a BMF allocation */
+ void solve() final;
+
+private:
+ using allocation_map_t = std::unordered_map<int, std::unordered_set<int>>;
+ /**
+ * @brief Solve equation system to find a fair-sharing of resources
+ *
+ * @param cnst_list Constraint list (modified for selective update or active)
+ */
+ template <class CnstList> void bmf_solve(const CnstList& cnst_list);
+ /**
+ * @brief Iterates over system and build the consumption matrix A_ji and maxA_ji
+ *
+ * Each row j represents a resource and each col i a player/flow
+ *
+ * Considers only active variables to build the matrix.
+ *
+ * @param number_cnsts Number of constraints in the system
+ * @param A Consumption matrix (OUTPUT)
+ * @param maxA Max subflow consumption matrix (OUTPUT)
+ * @param phi Bounds for variables
+ */
+ void get_flows_data(Eigen::Index number_cnsts, Eigen::MatrixXd& A, Eigen::MatrixXd& maxA, Eigen::VectorXd& phi);
+ /**
+ * @brief Builds the vector C_ with resource's capacity
+ *
+ * @param cnst_list Constraint list (modified for selective update or active)
+ * @param C Resource capacity vector
+ * @param shared Resource is shared or not (fatpipe links)
+ */
+ template <class CnstList>
+ void get_constraint_data(const CnstList& cnst_list, Eigen::VectorXd& C, std::vector<bool>& shared);
+
+ std::unordered_map<int, Variable*> idx2Var_; //!< Map player index (and position in matrices) to system's variable
+ std::unordered_map<const Constraint*, int> cnst2idx_; //!< Conversely map constraint to index
+ bool warned_nonlinear_ = false;
+};
+
+} // namespace lmm
+} // namespace kernel
+} // namespace simgrid
+
+#endif
--- /dev/null
+/* Copyright (c) 2019-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. */
+
+#include "src/include/catch.hpp"
+#include "src/kernel/lmm/bmf.hpp"
+#include "src/surf/surf_interface.hpp"
+#include "xbt/log.h"
+
+namespace lmm = simgrid::kernel::lmm;
+
+TEST_CASE("kernel::bmf Basic tests", "[kernel-bmf-basic]")
+{
+ lmm::BmfSystem Sys(false);
+ xbt_log_control_set("ker_bmf.thres:debug");
+
+ SECTION("Single flow")
+ {
+ /*
+ * A single variable using a single resource
+ *
+ * In details:
+ * o System: a1 * p1 * \rho1 < C
+ * o consumption_weight: a1=1
+ * o sharing_penalty: p1=1
+ *
+ * Expectations
+ * o rho1 = C
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 3);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), 3, sg_maxmin_precision));
+ }
+
+ SECTION("Two flows")
+ {
+ /*
+ * Two flows sharing a single resource
+ *
+ * In details:
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C
+ * o consumption_weight: a1=1 ; a2=10
+ * o sharing_penalty: p1=1 ; p2=1
+ *
+ * Expectations
+ * o a1*rho1 = C/2
+ * o a2*rho2 = C/2
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 3);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1);
+
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst, rho_2, 10);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), 3.0 / 2.0, sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), (3.0 / 2.0) / 10.0, sg_maxmin_precision));
+ }
+
+ SECTION("Variable penalty/priority")
+ {
+ /*
+ * A variable with twice the penalty gets half of the share
+ *
+ * In details:
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C
+ * o consumption_weight: a1=1 ; a2=1
+ * o sharing_penalty: p1=1 ; p2=2
+ *
+ * Expectations
+ * o rho1 = 2* rho2 (because rho2 has twice the penalty)
+ * o rho1 + rho2 = C (because all weights are 1)
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 1);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 2);
+
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst, rho_2, 1);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), 2.0 / 3.0, sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), 1.0 / 3.0, sg_maxmin_precision));
+ }
+
+ SECTION("Disable variable doesn't count")
+ {
+ /*
+ * Two flows sharing a single resource, but one is disabled
+ *
+ * In details:
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C
+ * o consumption_weight: a1=1 ; a2=10
+ * o sharing_penalty: p1=1 ; p2=0
+ *
+ * Expectations
+ * o a1*rho1 = C
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 1);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 0);
+
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst, rho_2, 10);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), 1.0, sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), 0.0, sg_maxmin_precision));
+ }
+
+ SECTION("No consumption variable")
+ {
+ /*
+ * An empty variable, no consumption, just assure it receives something
+ *
+ * o System: a1 * p1 * \rho1 < C
+ * o consumption_weight: a1=0
+ * o sharing_penalty: p1=1
+ *
+ * Expectations
+ * o rho1 > 0
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 3);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 0);
+
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst, rho_2, 10);
+ Sys.solve();
+
+ REQUIRE(double_positive(rho_1->get_value(), sg_maxmin_precision));
+ }
+
+ SECTION("Bounded variable")
+ {
+ /*
+ * Assures a player receives the min(bound, share) if it's bounded
+ *
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C
+ * o bounds: b1=0.1, b2=-1
+ * o consumption_weight: a1=1, a2=1
+ * o sharing_penalty: p1=1, p2=1
+ *
+ * Expectations
+ * o rho1 = .1
+ * o rho2 = .8
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 1);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, .1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1);
+
+ Sys.expand(sys_cnst, rho_1, 2);
+ Sys.expand(sys_cnst, rho_2, 1);
+ Sys.solve();
+ REQUIRE(double_equals(rho_1->get_value(), .1, sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), .8, sg_maxmin_precision));
+ }
+
+ SECTION("Fatpipe")
+ {
+ /*
+ * Two flows using a fatpipe resource
+ *
+ * In details:
+ * o System: a1 * p1 * \rho1 < C and a2 * p2 * \rho2 < C
+ * o consumption_weight: a1=1 ; a2=1
+ * o sharing_penalty: p1=1 ; p2=1
+ *
+ * Expectations
+ * o a1*rho1 = C
+ * o a2*rho2 = C
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 3);
+ sys_cnst->set_sharing_policy(lmm::Constraint::SharingPolicy::FATPIPE, {});
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1);
+
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst, rho_2, 1);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), 3.0, sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), 3.0, sg_maxmin_precision));
+ }
+
+ SECTION("(un)Bounded variable")
+ {
+ /*
+ * Assures a player receives the share if bound is greater than share
+ *
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C
+ * o bounds: b1=1, b2=-1
+ * o consumption_weight: a1=1, a2=1
+ * o sharing_penalty: p1=1, p2=1
+ *
+ * Expectations
+ * o rho1 = .5
+ * o rho2 = .5
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 1);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1);
+
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst, rho_2, 1);
+ Sys.solve();
+ REQUIRE(double_equals(rho_1->get_value(), .5, sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), .5, sg_maxmin_precision));
+ }
+
+ SECTION("Dynamic bounds")
+ {
+ /*
+ * Resource bound is modified by user callback and shares are adapted accordingly
+ *
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C
+ * o consumption_weight: a1=1, a2=1
+ * o sharing_penalty: p1=1, p2=1
+ *
+ * Expectations
+ * o rho1 = .5 and .25
+ * o rho2 = - and .25
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 1);
+ sys_cnst->set_sharing_policy(lmm::Constraint::SharingPolicy::NONLINEAR,
+ [](double bound, int n) { return bound / n; });
+ // alone, full capacity
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.solve();
+ REQUIRE(double_equals(rho_1->get_value(), 1, sg_maxmin_precision));
+
+ // add another variable, half initial capacity
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1);
+ Sys.expand(sys_cnst, rho_2, 1);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), .25, sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), .25, sg_maxmin_precision));
+ }
+
+ Sys.variable_free_all();
+}
+
+TEST_CASE("kernel::bmf Advanced tests", "[kernel-bmf-advanced]")
+{
+ lmm::BmfSystem Sys(false);
+ xbt_log_control_set("ker_bmf.thres:debug");
+
+ SECTION("2 flows, 2 resources")
+ {
+ /*
+ * Two flows sharing 2 resources with opposite requirements
+ *
+ * In details:
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C1
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C2
+ * o C1 == C2
+ * o consumption_weight: a11=1, a12=10, a21=10, a22=1
+ * o sharing_penalty: p1=1, p2=1
+ *
+ * Expectations
+ * o rho1 = rho2 = C/11
+
+ * Matrices:
+ * [1 10] * [rho1 rho2] = [1]
+ * [10 1] [1]
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 1);
+ lmm::Constraint* sys_cnst2 = Sys.constraint_new(nullptr, 1);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, -1, 2);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1, -1, 2);
+
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst2, rho_1, 10);
+ Sys.expand(sys_cnst, rho_2, 10);
+ Sys.expand(sys_cnst2, rho_2, 1);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), 1.0 / 11.0, sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), 1.0 / 11.0, sg_maxmin_precision));
+ }
+
+ SECTION("BMF paper example")
+ {
+ /*
+ * 3 flows sharing 3 resources
+ *
+ * In details:
+ * [1 1 1/2] * [rho1 rho2 rho3] = [1]
+ * [1 1/2 1 ] [1]
+ * [1 3/4 3/4] [1]
+ *
+ * Expectations (several possible BMF allocations, our algorithm return this)
+ * o rho1 = rho2 = rho3 = 2/5
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 1);
+ lmm::Constraint* sys_cnst2 = Sys.constraint_new(nullptr, 1);
+ lmm::Constraint* sys_cnst3 = Sys.constraint_new(nullptr, 1);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, -1, 3);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1, -1, 3);
+ lmm::Variable* rho_3 = Sys.variable_new(nullptr, 1, -1, 3);
+
+ Sys.expand(sys_cnst3, rho_1, 1.0); // put this expand first to force a singular A' matrix
+ Sys.expand(sys_cnst, rho_1, 1.0);
+ Sys.expand(sys_cnst2, rho_1, 1.0);
+ Sys.expand(sys_cnst, rho_2, 1.0);
+ Sys.expand(sys_cnst2, rho_2, 1.0 / 2.0);
+ Sys.expand(sys_cnst3, rho_2, 3.0 / 4.0);
+ Sys.expand(sys_cnst, rho_3, 1.0 / 2.0);
+ Sys.expand(sys_cnst2, rho_3, 1.0);
+ Sys.expand(sys_cnst3, rho_3, 3.0 / 4.0);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), 1.0 / 3.0, sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), 4.0 / 9.0, sg_maxmin_precision));
+ REQUIRE(double_equals(rho_3->get_value(), 4.0 / 9.0, sg_maxmin_precision));
+ }
+
+ SECTION("IO - example")
+ {
+ /*
+ * Two flows sharing 1 disk
+ * read, write and readwrite constraint
+ *
+ * In details:
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C1
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C2
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C3
+ * o C1 == C2 == C3
+ * o consumption_weight: a1=1, a2=1
+ * o sharing_penalty: p1=1, p2=1
+ *
+ * Expectations
+ * o rho1 = rho2 = C/2
+
+ * Matrices:
+ * [1 10] * [rho1 rho2] = [1]
+ * [10 1] [1]
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 1e6);
+ lmm::Constraint* sys_cnst2 = Sys.constraint_new(nullptr, 1e6);
+ lmm::Constraint* sys_cnst3 = Sys.constraint_new(nullptr, 1e6);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, -1, 3);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1, -1, 3);
+
+ /* A' and C' matrices are dependent on the order of initialization
+ * this order is needed to identify a bug in the solver */
+ Sys.expand(sys_cnst2, rho_2, 1);
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst3, rho_1, 1);
+ Sys.expand(sys_cnst3, rho_2, 1);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), 1e6 / 2.0, sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), 1e6 / 2.0, sg_maxmin_precision));
+ }
+
+ SECTION("Proportional fairness")
+ {
+ /*
+ * 3 flows sharing 2 resources with crosstraffic
+ *
+ * Regular max-min would give B/2 for every flow.
+ * BMF is equivalent to proportional fairness in this case, and give a quite
+ * different sharing.
+ *
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 1);
+ lmm::Constraint* sys_cnst2 = Sys.constraint_new(nullptr, 1);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, -1, 2);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1, -1, 2);
+ lmm::Variable* rho_3 = Sys.variable_new(nullptr, 1, -1, 2);
+
+ double epsilon = 0.05;
+ Sys.expand(sys_cnst, rho_1, 1.0);
+ Sys.expand(sys_cnst2, rho_1, epsilon);
+ Sys.expand(sys_cnst, rho_2, 1.0);
+ Sys.expand(sys_cnst2, rho_2, epsilon);
+ Sys.expand(sys_cnst2, rho_3, 1.0);
+ Sys.expand(sys_cnst, rho_3, epsilon);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), 1.0 / (2.0 + 2 * epsilon), sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), 1.0 / (2.0 + 2 * epsilon), sg_maxmin_precision));
+ REQUIRE(double_equals(rho_3->get_value(), 1.0 / (1.0 + epsilon), sg_maxmin_precision));
+ }
+
+ Sys.variable_free_all();
+}
+
+TEST_CASE("kernel::bmf Subflows", "[kernel-bmf-subflow]")
+{
+ lmm::BmfSystem Sys(false);
+ xbt_log_control_set("ker_bmf.thres:debug");
+
+ SECTION("2 subflows and 1 resource")
+ {
+ /*
+ * 2 identical flows composed of 2 subflows
+ *
+ * They must receive the same share and use same amount of resources
+ *
+ * In details:
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C
+ * o consumption_weight: a11=5, a12=7, a2=7, a2=5
+ * o sharing_penalty: p1=1, p2=1
+ *
+ * Expectations
+ * o rho1 = rho2 = (C/2)/12
+
+ * Matrices:
+ * [12 12] * [rho1 rho2] = [1]
+ * [12 12] [0]
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 5);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1);
+
+ Sys.expand_add(sys_cnst, rho_1, 5);
+ Sys.expand_add(sys_cnst, rho_1, 7);
+ Sys.expand_add(sys_cnst, rho_2, 7);
+ Sys.expand_add(sys_cnst, rho_2, 5);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), 5.0 / 24.0, sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), 5.0 / 24.0, sg_maxmin_precision));
+ }
+
+ SECTION("1 subflows, 1 flow and 1 resource")
+ {
+ /*
+ * 2 flows, 1 resource
+ * 1 flow composed of 2 subflows
+ *
+ * Same share/rho, but subflow uses 50% more resources since it has a second connection/subflow
+ *
+ * In details:
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C
+ * o consumption_weight: a11=10, a12=5 a2=10
+ * o sharing_penalty: p1=1, p2=1
+ *
+ * Expectations
+ * o rho1 = (C/25)
+ * o rho2 = (C/25)
+
+ * Matrices:
+ * [15 10] * [rho1 rho2] = [1]
+ * [10 10] [0]
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 5);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1);
+
+ Sys.expand_add(sys_cnst, rho_1, 10);
+ Sys.expand_add(sys_cnst, rho_1, 5);
+ Sys.expand(sys_cnst, rho_2, 10);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), (5.0 / 25.0), sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), (5.0 / 25.0), sg_maxmin_precision));
+ REQUIRE(double_equals(15 * rho_1->get_value(), 10 * rho_2->get_value() * 3 / 2, sg_maxmin_precision));
+ }
+
+ SECTION("1 subflows using 2 resources: different max for each resource")
+ {
+ /*
+ * Test condition that we may have different max for different resources
+ *
+ * In details:
+ * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C
+ * o consumption_weight: a11=1, a12=1, a2=1
+ * o consumption_weight: a21=1/2, a12=1/2 a2=3/2
+ * o sharing_penalty: p1=1, p2=1
+ *
+ * Expectations
+ * o rho1 = (C1/3)
+ * o rho2 = (C1/3)
+
+ * Matrices:
+ * [2 1 ] * [rho1 rho2] = [1]
+ * [1 -1] [0]
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 1);
+ lmm::Constraint* sys_cnst2 = Sys.constraint_new(nullptr, 1);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, -1, 2);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1, -1, 2);
+
+ Sys.expand_add(sys_cnst, rho_1, 1.0);
+ Sys.expand_add(sys_cnst, rho_1, 1.0);
+ Sys.expand(sys_cnst, rho_2, 1);
+ Sys.expand_add(sys_cnst2, rho_1, 1.0 / 2.0);
+ Sys.expand_add(sys_cnst2, rho_1, 1.0 / 2.0);
+ Sys.expand(sys_cnst2, rho_2, 3.0 / 2.0);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), (1.0 / 3.0), sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), (1.0 / 3.0), sg_maxmin_precision));
+ }
+
+ Sys.variable_free_all();
+}
+
+TEST_CASE("kernel::bmf Loop", "[kernel-bmf-loop]")
+{
+ lmm::BmfSystem Sys(false);
+ xbt_log_control_set("ker_bmf.thres:debug");
+
+ SECTION("Initial allocation loops")
+ {
+ /*
+ * Complex matrix whose initial allocation loops and is unable
+ * to stabilize after 10 iterations.
+ *
+ * The algorithm needs to restart from another point
+ */
+
+ std::vector<double> C = {1.0, 1.0, 1.0, 1.0, 1.0};
+ std::vector<std::vector<double>> A = {
+ {0.0918589, 0.980201, 0.553352, 0.0471331, 0.397493, 0.0494386, 0.158874, 0.737557, 0.822504, 0.364411},
+ {0.852866, 0.383171, 0.924183, 0.318345, 0.937625, 0.980201, 0.0471331, 0.0494386, 0.737557, 0.364411},
+ {0.12043, 0.985661, 0.153195, 0.852866, 0.247113, 0.318345, 0.0918589, 0.0471331, 0.158874, 0.364411},
+ {0.387291, 0.159939, 0.641492, 0.985661, 0.0540999, 0.383171, 0.318345, 0.980201, 0.0494386, 0.364411},
+ {0.722983, 0.924512, 0.474874, 0.819576, 0.572598, 0.0540999, 0.247113, 0.937625, 0.397493, 0.364411}};
+
+ std::vector<lmm::Constraint*> sys_cnst;
+ for (auto c : C) {
+ sys_cnst.push_back(Sys.constraint_new(nullptr, c));
+ }
+ std::vector<lmm::Variable*> vars;
+ std::for_each(A[0].begin(), A[0].end(),
+ [&vars, &Sys, &A](const auto&) { vars.push_back(Sys.variable_new(nullptr, 1, -1, A.size())); });
+ for (size_t j = 0; j < A.size(); j++) {
+ for (size_t i = 0; i < A[j].size(); i++) {
+ Sys.expand_add(sys_cnst[j], vars[i], A[j][i]);
+ }
+ }
+ Sys.solve();
+
+ for (const auto* rho : vars) {
+ REQUIRE(double_positive(rho->get_value(), sg_maxmin_precision));
+ }
+ }
+
+ Sys.variable_free_all();
+}
+
+TEST_CASE("kernel::bmf Bugs", "[kernel-bmf-bug]")
+{
+ lmm::BmfSystem Sys(false);
+ xbt_log_control_set("ker_bmf.thres:debug");
+
+ SECTION("DadOu's bug: sum of bounds/phi greater than C")
+ {
+ /*
+ * Ptasks in a g5k platform.
+ * Extracted from original test.
+ * The sum of bounds for 1 resource exceed its capacity, giving a negative value in C'
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 2.5e9);
+ lmm::Constraint* sys_cnst2 = Sys.constraint_new(nullptr, 2.5e9);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, 2.27328e-10, 2);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1, 2.27328e-10, 2);
+ lmm::Variable* rho_3 = Sys.variable_new(nullptr, 1);
+
+ Sys.expand_add(sys_cnst, rho_1, 1.84467e+19);
+ Sys.expand_add(sys_cnst2, rho_1, 1.84467e+19);
+ Sys.expand_add(sys_cnst, rho_2, 1.84467e+19);
+ Sys.expand_add(sys_cnst, rho_3, 1.91268e+11);
+ Sys.solve();
+ }
+
+ SECTION("is_bmf bug: all limited by bound")
+ {
+ /*
+ * Particular case, 1 flow is saturated and the other increases
+ * its speed until the contraint is reached
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 10);
+ lmm::Constraint* sys_cnst2 = Sys.constraint_new(nullptr, 8);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, 1.5, 2);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1, 3, 2);
+
+ Sys.expand_add(sys_cnst, rho_1, 5.0);
+ Sys.expand_add(sys_cnst2, rho_1, 1.0);
+ Sys.expand_add(sys_cnst, rho_2, 1.0);
+ Sys.expand_add(sys_cnst2, rho_2, 1.0);
+ Sys.solve();
+ REQUIRE(double_equals(rho_1->get_value(), 1.4, sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), 3, sg_maxmin_precision));
+ }
+
+ Sys.variable_free_all();
+}
+
+TEST_CASE("kernel::bmf Stress-tests", "[.kernel-bmf-stress]")
+{
+ lmm::BmfSystem Sys(false);
+
+ auto create_cnsts = [&Sys](int C, int capacity) -> auto
+ {
+ std::vector<lmm::Constraint*> sys_cnst;
+ for (int i = 0; i < C; i++) {
+ sys_cnst.push_back(Sys.constraint_new(nullptr, capacity));
+ }
+ return sys_cnst;
+ };
+
+ auto test_shared = [&Sys, &create_cnsts](int C, int N, int capacity, const auto& data) {
+ auto sys_cnst = create_cnsts(C, capacity);
+ for (int j = 0; j < N; j++) {
+ lmm::Variable* rho = Sys.variable_new(nullptr, 1, -1, C);
+ for (int i = 0; i < C; i++) {
+ Sys.expand_add(sys_cnst[i], rho, data[i * j + j]);
+ }
+ }
+ Sys.solve();
+ };
+
+ SECTION("Random consumptions - independent flows")
+ {
+ int C = 5;
+ int N = 2;
+ auto data = GENERATE_COPY(chunk(C * N, take(100000, random(0., 1.0))));
+ auto sys_cnst = create_cnsts(C, 1);
+ for (int j = 0; j < N; j++) {
+ for (int i = 0; i < C; i++) {
+ lmm::Variable* rho = Sys.variable_new(nullptr, 1);
+ Sys.expand_add(sys_cnst[i], rho, data[i * j + j]);
+ }
+ }
+ Sys.solve();
+ }
+
+ SECTION("Random consumptions - flows sharing resources")
+ {
+ int C = 5;
+ int N = 10;
+ auto data = GENERATE_COPY(chunk(C * N, take(100000, random(0., 1.0))));
+ test_shared(C, N, 1, data);
+ }
+
+ SECTION("Random integer consumptions - flows sharing resources")
+ {
+ int C = 5;
+ int N = 10;
+ auto data = GENERATE_COPY(chunk(C * N, take(100000, random(1, 10))));
+ test_shared(C, N, 10, data);
+ }
+
+ SECTION("Random consumptions - high number of constraints")
+ {
+ int C = 500;
+ int N = 10;
+ auto data = GENERATE_COPY(chunk(C * N, take(100000, random(0., 1.0))));
+ test_shared(C, N, 1, data);
+ }
+
+ SECTION("Random integer consumptions - high number of constraints")
+ {
+ int C = 500;
+ int N = 10;
+ auto data = GENERATE_COPY(chunk(C * N, take(100000, random(1, 10))));
+ test_shared(C, N, 10, data);
+ }
+
+ Sys.variable_free_all();
+}
+
+TEST_CASE("kernel::AllocationGenerator Basic tests", "[kernel-bmf-allocation-gen]")
+{
+ SECTION("Full combinations")
+ {
+ Eigen::MatrixXd A(3, 3);
+ A << 1, .5, 1, 1, 1, .5, 1, .75, .75;
+ lmm::AllocationGenerator gen(std::move(A));
+ int i = 0;
+ std::vector<int> alloc;
+ while (gen.next(alloc))
+ i++;
+ REQUIRE(i == 3 * 3 * 3);
+ }
+
+ SECTION("Few options per player")
+ {
+ Eigen::MatrixXd A(3, 3);
+ A << 1, 0, 0, 0, 1, 0, 0, 1, 1;
+ lmm::AllocationGenerator gen(std::move(A));
+ int i = 0;
+ std::vector<int> alloc;
+ while (gen.next(alloc))
+ i++;
+ REQUIRE(i == 1 * 2 * 1);
+ }
+}
\ No newline at end of file
int Variable::next_rank_ = 1;
int Constraint::next_rank_ = 1;
+Element::Element(Constraint* constraint, Variable* variable, double cweight)
+ : constraint(constraint), variable(variable), consumption_weight(cweight), max_consumption_weight(cweight)
+{
+}
+
int Element::get_concurrency() const
{
// Ignore element with weight less than one (e.g. cross-traffic)
xbt_assert(var->cnsts_.size() < var->cnsts_.capacity(), "Too much constraints");
- var->cnsts_.emplace_back();
+ var->cnsts_.emplace_back(cnst, var, consumption_weight);
Element& elem = var->cnsts_.back();
- elem.consumption_weight = consumption_weight;
- elem.constraint = cnst;
- elem.variable = var;
-
if (var->sharing_penalty_ != 0.0) {
elem.constraint->enabled_element_set_.push_front(elem);
elem.increase_concurrency();
if (var->sharing_penalty_ != 0.0)
elem.decrease_concurrency();
+ elem.max_consumption_weight = std::max(elem.max_consumption_weight, value);
if (cnst->sharing_policy_ != Constraint::SharingPolicy::FATPIPE)
elem.consumption_weight += value;
else
public:
// Use rule-of-three, and implicitely disable the move constructor which should be 'noexcept' according to C++ Core
// Guidelines.
- Element() = default;
+ Element(Constraint* constraint, Variable* variable, double cweight);
Element(const Element&) = default;
~Element() = default;
// - if CPU, then probably 1.
// - If network, then 1 in forward direction and 0.05 backward for the ACKs
double consumption_weight;
+ // maximum consumption weight (can be different from consumption_weight with subflows/ptasks)
+ double max_consumption_weight;
};
class ConstraintLight {
public:
enum class SharingPolicy { NONLINEAR = 2, SHARED = 1, FATPIPE = 0 };
- Constraint() = delete;
Constraint(resource::Resource* id_value, double bound_value);
/** @brief Unshare a constraint. */
std::unique_ptr<resource::Action::ModifiedSet> modified_set_ = nullptr;
+protected:
+ bool selective_update_active; /* flag to update partially the system only selecting changed portions */
+ boost::intrusive::list<Constraint, boost::intrusive::member_hook<Constraint, boost::intrusive::list_member_hook<>,
+ &Constraint::modified_constraint_set_hook_>>
+ modified_constraint_set;
+
private:
using dyn_light_t = std::vector<int>;
std::vector<ConstraintLight> cnst_light_vec;
dyn_light_t saturated_constraints;
- bool selective_update_active; /* flag to update partially the system only selecting changed portions */
unsigned visited_counter_ = 1; /* used by System::update_modified_set() and System::remove_all_modified_set() to
* cleverly (un-)flag the constraints (more details in these functions) */
boost::intrusive::list<Constraint, boost::intrusive::member_hook<Constraint, boost::intrusive::list_member_hook<>,
&Constraint::constraint_set_hook_>>
constraint_set;
- boost::intrusive::list<Constraint, boost::intrusive::member_hook<Constraint, boost::intrusive::list_member_hook<>,
- &Constraint::modified_constraint_set_hook_>>
- modified_constraint_set;
xbt_mallocator_t variable_mallocator_ =
xbt_mallocator_new(65536, System::variable_mallocator_new_f, System::variable_mallocator_free_f, nullptr);
};
REQUIRE(double_equals(rho_3->get_value(), 2, sg_maxmin_precision));
}
+ Sys.variable_free_all();
+}
+
+TEST_CASE("kernel::lmm shared systems with crosstraffic", "[kernel-lmm-shared-crosstraffic]")
+{
+ lmm::System Sys(false);
+
+ SECTION("3 flows, 3 resource: crosstraffic")
+ {
+ /*
+ * 3 flows sharing 2 constraints, single
+ *
+ * In details:
+ * o System: a1 * \rho1 + a2 * \rho2 + epsilon * \rho3 < C1
+ * epsilon * \rho1 + epsilon * \rho2 + a3 * \rho3 < C2
+ * o consumption_weight: a1=1, a2=1, a3=1, epsilon=0.05
+ * o C1 = C2 = 1
+ *
+ * Expectations
+ * o rho1 = rho2 = rho3 = 1/2
+ */
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 1);
+ lmm::Constraint* sys_cnst2 = Sys.constraint_new(nullptr, 1);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, -1, 2);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1, -1, 2);
+ lmm::Variable* rho_3 = Sys.variable_new(nullptr, 1, -1, 2);
+
+ double epsilon = 0.05;
+ Sys.expand(sys_cnst, rho_1, 1.0);
+ Sys.expand(sys_cnst2, rho_1, epsilon);
+ Sys.expand(sys_cnst, rho_2, 1.0);
+ Sys.expand(sys_cnst2, rho_2, epsilon);
+ Sys.expand(sys_cnst2, rho_3, 1.0);
+ Sys.expand(sys_cnst, rho_3, epsilon);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), 1.0 / (2.0 + epsilon), sg_maxmin_precision));
+ REQUIRE(double_equals(rho_2->get_value(), 1.0 / (2.0 + epsilon), sg_maxmin_precision));
+ REQUIRE(double_equals(rho_3->get_value(), 1.0 / (2.0 + epsilon), sg_maxmin_precision));
+ }
+
Sys.variable_free_all();
}
\ No newline at end of file
#include "src/surf/cpu_cas01.hpp"
#include "src/surf/cpu_ti.hpp"
+#include <numeric>
+
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(res_vm, ker_resource, "Virtual Machines, containing actors and mobile across hosts");
void surf_vm_model_init_HL13(simgrid::kernel::resource::CpuModel* cpu_pm_model)
return -1.0;
}
+Action* VMModel::execute_thread(const s4u::Host* host, double flops_amount, int thread_count)
+{
+ auto cpu = host->get_cpu();
+ return cpu->execution_start(thread_count * flops_amount, thread_count, -1);
+}
+
/************
* Resource *
************/
double next_occurring_event(double now) override;
void update_actions_state(double /*now*/, double /*delta*/) override{};
+ Action* execute_thread(const s4u::Host* host, double flops_amount, int thread_count) override;
Action* execute_parallel(const std::vector<s4u::Host*>& host_list, const double* flops_amount,
const double* bytes_amount, double rate) override
{
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(Api, mc, "Logging specific to MC Facade APIs ");
XBT_LOG_EXTERNAL_CATEGORY(mc_global);
-using Simcall = simgrid::simix::Simcall;
-
namespace simgrid {
namespace mc {
-simgrid::mc::Exploration* Api::initialize(char** argv, simgrid::mc::CheckerAlgorithm algo)
+simgrid::mc::Exploration* Api::initialize(char** argv, simgrid::mc::ExplorationAlgorithm algo)
{
session_ = std::make_unique<simgrid::mc::Session>([argv] {
int i = 1;
simgrid::mc::Exploration* explo;
switch (algo) {
- case CheckerAlgorithm::CommDeterminism:
+ case ExplorationAlgorithm::CommDeterminism:
explo = simgrid::mc::create_communication_determinism_checker(session_.get());
break;
- case CheckerAlgorithm::UDPOR:
+ case ExplorationAlgorithm::UDPOR:
explo = simgrid::mc::create_udpor_checker(session_.get());
break;
- case CheckerAlgorithm::Safety:
- explo = simgrid::mc::create_safety_checker(session_.get());
+ case ExplorationAlgorithm::Safety:
+ explo = simgrid::mc::create_dfs_exploration(session_.get());
break;
- case CheckerAlgorithm::Liveness:
+ case ExplorationAlgorithm::Liveness:
explo = simgrid::mc::create_liveness_checker(session_.get());
break;
namespace simgrid {
namespace mc {
-XBT_DECLARE_ENUM_CLASS(CheckerAlgorithm, Safety, UDPOR, Liveness, CommDeterminism);
+XBT_DECLARE_ENUM_CLASS(ExplorationAlgorithm, Safety, UDPOR, Liveness, CommDeterminism);
/*
** This class aimes to implement FACADE APIs for simgrid. The FACADE layer sits between the CheckerSide
return api;
}
- simgrid::mc::Exploration* initialize(char** argv, simgrid::mc::CheckerAlgorithm algo);
+ simgrid::mc::Exploration* initialize(char** argv, simgrid::mc::ExplorationAlgorithm algo);
// ACTOR APIs
std::vector<simgrid::mc::ActorInformation>& get_actors() const;
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "src/kernel/activity/MailboxImpl.hpp"
-#include "src/mc/explo/SafetyChecker.hpp"
+#include "src/mc/explo/DFSExplorer.hpp"
#include "src/mc/mc_config.hpp"
#include "src/mc/mc_exit.hpp"
#include "src/mc/mc_forward.hpp"
auto extension = new CommDetExtension();
- SafetyChecker::on_exploration_start([extension]() {
+ DFSExplorer::on_exploration_start([extension]() {
XBT_INFO("Check communication determinism");
extension->exploration_start();
});
- SafetyChecker::on_backtracking([extension]() { extension->initial_communications_pattern_done = true; });
- SafetyChecker::on_state_creation([extension](State* state) { state->extension_set(new StateCommDet(extension)); });
+ DFSExplorer::on_backtracking([extension]() { extension->initial_communications_pattern_done = true; });
+ DFSExplorer::on_state_creation([extension](State* state) { state->extension_set(new StateCommDet(extension)); });
- SafetyChecker::on_restore_system_state(
- [extension](State* state) { extension->restore_communications_pattern(state); });
+ DFSExplorer::on_restore_system_state([extension](State* state) { extension->restore_communications_pattern(state); });
- SafetyChecker::on_restore_initial_state([extension]() {
+ DFSExplorer::on_restore_initial_state([extension]() {
const unsigned long maxpid = Api::get().get_maxpid();
assert(maxpid == extension->incomplete_communications_pattern.size());
assert(maxpid == extension->initial_communications_pattern.size());
}
});
- SafetyChecker::on_transition_replay([extension](Transition* t) { extension->handle_comm_pattern(t); });
- SafetyChecker::on_transition_execute([extension](Transition* t) { extension->handle_comm_pattern(t); });
+ DFSExplorer::on_transition_replay([extension](Transition* t) { extension->handle_comm_pattern(t); });
+ DFSExplorer::on_transition_execute([extension](Transition* t) { extension->handle_comm_pattern(t); });
- SafetyChecker::on_log_state([extension]() {
+ DFSExplorer::on_log_state([extension]() {
if (_sg_mc_comms_determinism) {
if (extension->send_deterministic && not extension->recv_deterministic) {
XBT_INFO("*******************************************************");
delete extension;
});
- return new SafetyChecker(session);
+ return new DFSExplorer(session);
}
} // namespace mc
/* 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. */
-#include "src/mc/explo/SafetyChecker.hpp"
+#include "src/mc/explo/DFSExplorer.hpp"
#include "src/mc/VisitedState.hpp"
#include "src/mc/mc_config.hpp"
#include "src/mc/mc_exit.hpp"
#include <string>
#include <vector>
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_safety, mc, "Logging specific to MC safety verification ");
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(mc_dfs, mc, "DFS exploration algorithm of the model-checker");
namespace simgrid {
namespace mc {
-xbt::signal<void()> SafetyChecker::on_exploration_start_signal;
-xbt::signal<void()> SafetyChecker::on_backtracking_signal;
+xbt::signal<void()> DFSExplorer::on_exploration_start_signal;
+xbt::signal<void()> DFSExplorer::on_backtracking_signal;
-xbt::signal<void(State*)> SafetyChecker::on_state_creation_signal;
+xbt::signal<void(State*)> DFSExplorer::on_state_creation_signal;
-xbt::signal<void(State*)> SafetyChecker::on_restore_system_state_signal;
-xbt::signal<void()> SafetyChecker::on_restore_initial_state_signal;
-xbt::signal<void(Transition*)> SafetyChecker::on_transition_replay_signal;
-xbt::signal<void(Transition*)> SafetyChecker::on_transition_execute_signal;
+xbt::signal<void(State*)> DFSExplorer::on_restore_system_state_signal;
+xbt::signal<void()> DFSExplorer::on_restore_initial_state_signal;
+xbt::signal<void(Transition*)> DFSExplorer::on_transition_replay_signal;
+xbt::signal<void(Transition*)> DFSExplorer::on_transition_execute_signal;
-xbt::signal<void()> SafetyChecker::on_log_state_signal;
+xbt::signal<void()> DFSExplorer::on_log_state_signal;
-void SafetyChecker::check_non_termination(const State* current_state)
+void DFSExplorer::check_non_termination(const State* current_state)
{
for (auto state = stack_.rbegin(); state != stack_.rend(); ++state)
if (Api::get().snapshot_equal((*state)->system_state_.get(), current_state->system_state_.get())) {
}
}
-RecordTrace SafetyChecker::get_record_trace() // override
+RecordTrace DFSExplorer::get_record_trace() // override
{
RecordTrace res;
for (auto const& state : stack_)
return res;
}
-std::vector<std::string> SafetyChecker::get_textual_trace() // override
+std::vector<std::string> DFSExplorer::get_textual_trace() // override
{
std::vector<std::string> trace;
for (auto const& state : stack_)
return trace;
}
-void SafetyChecker::log_state() // override
+void DFSExplorer::log_state() // override
{
on_log_state_signal();
XBT_INFO("DFS exploration ended. %ld unique states visited; %ld backtracks (%lu transition replays, %lu states "
Transition::get_replayed_transitions());
}
-void SafetyChecker::run()
+void DFSExplorer::run()
{
on_exploration_start_signal();
/* This function runs the DFS algorithm the state space.
log_state();
}
-void SafetyChecker::backtrack()
+void DFSExplorer::backtrack()
{
backtrack_count_++;
XBT_VERB("Backtracking from %s", get_record_trace().to_string().c_str());
}
}
-void SafetyChecker::restore_state()
+void DFSExplorer::restore_state()
{
/* If asked to rollback on a state that has a snapshot, restore it */
State* last_state = stack_.back().get();
}
}
-SafetyChecker::SafetyChecker(Session* session) : Exploration(session)
+DFSExplorer::DFSExplorer(Session* session) : Exploration(session)
{
reductionMode_ = reduction_mode;
if (_sg_mc_termination)
get_session().take_initial_snapshot();
- XBT_DEBUG("Starting the safety algorithm");
+ XBT_DEBUG("Starting the DFS exploration");
auto initial_state = std::make_unique<State>();
stack_.push_back(std::move(initial_state));
}
-Exploration* create_safety_checker(Session* session)
+Exploration* create_dfs_exploration(Session* session)
{
- return new SafetyChecker(session);
+ return new DFSExplorer(session);
}
} // namespace mc
-/* Copyright (c) 2008-2022. The SimGrid Team.
- * All rights reserved. */
+/* Copyright (c) 2008-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. */
namespace simgrid {
namespace mc {
-class XBT_PRIVATE SafetyChecker : public Exploration {
+class XBT_PRIVATE DFSExplorer : public Exploration {
ReductionMode reductionMode_ = ReductionMode::unset;
long backtrack_count_ = 0;
static xbt::signal<void()> on_log_state_signal;
public:
- explicit SafetyChecker(Session* session);
+ explicit DFSExplorer(Session* session);
void run() override;
RecordTrace get_record_trace() override;
std::vector<std::string> get_textual_trace() override;
// External constructors so that the types (and the types of their content) remain hidden
XBT_PUBLIC Exploration* create_liveness_checker(Session* session);
-XBT_PUBLIC Exploration* create_safety_checker(Session* session);
+XBT_PUBLIC Exploration* create_dfs_exploration(Session* session);
XBT_PUBLIC Exploration* create_communication_determinism_checker(Session* session);
XBT_PUBLIC Exploration* create_udpor_checker(Session* session);
#endif
sg_config_init(&argc, argv);
- simgrid::mc::CheckerAlgorithm algo;
+ simgrid::mc::ExplorationAlgorithm algo;
if (_sg_mc_comms_determinism || _sg_mc_send_determinism)
- algo = simgrid::mc::CheckerAlgorithm::CommDeterminism;
+ algo = simgrid::mc::ExplorationAlgorithm::CommDeterminism;
else if (_sg_mc_unfolding_checker)
- algo = simgrid::mc::CheckerAlgorithm::UDPOR;
+ algo = simgrid::mc::ExplorationAlgorithm::UDPOR;
else if (_sg_mc_property_file.get().empty())
- algo = simgrid::mc::CheckerAlgorithm::Safety;
+ algo = simgrid::mc::ExplorationAlgorithm::Safety;
else
- algo = simgrid::mc::CheckerAlgorithm::Liveness;
+ algo = simgrid::mc::ExplorationAlgorithm::Liveness;
int res = SIMGRID_MC_EXIT_SUCCESS;
std::unique_ptr<simgrid::mc::Exploration> checker{simgrid::mc::Api::get().initialize(argv_copy.data(), algo)};
while (engine->has_actors_to_run()) {
engine->run_all_actors();
for (auto const& actor : engine->get_actors_that_ran()) {
- const s_smx_simcall* req = &actor->simcall_;
- if (req->call_ != simix::Simcall::NONE && not simgrid::mc::request_is_visible(req))
+ const kernel::actor::Simcall* req = &actor->simcall_;
+ if (req->call_ != kernel::actor::Simcall::Type::NONE && not simgrid::mc::request_is_visible(req))
actor->simcall_handle(0);
}
}
#endif
// Now, we are in the client app, no need for remote memory reading.
- smx_simcall_t req = &actor->simcall_;
+ kernel::actor::Simcall* req = &actor->simcall_;
if (req->observer_ != nullptr)
return req->observer_->is_enabled();
- if (req->call_ == simix::Simcall::NONE)
+ if (req->call_ == kernel::actor::Simcall::Type::NONE)
return false;
else
/* The rest of the requests are always enabled */
/* This is the list of requests that are visible from the checker algorithm.
* Any other requests are handled right away on the application side.
*/
-bool request_is_visible(const s_smx_simcall* req)
+bool request_is_visible(const kernel::actor::Simcall* req)
{
#if SIMGRID_HAVE_MC
xbt_assert(mc_model_checker == nullptr, "This should be called from the client side");
XBT_PRIVATE extern std::vector<double> processes_time;
/** Execute a given simcall */
-XBT_PRIVATE void handle_simcall(smx_simcall_t req, int req_num);
+XBT_PRIVATE void handle_simcall(kernel::actor::Simcall* req, int req_num);
/** Is the process ready to execute its simcall?
*
XBT_PRIVATE bool actor_is_enabled(smx_actor_t process);
/** Check if the given simcall is visible */
-XBT_PRIVATE bool request_is_visible(const s_smx_simcall* req);
+XBT_PRIVATE bool request_is_visible(const kernel::actor::Simcall* req);
} // namespace mc
} // namespace simgrid
#if SIMGRID_HAVE_MC
-/* Liveness */
-
-namespace simgrid {
-namespace mc {
-
-xbt_automaton_t property_automaton = nullptr;
-
-}
-}
-
/* Dot output */
FILE *dot_output = nullptr;
-
-/******************************* Initialization of MC *******************************/
-/*********************************************************************************/
-
void MC_init_dot_output()
{
dot_output = fopen(_sg_mc_dot_output_file.get().c_str(), "w");
"digraph graphname{\n fixedsize=true; rankdir=TB; ranksep=.25; edge [fontsize=12]; node [fontsize=10, shape=circle,width=.5 ]; graph [resolution=20, fontsize=10];\n");
}
-/******************************* Core of MC *******************************/
-/**************************************************************************/
-
-void MC_run()
-{
- simgrid::mc::processes_time.resize(simgrid::kernel::actor::get_maxpid());
- MC_ignore_heap(simgrid::mc::processes_time.data(),
- simgrid::mc::processes_time.size() * sizeof(simgrid::mc::processes_time[0]));
- simgrid::mc::AppSide::get()->main_loop();
-}
namespace simgrid {
namespace mc {
+/* Liveness */
+xbt_automaton_t property_automaton = nullptr;
+
+/******************************* Core of MC *******************************/
+/**************************************************************************/
void dumpStack(FILE* file, unw_cursor_t* cursor)
{
int nframe = 0;
// Choose a request:
kernel::actor::ActorImpl* actor = kernel::actor::ActorImpl::by_pid(transition->aid_);
xbt_assert(actor != nullptr, "Unexpected actor (id:%ld).", transition->aid_);
- const s_smx_simcall* simcall = &(actor->simcall_);
- xbt_assert(simcall->call_ != simix::Simcall::NONE, "No simcall for process %ld.", transition->aid_);
+ const kernel::actor::Simcall* simcall = &(actor->simcall_);
+ xbt_assert(simcall->call_ != kernel::actor::Simcall::Type::NONE, "No simcall for process %ld.", transition->aid_);
xbt_assert(simgrid::mc::request_is_visible(simcall) && simgrid::mc::actor_is_enabled(actor), "Unexpected simcall.");
// Execute the request:
* - `model_checker->process.smx_process_infos`
* (copy of `EngineImpl::actor_list_`);
*
- * - `model_checker->process.smx_old_process_infos`
- * (copy of `EngineImpl::actors_to_destroy_`);
- *
* - `model_checker->hostnames`.
*
* The process lists are currently refreshed each time MCed code is executed.
std::unique_ptr<AppSide> AppSide::instance_;
-AppSide* AppSide::initialize()
+AppSide* AppSide::initialize(xbt_dynar_t actors_addr)
{
if (not std::getenv(MC_ENV_SOCKET_FD)) // We are not in MC mode: don't initialize the MC world
return nullptr;
strerror(errno));
s_mc_message_initial_addresses_t message{MessageType::INITIAL_ADDRESSES, mmalloc_preinit(),
- kernel::actor::get_maxpid_addr(), kernel::get_actors_addr()};
+ kernel::actor::get_maxpid_addr(), actors_addr};
xbt_assert(instance_->channel_.send(message) == 0, "Could not send the initial message with addresses.");
instance_->handle_messages();
void AppSide::main_loop() const
{
+ simgrid::mc::processes_time.resize(simgrid::kernel::actor::get_maxpid());
+ MC_ignore_heap(simgrid::mc::processes_time.data(),
+ simgrid::mc::processes_time.size() * sizeof(simgrid::mc::processes_time[0]));
+
coverage_checkpoint();
while (true) {
simgrid::mc::execute_actors();
// Singleton :/
// TODO, remove the singleton antipattern.
- static AppSide* initialize();
+ static AppSide* initialize(xbt_dynar_t actors_addr);
static AppSide* get() { return instance_.get(); }
};
} // namespace mc
kernel::actor::ActorImpl* issuer = kernel::actor::ActorImpl::self();
const kernel::actor::ActorImpl* target = pimpl_;
kernel::actor::simcall_blocking([issuer, target, timeout] {
- if (target->finished_) {
+ if (target->context_->wannadie()) {
// The joined actor is already finished, just wake up the issuer right away
issuer->simcall_answer();
} else {
Actor* Actor::set_auto_restart(bool autorestart)
{
+ if (autorestart == pimpl_->has_to_auto_restart()) // not changed
+ return this;
+
kernel::actor::simcall_answered([this, autorestart]() {
- xbt_assert(autorestart && not pimpl_->has_to_auto_restart()); // FIXME: handle all cases
+ xbt_assert(autorestart, "Asking an actor to stop being autorestart is not implemented yet. Ask us if you need it.");
pimpl_->set_auto_restart(autorestart);
auto* arg = new kernel::actor::ProcessArg(pimpl_->get_host(), pimpl_);
});
return this;
}
+int Actor::get_restart_count() const
+{
+ return pimpl_->get_restart_count();
+}
void Actor::on_exit(const std::function<void(bool /*failed*/)>& fun) const
{
exec_init(hosts, flops_amounts, bytes_amounts)->wait();
}
+void thread_execute(s4u::Host* host, double flops_amount, int thread_count)
+{
+ Exec::init()->set_flops_amount(flops_amount)->set_host(host)->set_thread_count(thread_count)->wait();
+}
ExecPtr exec_init(double flops_amount)
{
return Exec::init()->set_flops_amount(flops_amount)->set_host(get_host());
/* 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. */
-//#include "src/msg/msg_private.hpp"
-//#include "xbt/log.h"
-
+#include <cmath>
#include <simgrid/Exception.hpp>
#include <simgrid/comm.h>
#include <simgrid/s4u/Comm.hpp>
#include <simgrid/s4u/Engine.hpp>
#include <simgrid/s4u/Mailbox.hpp>
+#include "mc/mc.h"
#include "src/kernel/activity/CommImpl.hpp"
#include "src/kernel/actor/ActorImpl.hpp"
#include "src/kernel/actor/SimcallObserver.hpp"
+#include "src/mc/mc_replay.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_comm, s4u_activity, "S4U asynchronous communications");
xbt::signal<void(Comm const&)> Comm::on_recv;
xbt::signal<void(Comm const&)> Comm::on_completion;
-CommPtr Comm::set_copy_data_callback(void (*callback)(kernel::activity::CommImpl*, void*, size_t))
+CommPtr Comm::set_copy_data_callback(const std::function<void(kernel::activity::CommImpl*, void*, size_t)>& callback)
{
copy_data_function_ = callback;
return this;
}
}
+void Comm::send(kernel::actor::ActorImpl* sender, const Mailbox* mbox, double task_size, double rate, void* src_buff,
+ size_t src_buff_size,
+ const std::function<bool(void*, void*, simgrid::kernel::activity::CommImpl*)>& match_fun,
+ const std::function<void(simgrid::kernel::activity::CommImpl*, void*, size_t)>& copy_data_fun,
+ void* data, double timeout)
+{
+ /* checking for infinite values */
+ xbt_assert(std::isfinite(task_size), "task_size is not finite!");
+ xbt_assert(std::isfinite(rate), "rate is not finite!");
+ xbt_assert(std::isfinite(timeout), "timeout is not finite!");
+
+ xbt_assert(mbox, "No rendez-vous point defined for send");
+
+ if (MC_is_active() || MC_record_replay_is_active()) {
+ /* the model-checker wants two separate simcalls, and wants comm to be nullptr during the simcall */
+ simgrid::kernel::activity::ActivityImplPtr comm = nullptr;
+
+ simgrid::kernel::actor::CommIsendSimcall send_observer{
+ sender, mbox->get_impl(), task_size, rate, static_cast<unsigned char*>(src_buff), src_buff_size, match_fun,
+ nullptr, copy_data_fun, data, false};
+ comm = simgrid::kernel::actor::simcall_answered(
+ [&send_observer] { return simgrid::kernel::activity::CommImpl::isend(&send_observer); }, &send_observer);
+
+ simgrid::kernel::actor::ActivityWaitSimcall wait_observer{sender, comm.get(), timeout};
+ if (simgrid::kernel::actor::simcall_blocking(
+ [&wait_observer] {
+ wait_observer.get_activity()->wait_for(wait_observer.get_issuer(), wait_observer.get_timeout());
+ },
+ &wait_observer)) {
+ throw simgrid::TimeoutException(XBT_THROW_POINT, "Timeouted");
+ }
+ comm = nullptr;
+ } else {
+ simgrid::kernel::actor::CommIsendSimcall observer(sender, mbox->get_impl(), task_size, rate,
+ static_cast<unsigned char*>(src_buff), src_buff_size, match_fun,
+ nullptr, copy_data_fun, data, false);
+ simgrid::kernel::actor::simcall_blocking([&observer, timeout] {
+ simgrid::kernel::activity::ActivityImplPtr comm = simgrid::kernel::activity::CommImpl::isend(&observer);
+ comm->wait_for(observer.get_issuer(), timeout);
+ });
+ }
+}
+
+void Comm::recv(kernel::actor::ActorImpl* receiver, const Mailbox* mbox, void* dst_buff, size_t* dst_buff_size,
+ const std::function<bool(void*, void*, simgrid::kernel::activity::CommImpl*)>& match_fun,
+ const std::function<void(simgrid::kernel::activity::CommImpl*, void*, size_t)>& copy_data_fun,
+ void* data, double timeout, double rate)
+{
+ xbt_assert(std::isfinite(timeout), "timeout is not finite!");
+ xbt_assert(mbox, "No rendez-vous point defined for recv");
+
+ if (MC_is_active() || MC_record_replay_is_active()) {
+ /* the model-checker wants two separate simcalls, and wants comm to be nullptr during the simcall */
+ simgrid::kernel::activity::ActivityImplPtr comm = nullptr;
+
+ simgrid::kernel::actor::CommIrecvSimcall observer{receiver,
+ mbox->get_impl(),
+ static_cast<unsigned char*>(dst_buff),
+ dst_buff_size,
+ match_fun,
+ copy_data_fun,
+ data,
+ rate};
+ comm = simgrid::kernel::actor::simcall_answered(
+ [&observer] { return simgrid::kernel::activity::CommImpl::irecv(&observer); }, &observer);
+
+ simgrid::kernel::actor::ActivityWaitSimcall wait_observer{receiver, comm.get(), timeout};
+ if (simgrid::kernel::actor::simcall_blocking(
+ [&wait_observer] {
+ wait_observer.get_activity()->wait_for(wait_observer.get_issuer(), wait_observer.get_timeout());
+ },
+ &wait_observer)) {
+ throw simgrid::TimeoutException(XBT_THROW_POINT, "Timeouted");
+ }
+ comm = nullptr;
+ } else {
+ simgrid::kernel::actor::CommIrecvSimcall observer(receiver, mbox->get_impl(), static_cast<unsigned char*>(dst_buff),
+ dst_buff_size, match_fun, copy_data_fun, data, rate);
+ simgrid::kernel::actor::simcall_blocking([&observer, timeout] {
+ simgrid::kernel::activity::ActivityImplPtr comm = simgrid::kernel::activity::CommImpl::irecv(&observer);
+ comm->wait_for(observer.get_issuer(), timeout);
+ });
+ }
+}
+
CommPtr Comm::sendto_init()
{
CommPtr res(new Comm());
return vetoable_start()->wait_for(timeout); // In the case of host2host comm, do it in two simcalls
} else if (src_buff_ != nullptr) {
on_send(*this);
- simcall_comm_send(sender_, mailbox_->get_impl(), remains_, rate_, src_buff_, src_buff_size_, match_fun_,
- copy_data_function_, get_data<void>(), timeout);
+ send(sender_, mailbox_, remains_, rate_, src_buff_, src_buff_size_, match_fun_, copy_data_function_,
+ get_data<void>(), timeout);
} else { // Receiver
on_recv(*this);
- simcall_comm_recv(receiver_, mailbox_->get_impl(), dst_buff_, &dst_buff_size_, match_fun_, copy_data_function_,
- get_data<void>(), timeout, rate_);
+ recv(receiver_, mailbox_, dst_buff_, &dst_buff_size_, match_fun_, copy_data_function_, get_data<void>(),
+ timeout, rate_);
}
break;
case State::STARTED:
#include <simgrid/modelchecker.h>
#include <simgrid/s4u/Engine.hpp>
+#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v333)
+#include <simgrid/simix.h>
+
#include "mc/mc.h"
#include "src/instr/instr_private.hpp"
#include "src/kernel/EngineImpl.hpp"
fflush(stdout);
fflush(stderr);
- if (MC_is_active()) {
- MC_run();
- } else {
- pimpl->run(max_date);
- }
+ pimpl->run(max_date);
}
void Engine::track_vetoed_activities(std::set<Activity*>* vetoed_activities) const
config::set_value(name.c_str(), value);
}
-Engine* Engine::set_default_comm_data_copy_callback(void (*callback)(kernel::activity::CommImpl*, void*, size_t))
+Engine* Engine::set_default_comm_data_copy_callback(
+ const std::function<void(kernel::activity::CommImpl*, void*, size_t)>& callback)
{
kernel::activity::CommImpl::set_copy_data_callback(callback);
return this;
return this;
}
+ExecPtr Exec::set_thread_count(int thread_count)
+{
+ xbt_assert(state_ == State::INITED || state_ == State::STARTING,
+ "Cannot change the bytes_amounts of an exec after its start");
+ kernel::actor::simcall_answered([this, thread_count] {
+ boost::static_pointer_cast<kernel::activity::ExecImpl>(pimpl_)->set_thread_count(thread_count);
+ });
+ return this;
+}
+
/** @brief Retrieve the host on which this activity takes place.
* If it runs on more than one host, only the first host is returned.
*/
}
kernel::activity::ActivityImplPtr
-Mailbox::iprobe(int type, bool (*match_fun)(void*, void*, kernel::activity::CommImpl*), void* data)
+Mailbox::iprobe(int type, const std::function<bool(void*, void*, kernel::activity::CommImpl*)>& match_fun, void* data)
{
return kernel::actor::simcall_answered(
- [this, type, match_fun, data] { return pimpl_->iprobe(type, match_fun, data); });
+ [this, type, &match_fun, data] { return pimpl_->iprobe(type, match_fun, data); });
}
} // namespace s4u
} // namespace simgrid
"Maximum number of concurrent variables in the maxmim system. Also limits the number of "
"processes on each host, at higher level. (default: -1 means no such limitation)");
+ simgrid::config::bind_flag(sg_bmf_max_iterations, "bmf/max-iterations",
+ "Maximum number of steps to be performed while searching for a BMF allocation");
+
+ simgrid::config::declare_flag<bool>("bmf/selective-update",
+ "Update the constraint set propagating recursively to others constraints "
+ "(off by default)",
+ false);
+
/* The parameters of network models */
sg_latency_factor = 13.01; // comes from the default LV08 network model
/* 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. */
-#include "mc/mc.h"
#include "src/kernel/EngineImpl.hpp"
#include "src/kernel/activity/CommImpl.hpp"
-#include "src/kernel/activity/ConditionVariableImpl.hpp"
-#include "src/kernel/activity/MutexImpl.hpp"
-#include "src/kernel/activity/SemaphoreImpl.hpp"
#include "src/kernel/actor/SimcallObserver.hpp"
-#include "src/mc/mc_replay.hpp"
-#include "xbt/random.hpp"
-#include <simgrid/Exception.hpp>
#include <simgrid/s4u/Activity.hpp>
-#include <boost/core/demangle.hpp>
-#include <string>
-#include <typeinfo>
+#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v335)
+#include <simgrid/simix.h>
-XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix);
+XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(ker_simcall);
/**
* @ingroup simix_comm_management
void simcall_comm_send(smx_actor_t sender, smx_mailbox_t mbox, double task_size, double rate, void* src_buff,
size_t src_buff_size, bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*),
void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data,
- double timeout)
+ double timeout) // XBT_ATTRIB_DEPRECATED_v335
{
- /* checking for infinite values */
- xbt_assert(std::isfinite(task_size), "task_size is not finite!");
- xbt_assert(std::isfinite(rate), "rate is not finite!");
- xbt_assert(std::isfinite(timeout), "timeout is not finite!");
-
xbt_assert(mbox, "No rendez-vous point defined for send");
-
- if (MC_is_active() || MC_record_replay_is_active()) {
- /* the model-checker wants two separate simcalls, and wants comm to be nullptr during the simcall */
- simgrid::kernel::activity::ActivityImplPtr comm = nullptr;
-
- simgrid::kernel::actor::CommIsendSimcall send_observer{
- sender, mbox, task_size, rate, static_cast<unsigned char*>(src_buff), src_buff_size, match_fun,
- nullptr, copy_data_fun, data, false};
- comm = simgrid::kernel::actor::simcall_answered(
- [&send_observer] { return simgrid::kernel::activity::CommImpl::isend(&send_observer); }, &send_observer);
-
- simgrid::kernel::actor::ActivityWaitSimcall wait_observer{sender, comm.get(), timeout};
- if (simgrid::kernel::actor::simcall_blocking(
- [&wait_observer] {
- wait_observer.get_activity()->wait_for(wait_observer.get_issuer(), wait_observer.get_timeout());
- },
- &wait_observer)) {
- throw simgrid::TimeoutException(XBT_THROW_POINT, "Timeouted");
- }
- comm = nullptr;
- }
- else {
- simgrid::kernel::actor::CommIsendSimcall observer(sender, mbox, task_size, rate,
- static_cast<unsigned char*>(src_buff), src_buff_size, match_fun,
- nullptr, copy_data_fun, data, false);
- simgrid::kernel::actor::simcall_blocking([&observer, timeout] {
- simgrid::kernel::activity::ActivityImplPtr comm = simgrid::kernel::activity::CommImpl::isend(&observer);
- comm->wait_for(observer.get_issuer(), timeout);
- });
- }
+ simgrid::s4u::Comm::send(sender, mbox->get_iface(), task_size, rate, src_buff, src_buff_size, match_fun,
+ copy_data_fun, data, timeout);
}
/**
simcall_comm_isend(smx_actor_t sender, smx_mailbox_t mbox, double task_size, double rate, void* src_buff,
size_t src_buff_size, bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*),
void (*clean_fun)(void*), void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t),
- void* data, bool detached)
+ void* data, bool detached) // XBT_ATTRIB_DEPRECATED_v335
{
/* checking for infinite values */
xbt_assert(std::isfinite(task_size), "task_size is not finite!");
void simcall_comm_recv(smx_actor_t receiver, smx_mailbox_t mbox, void* dst_buff, size_t* dst_buff_size,
bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*),
void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data,
- double timeout, double rate)
+ double timeout, double rate) // XBT_ATTRIB_DEPRECATED_v335
{
- xbt_assert(std::isfinite(timeout), "timeout is not finite!");
xbt_assert(mbox, "No rendez-vous point defined for recv");
-
- if (MC_is_active() || MC_record_replay_is_active()) {
- /* the model-checker wants two separate simcalls, and wants comm to be nullptr during the simcall */
- simgrid::kernel::activity::ActivityImplPtr comm = nullptr;
-
- simgrid::kernel::actor::CommIrecvSimcall observer{
- receiver, mbox, static_cast<unsigned char*>(dst_buff), dst_buff_size, match_fun, copy_data_fun, data, rate};
- comm = simgrid::kernel::actor::simcall_answered(
- [&observer] { return simgrid::kernel::activity::CommImpl::irecv(&observer); }, &observer);
-
- simgrid::kernel::actor::ActivityWaitSimcall wait_observer{receiver, comm.get(), timeout};
- if (simgrid::kernel::actor::simcall_blocking(
- [&wait_observer] {
- wait_observer.get_activity()->wait_for(wait_observer.get_issuer(), wait_observer.get_timeout());
- },
- &wait_observer)) {
- throw simgrid::TimeoutException(XBT_THROW_POINT, "Timeouted");
- }
- comm = nullptr;
- }
- else {
- simgrid::kernel::actor::CommIrecvSimcall observer(receiver, mbox, static_cast<unsigned char*>(dst_buff),
- dst_buff_size, match_fun, copy_data_fun, data, rate);
- simgrid::kernel::actor::simcall_blocking([&observer, timeout] {
- simgrid::kernel::activity::ActivityImplPtr comm = simgrid::kernel::activity::CommImpl::irecv(&observer);
- comm->wait_for(observer.get_issuer(), timeout);
- });
- }
+ simgrid::s4u::Comm::recv(receiver, mbox->get_iface(), dst_buff, dst_buff_size, match_fun, copy_data_fun, data,
+ timeout, rate);
}
+
/**
* @ingroup simix_comm_management
*/
simgrid::kernel::activity::ActivityImplPtr
simcall_comm_irecv(smx_actor_t receiver, smx_mailbox_t mbox, void* dst_buff, size_t* dst_buff_size,
bool (*match_fun)(void*, void*, simgrid::kernel::activity::CommImpl*),
- void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data, double rate)
+ void (*copy_data_fun)(simgrid::kernel::activity::CommImpl*, void*, size_t), void* data,
+ double rate) // XBT_ATTRIB_DEPRECATED_v335
{
xbt_assert(mbox, "No rendez-vous point defined for irecv");
/**
* @ingroup simix_comm_management
*/
-void simcall_comm_wait(simgrid::kernel::activity::ActivityImpl* comm, double timeout)
+void simcall_comm_wait(simgrid::kernel::activity::ActivityImpl* comm, double timeout) // XBT_ATTRIB_DEPRECATED_v335
{
xbt_assert(std::isfinite(timeout), "timeout is not finite!");
-
simgrid::kernel::actor::ActorImpl* issuer = simgrid::kernel::actor::ActorImpl::self();
-
simgrid::kernel::actor::simcall_blocking([issuer, comm, timeout] { comm->wait_for(issuer, timeout); });
}
return false;
}
-static void simcall(simgrid::simix::Simcall call, std::function<void()> const& code)
+static void simcall(simgrid::kernel::actor::Simcall::Type call, std::function<void()> const& code)
{
auto self = simgrid::kernel::actor::ActorImpl::self();
self->simcall_.call_ = call;
self->simcall_.code_ = &code;
if (not simgrid::kernel::EngineImpl::get_instance()->is_maestro(self)) {
- XBT_DEBUG("Yield process '%s' on simcall %s", self->get_cname(), SIMIX_simcall_name(self->simcall_));
+ XBT_DEBUG("Yield process '%s' on simcall %s", self->get_cname(), self->simcall_.get_cname());
self->yield();
} else {
self->simcall_handle(0);
simgrid::kernel::actor::ActorImpl::self()->simcall_.observer_ = observer;
// The function `code` is called in kernel mode (either because we are already in maestor or after a context switch)
// and simcall_answer() is called
- simcall(simgrid::simix::Simcall::RUN_ANSWERED, code);
+ simcall(simgrid::kernel::actor::Simcall::Type::RUN_ANSWERED, code);
simgrid::kernel::actor::ActorImpl::self()->simcall_.observer_ = nullptr;
}
simgrid::kernel::actor::ActorImpl::self()->simcall_.observer_ = observer;
// The function `code` is called in kernel mode (either because we are already in maestor or after a context switch)
// BUT simcall_answer IS NOT CALLED
- simcall(simgrid::simix::Simcall::RUN_BLOCKING, code);
+ simcall(simgrid::kernel::actor::Simcall::Type::RUN_BLOCKING, code);
simgrid::kernel::actor::ActorImpl::self()->simcall_.observer_ = nullptr;
}
#include "src/kernel/context/Context.hpp"
+#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v333)
+#include <simgrid/simix.h>
+
int SIMIX_context_is_parallel() // XBT_ATTRIB_DEPRECATED_v333
{
return simgrid::kernel::context::is_parallel();
#include "mc/mc.h"
#include "private.hpp"
#include "smpi_coll.hpp"
+#include "xbt/ex.h"
#include "xbt/parse_units.hpp"
#include <cfloat> /* DBL_MAX */
static simgrid::config::Flag<int> smpi_map("smpi/map", "Display the mapping between nodes and processes", 0);
-void (*smpi_comm_copy_data_callback)(simgrid::kernel::activity::CommImpl*, void*,
- size_t) = &smpi_comm_copy_buffer_callback;
+std::function<void(simgrid::kernel::activity::CommImpl*, void*, size_t)> smpi_comm_copy_data_callback =
+ &smpi_comm_copy_buffer_callback;
simgrid::smpi::ActorExt* smpi_process()
{
void smpi_comm_set_copy_data_callback(void (*callback) (smx_activity_t, void*, size_t))
{
- static void (*saved_callback)(smx_activity_t, void*, size_t);
- saved_callback = callback;
- smpi_comm_copy_data_callback = [](simgrid::kernel::activity::CommImpl* comm, void* buff, size_t size) {
- saved_callback(comm, buff, size);
- };
+ smpi_comm_copy_data_callback = callback;
}
static void memcpy_private(void* dest, const void* src, const std::vector<std::pair<size_t, size_t>>& private_blocks)
fflush(stdout);
fflush(stderr);
- if (MC_is_active()) {
- MC_run();
- } else {
- engine.get_impl()->run(-1);
+ engine.get_impl()->run(-1);
+
+ xbt_os_walltimer_stop(global_timer);
+ simgrid::smpi::utils::print_time_analysis(xbt_os_timer_elapsed(global_timer));
- xbt_os_walltimer_stop(global_timer);
- simgrid::smpi::utils::print_time_analysis(xbt_os_timer_elapsed(global_timer));
- }
SMPI_finalize();
#if SMPI_IFORT
#include <sys/mman.h>
#include <unistd.h>
-#include "src/internal_config.h"
-#include "src/xbt/memory_map.hpp"
-
#include "private.hpp"
+#include "src/internal_config.h"
#include "src/smpi/include/smpi_actor.hpp"
+#include "src/xbt/memory_map.hpp"
+#include "xbt/virtu.h"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_memory, smpi, "Memory layout support for SMPI");
std::vector<s_smpi_factor_t> smpi_ois_values;
-extern void (*smpi_comm_copy_data_callback)(simgrid::kernel::activity::CommImpl*, void*, size_t);
+extern std::function<void(simgrid::kernel::activity::CommImpl*, void*, size_t)> smpi_comm_copy_data_callback;
namespace simgrid{
namespace smpi{
colls::allgather(&connected_wins_[rank_], sizeof(MPI_Win), MPI_BYTE, connected_wins_.data(), sizeof(MPI_Win),
MPI_BYTE, comm);
if (MC_is_active() || MC_record_replay_is_active()){
- if (bar_.get() == 0) // First to arrive on the barrier
+ if (bar_.get() == nullptr) // First to arrive on the barrier
bar_ = s4u::Barrier::create(comm->size());
bar_->wait();
}else{
{
for (auto const& arg : actors_at_boot_) {
XBT_DEBUG("Booting Actor %s(%s) right now", arg->name.c_str(), arg->host->get_cname());
- actor::ActorImplPtr actor = actor::ActorImpl::create(arg->name, arg->code, nullptr, arg->host, nullptr);
- actor->set_properties(arg->properties);
- if (arg->on_exit)
- *actor->on_exit = *arg->on_exit;
- if (arg->kill_time >= 0)
- actor->set_kill_time(arg->kill_time);
- if (arg->auto_restart)
- actor->set_auto_restart(arg->auto_restart);
- if (arg->daemon_)
- actor->daemonize();
+ actor::ActorImplPtr actor = actor::ActorImpl::create(arg);
}
}
class XBT_PRIVATE HostModel : public Model {
public:
using Model::Model;
+ virtual Action* execute_thread(const s4u::Host* host, double flops_amount, int thread_count) = 0;
+
virtual Action* execute_parallel(const std::vector<s4u::Host*>& host_list, const double* flops_amount,
const double* bytes_amount, double rate) = 0;
};
return action;
}
+Action* HostCLM03Model::execute_thread(const s4u::Host* host, double flops_amount, int thread_count)
+{
+ auto cpu = host->get_cpu();
+ /* Create a single action whose cost is thread_count * flops_amount and that requests thread_count cores. */
+ return cpu->execution_start(thread_count * flops_amount, thread_count, -1);
+}
+
} // namespace resource
} // namespace kernel
} // namespace simgrid
using HostModel::HostModel;
double next_occurring_event(double now) override;
void update_actions_state(double now, double delta) override;
+ Action* execute_thread(const s4u::Host* host, double flops_amount, int thread_count) override;
Action* execute_parallel(const std::vector<s4u::Host*>& host_list, const double* flops_amount,
const double* bytes_amount, double rate) override;
};
#include <xbt/config.hpp>
#include "src/kernel/EngineImpl.hpp"
+#include "src/kernel/lmm/bmf.hpp"
#include "src/kernel/resource/profile/Event.hpp"
#include "src/surf/ptask_L07.hpp"
{
XBT_CINFO(xbt_cfg, "Switching to the L07 model to handle parallel tasks.");
- auto host_model = std::make_shared<simgrid::kernel::resource::HostL07Model>("Host_Ptask");
+ auto* system = new simgrid::kernel::lmm::FairBottleneck(true /* selective update */);
+ auto host_model = std::make_shared<simgrid::kernel::resource::HostL07Model>("Host_Ptask", system);
+ auto* engine = simgrid::kernel::EngineImpl::get_instance();
+ engine->add_model(host_model);
+ engine->get_netzone_root()->set_host_model(host_model);
+}
+
+void surf_host_model_init_ptask_BMF()
+{
+ XBT_CINFO(xbt_cfg, "Switching to the BMF model to handle parallel tasks.");
+
+ bool select = simgrid::config::get_value<bool>("bmf/selective-update");
+ auto* system = new simgrid::kernel::lmm::BmfSystem(select);
+ auto host_model = std::make_shared<simgrid::kernel::resource::HostL07Model>("Host_Ptask", system);
auto* engine = simgrid::kernel::EngineImpl::get_instance();
engine->add_model(host_model);
engine->get_netzone_root()->set_host_model(host_model);
namespace kernel {
namespace resource {
-HostL07Model::HostL07Model(const std::string& name) : HostModel(name)
+HostL07Model::HostL07Model(const std::string& name, lmm::System* sys) : HostModel(name)
{
- auto* maxmin_system = new lmm::FairBottleneck(true /* selective update */);
- set_maxmin_system(maxmin_system);
+ set_maxmin_system(sys);
- auto net_model = std::make_shared<NetworkL07Model>("Network_Ptask", this, maxmin_system);
+ auto net_model = std::make_shared<NetworkL07Model>("Network_Ptask", this, sys);
auto engine = EngineImpl::get_instance();
engine->add_model(net_model);
engine->get_netzone_root()->set_network_model(net_model);
- auto cpu_model = std::make_shared<CpuL07Model>("Cpu_Ptask", this, maxmin_system);
+ auto cpu_model = std::make_shared<CpuL07Model>("Cpu_Ptask", this, sys);
engine->add_model(cpu_model);
engine->get_netzone_root()->set_cpu_pm_model(cpu_model);
}
/* Expand it for the CPUs even if there is nothing to compute, to make sure that it gets expended even if there is no
* communication either */
for (size_t i = 0; i < host_list.size(); i++) {
- model->get_maxmin_system()->expand(host_list[i]->get_cpu()->get_constraint(), get_variable(),
- (flops_amount == nullptr ? 0.0 : flops_amount[i]));
+ model->get_maxmin_system()->expand_add(host_list[i]->get_cpu()->get_constraint(), get_variable(),
+ (flops_amount == nullptr ? 0.0 : flops_amount[i]));
}
if (bytes_amount != nullptr) {
*********/
class HostL07Model : public HostModel {
public:
- explicit HostL07Model(const std::string& name);
+ HostL07Model(const std::string& name, lmm::System* sys);
HostL07Model(const HostL07Model&) = delete;
HostL07Model& operator=(const HostL07Model&) = delete;
double next_occurring_event(double now) override;
void update_actions_state(double now, double delta) override;
+ Action* execute_thread(const s4u::Host* host, double flops_amount, int thread_count) override { return nullptr; }
CpuAction* execute_parallel(const std::vector<s4u::Host*>& host_list, const double* flops_amount,
const double* bytes_amount, double rate) override;
};
simgrid::kernel::actor::ActorCode code = factory(std::move(actor->args));
auto* arg = new simgrid::kernel::actor::ProcessArg(actor_name, code, nullptr, host, kill_time, actor->properties,
- auto_restart);
+ auto_restart, /*daemon=*/false, /*restart_count=*/0);
host->get_impl()->add_actor_at_boot(arg);
if (start_time > simgrid::s4u::Engine::get_clock()) {
arg = new simgrid::kernel::actor::ProcessArg(actor_name, code, nullptr, host, kill_time, actor->properties,
- auto_restart);
-
- XBT_DEBUG("Process %s@%s will be started at time %f", arg->name.c_str(), arg->host->get_cname(), start_time);
- simgrid::kernel::timer::Timer::set(start_time, [arg, auto_restart]() {
- simgrid::kernel::actor::ActorImplPtr new_actor =
- simgrid::kernel::actor::ActorImpl::create(arg->name.c_str(), arg->code, arg->data, arg->host, nullptr);
- new_actor->set_properties(arg->properties);
- if (arg->kill_time >= 0)
- new_actor->set_kill_time(arg->kill_time);
- if (auto_restart)
- new_actor->set_auto_restart(auto_restart);
+ auto_restart, /*daemon=*/false, /*restart_count=*/0);
+
+ XBT_DEBUG("Actor %s@%s will be started at time %f", arg->name.c_str(), arg->host->get_cname(), start_time);
+ simgrid::kernel::timer::Timer::set(start_time, [arg]() {
+ simgrid::kernel::actor::ActorImplPtr new_actor = simgrid::kernel::actor::ActorImpl::create(arg);
delete arg;
});
} else { // start_time <= simgrid::s4u::Engine::get_clock()
- XBT_DEBUG("Starting Process %s(%s) right now", arg->name.c_str(), host->get_cname());
+ XBT_DEBUG("Starting actor %s(%s) right now", arg->name.c_str(), host->get_cname());
try {
- simgrid::kernel::actor::ActorImplPtr new_actor = nullptr;
- new_actor = simgrid::kernel::actor::ActorImpl::create(arg->name.c_str(), code, nullptr, host, nullptr);
- new_actor->set_properties(arg->properties);
- /* The actor creation will fail if the host is currently dead, but that's fine */
- if (arg->kill_time >= 0)
- new_actor->set_kill_time(arg->kill_time);
- if (auto_restart)
- new_actor->set_auto_restart(auto_restart);
+ simgrid::kernel::actor::ActorImplPtr new_actor = simgrid::kernel::actor::ActorImpl::create(arg);
} catch (simgrid::HostFailureException const&) {
- XBT_WARN("Deployment includes some initially turned off Hosts ... nevermind.");
+ XBT_WARN("Starting actor %s(%s) failed because its host is turned off.", arg->name.c_str(), host->get_cname());
}
}
}
&surf_host_model_init_compound},
{"ptask_L07", "Host model somehow similar to Cas01+CM02 but allowing parallel tasks",
&surf_host_model_init_ptask_L07},
+ {"ptask_BMF", "Host model which implements BMF resource allocation and allows parallel tasks",
+ &surf_host_model_init_ptask_BMF},
};
const std::vector<surf_model_description_t> surf_optimization_mode_description = {
XBT_PUBLIC_DATA double sg_maxmin_precision;
XBT_PUBLIC_DATA double sg_surf_precision;
XBT_PUBLIC_DATA int sg_concurrency_limit;
+XBT_PUBLIC_DATA int sg_bmf_max_iterations;
extern XBT_PRIVATE double sg_latency_factor;
extern XBT_PRIVATE double sg_bandwidth_factor;
*/
XBT_PUBLIC void surf_host_model_init_ptask_L07();
+/** @ingroup SURF_models
+ * @brief Initializes the platform with the model BMF
+ *
+ * With this model, only parallel tasks can be used.
+ * Resource sharing is done by calculating a BMF (bottleneck max fairness) allocation
+ */
+XBT_PUBLIC void surf_host_model_init_ptask_BMF();
+
XBT_PUBLIC void surf_disk_model_init_default();
/* --------------------
-foreach(x cloud-sharing ptask_L07_usage wifi_usage wifi_usage_decay cm02-set-lat-bw)
+foreach(x cloud-sharing ptask_L07_usage ptask-subflows wifi_usage wifi_usage_decay cm02-set-lat-bw)
add_executable (${x} EXCLUDE_FROM_ALL ${x}/${x}.cpp)
target_link_libraries(${x} simgrid)
set_target_properties(${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x})
--- /dev/null
+/* Copyright (c) 2007-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. */
+
+#include <simgrid/s4u.hpp>
+
+namespace sg4 = simgrid::s4u;
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(ptask_subflows_test, "Messages specific for this s4u example");
+
+static void ptask(sg4::Host* recv, sg4::Host* sender)
+{
+ XBT_INFO("TEST: 1 parallel task with 2 flows");
+ XBT_INFO("Parallel task sends 1.5B to other host.");
+ XBT_INFO("Same result for L07 and BMF since the ptask is alone.");
+ XBT_INFO("Should be done in 2.5 seconds: 1s latency and 1.5 second for transfer");
+
+ double start_time = sg4::Engine::get_clock();
+ sg4::Exec::init()
+ ->set_bytes_amounts(std::vector<double>({0.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0}))
+ ->set_hosts(std::vector<sg4::Host*>({sender, sender, recv}))
+ ->wait();
+ double end_time = sg4::Engine::get_clock();
+ XBT_INFO("Parallel task finished after %lf seconds", end_time - start_time);
+
+ XBT_INFO("TEST: Same parallel task but with a noisy communication at the side");
+ XBT_INFO("Parallel task sends 1.5B to other host.");
+ XBT_INFO("With BMF: Should be done in 3.5 seconds: 1s latency and 2 second for transfer.");
+ XBT_INFO("With L07: Should be done in 4 seconds: 1s latency and 3 second for transfer.");
+ XBT_INFO("With BMF, ptask gets 50%% more bandwidth than the noisy flow (because of the sub).");
+ start_time = sg4::Engine::get_clock();
+ auto noisy = sg4::Comm::sendto_async(sender, recv, 10);
+ sg4::Exec::init()
+ ->set_bytes_amounts(std::vector<double>({0.0, 0.0, 1.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0}))
+ ->set_hosts(std::vector<sg4::Host*>({sender, sender, recv}))
+ ->wait();
+ end_time = sg4::Engine::get_clock();
+ XBT_INFO("Parallel task finished after %lf seconds", end_time - start_time);
+ noisy->wait(); // gracefully wait the noisy flow
+}
+
+int main(int argc, char* argv[])
+{
+ sg4::Engine e(&argc, argv);
+
+ auto* rootzone = sg4::create_full_zone("root");
+ auto* hostA = rootzone->create_host("hostA", 1e9);
+ auto* hostB = rootzone->create_host("hostB", 1e9);
+ sg4::LinkInRoute link(rootzone->create_link("backbone", "1")->set_latency("1s")->seal());
+ rootzone->add_route(hostA->get_netpoint(), hostB->get_netpoint(), nullptr, nullptr, {link}, true);
+ rootzone->seal();
+
+ sg4::Actor::create("ptask", hostA, ptask, hostA, hostB);
+
+ e.run();
+
+ return 0;
+}
--- /dev/null
+p Test subflows with new BMF model
+$ ${bindir:=.}/ptask-subflows --cfg=host/model:ptask_BMF
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'host/model' to 'ptask_BMF'
+> [0.000000] [xbt_cfg/INFO] Switching to the BMF model to handle parallel tasks.
+> [hostA:ptask:(1) 0.000000] [ptask_subflows_test/INFO] TEST: 1 parallel task with 2 flows
+> [hostA:ptask:(1) 0.000000] [ptask_subflows_test/INFO] Parallel task sends 1.5B to other host.
+> [hostA:ptask:(1) 0.000000] [ptask_subflows_test/INFO] Same result for L07 and BMF since the ptask is alone.
+> [hostA:ptask:(1) 0.000000] [ptask_subflows_test/INFO] Should be done in 2.5 seconds: 1s latency and 1.5 second for transfer
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] Parallel task finished after 2.500000 seconds
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] TEST: Same parallel task but with a noisy communication at the side
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] Parallel task sends 1.5B to other host.
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] With BMF: Should be done in 3.5 seconds: 1s latency and 2 second for transfer.
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] With L07: Should be done in 4 seconds: 1s latency and 3 second for transfer.
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] With BMF, ptask gets 50% more bandwidth than the noisy flow (because of the sub).
+> [hostA:ptask:(1) 6.000000] [ptask_subflows_test/INFO] Parallel task finished after 3.500000 seconds
+
+
+p Test subflows with old L07 model to verify the difference
+$ ${bindir:=.}/ptask-subflows --cfg=host/model:ptask_L07
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'host/model' to 'ptask_L07'
+> [0.000000] [xbt_cfg/INFO] Switching to the L07 model to handle parallel tasks.
+> [hostA:ptask:(1) 0.000000] [ptask_subflows_test/INFO] TEST: 1 parallel task with 2 flows
+> [hostA:ptask:(1) 0.000000] [ptask_subflows_test/INFO] Parallel task sends 1.5B to other host.
+> [hostA:ptask:(1) 0.000000] [ptask_subflows_test/INFO] Same result for L07 and BMF since the ptask is alone.
+> [hostA:ptask:(1) 0.000000] [ptask_subflows_test/INFO] Should be done in 2.5 seconds: 1s latency and 1.5 second for transfer
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] Parallel task finished after 2.500000 seconds
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] TEST: Same parallel task but with a noisy communication at the side
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] Parallel task sends 1.5B to other host.
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] With BMF: Should be done in 3.5 seconds: 1s latency and 2 second for transfer.
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] With L07: Should be done in 4 seconds: 1s latency and 3 second for transfer.
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] With BMF, ptask gets 50% more bandwidth than the noisy flow (because of the sub).
+> [hostA:ptask:(1) 6.500000] [ptask_subflows_test/INFO] Parallel task finished after 4.000000 seconds
+
+p Test selective_update enable
+$ ${bindir:=.}/ptask-subflows --cfg=host/model:ptask_BMF --cfg=bmf/selective-update:true
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'host/model' to 'ptask_BMF'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'bmf/selective-update' to 'true'
+> [0.000000] [xbt_cfg/INFO] Switching to the BMF model to handle parallel tasks.
+> [hostA:ptask:(1) 0.000000] [ptask_subflows_test/INFO] TEST: 1 parallel task with 2 flows
+> [hostA:ptask:(1) 0.000000] [ptask_subflows_test/INFO] Parallel task sends 1.5B to other host.
+> [hostA:ptask:(1) 0.000000] [ptask_subflows_test/INFO] Same result for L07 and BMF since the ptask is alone.
+> [hostA:ptask:(1) 0.000000] [ptask_subflows_test/INFO] Should be done in 2.5 seconds: 1s latency and 1.5 second for transfer
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] Parallel task finished after 2.500000 seconds
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] TEST: Same parallel task but with a noisy communication at the side
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] Parallel task sends 1.5B to other host.
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] With BMF: Should be done in 3.5 seconds: 1s latency and 2 second for transfer.
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] With L07: Should be done in 4 seconds: 1s latency and 3 second for transfer.
+> [hostA:ptask:(1) 2.500000] [ptask_subflows_test/INFO] With BMF, ptask gets 50% more bandwidth than the noisy flow (because of the sub).
+> [hostA:ptask:(1) 6.000000] [ptask_subflows_test/INFO] Parallel task finished after 3.500000 seconds
simgrid::s4u::this_actor::sleep_for(1.5);
};
-static simgrid::s4u::ActorPtr sender_basic(bool& ending_boolean, bool expected_success, double duration)
+static simgrid::s4u::ActorPtr sender_basic(bool& ending_boolean, bool expected_success, double duration,
+ double delay = -1.0)
{
- return simgrid::s4u::Actor::create("sender", all_hosts[1], [&ending_boolean, expected_success, duration]() {
+ return simgrid::s4u::Actor::create("sender", all_hosts[1], [&ending_boolean, expected_success, duration, delay]() {
assert_exit(expected_success, duration);
// Encapsulate the payload in a std::unique_ptr so that it is correctly free'd if/when the sender is killed during
// its communication (thanks to RAII). The pointer is then released when the communication is over.
std::unique_ptr<char, decltype(&xbt_free_f)> payload(xbt_strdup("toto"), &xbt_free_f);
- simgrid::s4u::Mailbox::by_name("mb")->put(payload.get(), 5000);
+ if (delay > 0.0) {
+ simgrid::s4u::this_actor::sleep_for(delay / 2.0);
+ auto comm = simgrid::s4u::Mailbox::by_name("mb")->put_init(payload.get(), 5000);
+ simgrid::s4u::this_actor::sleep_for(delay / 2.0);
+ comm->wait();
+ } else {
+ simgrid::s4u::Mailbox::by_name("mb")->put(payload.get(), 5000);
+ }
payload.release();
ending_boolean = true;
});
}
-static simgrid::s4u::ActorPtr receiver_basic(bool& ending_boolean, bool expected_success, double duration)
+static simgrid::s4u::ActorPtr receiver_basic(bool& ending_boolean, bool expected_success, double duration,
+ double delay = -1.0)
{
- return simgrid::s4u::Actor::create("receiver", all_hosts[2], [&ending_boolean, expected_success, duration]() {
+ return simgrid::s4u::Actor::create("receiver", all_hosts[2], [&ending_boolean, expected_success, duration, delay]() {
assert_exit(expected_success, duration);
- char* payload = simgrid::s4u::Mailbox::by_name("mb")->get<char>();
+ char* payload;
+ if (delay > 0.0) {
+ simgrid::s4u::this_actor::sleep_for(delay / 2.0);
+ auto comm = simgrid::s4u::Mailbox::by_name("mb")->get_init()->set_dst_data(reinterpret_cast<void**>(&payload),
+ sizeof(void*));
+ simgrid::s4u::this_actor::sleep_for(delay / 2.0);
+ comm->wait();
+ } else {
+ payload = simgrid::s4u::Mailbox::by_name("mb")->get<char>();
+ }
xbt_free(payload);
ending_boolean = true;
});
END_SECTION;
}
+ BEGIN_SECTION("comm (delayed send)")
+ {
+ XBT_INFO("Launch a communication with a delay for the send");
+ bool send_done = false;
+ bool recv_done = false;
+
+ sender_basic(send_done, true, 6, 1); // cover Comm::send
+ receiver_basic(recv_done, true, 6);
+
+ simgrid::s4u::this_actor::sleep_for(9);
+ INFO("Sender or receiver killed somehow. It shouldn't");
+ REQUIRE(send_done);
+ REQUIRE(recv_done);
+
+ END_SECTION;
+ }
+
+ BEGIN_SECTION("comm (delayed recv)")
+ {
+ XBT_INFO("Launch a communication with a delay for the recv");
+ bool send_done = false;
+ bool recv_done = false;
+
+ sender_basic(send_done, true, 6);
+ receiver_basic(recv_done, true, 6, 1); // cover Comm::recv
+
+ simgrid::s4u::this_actor::sleep_for(9);
+ INFO("Sender or receiver killed somehow. It shouldn't");
+ REQUIRE(send_done);
+ REQUIRE(recv_done);
+
+ END_SECTION;
+ }
+
BEGIN_SECTION("comm dsend and quit (put before get)")
{
XBT_INFO("Launch a detached communication and end right after");
static void dummy()
{
XBT_INFO("I start");
- simgrid::s4u::this_actor::sleep_for(200);
- XBT_INFO("I stop");
+ simgrid::s4u::this_actor::sleep_for(200);
+ XBT_INFO("I stop");
}
static void dummy_daemon()
{
- simgrid::s4u::Actor::self()->daemonize();
while (simgrid::s4u::this_actor::get_host()->is_on()) {
XBT_INFO("Hello from the infinite loop");
simgrid::s4u::this_actor::sleep_for(80.0);
XBT_INFO("starting a dummy process on %s", host->get_cname());
simgrid::s4u::ActorPtr dummy_actor = simgrid::s4u::Actor::create("Dummy", host, dummy);
- dummy_actor->on_exit([](bool) { XBT_INFO("On_exit callback set before autorestart"); });
+ dummy_actor->on_exit([](bool failed) { XBT_INFO("Dummy actor %s.", failed ? "failed" : "terminating"); });
dummy_actor->set_auto_restart(true);
dummy_actor->on_exit([](bool) { XBT_INFO("On_exit callback set after autorestart"); });
XBT_INFO("starting a daemon process on %s", host->get_cname());
simgrid::s4u::ActorPtr daemon_actor = simgrid::s4u::Actor::create("Daemon", host, dummy_daemon);
- daemon_actor->on_exit([](bool) { XBT_INFO("On_exit callback set before autorestart"); });
- daemon_actor->set_auto_restart(true);
+ daemon_actor->on_exit([](bool failed) { XBT_INFO("Daemon actor %s.", failed ? "failed" : "terminating"); });
+ daemon_actor->daemonize()->set_auto_restart(true);
daemon_actor->on_exit([](bool) { XBT_INFO("On_exit callback set after autorestart"); });
simgrid::s4u::this_actor::sleep_for(50);
> [Fafard:Daemon:(3) 0.000000] [s4u_test/INFO] Hello from the infinite loop
> [Tremblay:Autostart:(1) 50.000000] [s4u_test/INFO] powering off Fafard
> [Fafard:Dummy:(2) 50.000000] [s4u_test/INFO] On_exit callback set after autorestart
-> [Fafard:Dummy:(2) 50.000000] [s4u_test/INFO] On_exit callback set before autorestart
+> [Fafard:Dummy:(2) 50.000000] [s4u_test/INFO] Dummy actor failed.
> [Fafard:Daemon:(3) 50.000000] [s4u_test/INFO] On_exit callback set after autorestart
-> [Fafard:Daemon:(3) 50.000000] [s4u_test/INFO] On_exit callback set before autorestart
+> [Fafard:Daemon:(3) 50.000000] [s4u_test/INFO] Daemon actor failed.
> [Tremblay:Autostart:(1) 60.000000] [s4u_test/INFO] powering on Fafard
> [Fafard:Dummy:(4) 60.000000] [s4u_test/INFO] I start
> [Fafard:Daemon:(5) 60.000000] [s4u_test/INFO] Hello from the infinite loop
> [Fafard:Daemon:(5) 220.000000] [s4u_test/INFO] Hello from the infinite loop
> [Fafard:Dummy:(4) 260.000000] [s4u_test/INFO] I stop
> [Fafard:Dummy:(4) 260.000000] [s4u_test/INFO] On_exit callback set after autorestart
-> [Fafard:Dummy:(4) 260.000000] [s4u_test/INFO] On_exit callback set before autorestart
+> [Fafard:Dummy:(4) 260.000000] [s4u_test/INFO] Dummy actor terminating.
> [Fafard:Daemon:(5) 260.000000] [s4u_test/INFO] On_exit callback set after autorestart
-> [Fafard:Daemon:(5) 260.000000] [s4u_test/INFO] On_exit callback set before autorestart
+> [Fafard:Daemon:(5) 260.000000] [s4u_test/INFO] Daemon actor failed.
> [260.000000] [s4u_test/INFO] Simulation time 260
simgrid::s4u::Engine::get_instance()->get_actor_count(), tasks_done);
break;
case 2:
- // Create an actorthat on a host that is turned off (this is not allowed)
+ // Create an actor on an host that is turned off (this is not allowed)
XBT_INFO("Test 2:");
XBT_INFO(" Turn off Jupiter");
// adsein: Jupiter is already off, hence nothing should happen
simgrid::s4u::this_actor::sleep_for(10);
XBT_INFO(" Turn Jupiter off");
jupiter->turn_off();
+ simgrid::s4u::this_actor::sleep_for(1); // Allow some time to the other actors to die
XBT_INFO("Test 4 is ok. (number of actors : %zu, it should be 1 or 2 if RX has not been satisfied)."
" An exception is raised when we turn off a node that has an actor sleeping",
simgrid::s4u::Engine::get_instance()->get_actor_count());
simgrid::s4u::this_actor::sleep_for(10);
XBT_INFO(" Turn Jupiter off");
jupiter->turn_off();
+ simgrid::s4u::this_actor::sleep_for(1); // Allow some time to the other actors to die
XBT_INFO("Test 5 seems ok (number of actors: %zu, it should be 2)",
simgrid::s4u::Engine::get_instance()->get_actor_count());
break;
> [Jupiter:commTX:(3) 10.000000] [s4u_test/INFO] Start TX
> [Tremblay:test_launcher:(1) 10.000000] [s4u_test/INFO] number of actors: 3
> [Tremblay:test_launcher:(1) 20.000000] [s4u_test/INFO] Turn Jupiter off
-> [Tremblay:test_launcher:(1) 20.000000] [s4u_test/INFO] Test 4 is ok. (number of actors : 2, it should be 1 or 2 if RX has not been satisfied). An exception is raised when we turn off a node that has an actor sleeping
-> [Tremblay:test_launcher:(1) 20.000000] [s4u_test/INFO] Test done. See you!
+> [Tremblay:test_launcher:(1) 21.000000] [s4u_test/INFO] Test 4 is ok. (number of actors : 2, it should be 1 or 2 if RX has not been satisfied). An exception is raised when we turn off a node that has an actor sleeping
+> [Tremblay:test_launcher:(1) 21.000000] [s4u_test/INFO] Test done. See you!
> [Tremblay:commRX:(2) 25.033047] [s4u_test/INFO] Receive message: TRANSFER_FAILURE
> [Tremblay:commRX:(2) 25.033047] [s4u_test/INFO] RX Done
> [25.033047] [s4u_test/INFO] Simulation time 25.033
> [Tremblay:commTX:(3) 10.000000] [s4u_test/INFO] Start TX
> [Tremblay:test_launcher:(1) 10.000000] [s4u_test/INFO] number of actors: 3
> [Tremblay:test_launcher:(1) 20.000000] [s4u_test/INFO] Turn Jupiter off
-> [Tremblay:test_launcher:(1) 20.000000] [s4u_test/INFO] Test 5 seems ok (number of actors: 2, it should be 2)
-> [Tremblay:test_launcher:(1) 20.000000] [s4u_test/INFO] Test done. See you!
+> [Tremblay:test_launcher:(1) 21.000000] [s4u_test/INFO] Test 5 seems ok (number of actors: 2, it should be 2)
+> [Tremblay:test_launcher:(1) 21.000000] [s4u_test/INFO] Test done. See you!
> [Tremblay:commTX:(3) 40.000000] [s4u_test/INFO] TX done
> [40.000000] [s4u_test/INFO] Simulation time 40
static simgrid::config::Flag<int> cfg_host_count{"host-count", "Host count (master on one, workers on the others)", 3};
static simgrid::config::Flag<double> cfg_deadline{"deadline", "When to fail the simulation (infinite loop detection)",
120};
-static simgrid::config::Flag<int> cfg_task_count{"task-count", "Amount of tasks that must be executed to succeed", 2};
+static simgrid::config::Flag<int> cfg_task_count{"task-count", "Amount of tasks that must be executed to succeed", 1};
int todo; // remaining amount of tasks to execute, a global variable
sg4::Mailbox* mailbox; // as a global to reduce the amount of simcalls during actor reboot
{
double comp_size = 1e6;
long comm_size = 1e6;
- XBT_INFO("Master booting");
- sg4::Actor::self()->daemonize();
- sg4::this_actor::on_exit(
- [](bool forcefully) { XBT_INFO("Master dying %s.", forcefully ? "forcefully" : "peacefully"); });
+ bool rebooting = sg4::Actor::self()->get_restart_count() > 0;
+
+ XBT_INFO("Master %s", rebooting ? "rebooting" : "booting");
+ if (not rebooting) // Starting for the first time
+ sg4::this_actor::on_exit(
+ [](bool forcefully) { XBT_INFO("Master dying %s.", forcefully ? "forcefully" : "peacefully"); });
while (true) { // This is a daemon
xbt_assert(sg4::Engine::get_clock() < cfg_deadline,
static void worker(int id)
{
- XBT_INFO("Worker booting");
- sg4::this_actor::on_exit(
- [id](bool forcefully) { XBT_INFO("worker %d dying %s.", id, forcefully ? "forcefully" : "peacefully"); });
+ bool rebooting = sg4::Actor::self()->get_restart_count() > 0;
+
+ XBT_INFO("Worker %s", rebooting ? "rebooting" : "booting");
+ if (not rebooting) // Starting for the first time
+ sg4::this_actor::on_exit(
+ [id](bool forcefully) { XBT_INFO("worker %d dying %s.", id, forcefully ? "forcefully" : "peacefully"); });
while (todo > 0) {
xbt_assert(sg4::Engine::get_clock() < cfg_deadline,
}
rootzone->seal();
- sg4::Actor::create("master", main, master)->set_auto_restart(true);
+ sg4::Actor::create("master", main, master)->daemonize()->set_auto_restart(true);
int id = 0;
for (auto* h : worker_hosts) {
sg4::Actor::create("worker", h, worker, id)->set_auto_restart(true);
p Smoke test: do one arbitrary run of the monkey, just to make sure that *something* is happening.
-$ ${bindir:=.}/monkey-masterworkers --cfg=plugin:cmonkey --cfg=cmonkey/time:1 --cfg=cmonkey/host:1
+$ ${bindir:=.}/monkey-masterworkers --cfg=plugin:cmonkey --cfg=cmonkey/time:1 --cfg=cmonkey/host:1 --cfg=task-count:2
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'plugin' to 'cmonkey'
> [0.000000] [cmonkey/INFO] Initializing the chaos monkey
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'cmonkey/time' to '1'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'cmonkey/host' to '1'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'task-count' to '2'
> [lilibeth 0:master:(1) 0.000000] [s4u_test/INFO] Master booting
> [lilibeth 1:worker:(2) 0.000000] [s4u_test/INFO] Worker booting
> [lilibeth 2:worker:(3) 0.000000] [s4u_test/INFO] Worker booting
+> [lilibeth 0:master:(1) 0.000000] [s4u_test/INFO] Try to send a message
> [lilibeth 1:worker:(2) 0.000000] [s4u_test/INFO] Waiting a message on mailbox
> [lilibeth 2:worker:(3) 0.000000] [s4u_test/INFO] Waiting a message on mailbox
-> [lilibeth 0:master:(1) 0.000000] [s4u_test/INFO] Try to send a message
> [1.000000] [cmonkey/INFO] Kill host lilibeth 1
> [lilibeth 0:master:(1) 1.000000] [s4u_test/INFO] Got a NetworkFailureException. Wait a second before starting again.
> [lilibeth 1:worker:(2) 1.000000] [s4u_test/INFO] worker 0 dying forcefully.
> [lilibeth 2:worker:(3) 4.167573] [s4u_test/INFO] worker 1 dying peacefully.
> [lilibeth 0:master:(1) 4.167573] [s4u_test/INFO] Master dying forcefully.
> [31.000000] [cmonkey/INFO] Restart host lilibeth 1
-> [lilibeth 1:worker:(4) 31.000000] [s4u_test/INFO] Worker booting
-> [lilibeth 1:worker:(4) 31.000000] [s4u_test/INFO] worker 0 dying peacefully.
+> [lilibeth 1:worker:(4) 31.000000] [s4u_test/INFO] Worker rebooting
> [lilibeth 1:worker:(4) 31.000000] [s4u_test/INFO] worker 0 dying peacefully.
> [31.000000] [cmonkey/INFO] Chaos Monkey done!
> [31.000000] [s4u_test/INFO] WE SURVIVED!
XBT_LOG_NEW_DEFAULT_CATEGORY(sem_monkey, "Simple test of the semaphore");
-int buffer; /* Where the data is exchanged */
-sg4::SemaphorePtr sem_empty = sg4::Semaphore::create(1); /* indicates whether the buffer is empty */
-sg4::SemaphorePtr sem_full = sg4::Semaphore::create(0); /* indicates whether the buffer is full */
-
static simgrid::config::Flag<int> cfg_item_count{"item-count", "Amount of items that must be exchanged to succeed", 2};
static simgrid::config::Flag<double> cfg_deadline{"deadline", "When to fail the simulation (infinite loop detection)",
120};
-int todo; // remaining amount of items to exchange
+struct SharedBuffer {
+ int value = 0; /* Where the data is exchanged */
+ sg4::SemaphorePtr sem_empty = sg4::Semaphore::create(1); /* indicates whether the buffer is empty */
+ sg4::SemaphorePtr sem_full = sg4::Semaphore::create(0); /* indicates whether the buffer is full */
+};
+
+// A stack to keep track of semaphores. When destroyed, semaphores remaining on stack are automatically released.
+class SemStack {
+ std::vector<sg4::Semaphore*> to_release;
+
+public:
+ SemStack() = default;
+ SemStack(const SemStack&) = delete;
+ SemStack& operator=(const SemStack&) = delete;
+ ~SemStack()
+ {
+ for (auto* sem : to_release) {
+ sem->release();
+ XBT_INFO("Released a semaphore on exit. It's now %d", sem->get_capacity());
+ }
+ }
+ void push(const sg4::SemaphorePtr& sem) { to_release.push_back(sem.get()); }
+ void pop() { to_release.pop_back(); }
+};
-static void producer()
+static void producer(SharedBuffer& buf)
{
- static bool inited = false;
- static std::vector<sg4::Semaphore*> to_release;
- XBT_INFO("Producer %s", inited ? "rebooting" : "booting");
+ static int todo = cfg_item_count; // remaining amount of items to exchange
+ SemStack to_release;
+ bool rebooting = sg4::Actor::self()->get_restart_count() > 0;
- if (not inited) {
+ XBT_INFO("Producer %s", rebooting ? "rebooting" : "booting");
+ if (not rebooting) // Starting for the first time
sg4::this_actor::on_exit(
[](bool forcefully) { XBT_INFO("Producer dying %s.", forcefully ? "forcefully" : "peacefully"); });
- inited = true;
- }
- while (not to_release.empty()) { // Clean up a previous run. Cannot be done in on_exit, as it entails a simcall
- auto* sem = to_release.back();
- sem->release();
- XBT_INFO("Released a semaphore on reboot. It's now %d", sem->get_capacity());
- to_release.pop_back();
- }
while (todo > 0) {
xbt_assert(sg4::Engine::get_clock() < cfg_deadline,
sg4::this_actor::sleep_for(1); // Give a chance to the monkey to kill this actor at this point
- while (sem_empty->acquire_timeout(10))
+ while (buf.sem_empty->acquire_timeout(10))
XBT_INFO("Timeouted");
- to_release.push_back(sem_empty.get());
+ to_release.push(buf.sem_empty);
XBT_INFO("sem_empty acquired");
sg4::this_actor::sleep_for(1); // Give a chance to the monkey to kill this actor at this point
XBT_INFO("Pushing item %d", todo - 1);
- buffer = todo - 1;
- sem_full->release();
- to_release.pop_back();
+ buf.value = todo - 1;
+ buf.sem_full->release();
+ to_release.pop();
XBT_INFO("sem_empty removed from to_release");
todo--;
}
}
-static void consumer()
+
+static void consumer(const SharedBuffer& buf)
{
- static std::vector<sg4::Semaphore*> to_release;
+ SemStack to_release;
+ bool rebooting = sg4::Actor::self()->get_restart_count() > 0;
- static bool inited = false;
- XBT_INFO("Consumer %s", inited ? "rebooting" : "booting");
- if (not inited) {
+ XBT_INFO("Consumer %s", rebooting ? "rebooting" : "booting");
+ if (not rebooting) // Starting for the first time
sg4::this_actor::on_exit(
[](bool forcefully) { XBT_INFO("Consumer dying %s.", forcefully ? "forcefully" : "peacefully"); });
- inited = true;
- }
- while (not to_release.empty()) { // Clean up a previous run. Cannot be done in on_exit, as it entails a simcall
- auto* sem = to_release.back();
- sem->release();
- XBT_INFO("Released a semaphore on reboot. It's now %d", sem->get_capacity());
- to_release.pop_back();
- }
int item;
do {
sg4::this_actor::sleep_for(0.75); // Give a chance to the monkey to kill this actor at this point
- while (sem_full->acquire_timeout(10))
+ while (buf.sem_full->acquire_timeout(10))
XBT_INFO("Timeouted");
- to_release.push_back(sem_full.get());
+ to_release.push(buf.sem_full);
sg4::this_actor::sleep_for(0.75); // Give a chance to the monkey to kill this actor at this point
- item = buffer;
+ item = buf.value;
XBT_INFO("Receiving item %d", item);
- sem_empty->release();
- to_release.pop_back();
+ buf.sem_empty->release();
+ to_release.pop();
} while (item != 0);
XBT_INFO("Bye!");
{
sg4::Engine e(&argc, argv);
- todo = cfg_item_count;
auto* rootzone = sg4::create_full_zone("root");
auto* paul = rootzone->create_host("Paul", 1e9);
auto* carol = rootzone->create_host("Carol", 1e9);
sg4::LinkInRoute link(rootzone->create_link("link", "1MBps")->set_latency("24us")->seal());
rootzone->add_route(paul->get_netpoint(), carol->get_netpoint(), nullptr, nullptr, {link}, true);
- sg4::Actor::create("producer", paul, producer)->set_auto_restart();
- sg4::Actor::create("consumer", carol, consumer)->set_auto_restart();
+ SharedBuffer buffer;
+ sg4::Actor::create("producer", paul, producer, std::ref(buffer))->set_auto_restart();
+ sg4::Actor::create("consumer", carol, consumer, std::cref(buffer))->set_auto_restart();
e.run();
return 0;
file(GLOB cfiles RELATIVE ${CMAKE_BINARY_DIR}/MBI/tmp ${CMAKE_BINARY_DIR}/MBI/tmp/*.c )
foreach(cfile ${cfiles})
- # Copy the generated files only if different
- file(COPY_FILE ${CMAKE_BINARY_DIR}/MBI/tmp/${cfile} ${CMAKE_BINARY_DIR}/MBI/${cfile} ONLY_IF_DIFFERENT)
+ # Copy the generated files only if different (needs cmake ≥ 3.21)
+ if (CMAKE_VERSION VERSION_LESS 3.21)
+ file(COPY ${CMAKE_BINARY_DIR}/MBI/tmp/${cfile} DESTINATION ${CMAKE_BINARY_DIR}/MBI/)
+ else()
+ file(COPY_FILE ${CMAKE_BINARY_DIR}/MBI/tmp/${cfile} ${CMAKE_BINARY_DIR}/MBI/${cfile} ONLY_IF_DIFFERENT)
+ endif()
string(REGEX REPLACE "[.]c" "" basefile ${cfile})
# Generate an executable for each of them
SET_TESTS_PROPERTIES(mbi-${basefile} PROPERTIES DEPENDS mbi-${basefile})
SET_TESTS_PROPERTIES(mbi-${basefile} PROPERTIES DEPENDS simgrid-mc)
endforeach()
+ file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/MBI/tmp) # Clean temp files
if("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_HOME_DIRECTORY}")
else()
${CMAKE_CURRENT_SOURCE_DIR}/MBI.py
${CMAKE_CURRENT_SOURCE_DIR}/MBIutils.py
${CMAKE_CURRENT_SOURCE_DIR}/simgrid.py
- PARENT_SCOPE)
\ No newline at end of file
+ PARENT_SCOPE)
-# Copyright 2021-2022. The MBI project. All rights reserved.
+# Copyright 2021-2022. The MBI project. All rights reserved.
# This program is free software; you can redistribute it and/or modify it under the terms of the license (GNU GPL).
# This is a simple templating system, dedicated to the systematic generation of MPI source code
init['MPI_Comm_split'] = lambda n: f'MPI_Comm com[size]; color = rank % 2; int key = 1;'
start['MPI_Comm_split'] = lambda n: ""
-operation['MPI_Comm_split'] = lambda n: 'MPI_Comm_split(MPI_COMM_WORLD,color,key, com + j);'
+operation['MPI_Comm_split'] = lambda n: 'MPI_Comm_split(MPI_COMM_WORLD,color,key, &com[j]);'
error['MPI_Comm_split'] = 'CommunicatorLeak'
-fini['MPI_Comm_split'] = lambda n: "if(com[j] != MPI_COMM_NULL) MPI_Comm_free(com + j);"
+fini['MPI_Comm_split'] = lambda n: "if(com[j] != MPI_COMM_NULL) MPI_Comm_free(&com[j]);"
free['MPI_Comm_split'] = lambda n: ""
free['MPI_Op_create'] = lambda n: ""
init['MPI_Comm_group'] = lambda n: 'MPI_Group grp[size];'
-operation['MPI_Comm_group'] = lambda n: 'MPI_Comm_group(MPI_COMM_WORLD, grp + j);'
+operation['MPI_Comm_group'] = lambda n: 'MPI_Comm_group(MPI_COMM_WORLD, &grp[j]);'
error['MPI_Comm_group'] = 'GroupLeak'
-fini['MPI_Comm_group'] = lambda n: "MPI_Group_free(grp + j);"
+fini['MPI_Comm_group'] = lambda n: "MPI_Group_free(&grp[j]);"
free['MPI_Comm_group'] = lambda n: ""
init['MPI_Group_excl'] = lambda n: 'MPI_Group worldgroup, grp[size];\n MPI_Comm_group(MPI_COMM_WORLD, &worldgroup);'
-operation['MPI_Group_excl'] = lambda n: 'MPI_Group_excl(worldgroup, 1, &rank, grp + j);'
+operation['MPI_Group_excl'] = lambda n: 'MPI_Group_excl(worldgroup, 1, &rank, &grp[j]);'
error['MPI_Group_excl'] = 'GroupLeak'
-fini['MPI_Group_excl'] = lambda n: "MPI_Group_free(grp + j);"
+fini['MPI_Group_excl'] = lambda n: "MPI_Group_free(&grp[j]);"
free['MPI_Group_excl'] = lambda n: "MPI_Group_free(&worldgroup);"
init['MPI_Comm_create'] = lambda n: 'MPI_Comm com[size]; MPI_Group grp[size];'
-operation['MPI_Comm_create'] = lambda n: 'MPI_Comm_group(MPI_COMM_WORLD, grp + j);\n MPI_Comm_create(MPI_COMM_WORLD, grp[j], com + j);\n MPI_Group_free(grp + j);'
+operation['MPI_Comm_create'] = lambda n: 'MPI_Comm_group(MPI_COMM_WORLD, &grp[j]);\n MPI_Comm_create(MPI_COMM_WORLD, grp[j], &com[j]);\n MPI_Group_free(&grp[j]);'
error['MPI_Comm_create'] = 'CommunicatorLeak'
-fini['MPI_Comm_create'] = lambda n: "MPI_Comm_free(com + j);"
+fini['MPI_Comm_create'] = lambda n: "MPI_Comm_free(&com[j]);"
free['MPI_Comm_create'] = lambda n: ""
init['MPI_Comm_dup'] = lambda n: f'MPI_Comm com[size];'
-operation['MPI_Comm_dup'] = lambda n: 'MPI_Comm_dup(MPI_COMM_WORLD, com + j);'
+operation['MPI_Comm_dup'] = lambda n: 'MPI_Comm_dup(MPI_COMM_WORLD, &com[j]);'
error['MPI_Comm_dup'] = 'CommunicatorLeak'
-fini['MPI_Comm_dup'] = lambda n: "MPI_Comm_free(com + j);"
+fini['MPI_Comm_dup'] = lambda n: "MPI_Comm_free(&com[j]);"
free['MPI_Comm_dup'] = lambda n: ""
init['MPI_Type_contiguous'] = lambda n: 'MPI_Datatype type[size];'
def parse(self, cachefile):
if os.path.exists(f'{cachefile}.timeout') or os.path.exists(f'logs/simgrid/{cachefile}.timeout'):
- outcome = 'timeout'
+ return 'timeout'
if not (os.path.exists(f'{cachefile}.txt') or os.path.exists(f'logs/simgrid/{cachefile}.txt')):
return 'failure'
p Test allreduce
$ $VALGRIND_NO_LEAK_CHECK ${bindir:=.}/../../../smpi_script/bin/smpirun -wrapper "${bindir:=.}/../../../bin/simgrid-mc" -map -hostfile ../hostfile_coll -platform ${platfdir:=.}/small_platform.xml -np 4 --log=xbt_cfg.thres:critical ${bindir:=.}/coll-allreduce-with-leaks --log=smpi_config.thres:warning --cfg=smpi/display-allocs:yes --cfg=smpi/simulate-computation:no --log=smpi_coll.thres:error --log=smpi_mpi.thres:error --log=smpi_pmpi.thres:error --cfg=smpi/list-leaks:10 --log=no_loc
-> [0.000000] [mc_safety/INFO] Start a DFS exploration. Reduction is: dpor.
+> [0.000000] [mc_dfs/INFO] Start a DFS exploration. Reduction is: dpor.
> [0.000000] [smpi/INFO] [rank 0] -> Tremblay
> [0.000000] [smpi/INFO] [rank 1] -> Tremblay
> [0.000000] [smpi/INFO] [rank 2] -> Tremblay
> If this is too much, consider sharing allocations for computation buffers.
> This can be done automatically by setting --cfg=smpi/auto-shared-malloc-thresh to the minimum size wanted size (this can alter execution if data content is necessary)
>
-> [0.000000] [mc_safety/INFO] DFS exploration ended. 73 unique states visited; 18 backtracks (592 transition replays, 502 states visited overall)
+> [0.000000] [mc_dfs/INFO] DFS exploration ended. 73 unique states visited; 18 backtracks (592 transition replays, 502 states visited overall)
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/engine.h"
-#include "simgrid/simix.h" // we don't need it, but someone must check that this file is actually usable in plain C
#include <xbt.h>
+#define SIMIX_H_NO_DEPRECATED_WARNING // avoid deprecation warning on include (remove with XBT_ATTRIB_DEPRECATED_v335)
+#include "simgrid/simix.h" // we don't need it, but someone must check that this file is actually usable in plain C
+
XBT_LOG_NEW_DEFAULT_CATEGORY(test, "Logging specific to this test");
int main(int argc, char** argv)
src/include/xbt/xbt_modinter.h
src/include/catch.hpp
src/include/xxhash.hpp
+ src/kernel/actor/Simcall.hpp
src/kernel/resource/LinkImpl.hpp
src/kernel/resource/SplitDuplexLinkImpl.hpp
src/kernel/resource/StandardLinkImpl.hpp
src/dag/dax.dtd
src/dag/dax_dtd.c
src/dag/dax_dtd.h
- src/simix/popping_private.hpp
src/smpi/colls/coll_tuned_topo.hpp
src/smpi/colls/colls_private.hpp
src/smpi/colls/smpi_mvapich2_selector_stampede.hpp
src/surf/ns3/ns3_simulator.cpp )
set(SURF_SRC
+ src/kernel/lmm/bmf.hpp
+ src/kernel/lmm/bmf.cpp
src/kernel/lmm/fair_bottleneck.cpp
src/kernel/lmm/maxmin.hpp
src/kernel/lmm/maxmin.cpp
)
set(SIMIX_SRC
- src/simix/libsmx.cpp
- src/simix/smx_context.cpp
src/kernel/context/Context.cpp
src/kernel/context/Context.hpp
src/kernel/context/ContextRaw.cpp
src/kernel/context/ContextSwapped.hpp
src/kernel/context/ContextThread.cpp
src/kernel/context/ContextThread.hpp
- src/simix/popping.cpp
src/kernel/activity/ActivityImpl.cpp
src/kernel/activity/ActivityImpl.hpp
src/kernel/activity/BarrierImpl.cpp
src/kernel/actor/ActorImpl.hpp
src/kernel/actor/CommObserver.cpp
src/kernel/actor/CommObserver.hpp
+ src/kernel/actor/Simcall.cpp
src/kernel/actor/SimcallObserver.cpp
src/kernel/actor/SimcallObserver.hpp
src/kernel/actor/SynchroObserver.cpp
src/kernel/actor/SynchroObserver.hpp
+ src/simix/libsmx.cpp
+ src/simix/smx_context.cpp
)
# Boost context may not be available
set(MC_SRC
src/mc/explo/Exploration.hpp
src/mc/explo/CommunicationDeterminismChecker.cpp
- src/mc/explo/SafetyChecker.cpp
- src/mc/explo/SafetyChecker.hpp
+ src/mc/explo/DFSExplorer.cpp
+ src/mc/explo/DFSExplorer.hpp
src/mc/explo/LivenessChecker.cpp
src/mc/explo/LivenessChecker.hpp
src/mc/explo/UdporChecker.cpp
WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}")
################################################################
-## Build a sain "make dist" target to build a source package ###
+## Build a sane "make dist" target to build a source package ###
## containing only the files that I explicitly state ###
## (instead of any cruft laying on my disk as CPack does) ###
################################################################
endif()
add_dependencies(check tests)
-#######################################
-### Fill in the "make xxx-clean" target ###
-#######################################
-
-add_custom_target(maintainer-clean
- COMMAND ${CMAKE_COMMAND} -E remove -f src/mpif.f90
- WORKING_DIRECTORY "${CMAKE_HOME_DIRECTORY}")
-
include(CPack)
list(REMOVE_ITEM src_list ${SIMIX_SRC} ${S4U_SRC})
# but...
list(APPEND src_list
- src/simix/popping.cpp
- src/simix/popping_generated.cpp
- src/simix/smx_global.cpp)
+ src/kernel/actor/Simcall.cpp)
foreach(src ${src_list})
set (mcCFLAGS "-O3 -funroll-loops -fno-strict-aliasing")
if(CMAKE_COMPILER_IS_GNUCC)
set(FLEX_MIN_MINOR 5)
set(FLEX_MIN_PATCH 39)
-# the rest should only be changed if you understand what you're doing
-if(enable_maintainer_mode AND NOT WIN32)
- if (PYTHON_EXECUTABLE)
- add_custom_command(
- OUTPUT
- ${CMAKE_HOME_DIRECTORY}/src/simix/popping_generated.cpp
- ${CMAKE_HOME_DIRECTORY}/src/simix/popping_bodies.cpp
- ${CMAKE_HOME_DIRECTORY}/src/simix/popping_enum.hpp
- ${CMAKE_HOME_DIRECTORY}/src/simix/popping_accessors.hpp
-
- DEPENDS
- ${CMAKE_HOME_DIRECTORY}/src/simix/simcalls.py
- ${CMAKE_HOME_DIRECTORY}/src/simix/simcalls.in
-
- COMMENT "Generating simcalls source files"
- COMMAND ${PYTHON_EXECUTABLE} simcalls.py
- WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}/src/simix/
- )
-
- add_custom_target(simcalls_generated_src
- DEPENDS
- ${CMAKE_HOME_DIRECTORY}/src/simix/popping_generated.cpp
- ${CMAKE_HOME_DIRECTORY}/src/simix/popping_bodies.cpp
- ${CMAKE_HOME_DIRECTORY}/src/simix/popping_enum.hpp
- ${CMAKE_HOME_DIRECTORY}/src/simix/popping_accessors.hpp
- )
-
- SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
- "${CMAKE_HOME_DIRECTORY}/src/simix/popping_enum.hpp;${CMAKE_HOME_DIRECTORY}/src/simix/popping_generated.cpp;${CMAKE_HOME_DIRECTORY}/src/simix/popping_bodies.cpp;${CMAKE_HOME_DIRECTORY}/src/simix/popping_accessors.hpp"
- )
- endif()
-endif()
-
# Let's generate header files required by SMPI when the call location tracing
# has been activated.
if(enable_maintainer_mode AND NOT WIN32)
if(enable_maintainer_mode)
add_dependencies(simgrid smpi_generated_headers_call_location_tracing)
endif()
-if(enable_maintainer_mode AND PYTHON_EXE)
- add_dependencies(simgrid simcalls_generated_src)
-endif()
if(enable_maintainer_mode AND BISON_EXE AND LEX_EXE)
add_dependencies(simgrid automaton_generated_src)
endif()
src/xbt/dynar_test.cpp
src/xbt/random_test.cpp
src/xbt/xbt_str_test.cpp
- src/kernel/lmm/maxmin_test.cpp)
+ src/kernel/lmm/bmf_test.cpp
+ src/kernel/lmm/maxmin_test.cpp)
if (SIMGRID_HAVE_MC)
set(UNIT_TESTS ${UNIT_TESTS} src/mc/sosp/Snapshot_test.cpp src/mc/sosp/PageStore_test.cpp)
else()
use strict;
use warnings;
-my @argv = ("valgrind");
+my @argv = ("valgrind", "--quiet");
my $count = 0;
while (defined(my $arg = shift)) {
git \
valgrind \
libboost-dev libboost-all-dev \
+ libeigen3-dev \
cmake \
python3-pip \
doxygen fig2dev \
wget https://framagit.org/${DLURL} && \
tar xf simgrid-* && rm simgrid-*tar.gz && \
cd simgrid-* && \
- apt install -y g++ gcc git valgrind gfortran libboost-dev libboost-all-dev cmake dpkg-dev python3-dev pybind11-dev && \
+ apt install -y g++ gcc git valgrind gfortran libboost-dev libboost-all-dev libeigen3-dev cmake dpkg-dev python3-dev pybind11-dev && \
cmake -DCMAKE_INSTALL_PREFIX=/usr/ -Denable_documentation=OFF -Denable_smpi=ON -Denable_compile_optimizations=ON . && \
make -j4 && \
mkdir debian/ && touch debian/control && dpkg-shlibdeps --ignore-missing-info lib/*.so -llib/ -O/tmp/deps && \
make install && make clean && \
- apt remove -y g++ gcc git valgrind default-jdk gfortran libboost-dev libboost-all-dev cmake dpkg-dev wget python3-dev pybind11-dev && \
+ apt remove -y g++ gcc git valgrind default-jdk gfortran libboost-dev libboost-all-dev libeigen3-dev cmake dpkg-dev wget python3-dev pybind11-dev && \
apt install `sed -e 's/shlibs:Depends=//' -e 's/([^)]*)//g' -e 's/,//g' /tmp/deps` && \
apt autoremove -y && apt autoclean && apt clean
# - Get the tutorial files (with an empty makefile advising to run cmake before make, just in case)
# - Remove everything that was installed, and re-install what's needed by the SimGrid libraries before the Gran Final Cleanup
# - Keep g++ gcc gfortran as any MC user will use (some of) them
-RUN apt install -y g++ gcc git valgrind gfortran libboost-dev libboost-stacktrace-dev cmake dpkg-dev libunwind-dev libdw-dev libelf-dev libevent-dev python3-dev && \
+RUN apt install -y g++ gcc git valgrind gfortran libboost-dev libeigen3-dev libboost-stacktrace-dev cmake dpkg-dev libunwind-dev libdw-dev libelf-dev libevent-dev python3-dev && \
mkdir /source/ && cd /source && git clone --depth=1 https://framagit.org/simgrid/simgrid.git simgrid.git && \
cd simgrid.git && \
cmake -DCMAKE_INSTALL_PREFIX=/usr/ -Denable_model-checking=ON -Denable_documentation=OFF -Denable_java=OFF -Denable_smpi=ON -Denable_compile_optimizations=ON . && \
# - Clone simgrid-template-s4u, as it is needed by the tutorial
# - Add an empty makefile advising to run cmake before make, just in case
-RUN apt install -y python-is-python3 pajeng r-base r-cran-tidyverse r-cran-devtools cmake g++ git libboost-dev flex bison libfmt-dev && \
+RUN apt install -y python-is-python3 pajeng r-base r-cran-tidyverse r-cran-devtools cmake g++ git libboost-dev libeigen3-dev flex bison libfmt-dev && \
cd /source && \
git clone --depth=1 https://framagit.org/simgrid/simgrid-template-s4u.git simgrid-template-s4u.git && \
printf "master-workers ping-pong:\n\t@echo \"Please run the following command before make:\";echo \" cmake .\"; exit 1" > Makefile && \
RUN apt update && apt -y upgrade
# - Clone simgrid-template-smpi, as it is needed by the tutorial
-RUN apt install -y python3 pajeng libssl-dev r-base r-cran-devtools r-cran-tidyverse build-essential g++ gfortran git libboost-dev cmake flex bison libfmt-dev && \
+RUN apt install -y python3 pajeng libssl-dev r-base r-cran-devtools r-cran-tidyverse build-essential g++ gfortran git libboost-dev libeigen3-dev cmake flex bison libfmt-dev && \
cd /source && \
git clone --depth=1 https://framagit.org/simgrid/simgrid-template-smpi.git simgrid-template-smpi.git && \
apt autoremove -y && apt clean && apt autoclean
# - Compile and install SimGrid itself. Clean the tree.
# - Remove everything that was installed, and re-install what's needed by the SimGrid libraries before the Gran Final Cleanup
RUN apt-get --allow-releaseinfo-change update && apt -y upgrade && \
- apt install -y g++ gcc git valgrind gfortran libboost-dev libboost-all-dev cmake dpkg-dev python3-dev pybind11-dev && \
+ apt install -y g++ gcc git valgrind gfortran libboost-dev libboost-all-dev libeigen3-dev cmake dpkg-dev python3-dev pybind11-dev && \
mkdir /source/ && cd /source && git clone --depth=1 https://framagit.org/simgrid/simgrid.git simgrid.git && \
cd simgrid.git && \
cmake -DCMAKE_INSTALL_PREFIX=/usr/ -Denable_documentation=OFF -Denable_smpi=ON -Denable_compile_optimizations=ON . && \
make -j4 install && \
mkdir debian/ && touch debian/control && dpkg-shlibdeps --ignore-missing-info lib/*.so -llib/ -O/tmp/deps && \
git reset --hard master && git clean -dfx && \
- apt remove -y g++ gcc git valgrind default-jdk gfortran libboost-dev libboost-all-dev cmake dpkg-dev python3-dev pybind11-dev && \
+ apt remove -y g++ gcc git valgrind default-jdk gfortran libboost-dev libboost-all-dev libeigen3-dev cmake dpkg-dev python3-dev pybind11-dev && \
apt install `sed -e 's/shlibs:Depends=//' -e 's/([^)]*)//g' -e 's/,//g' /tmp/deps` && \
apt autoremove -y && apt autoclean && apt clean
die "Call this script from its location or from the SimGrid root directory\n" unless (-e $DICTFILE);
die "Usage: ". ($DICTFILE eq "./spell_dict.txt"? "./":"tools/internal/")."spell_comments.pl "
- ."`find ". ($DICTFILE eq "./spell_dict.txt"? "../../":".")." -name '*.[ch]' -o -name '*.hpp' -o -name '*.cpp' |grep -v umpire|grep -v smpi/mpich3-test|grep -v NAS | grep -v src/smpi/colls`\n"
+ ."`find ". ($DICTFILE eq "./spell_dict.txt"? "../../":".")." -name '*.[ch]' -o -name '*.hpp' -o -name '*.cpp' |grep -v smpi/mpich3-test|grep -v NAS | grep -v src/smpi/colls`\n"
unless scalar(@ARGV)>0;
my $total = 0;
have_NS3="yes"
fi
fi
-if [ "$os" = "NixOS" ] ; then
+if [ "$os" = "nixos" ] ; then
have_NS3="yes"
fi
echo "XX have_NS3: ${have_NS3}"
SIMGRID_PYTHON_LIBDIR=""
-if [ "$os" = "NixOS" ] ; then
+if [ "$os" = "nixos" ] ; then
SIMGRID_PYTHON_LIBDIR="/home/ci/simgrid_install/lib64"
fi
echo "XX SIMGRID_PYTHON_LIBDIR: ${SIMGRID_PYTHON_LIBDIR}"
MAY_DISABLE_SOURCE_CHANGE="-DCMAKE_DISABLE_SOURCE_CHANGES=ON"
fi
-if [ "$os" = "CentOS" ] && [ "$(ld -v | cut -d\ -f4 | cut -c1-4)" = "2.30" ]; then
- echo "Temporary disable LTO, believed to be broken on this system."
- MAY_DISABLE_LTO=-Denable_lto=OFF
-else
- MAY_DISABLE_LTO=
+if [ "$os" = "CentOS" ]; then
+ if [ "$(ld -v | cut -d\ -f4 | cut -c1-4)" = "2.30" ]; then
+ echo "Temporary disable LTO, believed to be broken on this system."
+ MAY_DISABLE_LTO=-Denable_lto=OFF
+ else
+ MAY_DISABLE_LTO=
+ fi
+ if [ "$(rpm -q eigen3-devel --qf '%{VERSION}')" = "3.3.4" ]; then
+ echo "Temporary avoid build error seen with eigen3 version 3.3.4"
+ export CXXFLAGS=-Wno-error=int-in-bool-context
+ fi
fi
cmake -G"$GENERATOR" ${INSTALL:+-DCMAKE_INSTALL_PREFIX=$INSTALL} \