• 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

85.39
/examples/quickstart/fibonacci_futures_distributed.cpp
1
//  Copyright (c) 2007-2013 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
#if !defined(HPX_COMPUTE_DEVICE_CODE)
9
#include <hpx/hpx_init.hpp>
10
#include <hpx/include/actions.hpp>
11
#include <hpx/include/lcos.hpp>
12
#include <hpx/include/runtime.hpp>
13
#include <hpx/include/util.hpp>
14

15
#include <atomic>
16
#include <cstddef>
17
#include <cstdint>
18
#include <iostream>
19
#include <string>
20
#include <vector>
21

22
///////////////////////////////////////////////////////////////////////////////
23
std::uint64_t threshold = 2;
24
std::uint64_t distribute_at = 2;
25
int num_repeats = 1;
26

27
///////////////////////////////////////////////////////////////////////////////
28
std::atomic<std::size_t> serial_execution_count(0);
29

30
std::size_t get_serial_execution_count()
×
31
{
32
    return serial_execution_count.load();
×
33
}
34
HPX_PLAIN_ACTION(get_serial_execution_count)
×
35

36
///////////////////////////////////////////////////////////////////////////////
37
std::atomic<std::size_t> next_locality(0);
38
std::vector<hpx::id_type> localities;
39
hpx::id_type here;
40

41
struct when_all_wrapper
42
{
43
    typedef hpx::tuple<hpx::future<std::uint64_t>, hpx::future<std::uint64_t>>
44
        data_type;
45

46
    std::uint64_t operator()(hpx::future<data_type> data) const
88✔
47
    {
48
        data_type v = data.get();
88✔
49
        return hpx::get<0>(v).get() + hpx::get<1>(v).get();
176✔
50
    }
51
};
52

53
///////////////////////////////////////////////////////////////////////////////
54
HPX_NOINLINE std::uint64_t fibonacci_serial_sub(std::uint64_t n)
89✔
55
{
56
    if (n < 2)
177✔
57
        return n;
58
    return fibonacci_serial_sub(n - 1) + fibonacci_serial_sub(n - 2);
88✔
59
}
60

61
std::uint64_t fibonacci_serial(std::uint64_t n)
×
62
{
63
    ++serial_execution_count;
64
    return fibonacci_serial_sub(n);
1✔
65
}
66

67
///////////////////////////////////////////////////////////////////////////////
68
hpx::id_type const& get_next_locality(std::uint64_t next)
×
69
{
70
    return localities[next % localities.size()];
55✔
71
}
72

73
///////////////////////////////////////////////////////////////////////////////
74
hpx::future<std::uint64_t> fibonacci_future(std::uint64_t n);
75
HPX_PLAIN_ACTION(fibonacci_future)
×
76

77
hpx::future<std::uint64_t> fibonacci_future(std::uint64_t n)
177✔
78
{
79
    // if we know the answer, we return a future encapsulating the final value
80
    if (n < 2)
177✔
81
        return hpx::make_ready_future(n);
82
    if (n < threshold)
88✔
83
        return hpx::make_ready_future(fibonacci_serial(n));
×
84

85
    fibonacci_future_action fib;
86
    hpx::id_type loc1 = here;
87
    hpx::id_type loc2 = here;
88

89
    if (n == distribute_at)
88✔
90
    {
91
        loc2 = get_next_locality(++next_locality);
92
    }
93
    else if (n - 1 == distribute_at)
54✔
94
    {
95
        std::uint64_t next = next_locality += 2;
96
        loc1 = get_next_locality(next - 1);
21✔
97
        loc2 = get_next_locality(next);
98
    }
99

100
    hpx::future<std::uint64_t> f = hpx::async(fib, loc1, n - 1);
88✔
101
    hpx::future<std::uint64_t> r = fib(loc2, n - 2);
176✔
102

103
    return hpx::when_all(f, r).then(when_all_wrapper());
88✔
104
}
105

106
///////////////////////////////////////////////////////////////////////////////
107
int hpx_main(hpx::program_options::variables_map& vm)
1✔
108
{
109
    // extract command line argument, i.e. fib(N)
110
    std::uint64_t n = vm["n-value"].as<std::uint64_t>();
2✔
111
    std::string test = vm["test"].as<std::string>();
1✔
112
    std::uint64_t max_runs = vm["n-runs"].as<std::uint64_t>();
2✔
113

114
    if (max_runs == 0)
1✔
115
    {
116
        std::cerr << "fibonacci_futures_distributed: wrong command "
117
                     "line argument value for "
118
                     "option 'n-runs', should not be zero"
119
                  << std::endl;
120
        return hpx::finalize();    // Handles HPX shutdown
121
    }
122

123
    bool executed_one = false;
124
    std::uint64_t r = 0;
1✔
125

126
    if (test == "all" || test == "0")
1✔
127
    {
128
        // Keep track of the time required to execute.
129
        std::uint64_t start = hpx::chrono::high_resolution_clock::now();
130

131
        // Synchronous execution, use as reference only.
132
        r = fibonacci_serial(n);
1✔
133

134
        std::uint64_t d = hpx::chrono::high_resolution_clock::now() - start;
1✔
135
        char const* fmt = "fibonacci_serial({1}) == {2},"
136
                          "elapsed time:,{3},[s]\n";
137
        hpx::util::format_to(std::cout, fmt, n, r, d);
1✔
138

139
        executed_one = true;
140
    }
141

142
    if (test == "all" || test == "1")
1✔
143
    {
144
        // Keep track of the time required to execute.
145
        std::uint64_t start = hpx::chrono::high_resolution_clock::now();
146

147
        for (std::size_t i = 0; i != max_runs; ++i)
2✔
148
        {
149
            // Create a Future for the whole calculation and wait for it.
150
            next_locality.store(0);
151
            r = fibonacci_future(n).get();
1✔
152
        }
153

154
        std::uint64_t d = hpx::chrono::high_resolution_clock::now() - start;
1✔
155
        char const* fmt =
156
            "fibonacci_future({1}) == {2},elapsed time:,{3},[s],{4}\n";
157
        hpx::util::format_to(
1✔
158
            std::cout, fmt, n, r, d / max_runs, next_locality.load());
1✔
159

160
        get_serial_execution_count_action serial_count;
161
        for (hpx::id_type const& loc : hpx::find_all_localities())
2✔
162
        {
163
            std::size_t count = serial_count(loc);
164
            hpx::util::format_to(
1✔
165
                std::cout, "  serial-count,{1},{2}\n", loc, count / max_runs);
1✔
166
        }
1✔
167

168
        executed_one = true;
169
    }
170

171
    if (!executed_one)
×
172
    {
173
        std::cerr
174
            << "fibonacci_futures_distributed: wrong command line argument "
175
               "value for option 'tests', should be either 'all' or a number "
176
               "between "
177
               "zero and 1, value specified: "
178
            << test << std::endl;
179
    }
180

181
    return hpx::finalize();    // Handles HPX shutdown
182
}
183

