Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add `udpor` directory under `mc/explo`
authorMaxwell Pirtle <maxwellpirtle@gmail.com>
Tue, 14 Feb 2023 13:20:10 +0000 (14:20 +0100)
committerMaxwell Pirtle <maxwellpirtle@gmail.com>
Mon, 20 Feb 2023 09:43:53 +0000 (10:43 +0100)
The `udpor` directory was created to better
house/separate all of the functionality that will
eventually be required by the UDPOR algorithm.
Currently, the files are not used as part of the
compilation process. Subsequent commits will remove
the `udpor_global.cpp` file and adjust the compilation
as necessary

src/mc/explo/udpor/Configuration.cpp [new file with mode: 0644]
src/mc/explo/udpor/Configuration.hpp [new file with mode: 0644]
src/mc/explo/udpor/EventSet.cpp [new file with mode: 0644]
src/mc/explo/udpor/EventSet.hpp [new file with mode: 0644]
src/mc/explo/udpor/StateManager.cpp [new file with mode: 0644]
src/mc/explo/udpor/StateManager.hpp [new file with mode: 0644]
src/mc/explo/udpor/UnfoldingEvent.cpp [new file with mode: 0644]
src/mc/explo/udpor/UnfoldingEvent.hpp [new file with mode: 0644]
src/mc/explo/udpor/udpor_forward.hpp [new file with mode: 0644]

