SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Events - ObserveDataBox.hpp Hit Total Coverage
Commit: 1f2210958b4f38fdc0400907ee7c6d5af5111418 Lines: 2 20 10.0 %
Date: 2025-12-05 05:03:31
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 <map>
       7             : #include <pup.h>
       8             : #include <tuple>
       9             : #include <vector>
      10             : 
      11             : #include "DataStructures/DataBox/Access.hpp"
      12             : #include "DataStructures/DataBox/DataBox.hpp"
      13             : #include "Domain/Structure/ElementId.hpp"
      14             : #include "IO/Observer/ObserverComponent.hpp"
      15             : #include "IO/Observer/ReductionActions.hpp"
      16             : #include "Options/Auto.hpp"
      17             : #include "Options/String.hpp"
      18             : #include "Parallel/DistributedObject.hpp"
      19             : #include "Parallel/GlobalCache.hpp"
      20             : #include "Parallel/Invoke.hpp"
      21             : #include "Parallel/Reduction.hpp"
      22             : #include "ParallelAlgorithms/EventsAndTriggers/Event.hpp"
      23             : #include "Utilities/PrettyType.hpp"
      24             : #include "Utilities/TMPL.hpp"
      25             : 
      26             : namespace Events {
      27             : 
      28             : namespace detail {
      29             : 
      30             : struct map_add {
      31             :   std::map<std::string, size_t> operator()(
      32             :       std::map<std::string, size_t> map_1,
      33             :       const std::map<std::string, size_t>& map_2) {
      34             :     for (const auto& [key, value] : map_2) {
      35             :       map_1.at(key) += value;
      36             :     }
      37             :     return map_1;
      38             :   }
      39             : };
      40             : 
      41             : using ReductionType = Parallel::ReductionData<
      42             :     // Time
      43             :     Parallel::ReductionDatum<double, funcl::AssertEqual<>>,
      44             :     // Map of total mem usage in MB per item in DataBoxes
      45             :     Parallel::ReductionDatum<std::map<std::string, size_t>, map_add>>;
      46             : 
      47             : template <typename ContributingComponent>
      48             : struct ReduceDataBoxSize {
      49             :   template <typename ParallelComponent, typename DbTags, typename Metavariables,
      50             :             typename ArrayIndex>
      51             :   static void apply(db::DataBox<DbTags>& /*box*/,
      52             :                     Parallel::GlobalCache<Metavariables>& cache,
      53             :                     const ArrayIndex& /*array_index*/, const double time,
      54             :                     const std::map<std::string, size_t>& item_sizes) {
      55             :     auto& observer_writer_proxy = Parallel::get_parallel_component<
      56             :         observers::ObserverWriter<Metavariables>>(cache);
      57             :     const std::string subfile_name =
      58             :         "/DataBoxSizeInMb/" + pretty_type::name<ContributingComponent>();
      59             :     std::vector<std::string> legend;
      60             :     legend.reserve(item_sizes.size() + 1);
      61             :     legend.emplace_back("Time");
      62             :     std::vector<double> columns;
      63             :     columns.reserve(item_sizes.size() + 1);
      64             :     columns.emplace_back(time);
      65             :     const double scaling = 1.0 / 1048576.0;  // so size is in MB
      66             :     for (const auto& [name, size] : item_sizes) {
      67             :       legend.emplace_back(name);
      68             :       columns.emplace_back(scaling * static_cast<double>(size));
      69             :     }
      70             :     Parallel::threaded_action<
      71             :         observers::ThreadedActions::WriteReductionDataRow>(
      72             :         // Node 0 is always the writer
      73             :         observer_writer_proxy[0], subfile_name, legend,
      74             :         std::make_tuple(columns));
      75             :   }
      76             : };
      77             : 
      78             : struct ContributeDataBoxSize {
      79             :   template <typename ParallelComponent, typename DbTags, typename Metavariables,
      80             :             typename ArrayIndex>
      81             :   static void apply(db::DataBox<DbTags>& box,
      82             :                     Parallel::GlobalCache<Metavariables>& cache,
      83             :                     const ArrayIndex& array_index, const double time) {
      84             :     const auto& my_proxy =
      85             :         Parallel::get_parallel_component<ParallelComponent>(cache)[array_index];
      86             :     auto& target_proxy = Parallel::get_parallel_component<
      87             :         observers::ObserverWriter<Metavariables>>(cache);
      88             :     const auto item_sizes = box.size_of_items();
      89             :     if constexpr (Parallel::is_singleton_v<ParallelComponent>) {
      90             :       Parallel::simple_action<ReduceDataBoxSize<ParallelComponent>>(
      91             :           target_proxy[0], time, item_sizes);
      92             :     } else {
      93             :       Parallel::contribute_to_reduction<ReduceDataBoxSize<ParallelComponent>>(
      94             :           ReductionType{time, item_sizes}, my_proxy, target_proxy[0]);
      95             :     }
      96             :   }
      97             : };
      98             : }  // namespace detail
      99             : 
     100             : /// \brief Event that will collect the size in MBs used by each DataBox item on
     101             : /// each parallel component.
     102             : ///
     103             : /// \details The data will be written to disk in the reductions file under the
     104             : /// `/DataBoxSizeInMb/` group. The name of each file is the `pretty_type::name`
     105             : /// of each parallel component.  There will be a column for each item in the
     106             : /// DataBox that is not a subitem or reference item.
     107           1 : class ObserveDataBox : public Event {
     108           0 :   struct DoNotWrite {};
     109             : 
     110             :  public:
     111             :   /// \cond
     112             :   explicit ObserveDataBox(CkMigrateMessage* m);
     113             :   using PUP::able::register_constructor;
     114             :   WRAPPED_PUPable_decl_template(ObserveDataBox);  // NOLINT
     115             :   /// \endcond
     116             : 
     117           0 :   struct WriteTagNamesToFile {
     118           0 :     using type = ::Options::Auto<std::string, DoNotWrite>;
     119           0 :     static constexpr Options::String help = {
     120             :         "The text file to write the names of the DataBox tags to."};
     121             :   };
     122             : 
     123           0 :   using options = tmpl::list<WriteTagNamesToFile>;
     124           0 :   static constexpr Options::String help = {
     125             :       "Observe size (in MB) of each item (except reference items) in each "
     126             :       "DataBox"};
     127             : 
     128           0 :   ObserveDataBox() = default;
     129           0 :   explicit ObserveDataBox(std::optional<std::string> file_name_for_tag_names);
     130             : 
     131           0 :   using compute_tags_for_observation_box = tmpl::list<>;
     132             : 
     133           0 :   using return_tags = tmpl::list<>;
     134           0 :   using argument_tags = tmpl::list<::Tags::ObservationBox>;
     135             : 
     136             :   template <typename DataBoxType, size_t VolumeDim, typename ParallelComponent,
     137             :             typename Metavariables, typename ComputeTagsList>
     138           0 :   void operator()(const ObservationBox<DataBoxType, ComputeTagsList>& box,
     139             :                   Parallel::GlobalCache<Metavariables>& /*cache*/,
     140             :                   const ElementId<VolumeDim>& array_index,
     141             :                   const ParallelComponent* /*meta*/,
     142             :                   const ObservationValue& observation_value) const;
     143             : 
     144           0 :   using is_ready_argument_tags = tmpl::list<>;
     145             : 
     146             :   template <typename Metavariables, typename ArrayIndex, typename Component>
     147           0 :   bool is_ready(Parallel::GlobalCache<Metavariables>& /*cache*/,
     148             :                 const ArrayIndex& /*array_index*/,
     149             :                 const Component* const /*meta*/) const {
     150             :     return true;
     151             :   }
     152             : 
     153           1 :   bool needs_evolved_variables() const override { return false; }
     154             : 
     155             :   // NOLINTNEXTLINE(google-runtime-references)
     156           0 :   void pup(PUP::er& p) override;
     157             : 
     158             :  private:
     159             :   template <size_t VolumeDim>
     160           0 :   void impl(const db::Access& box_access,
     161             :             const ElementId<VolumeDim>& array_index,
     162             :             const ObservationValue& observation_value) const;
     163             : 
     164           0 :   std::optional<std::string> file_name_for_tag_names_;
     165             : };
     166             : 
     167             : template <typename DataBoxType, size_t VolumeDim, typename ParallelComponent,
     168             :           typename Metavariables, typename ComputeTagsList>
     169             : void ObserveDataBox::operator()(
     170             :     const ObservationBox<DataBoxType, ComputeTagsList>& box,
     171             :     Parallel::GlobalCache<Metavariables>& cache,
     172             :     const ElementId<VolumeDim>& array_index,
     173             :     const ParallelComponent* const /*meta*/,
     174             :     const ObservationValue& observation_value) const {
     175             :   if (is_zeroth_element(array_index)) {
     176             :     using component_list =
     177             :         tmpl::push_back<typename Metavariables::component_list>;
     178             :     tmpl::for_each<component_list>([&observation_value,
     179             :                                     &cache](auto component_v) {
     180             :       using component = tmpl::type_from<decltype(component_v)>;
     181             :       auto& target_proxy = Parallel::get_parallel_component<component>(cache);
     182             :       Parallel::simple_action<detail::ContributeDataBoxSize>(
     183             :           target_proxy, observation_value.value);
     184             :     });
     185             :   }
     186             :   impl(box.databox(), array_index, observation_value);
     187             : }
     188             : }  // namespace Events

Generated by: LCOV version 1.14