• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

STEllAR-GROUP / hpx / #882

31 Aug 2023 07:44PM UTC coverage: 41.798% (-44.7%) from 86.546%
#882

push

19442 of 46514 relevant lines covered (41.8%)

126375.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

6.35
/libs/full/performance_counters/src/server/arithmetics_counter.cpp
1
//  Copyright (c) 2007-2025 Hartmut Kaiser
2
//
3
//  SPDX-License-Identifier: BSL-1.0
4
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
5
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6

7
#include <hpx/config.hpp>
8
#include <hpx/async_distributed/continuation.hpp>
9
#include <hpx/components_base/agas_interface.hpp>
10
#include <hpx/modules/async_base.hpp>
11
#include <hpx/modules/errors.hpp>
12
#include <hpx/modules/runtime_local.hpp>
13
#include <hpx/modules/string_util.hpp>
14
#include <hpx/performance_counters/counter_creators.hpp>
15
#include <hpx/performance_counters/counters.hpp>
16
#include <hpx/performance_counters/performance_counter.hpp>
17
#include <hpx/performance_counters/server/arithmetics_counter.hpp>
18
#include <hpx/runtime_components/derived_component_factory.hpp>
19

20
#include <cstddef>
21
#include <cstdint>
22
#include <mutex>
23
#include <string>
24
#include <utility>
25
#include <vector>
26

27
#include <hpx/config/warnings_prefix.hpp>
28

29
///////////////////////////////////////////////////////////////////////////////
30
namespace hpx::performance_counters::server {
31

32
    ///////////////////////////////////////////////////////////////////////////
33
    namespace detail {
34

35
        template <typename Operation>
36
        struct init_value;
37

38
        template <>
39
        struct init_value<std::plus<double>>
40
        {
41
            static constexpr double call() noexcept
42
            {
43
                return 0.0;
44
            }
45
        };
46

47
        template <>
48
        struct init_value<std::minus<double>>
49
        {
50
            static constexpr double call() noexcept
51
            {
52
                return 0.0;
53
            }
54
        };
55

56
        template <>
57
        struct init_value<std::multiplies<double>>
58
        {
59
            static constexpr double call() noexcept
60
            {
61
                return 1.0;
62
            }
63
        };
64

65
        template <>
66
        struct init_value<std::divides<double>>
67
        {
68
            static constexpr double call() noexcept
69
            {
70
                return 1.0;
71
            }
72
        };
73
    }    // namespace detail
×
74

75
    ///////////////////////////////////////////////////////////////////////////
76
    template <typename Operation>
×
77
    arithmetics_counter<Operation>::arithmetics_counter() = default;
78

79
    template <typename Operation>
80
    arithmetics_counter<Operation>::arithmetics_counter(
×
81
        counter_info const& info,
82
        std::vector<std::string> const& base_counter_names)
×
83
      : base_type_holder(info)
84
      , counters_(base_counter_names)
×
85
    {
86
        if (info.type_ != counter_type::aggregating)
87
        {
88
            HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
89
                "arithmetics_counter<Operation>::arithmetics_counter",
90
                "unexpected counter type specified");
×
91
        }
92

×
93
        counter_path_elements paths;
94
        get_counter_path_elements(info.fullname_, paths);
×
95

96
        if (paths.countername_ == "divide")
×
97
        {
98
            if (counters_.size() < 2)
99
            {
100
                HPX_THROW_EXCEPTION(hpx::error::bad_parameter,
101
                    "arithmetics_counter<Operation>::arithmetics_counter",
102
                    "the parameter specification for an arithmetic counter "
103
                    "'/arithmetics/divide' has to expand to more than one "
104
                    "counter name: {}",
×
105
                    paths.parameters_);
106
            }
107
        }
108
    }
×
109

110
    template <typename Operation>
×
111
    hpx::performance_counters::counter_value
112
    arithmetics_counter<Operation>::get_counter_value(bool /* reset */)
113
    {
114
        std::vector<counter_value> base_values =
115
            counters_.get_counter_values(hpx::launch::sync);
×
116

117
        // apply arithmetic operation
×
118
        double value = detail::init_value<Operation>::call();
119
        for (counter_value const& base_value : base_values)
120
        {
×
121
            value = Operation()(value, base_value.get_value<double>());
×
122
        }
123

×
124
        if (base_values[0].scale_inverse_ &&
×
125
            static_cast<double>(base_values[0].scaling_) != 1.0)    //-V550
126
        {
127
            base_values[0].value_ = static_cast<std::int64_t>(
128
                value * static_cast<double>(base_values[0].scaling_));
×
129
        }
×
130
        else
131
        {
132
            base_values[0].value_ = static_cast<std::int64_t>(
×
133
                value / static_cast<double>(base_values[0].scaling_));
×
134
        }
×
135

136
        base_values[0].time_ =
×
137
            static_cast<std::int64_t>(hpx::get_system_uptime());
138
        base_values[0].count_ = counters_.get_invocation_count();
139

140
        return base_values[0];
×
141
    }
142

×
143
    template <typename Operation>
144
    bool arithmetics_counter<Operation>::start()
145
    {
146
        return counters_.start(hpx::launch::sync);
×
147
    }
148

×
149
    template <typename Operation>
150
    bool arithmetics_counter<Operation>::stop()
151
    {
152
        return counters_.stop(hpx::launch::sync);
×
153
    }
154

×
155
    template <typename Operation>
×
156
    void arithmetics_counter<Operation>::reset_counter_value()
157
    {
158
        counters_.reset(hpx::launch::sync);
×
159
    }
160

161
    template <typename Operation>
162
    void arithmetics_counter<Operation>::finalize()
