Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of https://framagit.org/simgrid/simgrid
authormlaurent <mathieu.laurent@ens-rennes.fr>
Thu, 29 Jun 2023 11:14:05 +0000 (13:14 +0200)
committermlaurent <mathieu.laurent@ens-rennes.fr>
Thu, 29 Jun 2023 11:14:05 +0000 (13:14 +0200)
53 files changed:
ChangeLog
MANIFEST.in
examples/cpp/task-storm/s4u-task-storm.cpp
examples/cpp/task-switch-host/s4u-task-switch-host.cpp
examples/python/CMakeLists.txt
examples/python/plugin-host-load/plugin-host-load.py [new file with mode: 0644]
examples/python/plugin-host-load/plugin-host-load.tesh [new file with mode: 0644]
include/simgrid/s4u/Activity.hpp
include/simgrid/s4u/Comm.hpp
include/simgrid/s4u/Exec.hpp
include/simgrid/s4u/Host.hpp
include/simgrid/s4u/Io.hpp
include/simgrid/s4u/Task.hpp
src/bindings/python/simgrid_python.cpp
src/dag/loaders.cpp
src/kernel/activity/CommImpl.cpp
src/mc/api/State.cpp
src/mc/api/strategy/BasicStrategy.hpp
src/mc/api/strategy/MaxMatchComm.hpp
src/mc/api/strategy/MinMatchComm.hpp
src/mc/api/strategy/Strategy.hpp
src/mc/api/strategy/UniformStrategy.hpp
src/mc/explo/DFSExplorer.cpp
src/mc/explo/UdporChecker.cpp
src/mc/explo/odpor/Execution.cpp
src/mc/explo/odpor/Execution_test.cpp
src/mc/explo/odpor/ReversibleRaceCalculator.cpp
src/mc/explo/odpor/WakeupTree.cpp
src/mc/explo/odpor/WakeupTree.hpp
src/mc/explo/udpor/Configuration.cpp
src/mc/explo/udpor/Configuration_test.cpp
src/mc/explo/udpor/EventSet.cpp
src/mc/explo/udpor/EventSet.hpp
src/mc/explo/udpor/EventSet_test.cpp
src/mc/explo/udpor/ExtensionSetCalculator.cpp
src/mc/explo/udpor/ExtensionSetCalculator.hpp
src/mc/explo/udpor/ExtensionSet_test.cpp
src/mc/explo/udpor/UnfoldingEvent.cpp
src/mc/explo/udpor/maximal_subsets_iterator.cpp
src/mc/explo/udpor/maximal_subsets_iterator.hpp
src/mc/mc_config.cpp
src/mc/transition/TransitionAny.hpp
src/plugins/battery.cpp
src/plugins/photovoltaic.cpp
src/s4u/s4u_Comm.cpp
src/s4u/s4u_Exec.cpp
src/s4u/s4u_Io.cpp
src/s4u/s4u_Task.cpp
src/xbt/utils/iter/powerset.hpp
src/xbt/utils/iter/subsets.hpp
src/xbt/utils/iter/subsets_tests.cpp
src/xbt/utils/iter/variable_for_loop.hpp
teshsuite/smpi/MBI/MBI.py

index 5157b9d..603816a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 SimGrid (3.34.1) not released (Target: fall 2023)
 
+Python:
+ - Make the host_load plugin available from Python. See examples/python/plugin-host-load
+
 ----------------------------------------------------------------------------
 
 SimGrid (3.34) June 26. 2023
index 069d589..f6767fe 100644 (file)
@@ -484,6 +484,8 @@ include examples/python/platform-failures/platform-failures.py
 include examples/python/platform-failures/platform-failures.tesh
 include examples/python/platform-profile/platform-profile.py
 include examples/python/platform-profile/platform-profile.tesh
+include examples/python/plugin-host-load/plugin-host-load.py
+include examples/python/plugin-host-load/plugin-host-load.tesh
 include examples/python/synchro-barrier/synchro-barrier.py
 include examples/python/synchro-barrier/synchro-barrier.tesh
 include examples/python/synchro-mutex/synchro-mutex.py
index d290ca0..58d08c3 100644 (file)
@@ -94,8 +94,8 @@ int main(int argc, char* argv[])
   });
 
   // The token sent by SA is forwarded by both communication tasks
-  SA_to_B1->on_this_start_cb([SA](sg4::Task* t) { t->set_token(t->get_next_token_from(SA)); });
-  SA_to_B2->on_this_start_cb([SA](sg4::Task* t) { t->set_token(t->get_next_token_from(SA)); });
+  SA_to_B1->on_this_start_cb([&SA](sg4::Task* t) { t->set_token(t->get_next_token_from(SA)); });
+  SA_to_B2->on_this_start_cb([&SA](sg4::Task* t) { t->set_token(t->get_next_token_from(SA)); });
 
   /* B1 and B2 read the value of the token received by their predecessors
      and use it to adapt their amount of work to do.
index 252f338..b007523 100644 (file)
@@ -52,7 +52,7 @@ int main(int argc, char* argv[])
   // Add a function to be called before each firing of comm0
   // This function modifies the graph of tasks by adding or removing
   // successors to comm0
-  comm0->on_this_start_cb([comm0, exec1, exec2, jupiter, fafard](sg4::Task*) {
+  comm0->on_this_start_cb([&comm0, exec1, exec2, jupiter, fafard](const sg4::Task*) {
     static int count = 0;
     if (count % 2 == 0) {
       comm0->set_destination(jupiter);
index f4afe5b..555cfc1 100644 (file)
@@ -5,6 +5,7 @@ foreach(example actor-create actor-daemon actor-join actor-kill actor-migrate ac
         exec-async exec-basic exec-dvfs exec-remote exec-ptask
         task-io task-simple task-switch-host task-variable-load
         platform-comm-serialize platform-profile platform-failures
+        plugin-host-load
         network-nonlinear clusters-multicpu io-degradation exec-cpu-nonlinear
         synchro-barrier synchro-mutex synchro-semaphore)
   set(tesh_files    ${tesh_files}   ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.tesh)
diff --git a/examples/python/plugin-host-load/plugin-host-load.py b/examples/python/plugin-host-load/plugin-host-load.py
new file mode 100644 (file)
index 0000000..9fce743
--- /dev/null
@@ -0,0 +1,87 @@
+# Copyright (c) 2006-2023. 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.
+
+
+from argparse import ArgumentParser
+import sys
+from simgrid import Engine, Host, this_actor, Actor, sg_host_load_plugin_init
+
+def parse():
+    parser = ArgumentParser()
+    parser.add_argument(
+        '--platform',
+        type=str,
+        required=True,
+        help='path to the platform description'
+    )
+    return parser.parse_args()
+
+def execute_load_test():
+  host = Host.by_name('MyHost1')
+  this_actor.info(f'Initial peak speed: {host.speed:.0E} flop/s; number of flops computed so far: {host.computed_flops:.0E} (should be 0) and current average load: {host.avg_load} (should be 0)')
+
+  start = Engine.clock
+  this_actor.info('Sleep for 10 seconds')
+  this_actor.sleep_for(10)
+
+  speed = host.speed
+  this_actor.info(f'Done sleeping {Engine.clock - start}s; peak speed: {host.speed:.0E} flop/s; number of flops computed so far: {host.computed_flops:.0E} (nothing should have changed)')
+
+  # Run an activity
+  start = e.clock
+  this_actor.info(f'Run an activity of {200E6:.0E} flops at current speed of {host.speed:.0E} flop/s')
+  this_actor.execute(200E6)
+
+  this_actor.info(f'Done working on my activity; this took {Engine.clock - start}s; current peak speed: {host.speed:.0E} flop/s (when I started the computation, \
+the speed was set to {speed:.0E} flop/s); number of flops computed so \
+far: {host.computed_flops:.0E}, average load as reported by the HostLoad plugin: {host.avg_load:.5f} (should be {200E6 / (10.5 * speed * host.core_count + (Engine.clock - start - 0.5) * host.speed * host.core_count):.5f})')
+
+  # ========= Change power peak =========
+  pstate = 1
+  host.pstate = pstate
+  this_actor.info(f'========= Requesting pstate {pstate} (speed should be of {host.pstate_speed(pstate):.0E} flop/s and is of {host.speed:.0E} flop/s, average load is {host.avg_load:.5f})')
+
+  # Run a second activity
+  start = Engine.clock
+  this_actor.info(f'Run an activity of {100E6:.0E} flops')
+  this_actor.execute(100E6)
+  this_actor.info(f'Done working on my activity; this took {Engine.clock - start}s; current peak speed: {host.speed:.0E} flop/s; number of flops computed so far: {host.computed_flops:.0E}')
+  Engine
+  start = Engine.clock
+  this_actor.info("========= Requesting a reset of the computation and load counters")
+  host.reset_load()
+  this_actor.info(f'After reset: {host.computed_flops:.0E} flops computed; load is {host.avg_load}')
+  this_actor.info('Sleep for 4 seconds')
+  this_actor.sleep_for(4)
+  this_actor.info(f'Done sleeping {Engine.clock - start}s; peak speed: {host.speed:.0E} flop/s; number of flops computed so far: {host.computed_flops:.0E}')
+
+  # =========== Turn the other host off ==========
+  host2 = Host.by_name('MyHost2')
+  this_actor.info(f'Turning MyHost2 off, and sleeping another 10 seconds. MyHost2 computed {host2.computed_flops:.0E} flops so far and has an average load of {host2.avg_load}')
+  host2.turn_off()
+  start = Engine.clock
+  this_actor.sleep_for(10)
+  this_actor.info(f'Done sleeping {Engine.clock - start}s; peak speed: {host.speed:.0E} flop/s; number of flops computed so far: {host.computed_flops:.0E}')
+
+def change_speed():
+  host = Host.by_name('MyHost1')
+  this_actor.sleep_for(10.5)
+  this_actor.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.pstate = 2
+
+if __name__ == '__main__':
+  args = parse()
+  
+  sg_host_load_plugin_init()
+  e = Engine(sys.argv)
+  e.load_platform(args.platform)
+
+  Actor.create('load_test', e.host_by_name('MyHost1'), execute_load_test)
+  Actor.create('change_speed', e.host_by_name('MyHost1'), change_speed)
+
+  e.run()
+
+  this_actor.info(f'Total simulation time: {Engine.clock}')
+
diff --git a/examples/python/plugin-host-load/plugin-host-load.tesh b/examples/python/plugin-host-load/plugin-host-load.tesh
new file mode 100644 (file)
index 0000000..ad14d19
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/bin/env tesh
+
+p This tests the Host Load plugin (that allows the user to get the current load of a host and the computed flops)
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/plugin-host-load.py --platform ${platfdir}/energy_platform.xml
+> [MyHost1:load_test:(1) 0.000000] [python/INFO] Initial peak speed: 1E+08 flop/s; number of flops computed so far: 0E+00 (should be 0) and current average load: 0.0 (should be 0)
+> [MyHost1:load_test:(1) 0.000000] [python/INFO] Sleep for 10 seconds
+> [MyHost1:load_test:(1) 10.000000] [python/INFO] Done sleeping 10.0s; peak speed: 1E+08 flop/s; number of flops computed so far: 0E+00 (nothing should have changed)
+> [MyHost1:load_test:(1) 10.000000] [python/INFO] Run an activity of 2E+08 flops at current speed of 1E+08 flop/s
+> [MyHost1:change_speed:(2) 10.500000] [python/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.
+> [MyHost1:load_test:(1) 18.000000] [python/INFO] Done working on my activity; this took 8.0s; current peak speed: 2E+07 flop/s (when I started the computation, the speed was set to 1E+08 flop/s); number of flops computed so far: 2E+08, average load as reported by the HostLoad plugin: 0.04167 (should be 0.04167)
+> [MyHost1:load_test:(1) 18.000000] [python/INFO] ========= Requesting pstate 1 (speed should be of 5E+07 flop/s and is of 5E+07 flop/s, average load is 0.04167)
+> [MyHost1:load_test:(1) 18.000000] [python/INFO] Run an activity of 1E+08 flops
+> [MyHost1:load_test:(1) 20.000000] [python/INFO] Done working on my activity; this took 2.0s; current peak speed: 5E+07 flop/s; number of flops computed so far: 3E+08
+> [MyHost1:load_test:(1) 20.000000] [python/INFO] ========= Requesting a reset of the computation and load counters
+> [MyHost1:load_test:(1) 20.000000] [python/INFO] After reset: 0E+00 flops computed; load is 0.0
+> [MyHost1:load_test:(1) 20.000000] [python/INFO] Sleep for 4 seconds
+> [MyHost1:load_test:(1) 24.000000] [python/INFO] Done sleeping 4.0s; peak speed: 5E+07 flop/s; number of flops computed so far: 0E+00
+> [MyHost1:load_test:(1) 24.000000] [python/INFO] Turning MyHost2 off, and sleeping another 10 seconds. MyHost2 computed 0E+00 flops so far and has an average load of 0.0
+> [MyHost1:load_test:(1) 34.000000] [python/INFO] Done sleeping 10.0s; peak speed: 5E+07 flop/s; number of flops computed so far: 0E+00
+> [34.000000] [python/INFO] Total simulation time: 34.0
index 46ab38b..b66268e 100644 (file)
@@ -104,14 +104,16 @@ protected:
    * It is forbidden to change the amount of work once the Activity is started */
   Activity* set_remaining(double remains);
 
-  virtual void fire_on_completion() const = 0;
+  virtual void fire_on_start() const           = 0;
+  virtual void fire_on_this_start() const      = 0;
+  virtual void fire_on_completion() const      = 0;
   virtual void fire_on_this_completion() const = 0;
-  virtual void fire_on_suspend() const = 0;
-  virtual void fire_on_this_suspend() const = 0;
-  virtual void fire_on_resume() const = 0;
-  virtual void fire_on_this_resume() const = 0;
-  virtual void fire_on_veto() const = 0;
-  virtual void fire_on_this_veto() const = 0;
+  virtual void fire_on_suspend() const         = 0;
+  virtual void fire_on_this_suspend() const    = 0;
+  virtual void fire_on_resume() const          = 0;
+  virtual void fire_on_this_resume() const     = 0;
+  virtual void fire_on_veto()                  = 0;
+  virtual void fire_on_this_veto()             = 0;
 
 public:
   void start()
