SpECTRE Documentation Coverage Report
Current view: top level - Parallel/ArrayCollection - DgElementArrayMemberBase.hpp Hit Total Coverage
Commit: e1f22ede76131d2a431eabbd2dd32008f3162edb Lines: 16 39 41.0 %
Date: 2025-04-16 15:32:12
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // Distributed under the MIT License.
       2             : // See LICENSE.txt for details.
       3             : 
       4             : #pragma once
       5             : 
       6             : #include <charm++.h>
       7             : #include <cstddef>
       8             : #include <limits>
       9             : #include <pup.h>
      10             : #include <string>
      11             : #include <unordered_map>
      12             : 
      13             : #include "Domain/Structure/ElementId.hpp"
      14             : #include "Parallel/NodeLock.hpp"
      15             : #include "Parallel/Phase.hpp"
      16             : #include "Utilities/Gsl.hpp"
      17             : #include "Utilities/Serialization/CharmPupable.hpp"
      18             : 
      19             : namespace Parallel {
      20             : /*!
      21             :  * \brief The base class of a member of an DG element array/map on a nodegroup.
      22             :  *
      23             :  * The nodegroup DgElementCollection stores all the elements on a node. Each
      24             :  * of those elements is a `DgElementArrayMember` and has this base class to
      25             :  * make access easier so it can be used in a type-erased context since
      26             :  * `DgElementArrayMember` depends on the metavariables,
      27             :  * phase-dependent-action-list, and the simple tags needed from options.
      28             :  *
      29             :  * This class essentially mimicks a lot of the functionality of
      30             :  * `Parallel::DistributedObject` but does not involve Charm++ beyond
      31             :  * serialization.
      32             :  */
      33             : template <size_t Dim>
      34           1 : class DgElementArrayMemberBase : PUP::able {
      35             :  public:
      36           0 :   DgElementArrayMemberBase() = default;
      37             : 
      38           0 :   DgElementArrayMemberBase(const DgElementArrayMemberBase& /*rhs*/) = default;
      39           0 :   DgElementArrayMemberBase& operator=(const DgElementArrayMemberBase& /*rhs*/) =
      40             :       default;
      41           0 :   DgElementArrayMemberBase(DgElementArrayMemberBase&& /*rhs*/) = default;
      42           0 :   DgElementArrayMemberBase& operator=(DgElementArrayMemberBase&& /*rhs*/) =
      43             :       default;
      44           0 :   ~DgElementArrayMemberBase() override = default;
      45             : 
      46           0 :   WRAPPED_PUPable_abstract(DgElementArrayMemberBase);  // NOLINT
      47             : 
      48           0 :   explicit DgElementArrayMemberBase(CkMigrateMessage* msg);
      49             : 
      50             :   /// Start execution of the phase-dependent action list in `next_phase`. If
      51             :   /// `next_phase` has already been visited, execution will resume at the point
      52             :   /// where the previous execution of the same phase left off.
      53             :   ///
      54             :   /// If \p force is true, then regardless of how this component terminated
      55             :   /// (error or deadlock), it will resume.
      56             :   ///
      57             :   /// \warning Don't set \p force to true unless you are absolutely sure you
      58             :   /// want to. This can have very unintended consequences if used incorrectly.
      59           1 :   virtual void start_phase(Parallel::Phase next_phase, bool force = false) = 0;
      60             : 
      61             :   /// Get the current phase
      62           1 :   Parallel::Phase phase() const;
      63             : 
      64             :   /// Tell the Algorithm it should no longer execute the algorithm. This does
      65             :   /// not mean that the execution of the program is terminated, but only that
      66             :   /// the algorithm has terminated. An algorithm can be restarted by passing
      67             :   /// `true` as the second argument to the `receive_data` method or by calling
      68             :   /// perform_algorithm(true).
      69           1 :   void set_terminate(gsl::not_null<size_t*> number_of_elements_terminated,
      70             :                      gsl::not_null<Parallel::NodeLock*> nodegroup_lock,
      71             :                      bool terminate);
      72             : 
      73             :   /// Check if an algorithm should continue being evaluated
      74           1 :   bool get_terminate() const;
      75             : 
      76             :   /// The zero-indexed step in the algorithm.
      77           1 :   size_t algorithm_step() const;
      78             : 
      79             :   /// Start evaluating the algorithm until it is stopped by an action.
      80           1 :   virtual void perform_algorithm() = 0;
      81             : 
      82             :   /// Print the expanded type aliases
      83           1 :   virtual std::string print_types() const = 0;
      84             : 
      85             :   /// Print the current state of the algorithm
      86           1 :   std::string print_state() const;
      87             : 
      88             :   /// Print the current contents of the inboxes
      89           1 :   virtual std::string print_inbox() const = 0;
      90             : 
      91             :   /// Print the current contents of the DataBox
      92           1 :   virtual std::string print_databox() const = 0;
      93             : 
      94             :   /// \brief The `inbox_lock()` only locks the inbox, nothing else. The inbox is
      95             :   /// unsafe to access without this lock.
      96             :   ///
      97             :   /// Use `element_lock()` to lock the rest of the element.
      98             :   ///
      99             :   /// This should always be managed by `std::unique_lock` or `std::lock_guard`.
     100           1 :   Parallel::NodeLock& inbox_lock();
     101             : 
     102             :   /// \brief Locks the element, except for the inbox, which is guarded by the
     103             :   /// `inbox_lock()`.
     104             :   ///
     105             :   /// This should always be managed by `std::unique_lock` or `std::lock_guard`.
     106           1 :   Parallel::NodeLock& element_lock();
     107             : 
     108             :   /// \brief Set which core this element should pretend to be bound to.
     109           1 :   void set_core(size_t core);
     110             : 
     111             :   /// \brief Get which core this element should pretend to be bound to.
     112           1 :   size_t get_core() const;
     113             : 
     114             :   /// Returns the name of the last "next iterable action" to be run before a
     115             :   /// deadlock occurred.
     116           1 :   const std::string& deadlock_analysis_next_iterable_action() const {
     117             :     return deadlock_analysis_next_iterable_action_;
     118             :   }
     119             : 
     120           0 :   void pup(PUP::er& p) override;
     121             : 
     122             :  protected:
     123           0 :   DgElementArrayMemberBase(ElementId<Dim> element_id, size_t node_number);
     124             : 
     125           0 :   Parallel::NodeLock inbox_lock_{};
     126           0 :   Parallel::NodeLock element_lock_{};
     127           0 :   bool performing_action_ = false;
     128           0 :   Parallel::Phase phase_{Parallel::Phase::Initialization};
     129           0 :   std::unordered_map<Parallel::Phase, size_t> phase_bookmarks_{};
     130           0 :   std::size_t algorithm_step_ = 0;
     131             : 
     132           0 :   bool terminate_{true};
     133           0 :   bool halt_algorithm_until_next_phase_{false};
     134             : 
     135             :   // Records the name of the next action to be called so that during deadlock
     136             :   // analysis we can print this out.
     137           0 :   std::string deadlock_analysis_next_iterable_action_{};
     138           0 :   ElementId<Dim> element_id_;
     139           0 :   size_t my_node_{std::numeric_limits<size_t>::max()};
     140             :   // There is no associated core. However, we use this as a method of
     141             :   // interoperating with core-aware concepts like the interpolation
     142             :   // framework. Once that framework is core-agnostic we will remove my_core_.
     143           0 :   size_t my_core_{std::numeric_limits<size_t>::max()};
     144             : };
     145             : }  // namespace Parallel

Generated by: LCOV version 1.14