SpECTRE Documentation Coverage Report
Current view: top level - Parallel/ArrayCollection - SetTerminateOnElement.hpp Hit Total Coverage
Commit: f679b1c7cc6e5bd6a5c72de114b5bff6a9facc98 Lines: 1 5 20.0 %
Date: 2024-05-20 02:45:36
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 <cstddef>
       7             : #include <mutex>
       8             : #include <stdexcept>
       9             : 
      10             : #include "DataStructures/DataBox/DataBox.hpp"
      11             : #include "Domain/Structure/ElementId.hpp"
      12             : #include "Parallel/ArrayCollection/Tags/NumberOfElementsTerminated.hpp"
      13             : #include "Parallel/GlobalCache.hpp"
      14             : #include "Parallel/Local.hpp"
      15             : #include "Parallel/NodeLock.hpp"
      16             : #include "Utilities/ErrorHandling/Assert.hpp"
      17             : #include "Utilities/ErrorHandling/Error.hpp"
      18             : #include "Utilities/Gsl.hpp"
      19             : 
      20             : namespace Parallel::Actions {
      21             : /// \brief Set the element with ID `my_element_id` to be terminated. This is
      22             : /// always invoked on the local component via
      23             : /// `Parallel::local_synchronous_action`
      24             : ///
      25             : /// In the future we can use this to try and elide Charm++ calls when the
      26             : /// receiver is local.
      27           1 : struct SetTerminateOnElement {
      28           0 :   using return_type = void;
      29             : 
      30             :   template <typename ParallelComponent, typename DbTagList,
      31             :             typename Metavariables, size_t Dim>
      32           0 :   static return_type apply(
      33             :       db::DataBox<DbTagList>& box, gsl::not_null<Parallel::NodeLock*> node_lock,
      34             :       gsl::not_null<Parallel::GlobalCache<Metavariables>*> cache,
      35             :       const ElementId<Dim>& my_element_id, bool terminate_value);
      36             : };
      37             : 
      38             : template <typename ParallelComponent, typename DbTagList,
      39             :           typename Metavariables, size_t Dim>
      40           0 : auto SetTerminateOnElement::apply(
      41             :     db::DataBox<DbTagList>& box,
      42             :     const gsl::not_null<Parallel::NodeLock*> node_lock,
      43             :     const gsl::not_null<Parallel::GlobalCache<Metavariables>*> cache,
      44             :     const ElementId<Dim>& my_element_id, const bool terminate_value)
      45             :     -> return_type {
      46             :   std::lock_guard node_guard(*node_lock);
      47             :   db::mutate<typename ParallelComponent::element_collection_tag,
      48             :              Parallel::Tags::NumberOfElementsTerminated>(
      49             :       [&cache, &my_element_id, &node_lock, terminate_value](
      50             :           const auto element_collection_ptr,
      51             :           const auto num_terminated_ptr) -> void {
      52             :         try {
      53             :           // Note: The nodelock is checked by set_terminate as a sanity
      54             :           // check and as a way of making set_terminate difficult to use
      55             :           // without this action.
      56             :           //
      57             :           // Note: since this is a local synchronous action running on the
      58             :           // element that called it, we already have the element locked and so
      59             :           // setting terminate is threadsafe.
      60             :           //
      61             :           // Note: the element's set_terminate updates num_terminated
      62             :           // correctly so we don't need to handle that here.
      63             :           element_collection_ptr->at(my_element_id)
      64             :               .set_terminate(num_terminated_ptr, node_lock, terminate_value);
      65             : 
      66             :           // Update the state of the nodegroup. Specifically, if _all_
      67             :           // elements are set to be terminated, we terminate the nodegroup,
      68             :           // otherwise we do not.
      69             :           auto* local_branch = Parallel::local_branch(
      70             :               Parallel::get_parallel_component<ParallelComponent>(*cache));
      71             :           ASSERT(local_branch != nullptr,
      72             :                  "The local branch is nullptr, which is inconsistent");
      73             :           local_branch->set_terminate(*num_terminated_ptr ==
      74             :                                       element_collection_ptr->size());
      75             :         } catch (const std::out_of_range&) {
      76             :           ERROR("Could not find element with ID " << my_element_id
      77             :                                                   << " on node");
      78             :         }
      79             :       },
      80             :       make_not_null(&box));
      81             : }
      82             : }  // namespace Parallel::Actions

Generated by: LCOV version 1.14