Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <type_traits>
7 :
8 : #include "DataStructures/DataBox/DataBox.hpp"
9 : #include "Parallel/GlobalCache.hpp"
10 : #include "Parallel/Info.hpp"
11 : #include "Parallel/Invoke.hpp"
12 : #include "Parallel/Local.hpp"
13 : #include "Parallel/MemoryMonitor/MemoryMonitor.hpp"
14 : #include "Parallel/TypeTraits.hpp"
15 : #include "Utilities/Serialization/Serialize.hpp"
16 :
17 : namespace mem_monitor {
18 : /*!
19 : * \brief Simple action meant to be run on every branch of a Group or NodeGroup
20 : * that computes the size of the local branch and reports that size to the
21 : * MemoryMonitor using the ContributeMemoryData simple action.
22 : */
23 1 : struct ProcessGroups {
24 : template <typename ParallelComponent, typename DbTags, typename Metavariables,
25 : typename ArrayIndex>
26 0 : static void apply(db::DataBox<DbTags>& /*box*/,
27 : Parallel::GlobalCache<Metavariables>& cache,
28 : const ArrayIndex& array_index, const double time) {
29 : static_assert(Parallel::is_group_v<ParallelComponent> or
30 : Parallel::is_nodegroup_v<ParallelComponent>,
31 : "ProcessGroups can only be run on Group or Nodegroup "
32 : "parallel components.");
33 : static_assert(std::is_same_v<ArrayIndex, int>,
34 : "ArrayIndex of Group or Nodegroup parallel components must "
35 : "be an int to use the ProcessGroups action.");
36 :
37 : auto& singleton_proxy =
38 : Parallel::get_parallel_component<MemoryMonitor<Metavariables>>(cache);
39 :
40 : auto& group_proxy =
41 : Parallel::get_parallel_component<ParallelComponent>(cache);
42 :
43 : const double size_in_bytes = static_cast<double>(
44 : size_of_object_in_bytes(*Parallel::local_branch(group_proxy)));
45 :
46 : const double size_in_MB = size_in_bytes / 1.0e6;
47 :
48 : // Note that we don't call Parallel::contribute_to_reduction here. This is
49 : // because Charm requires that all calls to contribute_to_reduction happen
50 : // in the exact same order every time, otherwise it is undefined behavior.
51 : // However, this simple action (ProcessGroups) is called on each branch
52 : // of a group or nodegroup. Because this is a simple action, the order that
53 : // the branches run the simple actions is completely random based on
54 : // communication patterns in charm. Thus, calling contribute_to_reduction
55 : // here would result in undefined behavior.
56 : // Also note that `array_index` here is my_node for nodegroups and my_proc
57 : // for groups
58 : Parallel::simple_action<ContributeMemoryData<ParallelComponent>>(
59 : singleton_proxy, time, array_index, size_in_MB);
60 : }
61 : };
62 : } // namespace mem_monitor
|