Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add WakeupTreeIterator and WakeupTree skeletons
authorMaxwell Pirtle <maxwellpirtle@gmail.com>
Tue, 9 May 2023 14:34:04 +0000 (16:34 +0200)
committerMaxwell Pirtle <maxwellpirtle@gmail.com>
Tue, 16 May 2023 07:50:34 +0000 (09:50 +0200)
MANIFEST.in
src/mc/explo/odpor/Execution.hpp
src/mc/explo/odpor/WakeupTree.cpp
src/mc/explo/odpor/WakeupTree.hpp
src/mc/explo/odpor/WakeupTreeIterator.cpp [new file with mode: 0644]
src/mc/explo/odpor/WakeupTreeIterator.hpp [new file with mode: 0644]
src/mc/explo/odpor/odpor_forward.hpp
tools/cmake/DefinePackages.cmake

index ec8c8d1..02e695c 100644 (file)
@@ -2197,6 +2197,8 @@ include src/mc/explo/odpor/Execution.hpp
 include src/mc/explo/odpor/Execution_test.cpp
 include src/mc/explo/odpor/WakeupTree.cpp
 include src/mc/explo/odpor/WakeupTree.hpp
+include src/mc/explo/odpor/WakeupTreeIterator.cpp
+include src/mc/explo/odpor/WakeupTreeIterator.hpp
 include src/mc/explo/odpor/odpor_forward.hpp
 include src/mc/explo/simgrid_mc.cpp
 include src/mc/explo/udpor/Comb.hpp
