SpECTRE Documentation Coverage Report
Current view: top level - Parallel/ArrayCollection - DgElementArrayMemberBase.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 41.0 % 39 16
Test Date: 2026-10-22 17:29:42
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 2.0-1