Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'changelog-operation-plugin' into 'master'
authorMartin Quinson <martin.quinson@ens-rennes.fr>
Wed, 10 May 2023 11:07:36 +0000 (11:07 +0000)
committerMartin Quinson <martin.quinson@ens-rennes.fr>
Wed, 10 May 2023 11:07:36 +0000 (11:07 +0000)
Add plugins operation and battery to changelog

See merge request simgrid/simgrid!149

13 files changed:
examples/cpp/operation-simple/s4u-operation-simple.cpp
examples/cpp/operation-switch-host/s4u-operation-switch-host.cpp
examples/cpp/operation-variable-load/s4u-operation-variable-load.cpp
examples/python/clusters-multicpu/clusters-multicpu.py
include/simgrid/plugins/operation.hpp
include/xbt/config.hpp
src/mc/api/State.cpp
src/mc/explo/udpor/Unfolding.hpp
src/mc/explo/udpor/maximal_subsets_iterator.hpp
src/plugins/operation.cpp
src/xbt/utils/iter/powerset.hpp
src/xbt/utils/iter/subsets_tests.cpp
src/xbt/utils/iter/variable_for_loop.hpp

index 70656e8..40a32b2 100644 (file)
@@ -38,7 +38,7 @@ int main(int argc, char* argv[])
   comm->add_successor(exec2);
 
   // Add a function to be called when operations end for log purpose