@@ -233,7 +235,8 @@ template <class AnyActivity> class Activity_T : public Activity {
   std::string name_             = "unnamed";
   std::string tracing_category_ = "";
 
-protected:
+  inline static xbt::signal<void(AnyActivity const&)> on_start;
+  xbt::signal<void(AnyActivity const&)> on_this_start;
   inline static xbt::signal<void(AnyActivity const&)> on_completion;
   xbt::signal<void(AnyActivity const&)> on_this_completion;
   inline static xbt::signal<void(AnyActivity const&)> on_suspend;
@@ -243,7 +246,23 @@ protected:
   inline static xbt::signal<void(AnyActivity&)> on_veto;
   xbt::signal<void(AnyActivity&)> on_this_veto;
 
+protected:
+  void fire_on_start() const override { on_start(static_cast<const AnyActivity&>(*this)); }
+  void fire_on_this_start() const override { on_this_start(static_cast<const AnyActivity&>(*this)); }
+  void fire_on_completion() const override { on_completion(static_cast<const AnyActivity&>(*this)); }
+  void fire_on_this_completion() const override { on_this_completion(static_cast<const AnyActivity&>(*this)); }
+  void fire_on_suspend() const override { on_suspend(static_cast<const AnyActivity&>(*this)); }
+  void fire_on_this_suspend() const override { on_this_suspend(static_cast<const AnyActivity&>(*this)); }
+  void fire_on_resume() const override { on_resume(static_cast<const AnyActivity&>(*this)); }
+  void fire_on_this_resume() const override { on_this_resume(static_cast<const AnyActivity&>(*this)); }
+  void fire_on_veto() override { on_veto(static_cast<AnyActivity&>(*this)); }
+  void fire_on_this_veto() override { on_this_veto(static_cast<AnyActivity&>(*this)); }
+
 public:
+  /*! \static Add a callback fired when any activity starts (no veto) */
+  static void on_start_cb(const std::function<void(AnyActivity const&)>& cb) { on_start.connect(cb); }
+  /*!  Add a callback fired when this specific activity starts (no veto) */
+  void on_this_start_cb(const std::function<void(AnyActivity const&)>& cb) { on_this_start.connect(cb); }
   /*! \static Add a callback fired when any activity completes (either normally, cancelled or failed) */
   static void on_completion_cb(const std::function<void(AnyActivity const&)>& cb) { on_completion.connect(cb); }
   /*! Add a callback fired when this specific activity completes (either normally, cancelled or failed) */
index e5b8ad4..3b1f417 100644 (file)
@@ -43,8 +43,6 @@ class XBT_PUBLIC Comm : public Activity_T<Comm> {
   xbt::signal<void(Comm const&)> on_this_send;
   static xbt::signal<void(Comm const&)> on_recv;
   xbt::signal<void(Comm const&)> on_this_recv;
-  inline static xbt::signal<void(Comm const&)> on_start;
-  xbt::signal<void(Comm const&)> on_this_start;
 
 protected:
   void fire_on_completion() const override {
@@ -54,15 +52,12 @@ protected:
   }
   void fire_on_this_completion() const override {
     /* The completion signal of a Comm has to be thrown only once and not by the sender AND the receiver.
-       then Comm::on_completion is thrown in the kernel in CommImpl::finish.
+       then Comm::on_this_completion is thrown in the kernel in CommImpl::finish.
      */
   }
-  void fire_on_suspend() const override { on_suspend(*this); }
-  void fire_on_this_suspend() const override { on_this_suspend(*this); }
-  void fire_on_resume() const override { on_resume(*this); }
-  void fire_on_this_resume() const override { on_this_resume(*this); }
-  void fire_on_veto() const override { on_veto(const_cast<Comm&>(*this)); }
-  void fire_on_this_veto() const override { on_this_veto(const_cast<Comm&>(*this)); }
+  /* These ensure that the on_completion signals are really thrown */
+  void fire_on_completion_for_real() const { Activity_T<Comm>::fire_on_completion(); }
+  void fire_on_this_completion_for_real() const { Activity_T<Comm>::fire_on_this_completion(); }
 
 public:
   /*! \static Add a callback fired when the send of any Comm is posted  */
@@ -73,10 +68,6 @@ public:
   static void on_recv_cb(const std::function<void(Comm const&)>& cb) { on_recv.connect(cb); }
   /*! Add a callback fired when the recv of this specific Comm is posted  */
   void on_this_recv_cb(const std::function<void(Comm const&)>& cb) { on_this_recv.connect(cb); }
-  /*! \static Add a callback fired when any Comm starts  */
-  static void on_start_cb(const std::function<void(Comm const&)>& cb) { on_start.connect(cb); }
-  /*!  Add a callback fired when this specific Comm starts  */
-  void on_this_start_cb(const std::function<void(Comm const&)>& cb) { on_this_start.connect(cb); }
 
   CommPtr set_copy_data_callback(const std::function<void(kernel::activity::CommImpl*, void*, size_t)>& callback);
   XBT_ATTRIB_DEPRECATED_v338("Please manifest if you actually need this function") static void copy_buffer_callback(
index 7de8e8e..b8e728a 100644 (file)
@@ -36,34 +36,17 @@ class XBT_PUBLIC Exec : public Activity_T<Exec> {
 
   bool parallel_ = false;
 
-  inline static xbt::signal<void(Exec const&)> on_start;
-  xbt::signal<void(Exec const&)> on_this_start;
-
 protected:
   explicit Exec(kernel::activity::ExecImplPtr pimpl);
   Exec* do_start() override;
 
   void reset() const;
 
-  void fire_on_completion() const override { on_completion(*this); }
-  void fire_on_this_completion() const override { on_this_completion(*this); }
-  void fire_on_suspend() const override { on_suspend(*this); }
-  void fire_on_this_suspend() const override { on_this_suspend(*this); }
-  void fire_on_resume() const override { on_resume(*this); }
-  void fire_on_this_resume() const override { on_this_resume(*this); }
-  void fire_on_veto() const override { on_veto(const_cast<Exec&>(*this)); }
-  void fire_on_this_veto() const override { on_this_veto(const_cast<Exec&>(*this)); }
-
 public:
 #ifndef DOXYGEN
   Exec(Exec const&) = delete;
   Exec& operator=(Exec const&) = delete;
 #endif
-  /*! \static Signal fired each time that any execution actually starts (no veto) */
-  static void on_start_cb(const std::function<void(Exec const&)>& cb) { on_start.connect(cb); }
-  /*! Signal fired each time that this specific execution actually starts (no veto) */
-  void on_this_start_cb(const std::function<void(Exec const&)>& cb) { on_this_start.connect(cb); }
-
   /*! \static Initiate the creation of an Exec. Setters have to be called afterwards */
   static ExecPtr init();
 
index 3b40ae7..28ce469 100644 (file)
@@ -51,6 +51,11 @@ class XBT_PUBLIC Host : public xbt::Extendable<Host> {
   friend kernel::resource::CpuAction; // signal exec_state_changed
 #endif
 
+  static xbt::signal<void(Host&)> on_creation;
+  static xbt::signal<void(Host const&)> on_destruction;
+  xbt::signal<void(Host const&)> on_this_destruction;
+  static xbt::signal<void(kernel::resource::CpuAction&, kernel::resource::Action::State)> on_exec_state_change;
+
 public:
   explicit Host(kernel::resource::HostImpl* pimpl) : pimpl_(pimpl) {}
 
@@ -58,11 +63,6 @@ protected:
   virtual ~Host(); // Call destroy() instead of manually deleting it.
   Host* set_netpoint(kernel::routing::NetPoint* netpoint);
 
-  static xbt::signal<void(Host&)> on_creation;
-  static xbt::signal<void(Host const&)> on_destruction;
-  xbt::signal<void(Host const&)> on_this_destruction;
-  static xbt::signal<void(kernel::resource::CpuAction&, kernel::resource::Action::State)> on_exec_state_change;
-
 public:
   static xbt::signal<void(Host const&)> on_speed_change;
   xbt::signal<void(Host const&)> on_this_speed_change;
index 3cc28a0..2dc88c6 100644 (file)
@@ -24,29 +24,13 @@ class XBT_PUBLIC Io : public Activity_T<Io> {
   friend kernel::EngineImpl;
 #endif
 
-  inline static xbt::signal<void(Io const&)> on_start;
-  xbt::signal<void(Io const&)> on_this_start;
-
 protected:
   explicit Io(kernel::activity::IoImplPtr pimpl);
   Io* do_start() override;
-  void fire_on_completion() const override { on_completion(*this); }
-  void fire_on_this_completion() const override { on_this_completion(*this); }
-  void fire_on_suspend() const override { on_suspend(*this); }
-  void fire_on_this_suspend() const override { on_this_suspend(*this); }
-  void fire_on_resume() const override { on_resume(*this); }
-  void fire_on_this_resume() const override { on_this_resume(*this); }
-  void fire_on_veto() const override { on_veto(const_cast<Io&>(*this)); }
-  void fire_on_this_veto() const override { on_this_veto(const_cast<Io&>(*this)); }
 
 public:
   enum class OpType { READ, WRITE };
 
-   /*! \static Signal fired each time that any I/O actually starts (no veto) */
-  static void on_start_cb(const std::function<void(Io const&)>& cb) { on_start.connect(cb); }
-   /*! Signal fired each time this specific I/O actually starts (no veto) */
-  void on_this_start_cb(const std::function<void(Io const&)>& cb) { on_this_start.connect(cb); }
-
    /*! \static Initiate the creation of an I/O. Setters have to be called afterwards */
   static IoPtr init();
   /*! \static take a vector of s4u::IoPtr and return when one of them is finished.
index 5c8050b..f854adb 100644 (file)
@@ -45,6 +45,11 @@ class Task {
   ActivityPtr previous_activity_;
   ActivityPtr current_activity_;
 
+  inline static xbt::signal<void(Task*)> on_start;
+  xbt::signal<void(Task*)> on_this_start;
+  inline static xbt::signal<void(Task*)> on_completion;
+  xbt::signal<void(Task*)> on_this_completion;
+
 protected:
   explicit Task(const std::string& name);
   virtual ~Task() = default;
@@ -54,11 +59,6 @@ protected:
 
   void set_current_activity(ActivityPtr a) { current_activity_ = a; }
 
-  inline static xbt::signal<void(Task*)> on_start;
-  xbt::signal<void(Task*)> on_this_start;
-  inline static xbt::signal<void(Task*)> on_completion;
-  xbt::signal<void(Task*)> on_this_completion;
-
 public:
   const std::string& get_name() const { return name_; }
   const char* get_cname() const { return name_.c_str(); }
index 268750f..07517ed 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "simgrid/kernel/ProfileBuilder.hpp"
 #include "simgrid/kernel/routing/NetPoint.hpp"
+#include "simgrid/plugins/load.h"
 #include <simgrid/Exception.hpp>
 #include <simgrid/s4u/Actor.hpp>
 #include <simgrid/s4u/Barrier.hpp>
@@ -365,6 +366,8 @@ PYBIND11_MODULE(simgrid, m)
            py::overload_cast<const std::string&, const std::string&, const std::string&>(&Host::create_disk),
            py::call_guard<py::gil_scoped_release>(), "Create a disk")
       .def("seal", &Host::seal, py::call_guard<py::gil_scoped_release>(), "Seal this host")
+      .def("turn_off", &Host::turn_off, py::call_guard<py::gil_scoped_release>(), "Turn off this host")
+      .def("turn_on", &Host::turn_on, py::call_guard<py::gil_scoped_release>(), "Turn on this host")
       .def_property("pstate", &Host::get_pstate,
                     py::cpp_function(&Host::set_pstate, py::call_guard<py::gil_scoped_release>()),
                     "The current pstate (read/write property).")
@@ -400,7 +403,28 @@ PYBIND11_MODULE(simgrid, m)
           "")
       .def(
           "__repr__", [](const Host* h) { return "Host(" + h->get_name() + ")"; },
-          "Textual representation of the Host");
+          "Textual representation of the Host.");
+
+  m.def("sg_host_load_plugin_init", [host]() {
+    sg_host_load_plugin_init();
+
+    static_cast<pybind11::class_<simgrid::s4u::Host, std::unique_ptr<simgrid::s4u::Host, pybind11::nodelete>>>(host)
+        .def(
+            "reset_load", [](const Host* h) { sg_host_load_reset(h); }, py::call_guard<py::gil_scoped_release>(),
+            "Reset counters of the host load plugin for this host.")
+        .def_property_readonly(
+            "current_load", [](const Host* h) { return sg_host_get_current_load(h); }, "Current load of the host.")
+        .def_property_readonly(
+            "avg_load", [](const Host* h) { return sg_host_get_avg_load(h); }, "Average load of the host.")
+        .def_property_readonly(
+            "idle_time", [](const Host* h) { return sg_host_get_idle_time(h); }, "Idle time of the host")
+        .def_property_readonly(
+            "total_idle_time", [](const Host* h) { return sg_host_get_total_idle_time(h); },
+            "Total idle time of the host.")
+        .def_property_readonly(
+            "computed_flops", [](const Host* h) { return sg_host_get_computed_flops(h); },
+            "Computed flops of the host.");
+  });
 
   py::enum_<simgrid::s4u::Host::SharingPolicy>(host, "SharingPolicy")
       .value("NONLINEAR", simgrid::s4u::Host::SharingPolicy::NONLINEAR)
index 218aa71..8520de5 100644 (file)
@@ -156,7 +156,7 @@ std::vector<ActivityPtr> create_DAG_from_json(const std::string& filename)
 
   // Start only Activities with dependencies solved
   for (auto const& activity: dag) {
-    if (dynamic_cast<Exec*>(activity.get()) != nullptr and activity->dependencies_solved())
+    if (dynamic_cast<Exec*>(activity.get()) != nullptr && activity->dependencies_solved())
       activity->start();
   }
   return dag;
index 5615d87..e5c1ddf 100644 (file)
@@ -486,8 +486,8 @@ void CommImpl::finish()
   if (get_iface()) {
     const auto& piface = static_cast<const s4u::Comm&>(*get_iface());
     set_iface(nullptr); // reset iface to protect against multiple trigger of the on_completion signals
-    s4u::Comm::on_completion(piface);
-    piface.on_this_completion(piface);
+    piface.fire_on_completion_for_real();
+    piface.fire_on_this_completion_for_real();
   }
 
   /* Update synchro state */
index d1919db..e1e5b8a 100644 (file)
@@ -183,7 +183,7 @@ std::unordered_set<aid_t> State::get_backtrack_set() const
 {
   std::unordered_set<aid_t> actors;
   for (const auto& [aid, state] : get_actors_list()) {
-    if (state.is_todo() or state.is_done()) {
+    if (state.is_todo() || state.is_done()) {
       actors.insert(aid);
     }
   }
@@ -291,7 +291,7 @@ void State::do_odpor_unwind()
     // works with ODPOR in the way we intend it to work. There is not a
     // good way to perform transition equality in SimGrid; instead, we
     // effectively simply check for the presence of an actor in the sleep set.
-    if (!get_actors_list().at(out_transition->aid_).has_more_to_consider())
+    if (not get_actors_list().at(out_transition->aid_).has_more_to_consider())
       add_sleep_set(std::move(out_transition));
   }
 }
index 7ecb325..fd28633 100644 (file)
@@ -18,7 +18,7 @@ class BasicStrategy : public Strategy {
 public:
   void copy_from(const Strategy* strategy) override
   {
-    const BasicStrategy* cast_strategy = dynamic_cast<BasicStrategy const*>(strategy);
+    const auto* cast_strategy = dynamic_cast<BasicStrategy const*>(strategy);
     xbt_assert(cast_strategy != nullptr);
     depth_ = cast_strategy->depth_ - 1;
     xbt_assert(depth_ > 0, "The exploration reached a depth greater than %d. We will stop here to prevent weird interaction with DFSExplorer. If you want to change that behaviour, you should augment the size of the search by using --cfg=model-check/max-depth:", _sg_mc_max_depth.get());
index 0bc3dad..77dadd1 100644 (file)
@@ -25,7 +25,7 @@ class MaxMatchComm : public Strategy {
 public:
   void copy_from(const Strategy* strategy) override
   {
-    const MaxMatchComm* cast_strategy = dynamic_cast<MaxMatchComm const*>(strategy);
+    const auto* cast_strategy = dynamic_cast<MaxMatchComm const*>(strategy);
     xbt_assert(cast_strategy != nullptr);
     for (auto& [id, val] : cast_strategy->mailbox_)
       mailbox_[id] = val;
@@ -42,52 +42,45 @@ public:
 
   std::pair<aid_t, int> best_transition(bool must_be_todo) const override
   {
-          std::pair<aid_t, int> min_found = std::make_pair(-1, value_of_state_+2);
+    std::pair<aid_t, int> min_found = std::make_pair(-1, value_of_state_ + 2);
     for (auto const& [aid, actor] : actors_to_run_) {
        if ((not actor.is_todo() && must_be_todo) || not actor.is_enabled() || actor.is_done())
            continue;
 
       int aid_value = value_of_state_;
       const Transition* transition = actor.get_transition(actor.get_times_considered()).get();
-     
-      const CommRecvTransition* cast_recv = dynamic_cast<CommRecvTransition const*>(transition);
-      if (cast_recv != nullptr) {
-         if (mailbox_.count(cast_recv->get_mailbox()) > 0 and
-             mailbox_.at(cast_recv->get_mailbox()) > 0) { 
-             aid_value--; // This means we have waiting recv corresponding to this recv
-         } else {
+
+      if (auto const* cast_recv = dynamic_cast<CommRecvTransition const*>(transition)) {
+            if (mailbox_.count(cast_recv->get_mailbox()) > 0 && mailbox_.at(cast_recv->get_mailbox()) > 0) {
+              aid_value--; // This means we have waiting recv corresponding to this recv
+            } else {
               aid_value++;
-          }
+            }
       }
-   
-      const CommSendTransition* cast_send = dynamic_cast<CommSendTransition const*>(transition);
-      if (cast_send != nullptr) {
-         if (mailbox_.count(cast_send->get_mailbox()) > 0 and
-             mailbox_.at(cast_send->get_mailbox()) < 0) {
-             aid_value--; // This means we have waiting recv corresponding to this send
-         }else {
-             aid_value++;
-         }
+
+      if (auto const* cast_send = dynamic_cast<CommSendTransition const*>(transition)) {
+            if (mailbox_.count(cast_send->get_mailbox()) > 0 && mailbox_.at(cast_send->get_mailbox()) < 0) {
+              aid_value--; // This means we have waiting recv corresponding to this send
+            } else {
+              aid_value++;
+            }
       }
-   
+
       if (aid_value < min_found.second)
          min_found = std::make_pair(aid, aid_value);
     }
     return min_found;
   }
 
-
   void execute_next(aid_t aid, RemoteApp& app) override
   {
     const Transition* transition = actors_to_run_.at(aid).get_transition(actors_to_run_.at(aid).get_times_considered()).get();
     last_transition_             = transition->type_;
 
-    const CommRecvTransition* cast_recv = dynamic_cast<CommRecvTransition const*>(transition);
-    if (cast_recv != nullptr)
+    if (auto const* cast_recv = dynamic_cast<CommRecvTransition const*>(transition))
       last_mailbox_ = cast_recv->get_mailbox();
 
-    const CommSendTransition* cast_send = dynamic_cast<CommSendTransition const*>(transition);
-    if (cast_send != nullptr)
+    if (auto const* cast_send = dynamic_cast<CommSendTransition const*>(transition))
       last_mailbox_ = cast_send->get_mailbox();
   }
 };
index 607a0a0..7d06c9d 100644 (file)
@@ -28,25 +28,25 @@ class MinMatchComm : public Strategy {
 public:
   void copy_from(const Strategy* strategy) override
   {
-      const MinMatchComm* cast_strategy = dynamic_cast<MinMatchComm const*>(strategy);
-      xbt_assert(cast_strategy != nullptr);
-      for (auto& [id, val] : cast_strategy->mailbox_)
-         mailbox_[id] = val;
-      if (cast_strategy->last_transition_ == Transition::Type::COMM_ASYNC_RECV)
-         mailbox_[cast_strategy->last_mailbox_]--;
-      if (cast_strategy->last_transition_ == Transition::Type::COMM_ASYNC_SEND)
-         mailbox_[cast_strategy->last_mailbox_]++;
-
-      for (auto const& [_, val] : mailbox_) 
-         value_of_state_ -= std::abs(val);
-      xbt_assert(value_of_state_ > 0, "MinMatchComm value shouldn't reach 0");
+    const auto* cast_strategy = dynamic_cast<MinMatchComm const*>(strategy);
+    xbt_assert(cast_strategy != nullptr);
+    for (auto& [id, val] : cast_strategy->mailbox_)
+      mailbox_[id] = val;
+    if (cast_strategy->last_transition_ == Transition::Type::COMM_ASYNC_RECV)
+      mailbox_[cast_strategy->last_mailbox_]--;
+    if (cast_strategy->last_transition_ == Transition::Type::COMM_ASYNC_SEND)
+      mailbox_[cast_strategy->last_mailbox_]++;
+
+    for (auto const& [_, val] : mailbox_)
+      value_of_state_ -= std::abs(val);
+    xbt_assert(value_of_state_ > 0, "MinMatchComm value shouldn't reach 0");
   }
     MinMatchComm()                     = default;
   ~MinMatchComm() override           = default;
 
  std::pair<aid_t, int> best_transition(bool must_be_todo) const override
   {
-    std::pair<aid_t, int> min_found = std::make_pair(-1, value_of_state_+2);
+    std::pair<aid_t, int> min_found = std::make_pair(-1, value_of_state_ + 2);
     for (auto const& [aid, actor] : actors_to_run_) {
        if ((not actor.is_todo() && must_be_todo) || not actor.is_enabled() || actor.is_done())
            continue;
@@ -54,23 +54,21 @@ public:
       int aid_value = value_of_state_;
       const Transition* transition = actor.get_transition(actor.get_times_considered()).get();
 
-      const CommRecvTransition* cast_recv = dynamic_cast<CommRecvTransition const*>(transition);
-      if (cast_recv != nullptr) {
-         if ((mailbox_.count(cast_recv->get_mailbox()) > 0 and
-              mailbox_.at(cast_recv->get_mailbox()) <= 0) or mailbox_.count(cast_recv->get_mailbox()) == 0) 
-             aid_value--; // This means we don't have waiting recv corresponding to this recv
-         else 
-             aid_value++; 
+      if (auto const* cast_recv = dynamic_cast<CommRecvTransition const*>(transition)) {
+            if ((mailbox_.count(cast_recv->get_mailbox()) > 0 && mailbox_.at(cast_recv->get_mailbox()) <= 0) ||
+                mailbox_.count(cast_recv->get_mailbox()) == 0)
+              aid_value--; // This means we don't have waiting recv corresponding to this recv
+            else
+              aid_value++;
       }
-      const CommSendTransition* cast_send = dynamic_cast<CommSendTransition const*>(transition);
-      if (cast_send != nullptr) {
-         if ((mailbox_.count(cast_send->get_mailbox()) > 0 and
-              mailbox_.at(cast_send->get_mailbox()) >= 0) or mailbox_.count(cast_send->get_mailbox()) == 0)
-             aid_value--;
-         else
-             aid_value++;
+      if (auto const* cast_send = dynamic_cast<CommSendTransition const*>(transition)) {
+            if ((mailbox_.count(cast_send->get_mailbox()) > 0 && mailbox_.at(cast_send->get_mailbox()) >= 0) ||
+                mailbox_.count(cast_send->get_mailbox()) == 0)
+              aid_value--;
+            else
+              aid_value++;
       }
-      
+
       if (aid_value < min_found.second)
          min_found = std::make_pair(aid, aid_value);
     }
@@ -83,12 +81,10 @@ public:
       const Transition* transition = actors_to_run_.at(aid).get_transition(actors_to_run_.at(aid).get_times_considered()).get();
     last_transition_             = transition->type_;
 
-    const CommRecvTransition* cast_recv = dynamic_cast<CommRecvTransition const*>(transition);
-    if (cast_recv != nullptr)
+    if (auto const* cast_recv = dynamic_cast<CommRecvTransition const*>(transition))
       last_mailbox_ = cast_recv->get_mailbox();
 
-    const CommSendTransition* cast_send = dynamic_cast<CommSendTransition const*>(transition);
-    if (cast_send != nullptr)
+    if (auto const* cast_send = dynamic_cast<CommSendTransition const*>(transition))
       last_mailbox_ = cast_send->get_mailbox();
   }
 };
index 96eb753..60e21f5 100644 (file)
@@ -35,7 +35,7 @@ public:
   virtual std::pair<aid_t, int> best_transition(bool must_be_todo) const = 0;
 
   /** Returns the best transition among those that should be interleaved. */
-  std::pair<aid_t, int> next_transition() { return best_transition(true); }
+  std::pair<aid_t, int> next_transition() const { return best_transition(true); }
 
   /** Allows for the strategy to update its fields knowing that the actor aid will
    *  be executed and a children strategy will then be created. */  
@@ -44,9 +44,9 @@ public:
   /** Ensure at least one transition is marked as todo among the enabled ones not done.
    *  If required, it marks as todo the best transition according to the strategy. */
   void consider_best() {
-    for (auto& [_, actor] :actors_to_run_)
-          if (actor.is_todo())
-             return;
+    if (std::any_of(begin(actors_to_run_), end(actors_to_run_),
+                    [](const auto& actor) { return actor.second.is_todo(); }))
+      return;
     aid_t best_aid = best_transition(false).first;
     if (best_aid != -1)
        actors_to_run_.at(best_aid).mark_todo();
@@ -56,7 +56,7 @@ public:
   // else raise an error
   void consider_one(aid_t aid)
   {
-    xbt_assert(actors_to_run_.at(aid).is_enabled() and not actors_to_run_.at(aid).is_done(),
+    xbt_assert(actors_to_run_.at(aid).is_enabled() && not actors_to_run_.at(aid).is_done(),
                "Tried to mark as TODO actor %ld but it is either not enabled or already done", aid);
     actors_to_run_.at(aid).mark_todo();
   }
@@ -66,10 +66,10 @@ public:
   {
     unsigned long count = 0;
     for (auto& [_, actor] : actors_to_run_)
-      if (actor.is_enabled() and not actor.is_done()) {
-        actor.mark_todo();
-        count++;
-      }
+        if (actor.is_enabled() && not actor.is_done()) {
+          actor.mark_todo();
+          count++;
+        }
     return count;
   }
 
index cc5bd85..0b665a8 100644 (file)
@@ -9,12 +9,12 @@
 #include "src/mc/transition/Transition.hpp"
 #include "xbt/random.hpp"
 
-#define MAX_RAND 100000
-
 namespace simgrid::mc {
 
 /** Guiding strategy that valuate states randomly */
 class UniformStrategy : public Strategy {
+  static constexpr int MAX_RAND = 100000;
+
   std::map<aid_t, int> valuation;
 
 public:
@@ -25,7 +25,7 @@ public:
   }
   void copy_from(const Strategy* strategy) override
   {
-    for (auto& [aid, _] : actors_to_run_)
+    for (auto const& [aid, _] : actors_to_run_)
       valuation[aid] = xbt::random::uniform_int(0, MAX_RAND);
   }
 
@@ -35,7 +35,7 @@ public:
 
     // Consider only valid actors
     for (auto const& [aid, actor] : actors_to_run_) {
-       if ((actor.is_todo() or not must_be_todo) and (not actor.is_done()) and actor.is_enabled())
+      if ((actor.is_todo() || not must_be_todo) && (not actor.is_done()) && actor.is_enabled())
         possibilities++;
     }
 
@@ -48,7 +48,7 @@ public:
        chosen = xbt::random::uniform_int(0, possibilities-1);
 
     for (auto const& [aid, actor] : actors_to_run_) {
-       if (((not actor.is_todo()) and must_be_todo) or actor.is_done() or (not actor.is_enabled()))
+        if (((not actor.is_todo()) && must_be_todo) || actor.is_done() || (not actor.is_enabled()))
         continue;
       if (chosen == 0) {
         return std::make_pair(aid, valuation.at(aid));
index 5bf8cd0..451920d 100644 (file)
@@ -205,7 +205,7 @@ void DFSExplorer::run()
     }
 
     /* Actually answer the request: let's execute the selected request (MCed does one step) */
-    const auto executed_transition = state->execute_next(next, get_remote_app());
+    auto executed_transition = state->execute_next(next, get_remote_app());
     on_transition_execute_signal(state->get_transition_out().get(), get_remote_app());
 
     // If there are processes to interleave and the maximum depth has not been
@@ -300,7 +300,7 @@ void DFSExplorer::run()
       for (const auto e_race : execution_seq_.get_reversible_races_of(next_E_p)) {
         State* prev_state  = stack_[e_race].get();
         const auto choices = execution_seq_.get_missing_source_set_actors_from(e_race, prev_state->get_backtrack_set());
-        if (!choices.empty()) {
+        if (not choices.empty()) {
           // NOTE: To incorporate the idea of attempting to select the "best"
           // backtrack point into SDPOR, instead of selecting the `first` initial,
           // we should instead compute all choices and decide which is best
@@ -401,7 +401,7 @@ std::shared_ptr<State> DFSExplorer::next_odpor_state()
     XBT_DEBUG("\tPerformed ODPOR 'clean-up'. Sleep set has:");
     for (const auto& [aid, transition] : state->get_sleep_set())
       XBT_DEBUG("\t  <%ld,%s>", aid, transition->to_string().c_str());
-    if (!state->has_empty_tree()) {
+    if (not state->has_empty_tree()) {
       return state;
     }
   }
@@ -428,8 +428,7 @@ void DFSExplorer::backtrack()
         XBT_DEBUG("ODPOR: Reversible race detected between events `%u` and `%u`", e, e_prime);
         State& prev_state = *stack_[e];
         if (const auto v = execution_seq_.get_odpor_extension_from(e, e_prime, prev_state); v.has_value()) {
-          const auto result = prev_state.insert_into_wakeup_tree(v.value(), execution_seq_.get_prefix_before(e));
-          switch (result) {
+          switch (prev_state.insert_into_wakeup_tree(v.value(), execution_seq_.get_prefix_before(e))) {
             case odpor::WakeupTree::InsertionResult::root: {
               XBT_DEBUG("ODPOR: Reversible race with `%u` unaccounted for in the wakeup tree for "
                         "the execution prior to event `%u`:",
index 43c229f..c8bac5b 100644 (file)
@@ -300,7 +300,7 @@ void UdporChecker::clean_up_explore(const UnfoldingEvent* e, const Configuration
 
   // "U (complicated expression)" portion
   const EventSet conflict_union = std::accumulate(
-      C_union_D.begin(), C_union_D.end(), EventSet(), [&](const EventSet acc, const UnfoldingEvent* e_prime) {
+      C_union_D.begin(), C_union_D.end(), EventSet(), [&](const EventSet& acc, const UnfoldingEvent* e_prime) {
         return acc.make_union(unfolding.get_immediate_conflicts_of(e_prime));
       });
 
index ef10e4f..162425d 100644 (file)
@@ -18,8 +18,8 @@ std::vector<std::string> get_textual_trace(const PartialExecution& w)
 {
   std::vector<std::string> trace;
   for (const auto& t : w) {
-    const auto a = xbt::string_printf("Actor %ld: %s", t->aid_, t->to_string(true).c_str());
-    trace.push_back(std::move(a));
+    auto a = xbt::string_printf("Actor %ld: %s", t->aid_, t->to_string(true).c_str());
+    trace.emplace_back(std::move(a));
   }
   return trace;
 }
@@ -55,9 +55,8 @@ std::vector<std::string> Execution::get_textual_trace() const
 {
   std::vector<std::string> trace;
   for (const auto& t : this->contents_) {
-    const auto a =
-        xbt::string_printf("Actor %ld: %s", t.get_transition()->aid_, t.get_transition()->to_string(true).c_str());
-    trace.push_back(std::move(a));
+    auto a = xbt::string_printf("Actor %ld: %s", t.get_transition()->aid_, t.get_transition()->to_string(true).c_str());
+    trace.emplace_back(std::move(a));
   }
   return trace;
 }
@@ -87,7 +86,7 @@ std::unordered_set<Execution::EventHandle> Execution::get_racing_events_of(Execu
       // 2. disqualified_events.count(e_j) > 0
       // then e_i --->_E target indirectly (either through
       // e_j directly, or transitively through e_j)
-      if (disqualified_events.count(e_j) > 0 and happens_before(e_i, e_j)) {
+      if (disqualified_events.count(e_j) > 0 && happens_before(e_i, e_j)) {
         disqualified_events.insert(e_i);
         break;
       }
@@ -164,7 +163,7 @@ Execution::get_missing_source_set_actors_from(EventHandle e, const std::unordere
     // happen after `e` is a member of `v`. In addition to marking
     // the event in `v`, we also "simulate" running the action `v`
     // from E'
-    if (not happens_before(e, e_prime) or e_prime == next_E_p) {
+    if (not happens_before(e, e_prime) || e_prime == next_E_p) {
       // First, push the transition onto the hypothetical execution
       E_prime_v.push_transition(get_event_with_handle(e_prime).get_transition());
       const EventHandle e_prime_in_E_prime_v = E_prime_v.get_latest_event_handle().value();
@@ -206,7 +205,7 @@ Execution::get_missing_source_set_actors_from(EventHandle e, const std::unordere
       }
     }
   }
-  xbt_assert(!I_E_prime_v.empty(),
+  xbt_assert(not I_E_prime_v.empty(),
              "For any non-empty execution, we know that "
              "at minimum one actor is an initial since "
              "some execution is possible with respect to a "
@@ -288,8 +287,8 @@ std::optional<PartialExecution> Execution::get_odpor_extension_from(EventHandle
       if (disqualified_actors.count(q) > 0) { // Did we already note that `q` is not an initial?
         continue;
       }
-      const bool is_initial = std::none_of(v_handles.begin(), v_handles.end(), [&](const auto& e_star) {
-        return E_prime_v.happens_before(e_star, e_star_in_E_prime_v);
+      const bool is_initial = std::none_of(v_handles.begin(), v_handles.end(), [&](const auto& handle) {
+        return E_prime_v.happens_before(handle, e_star_in_E_prime_v);
       });
       if (is_initial) {
         // If the sleep set already contains `q`, we're done:
@@ -315,42 +314,39 @@ std::optional<PartialExecution> Execution::get_odpor_extension_from(EventHandle
   //
   // Note the form of `v` in the pseudocode:
   //  `v := notdep(e, E).e'^
-  {
-    E_prime_v.push_transition(get_event_with_handle(e_prime).get_transition());
-    v.push_back(get_event_with_handle(e_prime).get_transition());
-
-    const EventHandle e_prime_in_E_prime_v = E_prime_v.get_latest_event_handle().value();
-    v_handles.push_back(e_prime_in_E_prime_v);
-
-    const bool is_initial = std::none_of(v_handles.begin(), v_handles.end(), [&](const auto& e_star) {
-      return E_prime_v.happens_before(e_star, e_prime_in_E_prime_v);
-    });
-    if (is_initial) {
-      if (const aid_t q = E_prime_v.get_actor_with_handle(e_prime_in_E_prime_v); sleep_E_prime.count(q) > 0) {
-        return std::nullopt;
-      } else {
-        WI_E_prime_v.insert(q);
-      }
+  E_prime_v.push_transition(get_event_with_handle(e_prime).get_transition());
+  v.push_back(get_event_with_handle(e_prime).get_transition());
+
+  const EventHandle e_prime_in_E_prime_v = E_prime_v.get_latest_event_handle().value();
+  v_handles.push_back(e_prime_in_E_prime_v);
+
+  const bool is_initial = std::none_of(v_handles.begin(), v_handles.end(), [&](const auto& handle) {
+    return E_prime_v.happens_before(handle, e_prime_in_E_prime_v);
+  });
+  if (is_initial) {
+    if (const aid_t q = E_prime_v.get_actor_with_handle(e_prime_in_E_prime_v); sleep_E_prime.count(q) > 0) {
+      return std::nullopt;
+    } else {
+      WI_E_prime_v.insert(q);
     }
   }
-  {
-    const Execution pre_E_e    = get_prefix_before(e);
-    const auto sleeping_actors = state_at_e.get_sleeping_actors();
-
-    // Check if any enabled actor that is independent with
-    // this execution after `v` is contained in the sleep set
-    for (const auto& [aid, astate] : state_at_e.get_actors_list()) {
-      const bool is_in_WI_E =
-          astate.is_enabled() and pre_E_e.is_independent_with_execution_of(v, astate.get_transition());
-      const bool is_in_sleep_set = sleeping_actors.count(aid) > 0;
-
-      // `action(aid)` is in `WI_[E](v)` but also is contained in the sleep set.
-      // This implies that the intersection between the two is non-empty
-      if (is_in_WI_E && is_in_sleep_set) {
-        return std::nullopt;
-      }
-    }
+
+  const Execution pre_E_e    = get_prefix_before(e);
+  const auto sleeping_actors = state_at_e.get_sleeping_actors();
+
+  // Check if any enabled actor that is independent with
+  // this execution after `v` is contained in the sleep set
+  for (const auto& [aid, astate] : state_at_e.get_actors_list()) {
+    const bool is_in_WI_E =
+        astate.is_enabled() and pre_E_e.is_independent_with_execution_of(v, astate.get_transition());
+    const bool is_in_sleep_set = sleeping_actors.count(aid) > 0;
+
+    // `action(aid)` is in `WI_[E](v)` but also is contained in the sleep set.
+    // This implies that the intersection between the two is non-empty
+    if (is_in_WI_E && is_in_sleep_set)
+      return std::nullopt;
   }
+
   return v;
 }
 
@@ -412,10 +408,8 @@ std::optional<PartialExecution> Execution::get_shortest_odpor_sq_subset_insertio
   auto w_now = w;
 
   for (const auto& next_E_p : v) {
-    const aid_t p = next_E_p->aid_;
-
     // Is `p in `I_[E](w)`?
-    if (E_v.is_initial_after_execution_of(w_now, p)) {
+    if (const aid_t p = next_E_p->aid_; E_v.is_initial_after_execution_of(w_now, p)) {
       // Remove `p` from w and continue
 
       // INVARIANT: If `p` occurs in `w`, it had better refer to the same
@@ -487,4 +481,4 @@ bool Execution::happens_before(Execution::EventHandle e1_handle, Execution::Even
   return false;
 }
 
-} // namespace simgrid::mc::odpor
\ No newline at end of file
+} // namespace simgrid::mc::odpor
index 364d9a0..302ccea 100644 (file)
@@ -160,7 +160,7 @@ TEST_CASE("simgrid::mc::odpor::Execution: Testing Happens-Before")
             const bool e_j_before_e_k = execution.happens_before(e_j, e_k);
             const bool e_i_before_e_k = execution.happens_before(e_i, e_k);
             // Logical equivalent of `e_i_before_e_j ^ e_j_before_e_k --> e_i_before_e_k`
-            REQUIRE((!(e_i_before_e_j and e_j_before_e_k) or e_i_before_e_k));
+            REQUIRE((not(e_i_before_e_j && e_j_before_e_k) || e_i_before_e_k));
           }
         }
       }
index 105a0f9..947ccc0 100644 (file)
@@ -20,26 +20,26 @@ bool ReversibleRaceCalculator::is_race_reversible(const Execution& E, Execution:
   using Handler    = std::function<bool(const Execution&, Execution::EventHandle, const Transition*)>;
   using HandlerMap = std::unordered_map<Action, Handler>;
 
-  const static HandlerMap handlers =
-      HandlerMap{{Action::ACTOR_JOIN, &ReversibleRaceCalculator::is_race_reversible_ActorJoin},
-                 {Action::BARRIER_ASYNC_LOCK, &ReversibleRaceCalculator::is_race_reversible_BarrierAsyncLock},
-                 {Action::BARRIER_WAIT, &ReversibleRaceCalculator::is_race_reversible_BarrierWait},
-                 {Action::COMM_ASYNC_SEND, &ReversibleRaceCalculator::is_race_reversible_CommSend},
-                 {Action::COMM_ASYNC_RECV, &ReversibleRaceCalculator::is_race_reversible_CommRecv},
-                 {Action::COMM_TEST, &ReversibleRaceCalculator::is_race_reversible_CommTest},
-                 {Action::COMM_WAIT, &ReversibleRaceCalculator::is_race_reversible_CommWait},
-                 {Action::MUTEX_ASYNC_LOCK, &ReversibleRaceCalculator::is_race_reversible_MutexAsyncLock},
-                 {Action::MUTEX_TEST, &ReversibleRaceCalculator::is_race_reversible_MutexTest},
-                 {Action::MUTEX_TRYLOCK, &ReversibleRaceCalculator::is_race_reversible_MutexTrylock},
-                 {Action::MUTEX_UNLOCK, &ReversibleRaceCalculator::is_race_reversible_MutexUnlock},
-                 {Action::MUTEX_WAIT, &ReversibleRaceCalculator::is_race_reversible_MutexWait},
-                 {Action::OBJECT_ACCESS, &ReversibleRaceCalculator::is_race_reversible_ObjectAccess},
-                 {Action::RANDOM, &ReversibleRaceCalculator::is_race_reversible_Random},
-                 {Action::SEM_ASYNC_LOCK, &ReversibleRaceCalculator::is_race_reversible_SemAsyncLock},
-                 {Action::SEM_UNLOCK, &ReversibleRaceCalculator::is_race_reversible_SemUnlock},
-                 {Action::SEM_WAIT, &ReversibleRaceCalculator::is_race_reversible_SemWait},
-                 {Action::TESTANY, &ReversibleRaceCalculator::is_race_reversible_TestAny},
-                 {Action::WAITANY, &ReversibleRaceCalculator::is_race_reversible_WaitAny}};
+  const static HandlerMap handlers = {
+      {Action::ACTOR_JOIN, &ReversibleRaceCalculator::is_race_reversible_ActorJoin},
+      {Action::BARRIER_ASYNC_LOCK, &ReversibleRaceCalculator::is_race_reversible_BarrierAsyncLock},
+      {Action::BARRIER_WAIT, &ReversibleRaceCalculator::is_race_reversible_BarrierWait},
+      {Action::COMM_ASYNC_SEND, &ReversibleRaceCalculator::is_race_reversible_CommSend},
+      {Action::COMM_ASYNC_RECV, &ReversibleRaceCalculator::is_race_reversible_CommRecv},
+      {Action::COMM_TEST, &ReversibleRaceCalculator::is_race_reversible_CommTest},
+      {Action::COMM_WAIT, &ReversibleRaceCalculator::is_race_reversible_CommWait},
+      {Action::MUTEX_ASYNC_LOCK, &ReversibleRaceCalculator::is_race_reversible_MutexAsyncLock},
+      {Action::MUTEX_TEST, &ReversibleRaceCalculator::is_race_reversible_MutexTest},
+      {Action::MUTEX_TRYLOCK, &ReversibleRaceCalculator::is_race_reversible_MutexTrylock},
+      {Action::MUTEX_UNLOCK, &ReversibleRaceCalculator::is_race_reversible_MutexUnlock},
+      {Action::MUTEX_WAIT, &ReversibleRaceCalculator::is_race_reversible_MutexWait},
+      {Action::OBJECT_ACCESS, &ReversibleRaceCalculator::is_race_reversible_ObjectAccess},
+      {Action::RANDOM, &ReversibleRaceCalculator::is_race_reversible_Random},
+      {Action::SEM_ASYNC_LOCK, &ReversibleRaceCalculator::is_race_reversible_SemAsyncLock},
+      {Action::SEM_UNLOCK, &ReversibleRaceCalculator::is_race_reversible_SemUnlock},
+      {Action::SEM_WAIT, &ReversibleRaceCalculator::is_race_reversible_SemWait},
+      {Action::TESTANY, &ReversibleRaceCalculator::is_race_reversible_TestAny},
+      {Action::WAITANY, &ReversibleRaceCalculator::is_race_reversible_WaitAny}};
 
   const auto* e2_action = E.get_transition_for_handle(e2);
   if (const auto handler = handlers.find(e2_action->type_); handler != handlers.end()) {
@@ -55,8 +55,8 @@ bool ReversibleRaceCalculator::is_race_reversible(const Execution& E, Execution:
   }
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_ActorJoin(const Execution&, Execution::EventHandle e1,
-                                                            const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_ActorJoin(const Execution&, Execution::EventHandle /*e1*/,
+                                                            const Transition* /*e2*/)
 {
   // ActorJoin races with another event iff its target `T` is the same as
   // the actor executing the other transition. Clearly, then, we could not join
@@ -64,15 +64,15 @@ bool ReversibleRaceCalculator::is_race_reversible_ActorJoin(const Execution&, Ex
   return false;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_BarrierAsyncLock(const Execution&, Execution::EventHandle e1,
-                                                                   const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_BarrierAsyncLock(const Execution&, Execution::EventHandle /*e1*/,
+                                                                   const Transition* /*e2*/)
 {
   // BarrierAsyncLock is always enabled
   return true;
 }
 
 bool ReversibleRaceCalculator::is_race_reversible_BarrierWait(const Execution& E, Execution::EventHandle e1,
-                                                              const Transition* e2)
+                                                              const Transition* /*e2*/)
 {
   // If the other event is a barrier lock event, then we
   // are not reversible; otherwise we are reversible.
@@ -80,116 +80,116 @@ bool ReversibleRaceCalculator::is_race_reversible_BarrierWait(const Execution& E
   return e1_action != Transition::Type::BARRIER_ASYNC_LOCK;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_CommRecv(const Execution&, Execution::EventHandle e1,
-                                                           const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_CommRecv(const Execution&, Execution::EventHandle /*e1*/,
+                                                           const Transition* /*e2*/)
 {
   // CommRecv is always enabled
   return true;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_CommSend(const Execution&, Execution::EventHandle e1,
-                                                           const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_CommSend(const Execution&, Execution::EventHandle /*e1*/,
+                                                           const Transition* /*e2*/)
 {
   // CommSend is always enabled
   return true;
 }
 
 bool ReversibleRaceCalculator::is_race_reversible_CommWait(const Execution& E, Execution::EventHandle e1,
-                                                           const Transition* e2)
+                                                           const Transition* /*e2*/)
 {
   // If the other event is a communication event, then we
   // are not reversible; otherwise we are reversible.
   const auto e1_action = E.get_transition_for_handle(e1)->type_;
-  return e1_action != Transition::Type::COMM_ASYNC_SEND and e1_action != Transition::Type::COMM_ASYNC_RECV;
+  return e1_action != Transition::Type::COMM_ASYNC_SEND && e1_action != Transition::Type::COMM_ASYNC_RECV;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_CommTest(const Execution&, Execution::EventHandle e1,
-                                                           const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_CommTest(const Execution&, Execution::EventHandle /*e1*/,
+                                                           const Transition* /*e2*/)
 {
   // CommTest is always enabled
   return true;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_MutexAsyncLock(const Execution&, Execution::EventHandle e1,
-                                                                 const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_MutexAsyncLock(const Execution&, Execution::EventHandle /*e1*/,
+                                                                 const Transition* /*e2*/)
 {
   // MutexAsyncLock is always enabled
   return true;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_MutexTest(const Execution&, Execution::EventHandle e1,
-                                                            const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_MutexTest(const Execution&, Execution::EventHandle /*e1*/,
+                                                            const Transition* /*e2*/)
 {
   // MutexTest is always enabled
   return true;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_MutexTrylock(const Execution&, Execution::EventHandle e1,
-                                                               const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_MutexTrylock(const Execution&, Execution::EventHandle /*e1*/,
+                                                               const Transition* /*e2*/)
 {
   // MutexTrylock is always enabled
   return true;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_MutexUnlock(const Execution&, Execution::EventHandle e1,
-                                                              const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_MutexUnlock(const Execution&, Execution::EventHandle /*e1*/,
+                                                              const Transition* /*e2*/)
 {
   // MutexUnlock is always enabled
   return true;
 }
 
 bool ReversibleRaceCalculator::is_race_reversible_MutexWait(const Execution& E, Execution::EventHandle e1,
-                                                            const Transition* e2)
+                                                            const Transition* /*e2*/)
 {
   // TODO: Get the semantics correct here
   const auto e1_action = E.get_transition_for_handle(e1)->type_;
-  return e1_action != Transition::Type::MUTEX_ASYNC_LOCK and e1_action != Transition::Type::MUTEX_UNLOCK;
+  return e1_action != Transition::Type::MUTEX_ASYNC_LOCK && e1_action != Transition::Type::MUTEX_UNLOCK;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_SemAsyncLock(const Execution&, Execution::EventHandle e1,
-                                                               const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_SemAsyncLock(const Execution&, Execution::EventHandle /*e1*/,
+                                                               const Transition* /*e2*/)
 {
   // SemAsyncLock is always enabled
   return true;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_SemUnlock(const Execution&, Execution::EventHandle e1,
-                                                            const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_SemUnlock(const Execution&, Execution::EventHandle /*e1*/,
+                                                            const Transition* /*e2*/)
 {
   // SemUnlock is always enabled
   return true;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_SemWait(const Execution&, Execution::EventHandle e1,
-                                                          const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_SemWait(const Execution&, Execution::EventHandle /*e1*/,
+                                                          const Transition* /*e2*/)
 {
   // TODO: Get the semantics correct here
   return false;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_ObjectAccess(const Execution&, Execution::EventHandle e1,
-                                                               const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_ObjectAccess(const Execution&, Execution::EventHandle /*e1*/,
+                                                               const Transition* /*e2*/)
 {
   // Object access is always enabled
   return true;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_Random(const Execution&, Execution::EventHandle e1,
-                                                         const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_Random(const Execution&, Execution::EventHandle /*e1*/,
+                                                         const Transition* /*e2*/)
 {
   // Random is always enabled
   return true;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_TestAny(const Execution&, Execution::EventHandle e1,
-                                                          const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_TestAny(const Execution&, Execution::EventHandle /*e1*/,
+                                                          const Transition* /*e2*/)
 {
   // TestAny is always enabled
   return true;
 }
 
-bool ReversibleRaceCalculator::is_race_reversible_WaitAny(const Execution&, Execution::EventHandle e1,
-                                                          const Transition* e2)
+bool ReversibleRaceCalculator::is_race_reversible_WaitAny(const Execution&, Execution::EventHandle /*e1*/,
+                                                          const Transition* /*e2*/)
 {
   // TODO: We need to check if any of the transitions
   // waited on occurred before `e1`
index 4489dd5..27d914a 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <algorithm>
 #include <exception>
+#include <memory>
 #include <queue>
 
 namespace simgrid::mc::odpor {
@@ -26,7 +27,7 @@ PartialExecution WakeupTreeNode::get_sequence() const
   // and instead track this with the iterator
   PartialExecution seq_;
   const WakeupTreeNode* cur_node = this;
-  while (cur_node != nullptr and !cur_node->is_root()) {
+  while (cur_node != nullptr && not cur_node->is_root()) {
     seq_.push_front(cur_node->action_);
     cur_node = cur_node->parent_;
   }
@@ -46,7 +47,7 @@ void WakeupTreeNode::detatch_from_parent()
   }
 }
 
-WakeupTree::WakeupTree() : WakeupTree(std::unique_ptr<WakeupTreeNode>(new WakeupTreeNode({}))) {}
+WakeupTree::WakeupTree() : WakeupTree(std::make_unique<WakeupTreeNode>()) {}
 WakeupTree::WakeupTree(std::unique_ptr<WakeupTreeNode> root) : root_(root.get())
 {
   this->insert_node(std::move(root));
@@ -56,9 +57,9 @@ std::vector<std::string> WakeupTree::get_single_process_texts() const
 {
   std::vector<std::string> trace;
   for (const auto* child : root_->children_) {
-    const auto t       = child->get_action();
-    const auto message = xbt::string_printf("Actor %ld: %s", t->aid_, t->to_string(true).c_str());
-    trace.push_back(std::move(message));
+    const auto t = child->get_action();
+    auto message = xbt::string_printf("Actor %ld: %s", t->aid_, t->to_string(true).c_str());
+    trace.emplace_back(std::move(message));
   }
   return trace;
 }
@@ -153,7 +154,7 @@ bool WakeupTree::contains(const WakeupTreeNode* node) const
 
 WakeupTreeNode* WakeupTree::make_node(std::shared_ptr<Transition> u)
 {
-  auto node                 = std::unique_ptr<WakeupTreeNode>(new WakeupTreeNode(std::move(u)));
+  auto node                 = std::make_unique<WakeupTreeNode>(std::move(u));
   auto* node_handle         = node.get();
   this->nodes_[node_handle] = std::move(node);
   return node_handle;
@@ -181,7 +182,7 @@ WakeupTree::InsertionResult WakeupTree::insert(const Execution& E, const Partial
         shortest_sequence.has_value()) {
       // Insert the sequence as a child of `node`, but only
       // if the node is not already a leaf
-      if (not node->is_leaf() or node == this->root_) {
+      if (not node->is_leaf() || node == this->root_) {
         // NOTE: It's entirely possible that the shortest
         // sequence we are inserting is empty. Consider the
         // following two cases:
index 0ffcc67..8247a91 100644 (file)
@@ -35,8 +35,6 @@ namespace simgrid::mc::odpor {
  */
 class WakeupTreeNode {
 private:
-  explicit WakeupTreeNode(std::shared_ptr<Transition> u) : action_(u) {}
-
   WakeupTreeNode* parent_ = nullptr;
 
   /** An ordered list of children of for this node in the tree */
@@ -53,6 +51,9 @@ private:
   friend WakeupTreeIterator;
 
 public:
+  explicit WakeupTreeNode(std::shared_ptr<Transition> u) : action_(u) {}
+
+  WakeupTreeNode()                                 = default;
   ~WakeupTreeNode()                                = default;
   WakeupTreeNode(const WakeupTreeNode&)            = delete;
   WakeupTreeNode(WakeupTreeNode&&)                 = default;
index 44ec270..2dd00cb 100644 (file)
@@ -32,7 +32,7 @@ Configuration::Configuration(const History& history) : Configuration(history.get
 
 Configuration::Configuration(const EventSet& events) : events_(events)
 {
-  if (!events_.is_valid_configuration()) {
+  if (not events_.is_valid_configuration()) {
     throw std::invalid_argument("The events do not form a valid configuration");
   }
 
@@ -67,7 +67,7 @@ void Configuration::add_event(const UnfoldingEvent* e)
   this->latest_event_mapping[e->get_actor()] = e;
 
   // Preserves the property that the configuration is causally closed
-  if (auto history = History(e); !this->events_.contains(history)) {
+  if (auto history = History(e); not this->events_.contains(history)) {
     throw std::invalid_argument("The newly added event has dependencies "
                                 "which are missing from this configuration");
   }
@@ -82,7 +82,7 @@ bool Configuration::is_compatible_with(const UnfoldingEvent* e) const
   // 2. `e` itself must not conflict with any events of
   // the configuration; otherwise adding the event would
   // violate the invariant that a configuration is conflict-free
-  return contains(e->get_history()) and (not e->conflicts_with_any(this->events_));
+  return contains(e->get_history()) && (not e->conflicts_with_any(this->events_));
 }
 
 bool Configuration::is_compatible_with(const History& history) const
@@ -138,7 +138,7 @@ EventSet Configuration::get_minimally_reproducible_events() const
   // we know that the prior set `S` covered the entire history of C and
   // was maximal. Subsequent sets will miss events earlier in the
   // topological ordering that appear in `S`
-  EventSet minimally_reproducible_events = EventSet();
+  EventSet minimally_reproducible_events;
 
   for (const auto& maximal_set : maximal_subsets_iterator_wrapper<Configuration>(*this)) {
     if (maximal_set.size() > minimally_reproducible_events.size()) {
@@ -213,7 +213,7 @@ std::optional<Configuration> Configuration::compute_k_partial_alternative_to(con
     for (const auto& event_in_spike : spikes) {
       events.push_back(*event_in_spike);
     }
-    return EventSet(std::move(events));
+    return EventSet(events);
   };
   const auto alternative =
       std::find_if(comb.combinations_begin(), comb.combinations_end(),
index dc3d900..a20f382 100644 (file)
@@ -377,15 +377,13 @@ TEST_CASE("simgrid::mc::udpor::Configuration: Topological Sort Order Very Compli
 
     SECTION("Forward direction")
     {
-      auto ordered_events              = C.get_topologically_sorted_events();
-      const EventSet ordered_event_set = EventSet(std::move(ordered_events));
+      const auto ordered_event_set = EventSet(C.get_topologically_sorted_events());
       REQUIRE(events_seen == ordered_event_set);
     }
 
     SECTION("Reverse direction")
     {
-      auto ordered_events              = C.get_topologically_sorted_events_of_reverse_graph();
-      const EventSet ordered_event_set = EventSet(std::move(ordered_events));
+      const auto ordered_event_set = EventSet(C.get_topologically_sorted_events_of_reverse_graph());
       REQUIRE(events_seen == ordered_event_set);
     }
   }
@@ -969,7 +967,7 @@ TEST_CASE("simgrid::mc::udpor::Configuration: Computing Full Alternatives in Rea
     // The first alternative that is found is the one that is chosen. Since
     // traversal over the elements of an unordered_set<> are not guaranteed,
     // both {e0, e4} and {e0, e7} are valid alternatives
-    REQUIRE((alternative.value().get_events() == EventSet({e0_handle, e4_handle}) or
+    REQUIRE((alternative.value().get_events() == EventSet({e0_handle, e4_handle}) ||
              alternative.value().get_events() == EventSet({e0_handle, e7_handle})));
   }
 
@@ -1059,8 +1057,8 @@ TEST_CASE("simgrid::mc::udpor::Configuration: Computing Full Alternatives in Rea
 
     const auto alternative = C.compute_alternative_to(D_plus_e, U);
     REQUIRE(alternative.has_value());
-    REQUIRE((alternative.value().get_events() == EventSet({e0_handle, e7_handle}) or
-             alternative.value().get_events() == EventSet({e0_handle, e4_handle, e7_handle}) or
+    REQUIRE((alternative.value().get_events() == EventSet({e0_handle, e7_handle}) ||
+             alternative.value().get_events() == EventSet({e0_handle, e4_handle, e7_handle}) ||
              alternative.value().get_events() == EventSet({e0_handle, e4_handle, e7_handle, e8_handle})));
   }
 
index feef1dd..929234e 100644 (file)
@@ -14,7 +14,7 @@
 
 namespace simgrid::mc::udpor {
 
-EventSet::EventSet(Configuration&& config) : EventSet(config.get_events()) {}
+EventSet::EventSet(const Configuration& config) : EventSet(config.get_events()) {}
 
 void EventSet::remove(const UnfoldingEvent* e)
 {
@@ -220,7 +220,7 @@ std::vector<const UnfoldingEvent*> EventSet::get_topological_ordering() const
         temporarily_marked_events.insert(evt);
 
         EventSet immediate_causes = evt->get_immediate_causes();
-        if (!immediate_causes.empty() && immediate_causes.is_subset_of(temporarily_marked_events)) {
+        if (not immediate_causes.empty() && immediate_causes.is_subset_of(temporarily_marked_events)) {
           throw std::invalid_argument("Attempted to perform a topological sort on a configuration "
                                       "whose contents contain a cycle. The configuration (and the graph "
                                       "connecting all of the events) is an invalid event structure");
@@ -285,4 +285,4 @@ std::vector<const UnfoldingEvent*> EventSet::move_into_vector() const&&
   return contents;
 }
 
-} // namespace simgrid::mc::udpor
\ No newline at end of file
+} // namespace simgrid::mc::udpor
index 9c09185..32be66f 100644 (file)
@@ -27,9 +27,12 @@ public:
   EventSet& operator=(const EventSet&) = default;
   EventSet& operator=(EventSet&&)      = default;
   EventSet(EventSet&&)                 = default;
-  explicit EventSet(Configuration&& config);
-  explicit EventSet(std::vector<const UnfoldingEvent*>&& raw_events) : events_(raw_events.begin(), raw_events.end()) {}
-  explicit EventSet(std::unordered_set<const UnfoldingEvent*>&& raw_events) : events_(raw_events) {}
+  explicit EventSet(const Configuration& config);
+  explicit EventSet(const std::vector<const UnfoldingEvent*>& raw_events)
+      : events_(raw_events.begin(), raw_events.end())
+  {
+  }
+  explicit EventSet(std::unordered_set<const UnfoldingEvent*>&& raw_events) : events_(std::move(raw_events)) {}
   explicit EventSet(std::initializer_list<const UnfoldingEvent*> event_list) : events_(std::move(event_list)) {}
 
   auto begin() const { return this->events_.begin(); }
index 32512e7..4c8287c 100644 (file)
@@ -770,15 +770,15 @@ TEST_CASE("simgrid::mc::udpor::EventSet: Moving into a collection")
   EventSet C_copy = C;
   EventSet D_copy = D;
 
-  std::vector<const UnfoldingEvent*> actual_A = std::move(A).move_into_vector();
-  std::vector<const UnfoldingEvent*> actual_B = std::move(B).move_into_vector();
-  std::vector<const UnfoldingEvent*> actual_C = std::move(C).move_into_vector();
-  std::vector<const UnfoldingEvent*> actual_D = std::move(D).move_into_vector();
+  const std::vector<const UnfoldingEvent*> actual_A = std::move(A).move_into_vector();
+  const std::vector<const UnfoldingEvent*> actual_B = std::move(B).move_into_vector();
+  const std::vector<const UnfoldingEvent*> actual_C = std::move(C).move_into_vector();
+  const std::vector<const UnfoldingEvent*> actual_D = std::move(D).move_into_vector();
 
-  EventSet A_copy_remade(std::move(actual_A));
-  EventSet B_copy_remade(std::move(actual_B));
-  EventSet C_copy_remade(std::move(actual_C));
-  EventSet D_copy_remade(std::move(actual_D));
+  EventSet A_copy_remade(actual_A);
+  EventSet B_copy_remade(actual_B);
+  EventSet C_copy_remade(actual_C);
+  EventSet D_copy_remade(actual_D);
 
   REQUIRE(A_copy == A_copy_remade);
   REQUIRE(B_copy == B_copy_remade);
@@ -1111,44 +1111,34 @@ TEST_CASE("simgrid::mc::udpor::EventSet: Topological Ordering Property Observed
       return subset_local;
     }();
 
-    {
-      // To test this, we verify that at each point none of the events
-      // that follow after any particular event `e` are contained in
-      // `e`'s history
-      EventSet invalid_events   = subset;
-      const auto ordered_events = subset.get_topological_ordering();
-
-      std::for_each(ordered_events.begin(), ordered_events.end(), [&](const UnfoldingEvent* e) {
-        History history(e);
-        for (const auto* e_hist : history) {
-          if (e_hist == e)
-            continue;
-          REQUIRE_FALSE(invalid_events.contains(e_hist));
-        }
-        invalid_events.remove(e);
-      });
+    // To test this, we verify that at each point none of the events
+    // that follow after any particular event `e` are contained in
+    // `e`'s history
+    EventSet invalid_events = subset;
+    for (const auto* e : subset.get_topological_ordering()) {
+      for (const auto* e_hist : History(e)) {
+        if (e_hist == e)
+          continue;
+        REQUIRE_FALSE(invalid_events.contains(e_hist));
+      }
+      invalid_events.remove(e);
     }
-    {
-      // To test this, we verify that at each point none of the events
-      // that we've processed in the ordering are ever seen again
-      // in anybody else's history
-      EventSet events_seen;
-      const auto ordered_events = subset.get_topological_ordering_of_reverse_graph();
-
-      std::for_each(ordered_events.begin(), ordered_events.end(), [&events_seen](const UnfoldingEvent* e) {
-        History history(e);
-
-        for (const auto* e_hist : history) {
-          // Unlike the test above, we DO want to ensure
-          // that `e` itself ALSO isn't yet seen
-
-          // If this event has been "seen" before,
-          // this implies that event `e` appears later
-          // in the list than one of its ancestors
-          REQUIRE_FALSE(events_seen.contains(e_hist));
-        }
-        events_seen.insert(e);
-      });
+
+    // To test this, we verify that at each point none of the events
+    // that we've processed in the ordering are ever seen again
+    // in anybody else's history
+    EventSet events_seen;
+    for (const auto* e : subset.get_topological_ordering_of_reverse_graph()) {
+      for (const auto* e_hist : History(e)) {
+        // Unlike the test above, we DO want to ensure
+        // that `e` itself ALSO isn't yet seen
+
+        // If this event has been "seen" before,
+        // this implies that event `e` appears later
+        // in the list than one of its ancestors
+        REQUIRE_FALSE(events_seen.contains(e_hist));
+      }
+      events_seen.insert(e);
     }
   }
 }
index e2e2e67..e928105 100644 (file)
@@ -18,22 +18,22 @@ using namespace simgrid::mc;
 namespace simgrid::mc::udpor {
 
 EventSet ExtensionSetCalculator::partially_extend(const Configuration& C, Unfolding* U,
-                                                  const std::shared_ptr<Transition> action)
+                                                  std::shared_ptr<Transition> action)
 {
   using Action     = Transition::Type;
   using Handler    = std::function<EventSet(const Configuration&, Unfolding*, const std::shared_ptr<Transition>)>;
   using HandlerMap = std::unordered_map<Action, Handler>;
 
-  const static HandlerMap handlers =
-      HandlerMap{{Action::COMM_ASYNC_RECV, &ExtensionSetCalculator::partially_extend_CommRecv},
-                 {Action::COMM_ASYNC_SEND, &ExtensionSetCalculator::partially_extend_CommSend},
-                 {Action::COMM_WAIT, &ExtensionSetCalculator::partially_extend_CommWait},
-                 {Action::COMM_TEST, &ExtensionSetCalculator::partially_extend_CommTest},
-                 {Action::MUTEX_ASYNC_LOCK, &ExtensionSetCalculator::partially_extend_MutexAsyncLock},
-                 {Action::MUTEX_UNLOCK, &ExtensionSetCalculator::partially_extend_MutexUnlock},
-                 {Action::MUTEX_WAIT, &ExtensionSetCalculator::partially_extend_MutexWait},
-                 {Action::MUTEX_TEST, &ExtensionSetCalculator::partially_extend_MutexTest},
-                 {Action::ACTOR_JOIN, &ExtensionSetCalculator::partially_extend_ActorJoin}};
+  const static HandlerMap handlers = {
+      {Action::COMM_ASYNC_RECV, &ExtensionSetCalculator::partially_extend_CommRecv},
+      {Action::COMM_ASYNC_SEND, &ExtensionSetCalculator::partially_extend_CommSend},
+      {Action::COMM_WAIT, &ExtensionSetCalculator::partially_extend_CommWait},
+      {Action::COMM_TEST, &ExtensionSetCalculator::partially_extend_CommTest},
+      {Action::MUTEX_ASYNC_LOCK, &ExtensionSetCalculator::partially_extend_MutexAsyncLock},
+      {Action::MUTEX_UNLOCK, &ExtensionSetCalculator::partially_extend_MutexUnlock},
+      {Action::MUTEX_WAIT, &ExtensionSetCalculator::partially_extend_MutexWait},
+      {Action::MUTEX_TEST, &ExtensionSetCalculator::partially_extend_MutexTest},
+      {Action::ACTOR_JOIN, &ExtensionSetCalculator::partially_extend_ActorJoin}};
 
   if (const auto handler = handlers.find(action->type_); handler != handlers.end()) {
     return handler->second(C, U, std::move(action));
@@ -49,11 +49,11 @@ EventSet ExtensionSetCalculator::partially_extend(const Configuration& C, Unfold
 }
 
 EventSet ExtensionSetCalculator::partially_extend_CommSend(const Configuration& C, Unfolding* U,
-                                                           const std::shared_ptr<Transition> action)
+                                                           std::shared_ptr<Transition> action)
 {
   EventSet exC;
 
-  const auto send_action        = std::static_pointer_cast<CommSendTransition>(std::move(action));
+  const auto send_action        = std::static_pointer_cast<CommSendTransition>(action);
   const auto pre_event_a_C      = C.pre_event(send_action->aid_);
   const unsigned sender_mailbox = send_action->get_mailbox();
 
@@ -72,16 +72,13 @@ EventSet ExtensionSetCalculator::partially_extend_CommSend(const Configuration&
   // Com contains a matching c' = AsyncReceive(m, _) with `action`
   for (const auto e : C) {
     const bool transition_type_check = [&]() {
-      if (const auto* async_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
-          async_send != nullptr) {
-        return async_send->get_mailbox() == sender_mailbox;
-      }
+      const auto* async_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
+      return async_send && async_send->get_mailbox() == sender_mailbox;
       // TODO: Add `TestAny` dependency
-      return false;
     }();
 
     if (transition_type_check) {
-      const EventSet K = EventSet({e, pre_event_a_C.value_or(e)}).get_largest_maximal_subset();
+      EventSet K = EventSet({e, pre_event_a_C.value_or(e)}).get_largest_maximal_subset();
 
       // TODO: Check D_K(a, lambda(e)) (only matters in the case of CommTest)
       const auto e_prime = U->discover_event(std::move(K), send_action);
@@ -94,11 +91,11 @@ EventSet ExtensionSetCalculator::partially_extend_CommSend(const Configuration&
 }
 
 EventSet ExtensionSetCalculator::partially_extend_CommRecv(const Configuration& C, Unfolding* U,
-                                                           const std::shared_ptr<Transition> action)
+                                                           std::shared_ptr<Transition> action)
 {
   EventSet exC;
 
-  const auto recv_action      = std::static_pointer_cast<CommRecvTransition>(std::move(action));
+  const auto recv_action      = std::static_pointer_cast<CommRecvTransition>(action);
   const unsigned recv_mailbox = recv_action->get_mailbox();
   const auto pre_event_a_C    = C.pre_event(recv_action->aid_);
 
@@ -115,16 +112,13 @@ EventSet ExtensionSetCalculator::partially_extend_CommRecv(const Configuration&
   // Com contains a matching c' = AsyncReceive(m, _) with a
   for (const auto e : C) {
     const bool transition_type_check = [&]() {
-      if (const auto* async_recv = dynamic_cast<const CommRecvTransition*>(e->get_transition());
-          async_recv != nullptr && async_recv->get_mailbox() == recv_mailbox) {
-        return true;
-      }
+      const auto* async_recv = dynamic_cast<const CommRecvTransition*>(e->get_transition());
+      return async_recv && async_recv->get_mailbox() == recv_mailbox;
       // TODO: Add `TestAny` dependency
-      return false;
     }();
 
     if (transition_type_check) {
-      const EventSet K = EventSet({e, pre_event_a_C.value_or(e)}).get_largest_maximal_subset();
+      EventSet K = EventSet({e, pre_event_a_C.value_or(e)}).get_largest_maximal_subset();
 
       // TODO: Check D_K(a, lambda(e)) (ony matters in the case of TestAny)
       if (true) {
@@ -143,7 +137,7 @@ EventSet ExtensionSetCalculator::partially_extend_CommWait(const Configuration&
 {
   EventSet exC;
 
-  const auto wait_action   = std::static_pointer_cast<CommWaitTransition>(std::move(action));
+  const auto wait_action   = std::static_pointer_cast<CommWaitTransition>(action);
   const auto wait_comm     = wait_action->get_comm();
   const auto pre_event_a_C = C.pre_event(wait_action->aid_);
 
@@ -152,13 +146,11 @@ EventSet ExtensionSetCalculator::partially_extend_CommWait(const Configuration&
   // whose transition is the `CommRecv` or `CommSend` whose resulting
   // communication this `CommWait` waits on
   const auto issuer = std::find_if(C.begin(), C.end(), [&](const UnfoldingEvent* e) {
-    if (const CommRecvTransition* e_issuer_receive = dynamic_cast<const CommRecvTransition*>(e->get_transition());
-        e_issuer_receive != nullptr) {
+    if (const auto* e_issuer_receive = dynamic_cast<const CommRecvTransition*>(e->get_transition())) {
       return e_issuer_receive->aid_ == wait_action->aid_ && wait_comm == e_issuer_receive->get_comm();
     }
 
-    if (const CommSendTransition* e_issuer_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
-        e_issuer_send != nullptr) {
+    if (const auto* e_issuer_send = dynamic_cast<const CommSendTransition*>(e->get_transition())) {
       return e_issuer_send->aid_ == wait_action->aid_ && wait_comm == e_issuer_send->get_comm();
     }
 
@@ -192,58 +184,42 @@ EventSet ExtensionSetCalculator::partially_extend_CommWait(const Configuration&
       // as needed to reach the receive/send number that is `issuer`.
       // ...
       // ...
-      if (const CommRecvTransition* e_issuer_receive =
-              dynamic_cast<const CommRecvTransition*>(e_issuer->get_transition());
-          e_issuer_receive != nullptr) {
+      if (const auto* e_issuer_receive = dynamic_cast<const CommRecvTransition*>(e_issuer->get_transition())) {
         const unsigned issuer_mailbox = e_issuer_receive->get_mailbox();
 
         // Check from the config -> how many sends have there been
         const unsigned send_position =
             std::count_if(config_pre_event.begin(), config_pre_event.end(), [=](const auto e) {
-              const CommSendTransition* e_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
-              if (e_send != nullptr) {
-                return e_send->get_mailbox() == issuer_mailbox;
-              }
-              return false;
+              const auto* e_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
+              return e_send && e_send->get_mailbox() == issuer_mailbox;
             });
 
         // Check from e_issuer -> what place is the issuer in?
         const unsigned receive_position =
             std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto e) {
-              const CommRecvTransition* e_receive = dynamic_cast<const CommRecvTransition*>(e->get_transition());
-              if (e_receive != nullptr) {
-                return e_receive->get_mailbox() == issuer_mailbox;
-              }
-              return false;
+              const auto* e_receive = dynamic_cast<const CommRecvTransition*>(e->get_transition());
+              return e_receive && e_receive->get_mailbox() == issuer_mailbox;
             });
 
         if (send_position >= receive_position) {
           exC.insert(U->discover_event(EventSet({unwrapped_pre_event}), wait_action));
         }
 
-      } else if (const CommSendTransition* e_issuer_send =
-                     dynamic_cast<const CommSendTransition*>(e_issuer->get_transition());
-                 e_issuer_send != nullptr) {
+      } else if (const auto* e_issuer_send = dynamic_cast<const CommSendTransition*>(e_issuer->get_transition())) {
         const unsigned issuer_mailbox = e_issuer_send->get_mailbox();
 
         // Check from e_issuer -> what place is the issuer in?
         const unsigned send_position =
             std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto e) {
-              const CommSendTransition* e_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
-              if (e_send != nullptr) {
-                return e_send->get_mailbox() == issuer_mailbox;
-              }
-              return false;
+              const auto* e_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
+              return e_send && e_send->get_mailbox() == issuer_mailbox;
             });
 
         // Check from the config -> how many sends have there been
         const unsigned receive_position =
             std::count_if(config_pre_event.begin(), config_pre_event.end(), [=](const auto e) {
-              const CommRecvTransition* e_receive = dynamic_cast<const CommRecvTransition*>(e->get_transition());
-              if (e_receive != nullptr) {
-                return e_receive->get_mailbox() == issuer_mailbox;
-              }
-              return false;
+              const auto* e_receive = dynamic_cast<const CommRecvTransition*>(e->get_transition());
+              return e_receive && e_receive->get_mailbox() == issuer_mailbox;
             });
 
         if (send_position <= receive_position) {
@@ -261,8 +237,7 @@ EventSet ExtensionSetCalculator::partially_extend_CommWait(const Configuration&
   }
 
   // 3. foreach event e in C do
-  if (const CommSendTransition* e_issuer_send = dynamic_cast<const CommSendTransition*>(e_issuer->get_transition());
-      e_issuer_send != nullptr) {
+  if (const auto* e_issuer_send = dynamic_cast<const CommSendTransition*>(e_issuer->get_transition())) {
     for (const auto e : C) {
       // If the provider of the communication for `CommWait` is a
       // `CommSend(m)`, then we only care about `e` if `λ(e) == `CommRecv(m)`.
@@ -274,8 +249,8 @@ EventSet ExtensionSetCalculator::partially_extend_CommWait(const Configuration&
       }
 
       const auto issuer_mailbox        = e_issuer_send->get_mailbox();
-      const CommRecvTransition* e_recv = dynamic_cast<const CommRecvTransition*>(e->get_transition());
-      if (e_recv->get_mailbox() != issuer_mailbox) {
+      if (const auto* e_recv = dynamic_cast<const CommRecvTransition*>(e->get_transition());
+          e_recv->get_mailbox() != issuer_mailbox) {
         continue;
       }
 
@@ -283,37 +258,30 @@ EventSet ExtensionSetCalculator::partially_extend_CommWait(const Configuration&
       // `WaitAny()` is always disabled in `config(K)`; hence, it
       // is independent of any transition in `config(K)` (according
       // to formal definition of independence)
-      const EventSet K    = EventSet({e, pre_event_a_C.value_or(e)});
+      auto K              = EventSet({e, pre_event_a_C.value_or(e)});
       const auto config_K = History(K);
       if (not config_K.contains(e_issuer)) {
         continue;
       }
 
       // What send # is the issuer
-      const unsigned send_position = std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto e) {
-        const CommSendTransition* e_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
-        if (e_send != nullptr) {
-          return e_send->get_mailbox() == issuer_mailbox;
-        }
-        return false;
-      });
+      const unsigned send_position =
+          std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto ev) {
+            const auto* e_send = dynamic_cast<const CommSendTransition*>(ev->get_transition());
+            return e_send && e_send->get_mailbox() == issuer_mailbox;
+          });
 
       // What receive # is the event `e`?
-      const unsigned receive_position = std::count_if(config_K.begin(), config_K.end(), [=](const auto e) {
-        const CommRecvTransition* e_receive = dynamic_cast<const CommRecvTransition*>(e->get_transition());
-        if (e_receive != nullptr) {
-          return e_receive->get_mailbox() == issuer_mailbox;
-        }
-        return false;
+      const unsigned receive_position = std::count_if(config_K.begin(), config_K.end(), [=](const auto ev) {
+        const auto* e_receive = dynamic_cast<const CommRecvTransition*>(ev->get_transition());
+        return e_receive && e_receive->get_mailbox() == issuer_mailbox;
       });
 
       if (send_position == receive_position) {
         exC.insert(U->discover_event(std::move(K), wait_action));
       }
     }
-  } else if (const CommRecvTransition* e_issuer_recv =
-                 dynamic_cast<const CommRecvTransition*>(e_issuer->get_transition());
-             e_issuer_recv != nullptr) {
+  } else if (const auto* e_issuer_recv = dynamic_cast<const CommRecvTransition*>(e_issuer->get_transition())) {
     for (const auto e : C) {
       // If the provider of the communication for `CommWait` is a
       // `CommRecv(m)`, then we only care about `e` if `λ(e) == `CommSend(m)`.
@@ -325,8 +293,8 @@ EventSet ExtensionSetCalculator::partially_extend_CommWait(const Configuration&
       }
 
       const auto issuer_mailbox        = e_issuer_recv->get_mailbox();
-      const CommSendTransition* e_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
-      if (e_send->get_mailbox() != issuer_mailbox) {
+      if (const auto* e_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
+          e_send->get_mailbox() != issuer_mailbox) {
         continue;
       }
 
@@ -334,29 +302,23 @@ EventSet ExtensionSetCalculator::partially_extend_CommWait(const Configuration&
       // `WaitAny()` is always disabled in `config(K)`; hence, it
       // is independent of any transition in `config(K)` (according
       // to formal definition of independence)
-      const EventSet K    = EventSet({e, pre_event_a_C.value_or(e)});
+      auto K              = EventSet({e, pre_event_a_C.value_or(e)});
       const auto config_K = History(K);
       if (not config_K.contains(e_issuer)) {
         continue;
       }
 
       // What receive # is the event `e`?
-      const unsigned send_position = std::count_if(config_K.begin(), config_K.end(), [=](const auto e) {
-        const CommSendTransition* e_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
-        if (e_send != nullptr) {
-          return e_send->get_mailbox() == issuer_mailbox;
-        }
-        return false;
+      const unsigned send_position = std::count_if(config_K.begin(), config_K.end(), [=](const auto ev) {
+        const auto* e_send = dynamic_cast<const CommSendTransition*>(ev->get_transition());
+        return e_send && e_send->get_mailbox() == issuer_mailbox;
       });
 
       // What send # is the issuer
       const unsigned receive_position =
-          std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto e) {
-            const CommRecvTransition* e_receive = dynamic_cast<const CommRecvTransition*>(e->get_transition());
-            if (e_receive != nullptr) {
-              return e_receive->get_mailbox() == issuer_mailbox;
-            }
-            return false;
+          std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto ev) {
+            const auto* e_receive = dynamic_cast<const CommRecvTransition*>(ev->get_transition());
+            return e_receive && e_receive->get_mailbox() == issuer_mailbox;
           });
 
       if (send_position == receive_position) {
@@ -379,7 +341,7 @@ EventSet ExtensionSetCalculator::partially_extend_CommTest(const Configuration&
 {
   EventSet exC;
 
-  const auto test_action   = std::static_pointer_cast<CommTestTransition>(std::move(action));
+  const auto test_action   = std::static_pointer_cast<CommTestTransition>(action);
   const auto test_comm     = test_action->get_comm();
   const auto test_aid      = test_action->aid_;
   const auto pre_event_a_C = C.pre_event(test_action->aid_);
@@ -395,13 +357,11 @@ EventSet ExtensionSetCalculator::partially_extend_CommTest(const Configuration&
   // whose transition is the `CommRecv` or `CommSend` whose resulting
   // communication this `CommTest` tests on
   const auto issuer = std::find_if(C.begin(), C.end(), [=](const UnfoldingEvent* e) {
-    if (const CommRecvTransition* e_issuer_receive = dynamic_cast<const CommRecvTransition*>(e->get_transition());
-        e_issuer_receive != nullptr) {
+    if (const auto* e_issuer_receive = dynamic_cast<const CommRecvTransition*>(e->get_transition())) {
       return e_issuer_receive->aid_ == test_aid && test_comm == e_issuer_receive->get_comm();
     }
 
-    if (const CommSendTransition* e_issuer_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
-        e_issuer_send != nullptr) {
+    if (const auto* e_issuer_send = dynamic_cast<const CommSendTransition*>(e->get_transition())) {
       return e_issuer_send->aid_ == test_aid && test_comm == e_issuer_send->get_comm();
     }
 
@@ -418,8 +378,7 @@ EventSet ExtensionSetCalculator::partially_extend_CommTest(const Configuration&
   const History e_issuer_history(e_issuer);
 
   // 3. foreach event e in C do
-  if (const CommSendTransition* e_issuer_send = dynamic_cast<const CommSendTransition*>(e_issuer->get_transition());
-      e_issuer_send != nullptr) {
+  if (const auto* e_issuer_send = dynamic_cast<const CommSendTransition*>(e_issuer->get_transition())) {
     for (const auto e : C) {
       // If the provider of the communication for `CommTest` is a
       // `CommSend(m)`, then we only care about `e` if `λ(e) == `CommRecv(m)`.
@@ -432,7 +391,7 @@ EventSet ExtensionSetCalculator::partially_extend_CommTest(const Configuration&
 
       const auto issuer_mailbox = e_issuer_send->get_mailbox();
 
-      if (const CommRecvTransition* e_recv = dynamic_cast<const CommRecvTransition*>(e->get_transition());
+      if (const auto* e_recv = dynamic_cast<const CommRecvTransition*>(e->get_transition());
           e_recv->get_mailbox() != issuer_mailbox) {
         continue;
       }
@@ -441,37 +400,30 @@ EventSet ExtensionSetCalculator::partially_extend_CommTest(const Configuration&
       // `CommTest()` is always disabled in `config(K)`; hence, it
       // is independent of any transition in `config(K)` (according
       // to formal definition of independence)
-      const EventSet K    = EventSet({e, pre_event_a_C.value_or(e)});
+      auto K              = EventSet({e, pre_event_a_C.value_or(e)});
       const auto config_K = History(K);
       if (not config_K.contains(e_issuer)) {
         continue;
       }
 
       // What send # is the issuer
-      const unsigned send_position = std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto e) {
-        const CommSendTransition* e_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
-        if (e_send != nullptr) {
-          return e_send->get_mailbox() == issuer_mailbox;
-        }
-        return false;
-      });
+      const unsigned send_position =
+          std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto ev) {
+            const auto* e_send = dynamic_cast<const CommSendTransition*>(ev->get_transition());
+            return e_send && e_send->get_mailbox() == issuer_mailbox;
+          });
 
       // What receive # is the event `e`?
-      const unsigned receive_position = std::count_if(config_K.begin(), config_K.end(), [=](const auto e) {
-        const CommRecvTransition* e_receive = dynamic_cast<const CommRecvTransition*>(e->get_transition());
-        if (e_receive != nullptr) {
-          return e_receive->get_mailbox() == issuer_mailbox;
-        }
-        return false;
+      const unsigned receive_position = std::count_if(config_K.begin(), config_K.end(), [=](const auto ev) {
+        const auto* e_receive = dynamic_cast<const CommRecvTransition*>(ev->get_transition());
+        return e_receive && e_receive->get_mailbox() == issuer_mailbox;
       });
 
       if (send_position == receive_position) {
         exC.insert(U->discover_event(std::move(K), test_action));
       }
     }
-  } else if (const CommRecvTransition* e_issuer_recv =
-                 dynamic_cast<const CommRecvTransition*>(e_issuer->get_transition());
-             e_issuer_recv != nullptr) {
+  } else if (const auto* e_issuer_recv = dynamic_cast<const CommRecvTransition*>(e_issuer->get_transition())) {
     for (const auto e : C) {
       // If the provider of the communication for `CommTest` is a
       // `CommRecv(m)`, then we only care about `e` if `λ(e) == `CommSend(m)`.
@@ -483,8 +435,8 @@ EventSet ExtensionSetCalculator::partially_extend_CommTest(const Configuration&
       }
 
       const auto issuer_mailbox        = e_issuer_recv->get_mailbox();
-      const CommSendTransition* e_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
-      if (e_send->get_mailbox() != issuer_mailbox) {
+      if (const auto* e_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
+          e_send->get_mailbox() != issuer_mailbox) {
         continue;
       }
 
@@ -492,29 +444,23 @@ EventSet ExtensionSetCalculator::partially_extend_CommTest(const Configuration&
       // `WaitAny()` is always disabled in `config(K)`; hence, it
       // is independent of any transition in `config(K)` (according
       // to formal definition of independence)
-      const EventSet K    = EventSet({e, pre_event_a_C.value_or(e)});
+      auto K              = EventSet({e, pre_event_a_C.value_or(e)});
       const auto config_K = History(K);
       if (not config_K.contains(e_issuer)) {
         continue;
       }
 
       // What receive # is the event `e`?
-      const unsigned send_position = std::count_if(config_K.begin(), config_K.end(), [=](const auto e) {
-        const CommSendTransition* e_send = dynamic_cast<const CommSendTransition*>(e->get_transition());
-        if (e_send != nullptr) {
-          return e_send->get_mailbox() == issuer_mailbox;
-        }
-        return false;
+      const unsigned send_position = std::count_if(config_K.begin(), config_K.end(), [=](const auto ev) {
+        const auto* e_send = dynamic_cast<const CommSendTransition*>(ev->get_transition());
+        return e_send && e_send->get_mailbox() == issuer_mailbox;
       });
 
       // What send # is the issuer
       const unsigned receive_position =
-          std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto e) {
-            const CommRecvTransition* e_receive = dynamic_cast<const CommRecvTransition*>(e->get_transition());
-            if (e_receive != nullptr) {
-              return e_receive->get_mailbox() == issuer_mailbox;
-            }
-            return false;
+          std::count_if(e_issuer_history.begin(), e_issuer_history.end(), [=](const auto ev) {
+            const auto* e_receive = dynamic_cast<const CommRecvTransition*>(ev->get_transition());
+            return e_receive && e_receive->get_mailbox() == issuer_mailbox;
           });
 
       if (send_position == receive_position) {
@@ -535,7 +481,7 @@ EventSet ExtensionSetCalculator::partially_extend_MutexAsyncLock(const Configura
                                                                  std::shared_ptr<Transition> action)
 {
   EventSet exC;
-  const auto mutex_lock    = std::static_pointer_cast<MutexTransition>(std::move(action));
+  const auto mutex_lock    = std::static_pointer_cast<MutexTransition>(action);
   const auto pre_event_a_C = C.pre_event(mutex_lock->aid_);
 
   // for each event e in C
@@ -553,12 +499,10 @@ EventSet ExtensionSetCalculator::partially_extend_MutexAsyncLock(const Configura
   // for each event e in C
   for (const auto e : C) {
     // Check for other locks on the same mutex
-    if (const MutexTransition* e_mutex = dynamic_cast<const MutexTransition*>(e->get_transition());
-        e_mutex != nullptr) {
-      if (e_mutex->type_ == Transition::Type::MUTEX_ASYNC_LOCK && mutex_lock->get_mutex() == e_mutex->get_mutex()) {
-        const EventSet K = EventSet({e, pre_event_a_C.value_or(e)});
-        exC.insert(U->discover_event(std::move(K), mutex_lock));
-      }
+    if (const auto* e_mutex = dynamic_cast<const MutexTransition*>(e->get_transition());
+        e_mutex->type_ == Transition::Type::MUTEX_ASYNC_LOCK && mutex_lock->get_mutex() == e_mutex->get_mutex()) {
+      auto K = EventSet({e, pre_event_a_C.value_or(e)});
+      exC.insert(U->discover_event(std::move(K), mutex_lock));
     }
   }
   return exC;
@@ -568,7 +512,7 @@ EventSet ExtensionSetCalculator::partially_extend_MutexUnlock(const Configuratio
                                                               std::shared_ptr<Transition> action)
 {
   EventSet exC;
-  const auto mutex_unlock  = std::static_pointer_cast<MutexTransition>(std::move(action));
+  const auto mutex_unlock  = std::static_pointer_cast<MutexTransition>(action);
   const auto pre_event_a_C = C.pre_event(mutex_unlock->aid_);
 
   // for each event e in C
@@ -586,16 +530,14 @@ EventSet ExtensionSetCalculator::partially_extend_MutexUnlock(const Configuratio
   // for each event e in C
   for (const auto e : C) {
     // Check for MutexTest
-    if (const MutexTransition* e_mutex = dynamic_cast<const MutexTransition*>(e->get_transition());
-        e_mutex != nullptr) {
-      if (e_mutex->type_ == Transition::Type::MUTEX_TEST || e_mutex->type_ == Transition::Type::MUTEX_WAIT) {
-        // TODO: Check if dependent or not
-        // This entails getting information about
-        // the relative position of the mutex in the queue, which
-        // again means we need more context...
-        const EventSet K = EventSet({e, pre_event_a_C.value_or(e)});
-        exC.insert(U->discover_event(std::move(K), mutex_unlock));
-      }
+    if (const auto* e_mutex = dynamic_cast<const MutexTransition*>(e->get_transition());
+        e_mutex->type_ == Transition::Type::MUTEX_TEST || e_mutex->type_ == Transition::Type::MUTEX_WAIT) {
+      // TODO: Check if dependent or not
+      // This entails getting information about
+      // the relative position of the mutex in the queue, which
+      // again means we need more context...
+      auto K = EventSet({e, pre_event_a_C.value_or(e)});
+      exC.insert(U->discover_event(std::move(K), mutex_unlock));
     }
   }
   return exC;
@@ -605,7 +547,7 @@ EventSet ExtensionSetCalculator::partially_extend_MutexWait(const Configuration&
                                                             std::shared_ptr<Transition> action)
 {
   EventSet exC;
-  const auto mutex_wait    = std::static_pointer_cast<MutexTransition>(std::move(action));
+  const auto mutex_wait    = std::static_pointer_cast<MutexTransition>(action);
   const auto pre_event_a_C = C.pre_event(mutex_wait->aid_);
 
   // for each event e in C
@@ -622,13 +564,13 @@ EventSet ExtensionSetCalculator::partially_extend_MutexWait(const Configuration&
   // for each event e in C
   for (const auto e : C) {
     // Check for any unlocks
-    if (const MutexTransition* e_mutex = dynamic_cast<const MutexTransition*>(e->get_transition());
+    if (const auto* e_mutex = dynamic_cast<const MutexTransition*>(e->get_transition());
         e_mutex != nullptr && e_mutex->type_ == Transition::Type::MUTEX_UNLOCK) {
       // TODO: Check if dependent or not
       // This entails getting information about
       // the relative position of the mutex in the queue, which
       // again means we need more context...
-      const EventSet K = EventSet({e, pre_event_a_C.value_or(e)});
+      auto K = EventSet({e, pre_event_a_C.value_or(e)});
       exC.insert(U->discover_event(std::move(K), mutex_wait));
     }
   }
@@ -639,12 +581,12 @@ EventSet ExtensionSetCalculator::partially_extend_MutexTest(const Configuration&
                                                             std::shared_ptr<Transition> action)
 {
   EventSet exC;
-  const auto mutex_test    = std::static_pointer_cast<MutexTransition>(std::move(action));
+  const auto mutex_test    = std::static_pointer_cast<MutexTransition>(action);
   const auto pre_event_a_C = C.pre_event(mutex_test->aid_);
 
   // for each event e in C
   // 1. If lambda(e) := pre(a) -> add it. Note that if
-  // pre_evevnt_a_C.has_value() == false, this implies `C` is
+  // pre_event_a_C.has_value() == false, this implies `C` is
   // empty or which we treat as implicitly containing the bottom event
   if (pre_event_a_C.has_value()) {
     const auto e_prime = U->discover_event(EventSet({pre_event_a_C.value()}), mutex_test);
@@ -657,13 +599,13 @@ EventSet ExtensionSetCalculator::partially_extend_MutexTest(const Configuration&
   // for each event e in C
   for (const auto e : C) {
     // Check for any unlocks
-    if (const MutexTransition* e_mutex = dynamic_cast<const MutexTransition*>(e->get_transition());
+    if (const auto* e_mutex = dynamic_cast<const MutexTransition*>(e->get_transition());
         e_mutex != nullptr && e_mutex->type_ == Transition::Type::MUTEX_UNLOCK) {
       // TODO: Check if dependent or not
       // This entails getting information about
       // the relative position of the mutex in the queue, which
       // again means we need more context...
-      const EventSet K = EventSet({e, pre_event_a_C.value_or(e)});
+      auto K = EventSet({e, pre_event_a_C.value_or(e)});
       exC.insert(U->discover_event(std::move(K), mutex_test));
     }
   }
@@ -675,13 +617,12 @@ EventSet ExtensionSetCalculator::partially_extend_ActorJoin(const Configuration&
 {
   EventSet exC;
 
-  const auto join_action   = std::static_pointer_cast<ActorJoinTransition>(std::move(action));
-  const auto pre_event_a_C = C.pre_event(join_action->aid_);
+  const auto join_action = std::static_pointer_cast<ActorJoinTransition>(action);
 
   // Handling ActorJoin is very simple: it is independent with all
   // other transitions. Thus the only event it could possibly depend
   // on is pre(a, C) or the root
-  if (pre_event_a_C.has_value()) {
+  if (const auto pre_event_a_C = C.pre_event(join_action->aid_); pre_event_a_C.has_value()) {
     const auto e_prime = U->discover_event(EventSet({pre_event_a_C.value()}), join_action);
     exC.insert(e_prime);
   } else {
index f257a7f..60a4ac3 100644 (file)
@@ -38,7 +38,7 @@ private:
   static EventSet partially_extend_ActorJoin(const Configuration&, Unfolding*, std::shared_ptr<Transition>);
 
 public:
-  static EventSet partially_extend(const Configuration&, Unfolding*, const std::shared_ptr<Transition>);
+  static EventSet partially_extend(const Configuration&, Unfolding*, std::shared_ptr<Transition>);
 };
 
 } // namespace simgrid::mc::udpor
index 2f778bc..b427764 100644 (file)
@@ -214,20 +214,18 @@ TEST_CASE("simgrid::mc::udpor: Testing Waits, Receives, and Sends")
 
   // --- ex({⊥}) ---
   const auto incremental_exC_send = ExtensionSetCalculator::partially_extend(Configuration(), &U, comm_send);
-  { // Assert that event `a` has been added
-    UnfoldingEvent e_send(EventSet(), comm_send);
-    REQUIRE(incremental_exC_send.size() == 1);
-    REQUIRE(incremental_exC_send.contains_equivalent_to(&e_send));
-    REQUIRE(U.size() == 1);
-  }
+  // Assert that event `a` has been added
+  UnfoldingEvent e_send(EventSet(), comm_send);
+  REQUIRE(incremental_exC_send.size() == 1);
+  REQUIRE(incremental_exC_send.contains_equivalent_to(&e_send));
+  REQUIRE(U.size() == 1);
 
   const auto incremental_exC_recv = ExtensionSetCalculator::partially_extend(Configuration(), &U, comm_recv);
-  { // Assert that event `b` has been added
-    UnfoldingEvent e_recv(EventSet(), comm_recv);
-    REQUIRE(incremental_exC_recv.size() == 1);
-    REQUIRE(incremental_exC_recv.contains_equivalent_to(&e_recv));
-    REQUIRE(U.size() == 2);
-  }
+  // Assert that event `b` has been added
+  UnfoldingEvent e_recv(EventSet(), comm_recv);
+  REQUIRE(incremental_exC_recv.size() == 1);
+  REQUIRE(incremental_exC_recv.contains_equivalent_to(&e_recv));
+  REQUIRE(U.size() == 2);
   // --- ex({⊥}) ---
 
   // 2. UDPOR will then attempt to expand ex({⊥, a}) or ex({⊥, b}). Both have
@@ -241,27 +239,24 @@ TEST_CASE("simgrid::mc::udpor: Testing Waits, Receives, and Sends")
 
   // --- ex({⊥, a}) ---
   const auto incremental_exC_recv2 = ExtensionSetCalculator::partially_extend(Configuration({e_a}), &U, comm_recv);
-  { // Assert that no event has been added and that
-    // e_b is contained in the extension set
-    UnfoldingEvent e_send(EventSet(), comm_send);
-    REQUIRE(incremental_exC_recv2.size() == 1);
-    REQUIRE(incremental_exC_recv2.contains(e_b));
+  // Assert that no event has been added and that
+  // e_b is contained in the extension set
+  REQUIRE(incremental_exC_recv2.size() == 1);
+  REQUIRE(incremental_exC_recv2.contains(e_b));
 
-    // Here, `e_a` shouldn't be added again
-    REQUIRE(U.size() == 2);
-  }
+  // Here, `e_a` shouldn't be added again
+  REQUIRE(U.size() == 2);
   // --- ex({⊥, a}) ---
 
   // --- ex({⊥, b}) ---
   const auto incremental_exC_send2 = ExtensionSetCalculator::partially_extend(Configuration({e_b}), &U, comm_send);
-  // Assert that no event has been added and that
-    // e_a is contained in the extension set
-    REQUIRE(incremental_exC_send2.size() == 1);
-    REQUIRE(incremental_exC_send2.contains(e_a));
+  // Assert that no event has been added and that
+  // e_a is contained in the extension set
+  REQUIRE(incremental_exC_send2.size() == 1);
+  REQUIRE(incremental_exC_send2.contains(e_a));
 
-    // Here, `e_b` shouldn't be added again
-    REQUIRE(U.size() == 2);
-  }
+  // Here, `e_b` shouldn't be added again
+  REQUIRE(U.size() == 2);
   // --- ex({⊥, b}) ---
 
   // 3. Expanding from ex({⊥, a, b}) brings in both `CommWait` events since they
@@ -270,21 +265,19 @@ TEST_CASE("simgrid::mc::udpor: Testing Waits, Receives, and Sends")
   // --- ex({⊥, a, b}) ---
   const auto incremental_exC_wait_actor_1 =
       ExtensionSetCalculator::partially_extend(Configuration({e_a, e_b}), &U, comm_wait_1);
-  { // Assert that events `c` has been added
-    UnfoldingEvent e_wait_1(EventSet({e_a, e_b}), comm_wait_1);
-    REQUIRE(incremental_exC_wait_actor_1.size() == 1);
-    REQUIRE(incremental_exC_wait_actor_1.contains_equivalent_to(&e_wait_1));
-    REQUIRE(U.size() == 3);
-  }
+  // Assert that events `c` has been added
+  UnfoldingEvent e_wait_1(EventSet({e_a, e_b}), comm_wait_1);
+  REQUIRE(incremental_exC_wait_actor_1.size() == 1);
+  REQUIRE(incremental_exC_wait_actor_1.contains_equivalent_to(&e_wait_1));
+  REQUIRE(U.size() == 3);
 
   const auto incremental_exC_wait_actor_2 =
       ExtensionSetCalculator::partially_extend(Configuration({e_a, e_b}), &U, comm_wait_2);
-  { // Assert that events `d` has been added
-    UnfoldingEvent e_wait_2(EventSet({e_a, e_b}), comm_wait_2);
-    REQUIRE(incremental_exC_wait_actor_2.size() == 1);
-    REQUIRE(incremental_exC_wait_actor_2.contains_equivalent_to(&e_wait_2));
-    REQUIRE(U.size() == 4);
-  }
+  // Assert that events `d` has been added
+  UnfoldingEvent e_wait_2(EventSet({e_a, e_b}), comm_wait_2);
+  REQUIRE(incremental_exC_wait_actor_2.size() == 1);
+  REQUIRE(incremental_exC_wait_actor_2.contains_equivalent_to(&e_wait_2));
+  REQUIRE(U.size() == 4);
   // --- ex({⊥, a, b}) ---
 
   // 4. Expanding from either wait action should simply yield the other event
@@ -298,22 +291,20 @@ TEST_CASE("simgrid::mc::udpor: Testing Waits, Receives, and Sends")
   // --- ex({⊥, a, b, d}) ---
   const auto incremental_exC_wait_actor_1_2 =
       ExtensionSetCalculator::partially_extend(Configuration({e_a, e_b, e_d}), &U, comm_wait_1);
-  { // Assert that no event has been added and that
-    // `e_c` is contained in the extension set
-    REQUIRE(incremental_exC_wait_actor_1_2.size() == 1);
-    REQUIRE(incremental_exC_wait_actor_1_2.contains(e_c));
-    REQUIRE(U.size() == 4);
-  }
+  // Assert that no event has been added and that
+  // `e_c` is contained in the extension set
+  REQUIRE(incremental_exC_wait_actor_1_2.size() == 1);
+  REQUIRE(incremental_exC_wait_actor_1_2.contains(e_c));
+  REQUIRE(U.size() == 4);
   // --- ex({⊥, a, b, d}) ---
 
   // --- ex({⊥, a, b, c}) ---
   const auto incremental_exC_wait_actor_2_2 =
       ExtensionSetCalculator::partially_extend(Configuration({e_a, e_b, e_c}), &U, comm_wait_2);
-  { // Assert that no event has been added and that
-    // `e_d` is contained in the extension set
-    REQUIRE(incremental_exC_wait_actor_2_2.size() == 1);
-    REQUIRE(incremental_exC_wait_actor_2_2.contains(e_d));
-    REQUIRE(U.size() == 4);
-  }
+  // Assert that no event has been added and that
+  // `e_d` is contained in the extension set
+  REQUIRE(incremental_exC_wait_actor_2_2.size() == 1);
+  REQUIRE(incremental_exC_wait_actor_2_2.contains(e_d));
+  REQUIRE(U.size() == 4);
   // --- ex({⊥, a, b, c}) ---
-}
\ No newline at end of file
+}
index fd4dc2e..92ac709 100644 (file)
@@ -77,7 +77,7 @@ EventSet UnfoldingEvent::get_local_config() const
 
 bool UnfoldingEvent::related_to(const UnfoldingEvent* other) const
 {
-  return this->in_history_of(other) or other->in_history_of(this);
+  return this->in_history_of(other) || other->in_history_of(this);
 }
 
 bool UnfoldingEvent::in_history_of(const UnfoldingEvent* other) const
@@ -103,7 +103,7 @@ bool UnfoldingEvent::conflicts_with(const UnfoldingEvent* other) const
                                                 [&](const UnfoldingEvent* e) { return e->is_dependent_with(other); });
   const bool conflicts_with_other = std::any_of(unique_to_other.begin(), unique_to_other.end(),
                                                 [&](const UnfoldingEvent* e) { return e->is_dependent_with(this); });
-  return conflicts_with_me or conflicts_with_other;
+  return conflicts_with_me || conflicts_with_other;
 }
 
 bool UnfoldingEvent::conflicts_with_any(const EventSet& events) const
@@ -121,21 +121,15 @@ bool UnfoldingEvent::immediately_conflicts_with(const UnfoldingEvent* other) con
   auto combined_events = History(EventSet{this, other}).get_all_events();
 
   // See the definition of immediate conflicts in the original paper on UDPOR
-  {
-    combined_events.remove(this);
-    if (not combined_events.is_valid_configuration()) {
-      return false;
-    }
-    combined_events.insert(this);
-  }
+  combined_events.remove(this);
+  if (not combined_events.is_valid_configuration())
+    return false;
+  combined_events.insert(this);
 
-  {
-    combined_events.remove(other);
-    if (not combined_events.is_valid_configuration()) {
-      return false;
-    }
-    combined_events.insert(other);
-  }
+  combined_events.remove(other);
+  if (not combined_events.is_valid_configuration())
+    return false;
+  combined_events.insert(other);
 
   return true;
 }
index 472855a..6c2dee3 100644 (file)
@@ -6,11 +6,12 @@
 
 namespace simgrid::mc::udpor {
 
-maximal_subsets_iterator::maximal_subsets_iterator(const EventSet& events, std::optional<node_filter_function> filter,
+maximal_subsets_iterator::maximal_subsets_iterator(const EventSet& events,
+                                                   const std::optional<node_filter_function>& filter,
                                                    std::optional<size_t> maximum_subset_size)
     : maximum_subset_size(maximum_subset_size), current_maximal_set({EventSet()})
 {
-  const auto candidate_ordering = events.get_topological_ordering_of_reverse_graph();
+  auto candidate_ordering = events.get_topological_ordering_of_reverse_graph();
   if (filter.has_value()) {
     // Only store the events in the ordering that "matter" to us
     std::copy_if(std::move_iterator(candidate_ordering.begin()), std::move_iterator(candidate_ordering.end()),
@@ -34,7 +35,7 @@ void maximal_subsets_iterator::increment()
   }
 
   const auto next_event_ref = [&]() {
-    if (!has_started_searching) {
+    if (not has_started_searching) {
       has_started_searching = true;
       return bookkeeper.find_next_candidate_event(topological_ordering.begin(), topological_ordering.end());
     } else {
index 2c3c07f..49872d8 100644 (file)
@@ -40,13 +40,14 @@ public:
 
   maximal_subsets_iterator()                                    = default;
   explicit maximal_subsets_iterator(const Configuration& config,
-                                    std::optional<node_filter_function> filter = std::nullopt,
-                                    std::optional<size_t> maximum_subset_size  = std::nullopt)
+                                    const std::optional<node_filter_function>& filter = std::nullopt,
+                                    std::optional<size_t> maximum_subset_size         = std::nullopt)
       : maximal_subsets_iterator(config.get_events(), filter, maximum_subset_size)
   {
   }
-  explicit maximal_subsets_iterator(const EventSet& events, std::optional<node_filter_function> filter = std::nullopt,
-                                    std::optional<size_t> maximum_subset_size = std::nullopt);
+  explicit maximal_subsets_iterator(const EventSet& events,
+                                    const std::optional<node_filter_function>& filter = std::nullopt,
+                                    std::optional<size_t> maximum_subset_size         = std::nullopt);
 
 private:
   std::vector<const UnfoldingEvent*> topological_ordering;
@@ -138,7 +139,7 @@ private:
   bool equal(const maximal_subsets_iterator& other) const { return current_maximal_set == other.current_maximal_set; }
   const EventSet& dereference() const
   {
-    static const EventSet empty_set = EventSet();
+    static const EventSet empty_set;
     if (current_maximal_set.has_value()) {
       return current_maximal_set.value();
     }
index bde1a6b..9253c04 100644 (file)
@@ -66,11 +66,11 @@ simgrid::config::Flag<std::string> _sg_mc_strategy{
     "model-check/strategy",
     "Specify the the kind of heuristic to use for guided model-checking",
     "none",
-    {{"none", "No specific strategy: simply pick the first available transistion and act as a DFS."},
+    {{"none", "No specific strategy: simply pick the first available transition and act as a DFS."},
      {"max_match_comm", "Try to minimize the number of in-fly communication by appairing matching send and receive."},
-     {"min_match_comm", "Try to maximize the number of in-fly communication by not appairing matching send and receive."},
-     {"uniform", "No specific strategy: choices are made randomly based on a uniform sampling."}
-    }};
+     {"min_match_comm",
+      "Try to maximize the number of in-fly communication by not appairing matching send and receive."},
+     {"uniform", "No specific strategy: choices are made randomly based on a uniform sampling."}}};
 
 simgrid::config::Flag<int> _sg_mc_random_seed{"model-check/rand-seed",
                                               "give a specific random seed to initialize the uniform distribution", 0,
index b064811..494006b 100644 (file)
@@ -26,12 +26,10 @@ public:
   Transition* get_current_transition() const { return transitions_.at(times_considered_); }
   bool result() const
   {
-    for (Transition* transition : transitions_) {
-      CommTestTransition* tested_transition = static_cast<CommTestTransition*>(transition);
-      if (tested_transition->get_sender() != -1 and tested_transition->get_receiver() != -1)
-        return true;
-    }
-    return false;
+    return std::any_of(begin(transitions_), end(transitions_), [](const Transition* transition) {
+      const auto* tested_transition = static_cast<const CommTestTransition*>(transition);
+      return (tested_transition->get_sender() != -1 && tested_transition->get_receiver() != -1);
+    });
   }
 };
 
index b6cfd2a..21d1ceb 100644 (file)
@@ -427,7 +427,7 @@ void Battery::update()
   simgrid::kernel::actor::simcall_answered([this] {
     double now             = simgrid::s4u::Engine::get_clock();
     double time_delta_real = now - last_updated_;
-    if (time_delta_real <= 0 or not is_active())
+    if (time_delta_real <= 0 || not is_active())
       return;
     double time_delta_until_event = next_event_ - last_updated_;
     bool event                    = next_event_ != -1 and time_delta_until_event <= time_delta_real;
index 923153b..9d8a717 100644 (file)
@@ -218,9 +218,9 @@ void Photovoltaic::update()
     if (now <= last_updated_)
       return;
     double power_w = conversion_efficiency_ * area_m2_ * solar_irradiance_w_per_m2_;
-    if (min_power_w_ > 0 and power_w_ < min_power_w_)
+    if (min_power_w_ > 0 && power_w_ < min_power_w_)
       power_w = 0;
-    if (max_power_w_ > 0 and power_w_ > max_power_w_)
+    if (max_power_w_ > 0 && power_w_ > max_power_w_)
       power_w = max_power_w_;
     power_w_ = power_w;
     if (eval_cost_) {
@@ -288,4 +288,4 @@ double sg_photovoltaic_get_power(const_sg_host_t host)
 {
   ensure_plugin_inited();
   return host->extension<Photovoltaic>()->get_power();
-}
\ No newline at end of file
+}
index a36df4e..fe13409 100644 (file)
@@ -314,8 +314,8 @@ Comm* Comm::do_start()
     xbt_assert(src_buff_ == nullptr && dst_buff_ == nullptr,
                "Direct host-to-host communications cannot carry any data.");
     XBT_DEBUG("host-to-host Comm. Pimpl already created and set, just start it.");
-    on_start(*this);
-    on_this_start(*this);
+    fire_on_start();
+    fire_on_this_start();
     kernel::actor::simcall_answered([this] {
       pimpl_->set_state(kernel::activity::State::READY);
       boost::static_pointer_cast<kernel::activity::CommImpl>(pimpl_)->start();
@@ -364,8 +364,8 @@ Comm* Comm::do_start()
     pimpl_->set_actor(sender_);
     // Only throw the signal when both sides are here and the status is READY
     if (pimpl_->get_state() != kernel::activity::State::WAITING) {
-      on_start(*this);
-      on_this_start(*this);
+      fire_on_start();
+      fire_on_this_start();
     }
   }
 
index a6fd9cb..49f935e 100644 (file)
@@ -46,8 +46,8 @@ Exec* Exec::do_start()
     pimpl_->suspend();
 
   state_      = State::STARTED;
-  on_start(*this);
-  on_this_start(*this);
+  fire_on_start();
+  fire_on_this_start();
   return this;
 }
 
index 691be4a..7f0e45c 100644 (file)
@@ -89,8 +89,8 @@ Io* Io::do_start()
     pimpl_->suspend();
 
   state_ = State::STARTED;
-  on_start(*this);
-  on_this_start(*this);
+  fire_on_start();
+  fire_on_this_start();
   return this;
 }
 
index b6d8ccd..ee75342 100644 (file)
@@ -45,9 +45,10 @@ bool Task::ready_to_run() const
 void Task::receive(Task* source)
 {
   XBT_DEBUG("Task %s received a token from %s", name_.c_str(), source->name_.c_str());
-  auto source_count = predecessors_[source]++;
+  auto source_count = predecessors_[source];
+  predecessors_[source]++;
   if (tokens_received_.size() <= queued_firings_ + source_count)
-    tokens_received_.push_back({});
+    tokens_received_.emplace_back();
   tokens_received_[queued_firings_ + source_count][source] = source->token_;
   bool enough_tokens                                       = true;
   for (auto const& [key, val] : predecessors_)
@@ -131,7 +132,7 @@ void Task::fire()
   on_start(this);
   working_        = true;
   queued_firings_ = std::max(queued_firings_ - 1, 0);
-  if (tokens_received_.size() > 0)
+  if (not tokens_received_.empty())
     tokens_received_.pop_front();
 }
 
index b83bad7..68e0970 100644 (file)
@@ -74,8 +74,8 @@ template <typename Iterator> const std::vector<Iterator>& powerset_iterator<Iter
 
 template <typename Iterator> void powerset_iterator<Iterator>::increment()
 {
-  if (!current_subset_iter.has_value() || !current_subset_iter_end.has_value() || !current_subset_iter.has_value() ||
-      !iterator_end.has_value()) {
+  if (not current_subset_iter.has_value() || not current_subset_iter_end.has_value() ||
+      not current_subset_iter.has_value() || not iterator_end.has_value()) {
     return; // We've traversed all subsets at this point, or we're the "last" iterator
   }
 
index 1abea21..ec3cac8 100644 (file)
@@ -73,7 +73,7 @@ subsets_iterator<Iterator>::subsets_iterator(unsigned k, Iterator begin, Iterato
 
 template <typename Iterator> bool subsets_iterator<Iterator>::equal(const subsets_iterator<Iterator>& other) const
 {
-  if (this->end == std::nullopt and other.end == std::nullopt) {
+  if (this->end == std::nullopt && other.end == std::nullopt) {
     return true;
   }
   if (this->k != other.k) {
@@ -82,7 +82,7 @@ template <typename Iterator> bool subsets_iterator<Iterator>::equal(const subset
   if (this->k == 0) { // this->k == other.k == 0
     return true;
   }
-  return this->end != std::nullopt and other.end != std::nullopt and this->P[0] == other.P[0];
+  return this->end != std::nullopt && other.end != std::nullopt && this->P[0] == other.P[0];
 }
 
 template <typename Iterator> const std::vector<Iterator>& subsets_iterator<Iterator>::dereference() const
@@ -103,14 +103,13 @@ template <typename Iterator> void subsets_iterator<Iterator>::increment()
   ++current_subset[k - 1];
   ++P[k - 1];
 
-  const auto end                  = this->end.value();
-  const bool shift_other_elements = current_subset[k - 1] == end;
+  const bool shift_other_elements = current_subset[k - 1] == end.value();
 
   if (shift_other_elements) {
     if (k == 1) {
       // We're done in the case that k = 1; here, we've iterated
       // through the list once, which is all that is needed
-      this->end = std::nullopt;
+      end = std::nullopt;
       return;
     }
 
@@ -150,7 +149,7 @@ template <typename Iterator> void subsets_iterator<Iterator>::increment()
     // element can be located. Thus, if `P[0] > (n - k)`, this means
     // we've sucessfully iterated through all subsets so we're done
     if (P[0] > (n - k)) {
-      this->end = std::nullopt;
+      end = std::nullopt;
       return;
     }
 
index 7e71267..fd7cee5 100644 (file)
@@ -49,7 +49,7 @@ TEST_CASE("simgrid::xbt::powerset_iterator: Iteration General Properties")
   SECTION("Each element of each subset is distinct and appears half of the time in all subsets iteration")
   {
     // Each element is expected to be found in half of the sets
-    const unsigned k         = static_cast<unsigned>(example_vec.size());
+    const auto k             = static_cast<unsigned>(example_vec.size());
     const int expected_count = integer_power(2, k - 1);
 
     std::unordered_map<int, int> element_counts(k);
index cbcb0a2..f283f66 100644 (file)
@@ -51,7 +51,7 @@ public:
     const auto has_effect =
         std::none_of(collections.begin(), collections.end(), [](const auto& c) { return c.get().empty(); });
 
-    if (has_effect and (not collections.empty())) {
+    if (has_effect && (not collections.empty())) {
       std::transform(collections.begin(), collections.end(), std::back_inserter(current_subset),
                      [](const auto& c) { return c.get().cbegin(); });
       underlying_collections = std::move(collections);
@@ -76,7 +76,7 @@ template <typename IterableType> void variable_for_loop<IterableType>::increment
 {
   // Termination occurs when `current_subset := the empty set`
   // or if we have nothing to iterate over
-  if (current_subset.empty() or underlying_collections.empty()) {
+  if (current_subset.empty() || underlying_collections.empty()) {
     return;
   }
 
index 6bd48c6..6484a0b 100755 (executable)
@@ -30,7 +30,7 @@ simgrid = sg.Tool()
 
 (name, path, binary, filename) = sys.argv
 for test in mbi.parse_one_code(filename):
-    execcmd = test['cmd'].replace("mpirun", f"{path}/smpi_script/bin/smpirun -wrapper '{path}/bin/simgrid-mc --log=mc_safety.t:info' -platform ./cluster.xml -analyze --cfg=smpi/barrier-finalization:on --cfg=smpi/list-leaks:10 --cfg=model-check/max-depth:10000")
+    execcmd = test['cmd'].replace("mpirun", f"{path}/smpi_script/bin/smpirun -wrapper '{path}/bin/simgrid-mc --cfg=model-check/reduction:odpor --log=mc_safety.t:info' -platform ./cluster.xml -analyze --cfg=smpi/barrier-finalization:on --cfg=smpi/list-leaks:10 --cfg=model-check/max-depth:10000")
     execcmd = execcmd.replace('${EXE}', binary)
     execcmd = execcmd.replace('$zero_buffer', "--cfg=smpi/buffering:zero")
     execcmd = execcmd.replace('$infty_buffer', "--cfg=smpi/buffering:infty")