diff --git a/src/mc/explo/udpor/Configuration.cpp b/src/mc/explo/udpor/Configuration.cpp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/mc/explo/udpor/Configuration.hpp b/src/mc/explo/udpor/Configuration.hpp
new file mode 100644 (file)
index 0000000..18c5c6f
--- /dev/null
@@ -0,0 +1,114 @@
+/* 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_UDPOR_CONFIGURATION_HPP
+#define SIMGRID_MC_UDPOR_CONFIGURATION_HPP
+
+#include "src/mc/explo/udpor/EventSet.hpp"
+#include "src/mc/explo/udpor/udpor_forward.hpp"
+
+namespace simgrid::mc::udpor {
+
+using StateHandle = uint64_t;
+
+class Configuration {
+public:
+  Configuration()                                = default;
+  Configuration(const Configuration&)            = default;
+  Configuration& operator=(Configuration const&) = default;
+  Configuration(Configuration&&)                 = default;
+
+  inline auto begin() const { return this->events_.begin(); }
+  inline auto end() const { return this->events_.end(); }
+  inline const EventSet& get_events() const { return this->events_; }
+  inline const EventSet& get_maximal_events() const { return this->max_events_; }
+
+  void add_event(UnfoldingEvent*);
+  UnfoldingEvent* get_latest_event() const;
+
+private:
+  /**
+   * @brief The most recent event added to the configuration
+   */
+  UnfoldingEvent* newest_event = nullptr;
+  EventSet events_;
+
+  /**
+   * The <-maxmimal events of the configuration. These are
+   * dynamically adjusted as events are added to the configuration
+   *
+   * @invariant: Each event that is part of this set is
+   *
+   * 1. a <-maxmimal event of the configuration, in the sense that
+   * there is no event in the configuration that is "greater" than it.
+   * In UDPOR terminology, each event does not "cause" another event
+   *
+   * 2. contained in the set of events `events_` which comprise
+   * the configuration
+   */
+  EventSet max_events_;
+
+private:
+  void recompute_maxmimal_events(UnfoldingEvent* new_event);
+};
+
+class UnfoldingEvent {
+public:
+  UnfoldingEvent(unsigned int nb_events, std::string const& trans_tag, EventSet const& immediate_causes,
+                 StateHandle sid);
+  UnfoldingEvent(unsigned int nb_events, std::string const& trans_tag, EventSet const& immediate_causes);
+  UnfoldingEvent(const UnfoldingEvent&)            = default;
+  UnfoldingEvent& operator=(UnfoldingEvent const&) = default;
+  UnfoldingEvent(UnfoldingEvent&&)                 = default;
+
+  EventSet get_history() const;
+  bool in_history(const UnfoldingEvent* otherEvent) const;
+
+  bool conflicts_with(const UnfoldingEvent* otherEvent) const;
+  bool conflicts_with(const Configuration& config) const;
+  bool immediately_conflicts_with(const UnfoldingEvent* otherEvt) const;
+
+  bool operator==(const UnfoldingEvent&) const { return false; };
+
+  inline StateHandle get_state_id() const { return state_id; }
+  inline void set_state_id(StateHandle sid) { state_id = sid; }
+
+private:
+  int id = -1;
+
+  /**
+   * @brief The "immediate" causes of this event.
+   *
+   * An event `e` is an immediate cause of an event `e'` if
+   *
+   * 1. e < e'
+   * 2. There is no event `e''` in E such that
+   * `e < e''` and `e'' < e'`
+   *
+   * Intuitively, an immediate cause "happened right before"
+   * this event was executed. It is sufficient to store
+   * only the immediate causes of any event `e`, as any indirect
+   * causes of that event would either be an indirect cause
+   * or an immediate cause of the immediate causes of `e`, and
+   * so on.
+   */
+  EventSet immediate_causes;
+  StateHandle state_id = 0ul;
+};
+
+class StateManager {
+private:
+  using Handle = StateHandle;
+
+  Handle current_handle_ = 1ul;
+  std::unordered_map<Handle, std::unique_ptr<State>> state_map_;
+
+public:
+  Handle record_state(std::unique_ptr<State>);
+  std::optional<std::reference_wrapper<State>> get_state(Handle);
+};
+
+} // namespace simgrid::mc::udpor
+#endif
diff --git a/src/mc/explo/udpor/EventSet.cpp b/src/mc/explo/udpor/EventSet.cpp
new file mode 100644 (file)
index 0000000..57aeeb9
--- /dev/null
@@ -0,0 +1,88 @@
+/* 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/udpor/EventSet.hpp"
+
+#include <algorithm>
+#include <iterator>
+#include <set>
+
+namespace simgrid::mc::udpor {
+
+void EventSet::remove(UnfoldingEvent* e)
+{
+  this->events_.erase(e);
+}
+
+void EventSet::subtract(const EventSet& other)
+{
+  this->events_ = std::move(subtracting(other).events_);
+}
+
+EventSet EventSet::subtracting(const EventSet& other) const
+{
+  std::set<UnfoldingEvent*> result;
+  std::set_difference(this->events_.begin(), this->events_.end(), other.events_.begin(), other.events_.end(),
+                      std::inserter(result, result.end()));
+  return EventSet(std::move(result));
+}
+
+EventSet EventSet::subtracting(UnfoldingEvent* e) const
+{
+  auto result = this->events_;
+  result.erase(e);
+  return EventSet(std::move(result));
+}
+
+void EventSet::insert(UnfoldingEvent* e)
+{
+  // TODO: Potentially react if the event is already inserted
+  this->events_.insert(e);
+}
+
+void EventSet::form_union(const EventSet& other)
+{
+  this->events_ = std::move(make_union(other).events_);
+}
+
+EventSet EventSet::make_union(UnfoldingEvent* e) const
+{
+  auto result = this->events_;
+  result.insert(e);
+  return EventSet(std::move(result));
+}
+
+EventSet EventSet::make_union(const EventSet& other) const
+{
+  std::set<UnfoldingEvent*> result;
+  std::set_union(this->events_.begin(), this->events_.end(), other.events_.begin(), other.events_.end(),
+                 std::inserter(result, result.end()));
+  return EventSet(std::move(result));
+}
+
+size_t EventSet::size() const
+{
+  return this->events_.size();
+}
+
+bool EventSet::empty() const
+{
+  return this->events_.empty();
+}
+
+bool EventSet::contains(UnfoldingEvent* e) const
+{
+  return this->events_.find(e) != this->events_.end();
+}
+
+bool EventSet::is_subset_of(const EventSet& other) const
+{
+  // If there is some element not contained in `other`, then
+  // the set difference will contain that element and the
+  // result won't be empty
+  return subtracting(other).empty();
+}
+
+} // namespace simgrid::mc::udpor
\ No newline at end of file
diff --git a/src/mc/explo/udpor/EventSet.hpp b/src/mc/explo/udpor/EventSet.hpp
new file mode 100644 (file)
index 0000000..3e5bbc3
--- /dev/null
@@ -0,0 +1,50 @@
+/* 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_UDPOR_EVENT_SET_HPP
+#define SIMGRID_MC_UDPOR_EVENT_SET_HPP
+
+#include "src/mc/explo/udpor/UnfoldingEvent.hpp"
+#include "src/mc/explo/udpor/udpor_forward.hpp"
+
+namespace simgrid::mc::udpor {
+
+class EventSet {
+private:
+  std::set<UnfoldingEvent*> events_;
+  explicit EventSet(std::set<UnfoldingEvent*>&& raw_events) : events_(raw_events) {}
+
+public:
+  EventSet()                           = default;
+  EventSet(const EventSet&)            = default;
+  EventSet& operator=(const EventSet&) = default;
+  EventSet& operator=(EventSet&&)      = default;
+  EventSet(EventSet&&)                 = default;
+
+  inline auto begin() const { return this->events_.begin(); }
+  inline auto end() const { return this->events_.end(); }
+
+  void remove(UnfoldingEvent* e);
+  void subtract(const EventSet& other);
+  void subtract(const Configuration& other);
+  EventSet subtracting(UnfoldingEvent* e) const;
+  EventSet subtracting(const EventSet& e) const;
+  EventSet subtracting(const Configuration* e) const;
+
+  void insert(UnfoldingEvent* e);
+  void form_union(const EventSet&);
+  void form_union(const Configuration&);
+  EventSet make_union(UnfoldingEvent* e) const;
+  EventSet make_union(const EventSet&) const;
+  EventSet make_union(const Configuration& e) const;
+
+  size_t size() const;
+  bool empty() const;
+  bool contains(UnfoldingEvent* e) const;
+  bool is_subset_of(const EventSet& other) const;
+};
+
+} // namespace simgrid::mc::udpor
+#endif
diff --git a/src/mc/explo/udpor/StateManager.cpp b/src/mc/explo/udpor/StateManager.cpp
new file mode 100644 (file)
index 0000000..a2fab12
--- /dev/null
@@ -0,0 +1,34 @@
+/* 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/udpor/StateManager.hpp"
+
+namespace simgrid::mc::udpor {
+
+StateManager::Handle StateManager::record_state(std::unique_ptr<State> state)
+{
+  if (state.get() == nullptr) {
+    throw std::invalid_argument("Expected a newly-allocated State but got NULL instead");
+  }
+
+  const auto integer_handle = this->current_handle_;
+  this->state_map_.insert({integer_handle, std::move(state)});
+
+  // TODO: Check for state handle overflow!
+  this->current_handle_++;
+  return integer_handle;
+}
+
+std::optional<std::reference_wrapper<State>> StateManager::get_state(StateManager::Handle handle)
+{
+  auto state = this->state_map_.find(handle);
+  if (state == this->state_map_.end()) {
+    return std::nullopt;
+  }
+  auto& state_ref = *state->second.get();
+  return std::optional<std::reference_wrapper<State>>{state_ref};
+}
+
+} // namespace simgrid::mc::udpor
diff --git a/src/mc/explo/udpor/StateManager.hpp b/src/mc/explo/udpor/StateManager.hpp
new file mode 100644 (file)
index 0000000..41f0179
--- /dev/null
@@ -0,0 +1,27 @@
+/* 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_UDPOR_GLOBAL_HPP
+#define SIMGRID_MC_UDPOR_GLOBAL_HPP
+
+#include "src/mc/api/State.hpp"
+#include "src/mc/explo/udpor/udpor_forward.hpp"
+
+namespace simgrid::mc::udpor {
+
+class StateManager {
+private:
+  using Handle = StateHandle;
+
+  Handle current_handle_ = 1ul;
+  std::unordered_map<Handle, std::unique_ptr<State>> state_map_;
+
+public:
+  Handle record_state(std::unique_ptr<State>);
+  std::optional<std::reference_wrapper<State>> get_state(Handle);
+};
+
+} // namespace simgrid::mc::udpor
+#endif
diff --git a/src/mc/explo/udpor/UnfoldingEvent.cpp b/src/mc/explo/udpor/UnfoldingEvent.cpp
new file mode 100644 (file)
index 0000000..779b6fd
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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/udpor/UnfoldingEvent.hpp"
+
+namespace simgrid::mc::udpor {
+
+UnfoldingEvent::UnfoldingEvent(unsigned int nb_events, std::string const& trans_tag, EventSet const& immediate_causes)
+    : UnfoldingEvent(nb_events, trans_tag, immediate_causes, 0)
+{
+  // TODO: Implement this correctly
+}
+
+UnfoldingEvent::UnfoldingEvent(unsigned int nb_events, std::string const& trans_tag, EventSet const& immediate_causes,
+                               StateHandle sid)
+{
+  // TODO: Implement this
+}
+
+} // namespace simgrid::mc::udpor
diff --git a/src/mc/explo/udpor/UnfoldingEvent.hpp b/src/mc/explo/udpor/UnfoldingEvent.hpp
new file mode 100644 (file)
index 0000000..8f94a0a
--- /dev/null
@@ -0,0 +1,63 @@
+/* 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_UDPOR_UNFOLDING_EVENT_HPP
+#define SIMGRID_MC_UDPOR_UNFOLDING_EVENT_HPP
+
+#include "src/mc/explo/udpor/EventSet.hpp"
+#include "src/mc/explo/udpor/udpor_forward.hpp"
+
+namespace simgrid::mc::udpor {
+
+class UnfoldingEvent {
+public:
+  UnfoldingEvent(unsigned int nb_events, std::string const& trans_tag, EventSet const& immediate_causes,
+                 StateHandle sid);
+  UnfoldingEvent(unsigned int nb_events, std::string const& trans_tag, EventSet const& immediate_causes);
+  UnfoldingEvent(const UnfoldingEvent&)            = default;
+  UnfoldingEvent& operator=(UnfoldingEvent const&) = default;
+  UnfoldingEvent(UnfoldingEvent&&)                 = default;
+
+  EventSet get_history() const;
+  bool in_history_of(const UnfoldingEvent* otherEvent) const;
+
+  bool conflicts_with(const UnfoldingEvent* otherEvent) const;
+  bool conflicts_with(const Configuration& config) const;
+  bool immediately_conflicts_with(const UnfoldingEvent* otherEvt) const;
+
+  inline StateHandle get_state_id() const { return state_id; }
+  inline void set_state_id(StateHandle sid) { state_id = sid; }
+
+  bool operator==(const UnfoldingEvent&) const
+  {
+    // TODO: Implement semantic equality
+    return false;
+  };
+
+private:
+  int id = -1;
+
+  /**
+   * @brief The "immediate" causes of this event.
+   *
+   * An event `e` is an immediate cause of an event `e'` if
+   *
+   * 1. e < e'
+   * 2. There is no event `e''` in E such that
+   * `e < e''` and `e'' < e'`
+   *
+   * Intuitively, an immediate cause "happened right before"
+   * this event was executed. It is sufficient to store
+   * only the immediate causes of any event `e`, as any indirect
+   * causes of that event would either be an indirect cause
+   * or an immediate cause of the immediate causes of `e`, and
+   * so on.
+   */
+  EventSet immediate_causes;
+  StateHandle state_id = 0ul;
+};
+
+} // namespace simgrid::mc::udpor
+#endif
\ No newline at end of file
diff --git a/src/mc/explo/udpor/udpor_forward.hpp b/src/mc/explo/udpor/udpor_forward.hpp
new file mode 100644 (file)
index 0000000..35c2542
--- /dev/null
@@ -0,0 +1,23 @@
+/* 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. */
+
+/** @file mc_forward.hpp
+ *
+ *  Forward definitions for MC types specific to UDPOR
+ */
+
+#ifndef SIMGRID_MC_UDPOR_FORWARD_HPP
+#define SIMGRID_MC_UDPOR_FORWARD_HPP
+
+namespace simgrid::mc::udpor {
+
+class EventSet;
+class UnfoldingEvent;
+class Configuration;
+class StateManager;
+
+} // namespace simgrid::mc::udpor
+
+#endif