SpECTRE Documentation Coverage Report
Current view: top level - ParallelAlgorithms/Events - ObserveDataBox.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 10.0 % 20 2
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 <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 2.0-1