index dca1c5d..f851cf4 100644 (file)
 
 namespace simgrid::mc::odpor {
 
-using ProcessSequence   = std::list<aid_t>;
-using ExecutionSequence = std::list<const State*>;
-using Hypothetical      = ExecutionSequence;
-
 /**
  * @brief The occurrence of a transition in an execution
  *
@@ -100,8 +96,6 @@ public:
   Execution(const Execution&)            = default;
   Execution& operator=(Execution const&) = default;
   Execution(Execution&&)                 = default;
-  Execution(ExecutionSequence&& seq);
-  Execution(const ExecutionSequence& seq);
 
   size_t size() const { return this->contents_.size(); }
   bool empty() const { return this->contents_.empty(); }
@@ -150,6 +144,9 @@ public:
    */
   std::optional<aid_t> get_first_sdpor_initial_from(EventHandle e, std::unordered_set<aid_t> backtrack_set) const;
 
+  std::optional<ProcessSequence> get_shortest_odpor_sq_subset_insert(const ProcessSequence& v,
+                                                                     const ExecutionSequence& w) const;
+
   /**
    * @brief Determines the event associated with
    * the given handle `handle`
index e69de29..bbe6b69 100644 (file)
@@ -0,0 +1,21 @@
+/* Copyright (c) 2008-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. */
+
+#include "src/mc/explo/odpor/WakeupTree.hpp"
+#include "src/mc/explo/odpor/Execution.hpp"
+
+#include <algorithm>
+
+namespace simgrid::mc::odpor {
+
+WakeupTree::WakeupTree() : root(nullptr) {}
+
+void WakeupTree::insert(const Execution& E, const ExecutionSequence& w)
+{
+  // Find the first node `v` in the tree such that
+  // `v ~_[E] w`
+}
+
+} // namespace simgrid::mc::odpor
\ No newline at end of file
index e69de29..81356cd 100644 (file)
@@ -0,0 +1,66 @@
+/* Copyright (c) 2007-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. */
+
+#ifndef SIMGRID_MC_ODPOR_WAKEUP_TREE_HPP
+#define SIMGRID_MC_ODPOR_WAKEUP_TREE_HPP
+
+#include "src/mc/explo/odpor/odpor_forward.hpp"
+
+#include <memory>
+#include <unordered_map>
+
+namespace simgrid::mc::odpor {
+
+class WakeupTreeNode {
+private:
+  /** An ordered list of children of for this node in the tree */
+  std::list<const WakeupTreeNode*> children_;
+
+  /** @brief The contents of the node */
+  ProcessSequence seq_;
+
+public:
+  const auto begin() const { return this->children_.begin(); }
+  const auto end() const { return this->children_.end(); }
+  const auto rbegin() const { return this->children_.rbegin(); }
+  const auto rend() const { return this->children_.rend(); }
+
+  const ProcessSequence& get_sequence() const { return seq_; }
+  const std::list<const WakeupTreeNode*>& get_ordered_children() const { return children_; }
+
+  bool is_leaf() const { return children_.empty(); }
+};
+
+class WakeupTree {
+private:
+  /** @brief The root node of the tree */
+  const WakeupTreeNode* const root;
+
+  /**
+   * @brief All of the nodes that are currently are a part of the tree
+   *
+   * @invariant Each node event maps itself to the owner of that node,
+   * i.e. the unique pointer that manages the data at the address. The tree owns all
+   * of the addresses that are referenced by the nodes WakeupTreeNode and Configuration.
+   * ODPOR guarantees that nodes are persisted as long as needed.
+   */
+  std::unordered_map<const WakeupTreeNode*, std::unique_ptr<WakeupTreeNode>> nodes_;
+
+  /* Allow the iterator to access the contents of the tree */
+  friend WakeupTreeIterator;
+
+public:
+  WakeupTree();
+
+  /**
+   * @brief Inserts an sequence `seq` of processes into the tree
+   * such that that this tree is a wakeup tree relative to the
+   * given execution
+   */
+  void insert(const Execution&, const ExecutionSequence& seq);
+};
+
+} // namespace simgrid::mc::odpor
+#endif
diff --git a/src/mc/explo/odpor/WakeupTreeIterator.cpp b/src/mc/explo/odpor/WakeupTreeIterator.cpp
new file mode 100644 (file)
index 0000000..684a633
--- /dev/null
@@ -0,0 +1,65 @@
+/* Copyright (c) 2008-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. */
+
+#include "src/mc/explo/odpor/WakeupTreeIterator.hpp"
+
+namespace simgrid::mc::odpor {
+
+WakeupTreeIterator::WakeupTreeIterator(const WakeupTree& tree)
+{
+  //   post_order_iteration.push(tree.root);
+  push_until_left_most_found();
+}
+
+void WakeupTreeIterator::push_until_left_most_found()
+{
+  // INVARIANT: Since we are traversing over a tree,
+  // there are no cycles. This means that at least
+  // one node in the tree won't have any children,
+  // so the loop will eventually terminate
+  auto* cur_top_node = *post_order_iteration.top();
+  while (!cur_top_node->is_leaf()) {
+    // INVARIANT: Since we push children in
+    // reverse order (right-most to left-most),
+    // we ensure that we'll always process left-most
+    // children first
+  }
+}
+
+void WakeupTreeIterator::increment()
+{
+  // If there are no nodes in the stack, we've
+  // completed the traversal: there's nothing left
+  // to do
+  if (post_order_iteration.empty()) {
+    return;
+  }
+
+  auto prev_top_handle = post_order_iteration.top();
+  post_order_iteration.pop();
+
+  // If there are now no longer any nodes left,
+  // we know that `prev_top` must be the original
+  // root; that is, we were *just* pointing at the
+  // original root, so we're done
+  if (post_order_iteration.empty()) {
+    return;
+  }
+
+  // Otherwise, look at the next top node. If
+  // `prev_top` is that node's right-most child,
+  // then we don't attempt to re-add `next_top`'s
+  // children again for we would have already seen them
+  const auto* next_top_node = *post_order_iteration.top();
+
+  // To actually determine "right-most", we check if
+  // moving over to the right one spot brings us to the
+  // end of the candidate parent's list
+  if ((++prev_top_handle) != next_top_node->get_ordered_children().end()) {
+    push_until_left_most_found();
+  }
+}
+
+} // namespace simgrid::mc::odpor
\ No newline at end of file
diff --git a/src/mc/explo/odpor/WakeupTreeIterator.hpp b/src/mc/explo/odpor/WakeupTreeIterator.hpp
new file mode 100644 (file)
index 0000000..2aae9b5
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (c) 2007-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. */
+
+#ifndef SIMGRID_MC_ODPOR_WAKEUP_TREE_ITERATOR_HPP
+#define SIMGRID_MC_ODPOR_WAKEUP_TREE_ITERATOR_HPP
+
+#include "src/mc/explo/odpor/WakeupTree.hpp"
+
+#include <boost/iterator/iterator_facade.hpp>
+#include <list>
+#include <stack>
+
+namespace simgrid::mc::odpor {
+
+struct WakeupTreeIterator
+    : public boost::iterator_facade<WakeupTreeIterator, const WakeupTreeNode*, boost::forward_traversal_tag> {
+public:
+  WakeupTreeIterator() = default;
+  explicit WakeupTreeIterator(const WakeupTree& tree);
+
+private:
+  using node_handle = std::list<const WakeupTreeNode*>::iterator;
+
+  /**
+   * @brief The current "view" of the iteration in post-order traversal
+   */
+  std::stack<node_handle> post_order_iteration;
+
+  /**
+   *
+   */
+  void push_until_left_most_found();
+
+  // boost::iterator_facade<...> interface to implement
+  void increment();
+  bool equal(const WakeupTreeIterator& other) const { return post_order_iteration == other.post_order_iteration; }
+  const WakeupTreeNode*& dereference() const { return *post_order_iteration.top(); }
+
+  // Allows boost::iterator_facade<...> to function properly
+  friend class boost::iterator_core_access;
+};
+
+} // namespace simgrid::mc::odpor
+#endif
index 1a439c1..dc1e4bd 100644 (file)
 #define SIMGRID_MC_ODPOR_FORWARD_HPP
 
 #include "src/mc/mc_forward.hpp"
+#include <list>
 #include <simgrid/forward.h>
 
 namespace simgrid::mc::odpor {
 
+using ProcessSequence   = std::list<aid_t>;
+using ExecutionSequence = std::list<const Transition*>;
+
 class Event;
 class Execution;
-class ExecutionView;
 class WakeupTree;
+class WakeupTreeIterator;
 
 } // namespace simgrid::mc::odpor
 
index 95e2a37..c395235 100644 (file)
@@ -539,6 +539,8 @@ set(MC_SRC_STATELESS
   src/mc/explo/odpor/Execution.hpp
   src/mc/explo/odpor/WakeupTree.cpp
   src/mc/explo/odpor/WakeupTree.hpp
+  src/mc/explo/odpor/WakeupTreeIterator.cpp
+  src/mc/explo/odpor/WakeupTreeIterator.hpp
   src/mc/explo/odpor/odpor_forward.hpp
 
   src/mc/remote/AppSide.cpp