184
///////////////////////////////////////////////////////////////////////////////
185
hpx::program_options::options_description get_commandline_options()
2✔
186
{
187
    // Configure application-specific options
188
    hpx::program_options::options_description desc_commandline(
189
        "Usage: " HPX_APPLICATION_STRING " [options]");
2✔
190

191
    using hpx::program_options::value;
192
    desc_commandline.add_options()("n-value",
4✔
193
        value<std::uint64_t>()->default_value(10),
2✔
194
        "n value for the Fibonacci function")("n-runs",
2✔
195
        value<std::uint64_t>()->default_value(1), "number of runs to perform")(
4✔
196
        "threshold", value<unsigned int>()->default_value(2),
2✔
197
        "threshold for switching to serial code")("distribute-at",
2✔
198
        value<unsigned int>()->default_value(2),
2✔
199
        "threshold for distribution to other nodes")("test",
2✔
200
        value<std::string>()->default_value("all"),
2✔
201
        "select tests to execute (0-7, default: all)")("loc-repeat",
2✔
202
        value<int>()->default_value(1),
4✔
203
        "how often should a locality > 0 be used");
204
    return desc_commandline;
2✔
205
}
×
206

207
///////////////////////////////////////////////////////////////////////////////
208
void init_globals()
1✔
209
{
210
    // Retrieve command line using the Boost.ProgramOptions library.
211
    hpx::program_options::variables_map vm;
1✔
212
    if (!hpx::util::retrieve_commandline_arguments(
1✔
213
            get_commandline_options(), vm))
2✔
214
    {
215
        HPX_THROW_EXCEPTION(hpx::error::commandline_option_error,
×
216
            "fibonacci_futures_distributed",
217
            "failed to handle command line options");
218
        return;
219
    }
220

221
    std::uint64_t n = vm["n-value"].as<std::uint64_t>();
2✔
222

223
    threshold = vm["threshold"].as<unsigned int>();
2✔
224
    if (threshold < 2 || threshold > n)
1✔
225
    {
226
        HPX_THROW_EXCEPTION(hpx::error::commandline_option_error,
×
227
            "fibonacci_futures_distributed",
228
            "wrong command line argument value for option 'threshold', "
229
            "should be in between 2 and n-value, value specified: " +
230
                std::to_string(threshold));
231
        return;
232
    }
233

234
    distribute_at = vm["distribute-at"].as<unsigned int>();
2✔
235
    if (distribute_at < 2 || distribute_at > n)
1✔
236
    {
237
        HPX_THROW_EXCEPTION(hpx::error::commandline_option_error,
×
238
            "fibonacci_futures_distributed",
239
            "wrong command line argument value for option 'distribute-at', "
240
            "should be in between 2 and n-value, value specified: " +
241
                std::to_string(distribute_at));
242
        return;
243
    }
244

245
    here = hpx::find_here();
2✔
246
    next_locality.store(0);
247
    serial_execution_count.store(0);
248

249
    // try to more evenly distribute the work over the participating localities
250
    std::vector<hpx::id_type> locs = hpx::find_all_localities();
1✔
251
    std::size_t num_repeats = vm["loc-repeat"].as<int>();
2✔
252

253
    localities.push_back(here);    // add ourselves
1✔
254
    for (std::size_t j = 0; j != num_repeats; ++j)
2✔
255
    {
256
        for (std::size_t i = 0; i != locs.size(); ++i)
2✔
257
        {
258
            if (here == locs[i])
1✔
259
                continue;
1✔
260
            localities.push_back(locs[i]);
×
261
        }
262
    }
263
}
1✔
264

265
int main(int argc, char* argv[])
1✔
266
{
267
    // Initialize and run HPX
268
    hpx::register_startup_function(&init_globals);
1✔
269
    hpx::init_params init_args;
1✔
270
    hpx::program_options::options_description cmdline =
271
        get_commandline_options();
1✔
272
    init_args.desc_cmdline = cmdline;
1✔
273

274
    return hpx::init(argc, argv, init_args);
1✔
275
}
1✔
276
#endif
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

© 2025 Coveralls, Inc