×
163
    {
164
        base_performance_counter::finalize();
165
        base_type::finalize();
×
166
    }
167

168
    template <typename Operation>
169
    naming::address arithmetics_counter<Operation>::get_current_address() const
170
    {
×
171
        return naming::address(
172
            naming::get_gid_from_locality_id(agas::get_locality_id()),
173
            components::get_component_type<arithmetics_counter>(),
174
            const_cast<arithmetics_counter*>(this));
175
    }
176
}    // namespace hpx::performance_counters::server
177

178
///////////////////////////////////////////////////////////////////////////////
179
template class HPX_EXPORT
180
    hpx::performance_counters::server::arithmetics_counter<std::plus<double>>;
181
template class HPX_EXPORT
182
    hpx::performance_counters::server::arithmetics_counter<std::minus<double>>;
183
template class HPX_EXPORT hpx::performance_counters::server::
184
    arithmetics_counter<std::multiplies<double>>;
185
template class HPX_EXPORT hpx::performance_counters::server::
186
    arithmetics_counter<std::divides<double>>;
187

188
///////////////////////////////////////////////////////////////////////////////
189
// Addition
190
using adding_counter_type = hpx::components::component<
×
191
    hpx::performance_counters::server::arithmetics_counter<std::plus<double>>>;
192

32✔
193
HPX_REGISTER_DERIVED_COMPONENT_FACTORY(adding_counter_type, adding_counter,
194
    "base_performance_counter", hpx::components::factory_state::enabled)
195
HPX_DEFINE_GET_COMPONENT_TYPE(adding_counter_type::wrapped_type)
196

197
///////////////////////////////////////////////////////////////////////////////
198
// Subtraction
199
using subtracting_counter_type = hpx::components::component<
200
    hpx::performance_counters::server::arithmetics_counter<std::minus<double>>>;
×
201

202
HPX_REGISTER_DERIVED_COMPONENT_FACTORY(subtracting_counter_type,
203
    subtracting_counter, "base_performance_counter",
32✔
204
    hpx::components::factory_state::enabled)
205
HPX_DEFINE_GET_COMPONENT_TYPE(subtracting_counter_type::wrapped_type)
206

207
///////////////////////////////////////////////////////////////////////////////
208
// Multiply
209
using multiplying_counter_type =
210
    hpx::components::component<hpx::performance_counters::server::
211
            arithmetics_counter<std::multiplies<double>>>;
×
212

213
HPX_REGISTER_DERIVED_COMPONENT_FACTORY(multiplying_counter_type,
214
    multiplying_counter, "base_performance_counter",
32✔
215
    hpx::components::factory_state::enabled)
216
HPX_DEFINE_GET_COMPONENT_TYPE(multiplying_counter_type::wrapped_type)
217

218
///////////////////////////////////////////////////////////////////////////////
219
// Division
220
using dividing_counter_type =
221
    hpx::components::component<hpx::performance_counters::server::
222
            arithmetics_counter<std::divides<double>>>;
×
223

224
HPX_REGISTER_DERIVED_COMPONENT_FACTORY(dividing_counter_type, dividing_counter,
32✔
225
    "base_performance_counter", hpx::components::factory_state::enabled)
226
HPX_DEFINE_GET_COMPONENT_TYPE(dividing_counter_type::wrapped_type)
227

228
///////////////////////////////////////////////////////////////////////////////
229
namespace hpx::performance_counters::detail {
230

×
231
    /// Creation function for aggregating performance counters to be registered
232
    /// with the counter types.
233
    naming::gid_type arithmetics_counter_creator(
×
234
        counter_info const& info, error_code& ec)
235
    {
236
        if (info.type_ != counter_type::aggregating)
237
        {
238
            HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
239
                "arithmetics_counter_creator",
×
240
                "invalid counter type requested");
241

242
            return naming::invalid_gid;
×
243
        }
244

245
        counter_path_elements paths;
246
        get_counter_path_elements(info.fullname_, paths, ec);
×
247
        if (ec)
×
248
            return naming::invalid_gid;
×
249

250
        if (!paths.parameters_.empty())
×
251
        {
252
            // try to interpret the additional parameter as a list of
×
253
            // two performance counter names
254
            std::vector<std::string> names;
255
            hpx::string_util::split(
256
                names, paths.parameters_, hpx::string_util::is_any_of(","));
257

258
            if (names.empty())
259
            {
260
                HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
261
                    "arithmetics_counter_creator",
262
                    "the parameter specification for an arithmetic counter "
263
                    "has to expand to at least one counter name: {}",
264
                    paths.parameters_);
×
265
                return naming::invalid_gid;
266
            }
267

×
268
            for (std::string const& name : names)
269
            {
270
                if (counter_status::valid_data !=
271
                        get_counter_path_elements(name, paths, ec) ||
272
                    ec)
273
                {
274
                    HPX_THROWS_IF(ec, hpx::error::bad_parameter,
×
275
                        "arithmetics_counter_creator",
276
                        "the given (expanded) counter name is not "
×
277
                        "a validly formed performance counter name: {}",
×
278
                        name);
279
                    return naming::invalid_gid;
280
                }
×
281
            }
282

283
            return create_arithmetics_counter(info, names, ec);
284
        }
285

286
        HPX_THROWS_IF(ec, hpx::error::bad_parameter,
287
            "arithmetics_counter_creator",
×
288
            "the parameter specification for an arithmetic counter "
289
            "has to be a comma separated list of performance "
290
            "counter names, none is given: {}",
291
            remove_counter_prefix(info.fullname_));
×
292

293
        return naming::invalid_gid;
294
    }
×
295
}    // namespace hpx::performance_counters::detail
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc