KaMPIng 0.1.1
Flexible and (near) zero-overhead C++ bindings for MPI
Loading...
Searching...
No Matches
counter.hpp
Go to the documentation of this file.
1// This file is part of KaMPIng.
2//
3// Copyright 2023 The KaMPIng Authors
4//
5// KaMPIng is free software : you can redistribute it and/or modify it under the
6// terms of the GNU Lesser General Public License as published by the Free
7// Software Foundation, either version 3 of the License, or (at your option) any
8// later version. KaMPIng is distributed in the hope that it will be useful, but
9// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11// for more details.
12//
13// You should have received a copy of the GNU Lesser General Public License
14// along with KaMPIng. If not, see <https://www.gnu.org/licenses/>.
15
16/// @file
17/// This file contains a (distributed) counter class.
18
19#pragma once
20
21#include <kassert/kassert.hpp>
22#include <mpi.h>
23
24#include "kamping/collectives/barrier.hpp"
25#include "kamping/collectives/gather.hpp"
26#include "kamping/communicator.hpp"
30
31namespace kamping::measurements {
32
33/// @brief Distributed counter object.
34/// @tparam CommunicatorType Communicator in which the measurements are
35/// executed.
36template <typename CommunicatorType = Communicator<>>
37class Counter {
38public:
39 using DataType = std::int64_t; ///< Data type of the stored measurements.
40 /// @brief Constructs a timer using the \c MPI_COMM_WORLD communicator.
41 Counter() : _tree{}, _comm{comm_world()} {}
42
43 /// @brief Constructs a timer using a given communicator.
44 ///
45 /// @param comm Communicator in which the time measurements are executed.
46 Counter(CommunicatorType const& comm) : _tree{}, _comm{comm} {}
47
48 /// @brief Creates a measurement entry with name \param name and stores \param data therein. If such an entry
49 /// already exists with associated data entry `data_prev`, \c data will be added to it, i.e. `data_prev +
50 /// data`.
51 /// @param global_aggregation_modi Specify how the measurement entry is aggregated over all participationg PEs when
52 /// Counter::aggregate() is called.
53 void
54 add(std::string const& name,
55 DataType const& data,
56 std::vector<GlobalAggregationMode> const& global_aggregation_modi = std::vector<GlobalAggregationMode>{}) {
57 add_measurement(name, data, LocalAggregationMode::accumulate, global_aggregation_modi);
58 }
59
60 /// @brief Looks for a measurement entry with name \param name and appends \param data to the list of previously
61 /// stored data. If no such entry exists, a new measurement entry with \c data as first entry will be created. entry
62 /// `data_prev`, \c data will be added to it, i.e. `data_prev + data`.
63 /// @param global_aggregation_modi Specify how the measurement entry is aggregated over all participationg PEs when
64 /// Counter::aggregate() is called.
65 void append(
66 std::string const& name,
67 DataType const& data,
68 std::vector<GlobalAggregationMode> const& global_aggregation_modi = std::vector<GlobalAggregationMode>{}
69 ) {
70 add_measurement(name, data, LocalAggregationMode::append, global_aggregation_modi);
71 }
72
73 /// @brief Aggregate the measurement entries globally.
74 /// @return AggregatedTree object which encapsulates the aggregated data in a tree structure representing the
75 /// measurements.
76 auto aggregate() {
78 return aggregated_tree;
79 }
80
81 /// @brief Clears all stored measurements.
82 void clear() {
83 _tree.reset();
84 }
85
86 /// @brief Aggregates and outputs the the executed measurements. The output is
87 /// done via the print() method of a given Printer object.
88 ///
89 /// The print() method must accept an object of type AggregatedTreeNode and
90 /// receives the root of the evaluated timer tree as parameter. The print()
91 /// method is only called on the root rank of the communicator. See
92 /// EvaluationTreeNode for the accessible data. The
93 /// EvaluationTreeNode::children() member function can be used to navigate the
94 /// nested measurement structure.
95 ///
96 /// @tparam Printer Type of printer which is used to output the aggregated
97 /// timing data. Printer must possess a member print() which accepts a
98 /// EvaluationTreeNode as parameter.
99 /// @param printer Printer object used to output the aggregated timing data.
100 template <typename Printer>
102 auto const aggregated_tree = aggregate();
103 if (_comm.is_root()) {
104 printer.print(aggregated_tree.root());
105 }
106 }
107
108private:
110 _tree; ///< Tree structure in which the counted values are stored. Note that unlike for Timer, the tree is
111 ///< always a star as there is currently no functionality to allow for "nested" counting, e.g. by
112 ///< defining different phase within your algorithm.
113 CommunicatorType const& _comm; ///< Communicator in which the time measurements take place.
114
115 /// @brief Adds a new measurement to the tree
116 /// @param local_aggregation_mode Specifies how the measurement duration is
117 /// locally aggregated when there are multiple measurements at the same level
118 /// with identical key.
119 /// @param global_aggregation_modi Specifies how the measurement data is
120 /// aggregated over all participationg ranks when Timer::aggregate() is
121 /// called.
122 void add_measurement(
123 std::string const& name,
124 DataType const& data,
126 std::vector<GlobalAggregationMode> const& global_aggreation_modi
127 ) {
128 auto& child = _tree.current_node->find_or_insert(name);
129 child.aggregate_measurements_locally(data, local_aggregation_mode);
130 if (!global_aggreation_modi.empty()) {
131 child.measurements_aggregation_operations() = global_aggreation_modi;
132 }
133 }
134};
135
136/// @brief A basic Counter that uses kamping::Communicator<> as underlying
137/// communicator type.
139
140/// @brief Gets a reference to a kamping::measurements::BasicTimer.
141///
142/// @return A reference to a kamping::measurements::BasicCounter.
145 return counter;
146}
147} // namespace kamping::measurements
STL-compatible allocator for requesting memory using the builtin MPI allocator.
Definition allocator.hpp:32
Distributed counter object.
Definition counter.hpp:37
void aggregate_and_print(Printer &&printer)
Aggregates and outputs the the executed measurements. The output is done via the print() method of a ...
Definition counter.hpp:101
Counter()
Constructs a timer using the MPI_COMM_WORLD communicator.
Definition counter.hpp:41
void clear()
Clears all stored measurements.
Definition counter.hpp:82
void append(std::string const &name, DataType const &data, std::vector< GlobalAggregationMode > const &global_aggregation_modi=std::vector< GlobalAggregationMode >{})
Looks for a measurement entry with name.
Definition counter.hpp:65
void add(std::string const &name, DataType const &data, std::vector< GlobalAggregationMode > const &global_aggregation_modi=std::vector< GlobalAggregationMode >{})
Creates a measurement entry with name.
Definition counter.hpp:54
auto aggregate()
Aggregate the measurement entries globally.
Definition counter.hpp:76
Counter(CommunicatorType const &comm)
Constructs a timer using a given communicator.
Definition counter.hpp:46
std::int64_t DataType
Definition counter.hpp:39
Counter< Communicator<> > & counter()
Gets a reference to a kamping::measurements::BasicTimer.
Definition counter.hpp:143
Wrapper for MPI functions that don't require a communicator.
LocalAggregationMode
Enum to specify how time measurements with same key shall be aggregated locally.
Definition measurement_aggregation_definitions.hpp:31
Tree consisting of objects of type NodeType. The tree constitutes a hierarchy of measurements such th...
Definition measurement_utils.hpp:278
NodeType * current_node
Pointer to the currently active node of the tree.
Definition measurement_utils.hpp:289