-  simgrid::plugins::Operation::on_end_cb([](simgrid::plugins::Operation* op) {
+  simgrid::plugins::Operation::on_end_cb([](const simgrid::plugins::Operation* op) {
     XBT_INFO("Operation %s finished (%d)", op->get_name().c_str(), op->get_count());
   });
 
index f8c183d..10b0b4c 100644 (file)
@@ -28,9 +28,9 @@ int main(int argc, char* argv[])
   simgrid::plugins::Operation::init();
 
   // Retrieve hosts
-  auto tremblay = e.host_by_name("Tremblay");
-  auto jupiter  = e.host_by_name("Jupiter");
-  auto fafard   = e.host_by_name("Fafard");
+  auto* tremblay = e.host_by_name("Tremblay");
+  auto* jupiter  = e.host_by_name("Jupiter");
+  auto* fafard   = e.host_by_name("Fafard");
 
   // Create operations
   auto comm0 = simgrid::plugins::CommOp::init("comm0");
@@ -47,15 +47,16 @@ int main(int argc, char* argv[])
   exec2->add_successor(comm2);
 
   // Add a function to be called when operations end for log purpose
-  simgrid::plugins::Operation::on_end_cb([](simgrid::plugins::Operation* op) {
+  simgrid::plugins::Operation::on_end_cb([](const simgrid::plugins::Operation* op) {
     XBT_INFO("Operation %s finished (%d)", op->get_name().c_str(), op->get_count());
   });
 
   // Add a function to be called before each executions of comm0
   // This function modifies the graph of operations by adding or removing
   // successors to comm0
-  int count = 0;
-  comm0->on_this_start([&](simgrid::plugins::Operation* op) {
+  comm0->on_this_start([exec1, exec2, jupiter, fafard](simgrid::plugins::Operation* op) {
+    auto* comm0      = dynamic_cast<simgrid::plugins::CommOp*>(op);
+    static int count = 0;
     if (count % 2 == 0) {
       comm0->set_destination(jupiter);
       comm0->add_successor(exec1);
index 9eea3da..02938b5 100644 (file)
@@ -51,7 +51,7 @@ int main(int argc, char* argv[])
   comm->add_successor(exec);
 
   // Add a function to be called when operations end for log purpose
-  simgrid::plugins::Operation::on_end_cb([](simgrid::plugins::Operation* op) {
+  simgrid::plugins::Operation::on_end_cb([](const simgrid::plugins::Operation* op) {
     XBT_INFO("Operation %s finished (%d)", op->get_name().c_str(), op->get_count());
   });
 
index 8f7240a..79ee80c 100644 (file)
@@ -101,7 +101,7 @@ def create_hostzone(zone: simgrid.NetZone, coord: typing.List[int], ident: int)
         host = host_zone.create_host(cpu_name, speed).seal()
         # the first CPU is the gateway
         if i == 0:
-            gateway = host
+            gateway = host.netpoint
         # create split-duplex link
         link = host_zone.create_split_duplex_link("link-" + cpu_name, link_bw)
         link.set_latency(link_lat).seal()
@@ -111,7 +111,7 @@ def create_hostzone(zone: simgrid.NetZone, coord: typing.List[int], ident: int)
 
     # seal newly created netzone
     host_zone.seal()
-    return host_zone.netpoint, gateway.netpoint
+    return host_zone.netpoint, gateway
 
 #####################################################################################################
 
index 0f2f0e6..6725466 100644 (file)
@@ -4,6 +4,7 @@
 #include <simgrid/s4u/Activity.hpp>
 #include <xbt/Extendable.hpp>
 
+#include <atomic>
 #include <map>
 #include <memory>
 #include <set>
 namespace simgrid::plugins {
 
 class Operation;
-using OperationPtr = std::shared_ptr<Operation>;
+using OperationPtr = boost::intrusive_ptr<Operation>;
+XBT_PUBLIC void intrusive_ptr_release(Operation* o);
+XBT_PUBLIC void intrusive_ptr_add_ref(Operation* o);
 class ExecOp;
-using ExecOpPtr = std::shared_ptr<ExecOp>;
+using ExecOpPtr = boost::intrusive_ptr<ExecOp>;
+XBT_PUBLIC void intrusive_ptr_release(ExecOp* e);
+XBT_PUBLIC void intrusive_ptr_add_ref(ExecOp* e);
 class CommOp;
-using CommOpPtr = std::shared_ptr<CommOp>;
+using CommOpPtr =  boost::intrusive_ptr<CommOp>;
+XBT_PUBLIC void intrusive_ptr_release(CommOp* c);
+XBT_PUBLIC void intrusive_ptr_add_ref(CommOp* c);
 
-class ExtendedAttributeActivity {
-public:
+struct ExtendedAttributeActivity {
   static simgrid::xbt::Extension<simgrid::s4u::Activity, ExtendedAttributeActivity> EXTENSION_ID;
   Operation* operation_;
-
-  ExtendedAttributeActivity(){};
 };
 
 class Operation {
@@ -43,26 +47,29 @@ protected:
   int queued_execs_ = 0;
   int count_        = 0;
   bool working_     = false;
-  simgrid::s4u::ActivityPtr current_activity_;
+  s4u::ActivityPtr current_activity_;
   std::function<void(Operation*)> end_func_;
   std::function<void(Operation*)> start_func_;
-  Operation(const std::string& name);
+  explicit Operation(const std::string& name);
   virtual ~Operation()   = default;
   virtual void execute() = 0;
 
   static xbt::signal<void(Operation*)> on_start;
   static xbt::signal<void(Operation*)> on_end;
+  std::atomic_int_fast32_t refcount_{0};
 
 public:
   static void init();
-  std::string get_name();
+  const std::string& get_name() const { return name_; }
+  const char* get_cname() const { return name_.c_str(); }
   void enqueue_execs(int n);
   void set_amount(double amount);
+  double get_amount() const { return amount_; }
   void add_successor(OperationPtr op);
   void remove_successor(OperationPtr op);
-  void on_this_start(std::function<void(Operation*)> func);
-  void on_this_end(std::function<void(Operation*)> func);
-  int get_count();
+  void on_this_start(const std::function<void(Operation*)>& func);
+  void on_this_end(const std::function<void(Operation*)>& func);
+  int get_count() const;
 
   /** Add a callback fired before an operation activity start.
    * Triggered after the on_this_start function**/
@@ -71,37 +78,58 @@ public:
    * Triggered after the on_this_end function, but before
    * sending tokens to successors.**/
   static void on_end_cb(const std::function<void(Operation*)>& cb) { on_end.connect(cb); }
+
+#ifndef DOXYGEN
+  friend void intrusive_ptr_release(Operation* o)
+  {
+    if (o->refcount_.fetch_sub(1, std::memory_order_release) == 1) {
+      std::atomic_thread_fence(std::memory_order_acquire);
+      delete o;
+    }
+  }
+  friend void intrusive_ptr_add_ref(Operation* o) { o->refcount_.fetch_add(1, std::memory_order_relaxed); }
+#endif
 };
 
 class ExecOp : public Operation {
 private:
-  simgrid::s4u::Host* host_;
+  s4u::Host* host_;
 
-  ExecOp(const std::string& name);
+  explicit ExecOp(const std::string& name);
   void execute() override;
 
 public:
   static ExecOpPtr init(const std::string& name);
-  static ExecOpPtr init(const std::string& name, double flops, simgrid::s4u::Host* host);
-  void set_host(simgrid::s4u::Host* host);
-  void set_flops(double flops);
+  static ExecOpPtr init(const std::string& name, double flops, s4u::Host* host);
+  ExecOpPtr set_host(s4u::Host* host);
+  s4u::Host* get_host() const { return host_; }
+  ExecOpPtr set_flops(double flops);
+  double get_flops() const { return get_amount(); }
+  friend void inline intrusive_ptr_release(ExecOp* e) { intrusive_ptr_release(static_cast<Operation*>(e)); }
+  friend void inline intrusive_ptr_add_ref(ExecOp* e) { intrusive_ptr_add_ref(static_cast<Operation*>(e)); }
 };
 
 class CommOp : public Operation {
 private:
-  simgrid::s4u::Host* source_;
-  simgrid::s4u::Host* destination_;
+  s4u::Host* source_;
+  s4u::Host* destination_;
 
-  CommOp(const std::string& name);
+  explicit CommOp(const std::string& name);
   void execute() override;
 
 public:
   static CommOpPtr init(const std::string& name);
-  static CommOpPtr init(const std::string& name, double bytes, simgrid::s4u::Host* source,
-                        simgrid::s4u::Host* destination);
-  void set_source(simgrid::s4u::Host* source);
-  void set_destination(simgrid::s4u::Host* destination);
-  void set_bytes(double bytes);
+  static CommOpPtr init(const std::string& name, double bytes, s4u::Host* source,
+                        s4u::Host* destination);
+  CommOpPtr set_source(s4u::Host* source);
+  s4u::Host* get_source() const { return source_; }
+  CommOpPtr set_destination(s4u::Host* destination);
+  s4u::Host* get_destination() const { return destination_; }
+  CommOpPtr set_bytes(double bytes);
+  double get_bytes() const { return get_amount(); }
+   friend void inline intrusive_ptr_release(CommOp* c) { intrusive_ptr_release(static_cast<Operation*>(c)); }
+  friend void inline intrusive_ptr_add_ref(CommOp* c) { intrusive_ptr_add_ref(static_cast<Operation*>(c)); }
+
 };
 } // namespace simgrid::plugins
 #endif
index 4cf17bf..372ec9b 100644 (file)
@@ -92,10 +92,10 @@ XBT_PUBLIC void alias(const char* realname, std::initializer_list<const char*> a
  */
 template <class T>
 XBT_PUBLIC void declare_flag(const std::string& name, const std::string& description, T value,
-                             std::function<void(const T&)> callback = std::function<void(const T&)>());
+                             std::function<void(const T&)> callback = nullptr);
 template <class T>
 void declare_flag(const std::string& name, std::initializer_list<const char*> aliases, const std::string& description,
-                  T value, std::function<void(const T&)> callback = std::function<void(const T&)>())
+                  T value, std::function<void(const T&)> callback = nullptr)
 {
   declare_flag(name, description, std::move(value), std::move(callback));
   alias(name.c_str(), aliases);
@@ -265,7 +265,7 @@ public:
        const std::map<std::string, std::string, std::less<>>& valid_values)
       : value_(value), name_(name)
   {
-    simgrid::config::bind_flag(value_, name, desc, valid_values, [](std::string) {});
+    simgrid::config::bind_flag(value_, name, desc, valid_values, [](const std::string&) {});
   }
 
   /* As earlier, a constructor accepting a map of valid values -> their description,
index 0366a31..34a41d6 100644 (file)
@@ -94,7 +94,7 @@ std::size_t State::count_todo_multiples() const
 std::deque<Transition*>& State::get_recipe()
 {
   if (recipe_.empty()) {
-    for (auto* s = this; s != nullptr; s = s->get_parent_state().get())
+    for (const auto* s = this; s != nullptr; s = s->get_parent_state().get())
       if (s->get_transition_in() != nullptr)
         recipe_.push_front(s->get_transition_in().get());
   }
index 140c893..3fa80f2 100644 (file)
@@ -73,7 +73,7 @@ public:
    * to an equivalent event that was already noted by the unfolding
    * at some point in the past
    */
-  template <typename... Args> const UnfoldingEvent* discover_event(Args... args)
+  template <typename... Args> const UnfoldingEvent* discover_event(Args&&... args)
   {
     auto candidate_event = std::make_unique<UnfoldingEvent>(std::forward<Args>(args)...);
     return insert(std::move(candidate_event));
index d172eda..2c3c07f 100644 (file)
@@ -58,7 +58,7 @@ private:
   bool has_started_searching                              = false;
   std::optional<size_t> maximum_subset_size               = std::nullopt;
   std::optional<EventSet> current_maximal_set             = std::nullopt;
-  std::stack<topological_order_position> backtrack_points = std::stack<topological_order_position>();
+  std::stack<topological_order_position, std::vector<topological_order_position>> backtrack_points;
 
   /**
    * @brief A small class which provides functionality for managing
index 0629065..ce34fe6 100644 (file)
@@ -31,11 +31,6 @@ xbt::signal<void(Operation*)> Operation::on_end;
 
 Operation::Operation(const std::string& name) : name_(name) {}
 
-std::string Operation::get_name()
-{
-  return name_;
-}
-
 /**
  *  @param predecessor The Operation to add.
  *  @brief Add a predecessor to this Operation.
@@ -124,7 +119,7 @@ void Operation::init()
     return;
   Operation::inited_                      = true;
   ExtendedAttributeActivity::EXTENSION_ID = simgrid::s4u::Activity::extension_create<ExtendedAttributeActivity>();
-  simgrid::s4u::Activity::on_completion_cb([&](simgrid::s4u::Activity const& activity) {
+  simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity const& activity) {
     activity.extension<ExtendedAttributeActivity>()->operation_->complete();
   });
 }
@@ -180,9 +175,9 @@ void Operation::remove_successor(OperationPtr successor)
  *  @brief Set a function to be called before each execution.
  *  @note The function is called before the underlying Activity starts.
  */
-void Operation::on_this_start(std::function<void(Operation*)> func)
+void Operation::on_this_start(const std::function<void(Operation*)>& func)
 {
-  simgrid::kernel::actor::simcall_answered([this, func] { start_func_ = func; });
+  simgrid::kernel::actor::simcall_answered([this, &func] { start_func_ = func; });
 }
 
 /** @ingroup plugin_operation
@@ -190,15 +185,15 @@ void Operation::on_this_start(std::function<void(Operation*)> func)
  *  @brief Set a function to be called after each execution.
  *  @note The function is called after the underlying Activity ends, but before sending tokens to successors.
  */
-void Operation::on_this_end(std::function<void(Operation*)> func)
+void Operation::on_this_end(const std::function<void(Operation*)>& func)
 {
-  simgrid::kernel::actor::simcall_answered([this, func] { end_func_ = func; });
+  simgrid::kernel::actor::simcall_answered([this, &func] { end_func_ = func; });
 }
 
 /** @ingroup plugin_operation
  *  @brief Return the number of completed executions.
  */
-int Operation::get_count()
+int Operation::get_count() const
 {
   return count_;
 }
@@ -213,19 +208,15 @@ ExecOp::ExecOp(const std::string& name) : Operation(name) {}
  */
 ExecOpPtr ExecOp::init(const std::string& name)
 {
-  auto op = ExecOpPtr(new ExecOp(name));
-  return op;
+  return ExecOpPtr(new ExecOp(name));
 }
 
 /** @ingroup plugin_operation
  *  @brief Smart Constructor.
  */
-ExecOpPtr ExecOp::init(const std::string& name, double flops, simgrid::s4u::Host* host)
+ExecOpPtr ExecOp::init(const std::string& name, double flops, s4u::Host* host)
 {
-  auto op = ExecOpPtr(new ExecOp(name));
-  op->set_flops(flops);
-  op->set_host(host);
-  return op;
+  return init(name)->set_flops(flops)->set_host(host);
 }
 
 /**
@@ -238,35 +229,37 @@ void ExecOp::execute()
   if (start_func_)
     start_func_(this);
   Operation::on_start(this);
-  simgrid::kernel::actor::simcall_answered([this] {
+  kernel::actor::simcall_answered([this] {
     working_      = true;
     queued_execs_ = std::max(queued_execs_ - 1, 0);
   });
-  simgrid::s4u::ExecPtr exec = simgrid::s4u::Exec::init();
+  s4u::ExecPtr exec = s4u::Exec::init();
   exec->set_name(name_);
   exec->set_flops_amount(amount_);
   exec->set_host(host_);
   exec->start();
   exec->extension_set(new ExtendedAttributeActivity());
   exec->extension<ExtendedAttributeActivity>()->operation_ = this;
-  simgrid::kernel::actor::simcall_answered([this, exec] { current_activity_ = exec; });
+  kernel::actor::simcall_answered([this, exec] { current_activity_ = exec; });
 }
 
 /** @ingroup plugin_operation
  *  @param host The host to set.
  *  @brief Set a new host.
  */
-void ExecOp::set_host(simgrid::s4u::Host* host)
+ExecOpPtr ExecOp::set_host(s4u::Host* host)
 {
-  simgrid::kernel::actor::simcall_answered([this, host] { host_ = host; });
+  kernel::actor::simcall_answered([this, host] { host_ = host; });
+  return this;
 }
 
 /** @ingroup plugin_operation
  *  @param flops The amount of flops to set.
  */
-void ExecOp::set_flops(double flops)
+ExecOpPtr ExecOp::set_flops(double flops)
 {
-  simgrid::kernel::actor::simcall_answered([this, flops] { amount_ = flops; });
+  kernel::actor::simcall_answered([this, flops] { amount_ = flops; });
+  return this;
 }
 
 /**
@@ -279,21 +272,16 @@ CommOp::CommOp(const std::string& name) : Operation(name) {}
  */
 CommOpPtr CommOp::init(const std::string& name)
 {
-  auto op = CommOpPtr(new CommOp(name));
-  return op;
+  return CommOpPtr(new CommOp(name));
 }
 
 /** @ingroup plugin_operation
  *  @brief Smart constructor.
  */
-CommOpPtr CommOp::init(const std::string& name, double bytes, simgrid::s4u::Host* source,
-                       simgrid::s4u::Host* destination)
+CommOpPtr CommOp::init(const std::string& name, double bytes, s4u::Host* source,
+                       s4u::Host* destination)
 {
-  auto op = CommOpPtr(new CommOp(name));
-  op->set_bytes(bytes);
-  op->set_source(source);
-  op->set_destination(destination);
-  return op;
+  return init(name)->set_bytes(bytes)->set_source(source)->set_destination(destination);
 }
 
 /**
@@ -306,43 +294,46 @@ void CommOp::execute()
   if (start_func_)
     start_func_(this);
   Operation::on_start(this);
-  simgrid::kernel::actor::simcall_answered([this] {
+  kernel::actor::simcall_answered([this] {
     working_      = true;
     queued_execs_ = std::max(queued_execs_ - 1, 0);
   });
-  simgrid::s4u::CommPtr comm = simgrid::s4u::Comm::sendto_init(source_, destination_);
+  s4u::CommPtr comm = s4u::Comm::sendto_init(source_, destination_);
   comm->set_name(name_);
   comm->set_payload_size(amount_);
   comm->start();
   comm->extension_set(new ExtendedAttributeActivity());
   comm->extension<ExtendedAttributeActivity>()->operation_ = this;
-  simgrid::kernel::actor::simcall_answered([this, comm] { current_activity_ = comm; });
+  kernel::actor::simcall_answered([this, comm] { current_activity_ = comm; });
 }
 
 /** @ingroup plugin_operation
  *  @param source The host to set.
  *  @brief Set a new source host.
  */
-void CommOp::set_source(simgrid::s4u::Host* source)
+CommOpPtr CommOp::set_source(s4u::Host* source)
 {
-  simgrid::kernel::actor::simcall_answered([this, source] { source_ = source; });
+  kernel::actor::simcall_answered([this, source] { source_ = source; });
+  return this;
 }
 
 /** @ingroup plugin_operation
  *  @param destination The host to set.
  *  @brief Set a new destination host.
  */
-void CommOp::set_destination(simgrid::s4u::Host* destination)
+CommOpPtr CommOp::set_destination(s4u::Host* destination)
 {
-  simgrid::kernel::actor::simcall_answered([this, destination] { destination_ = destination; });
+  kernel::actor::simcall_answered([this, destination] { destination_ = destination; });
+  return this;
 }
 
 /** @ingroup plugin_operation
  *  @param bytes The amount of bytes to set.
  */
-void CommOp::set_bytes(double bytes)
+CommOpPtr CommOp::set_bytes(double bytes)
 {
-  simgrid::kernel::actor::simcall_answered([this, bytes] { amount_ = bytes; });
+  kernel::actor::simcall_answered([this, bytes] { amount_ = bytes; });
+  return this;
 }
 
 } // namespace simgrid::plugins
index d7b2cdf..b83bad7 100644 (file)
@@ -40,8 +40,6 @@ private:
   std::optional<subsets_iterator<Iterator>> current_subset_iter     = std::nullopt;
   std::optional<subsets_iterator<Iterator>> current_subset_iter_end = std::nullopt;
 
-  const std::vector<Iterator> empty_subset = std::vector<Iterator>();
-
   // boost::iterator_facade<...> interface to implement
   void increment();
   bool equal(const powerset_iterator<Iterator>& other) const;
@@ -70,6 +68,7 @@ template <typename Iterator> const std::vector<Iterator>& powerset_iterator<Iter
   if (current_subset_iter.has_value()) {
     return *current_subset_iter.value();
   }
+  static const std::vector<Iterator> empty_subset;
   return empty_subset;
 }
 
index 41bdf41..59c95ae 100644 (file)
@@ -65,8 +65,8 @@ TEST_CASE("simgrid::xbt::powerset_iterator: Iteration General Properties")
       }
     }
 
-    for (const auto& iter : element_counts) {
-      REQUIRE(iter.second == expected_count);
+    for (const auto& [_, count] : element_counts) {
+      REQUIRE(count == expected_count);
     }
   }
 }
@@ -187,4 +187,4 @@ TEST_CASE("simgrid::xbt::variable_for_loop: Edge Cases")
               (outer_loop1.size() * outer_loop2.size() * outer_loop3.size() * outer_loop4.size() * outer_loop5.size()));
     }
   }
-}
\ No newline at end of file
+}
index bd5d29a..cbcb0a2 100644 (file)
@@ -85,11 +85,11 @@ template <typename IterableType> void variable_for_loop<IterableType>::increment
 
   for (auto j = k; j != std::numeric_limits<size_t>::max(); j--) {
     // Attempt to move to the next element of the `j`th collection
-    const auto& new_position = ++current_subset[j];
+    ++current_subset[j];
 
     // If the `j`th element has reached its own end, reset it
     // back to the beginning and keep moving forward
-    if (new_position == underlying_collections[j].get().cend()) {
+    if (current_subset[j] == underlying_collections[j].get().cend()) {
       current_subset[j] = underlying_collections[j].get().cbegin();
     } else {
       // Otherwise we've found the largest element which needed to