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

STEllAR-GROUP / hpx / #868

16 Jan 2023 08:21PM UTC coverage: 86.487%. Remained the same
#868

push

StellarBot
Merge #6137

6137: Adding example of a simple master/slave distributed application r=hkaiser a=hkaiser

The purpose of this example is to demonstrate how HPX actions can be used to build a simple master-slave application. The master (locality 0) assigns work to the slaves (all other localities). Note that if this application is run on one locality only it uses the same locality for the master and the slave functionalities.

The slaves receive a message that encodes how many sub-tasks of a certain type they should spawn locally.


Co-authored-by: Hartmut Kaiser <hartmut.kaiser@gmail.com>

72 of 72 new or added lines in 1 file covered. (100.0%)

174663 of 201952 relevant lines covered (86.49%)

1849169.69 hits per line

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

77.78
/examples/quickstart/simple_master_slave.cpp
1
//  Copyright (c) 2023 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
// The purpose of this example is to demonstrate how HPX actions can be used to
8
// build a simple master-slave application. The master (locality 0) assigns work
9
// to the slaves (all other localities). Note that if this application is run on
10
// one locality only it uses the same locality for the master and the slave
11
// functionalities.
12
//
13
// The slaves receive a message that encodes how many sub-tasks of a certain
14
// type they should spawn locally.
15

16
#include <hpx/hpx.hpp>
17
#include <hpx/hpx_init.hpp>
18

19
#include <iostream>
20
#include <random>
21
#include <vector>
22

23
// Below are the three different tasks a slave can execute
24
enum class task_type
25
{
26
    one = 1,
27
    two = 2,
28
    three = 3
29
};
30

31
// task_type::one
32
void work_item1(int sequence_number)
10✔
33
{
34
    std::cout << hpx::util::format("locality {}: work_item1: {}\n",
20✔
35
        hpx::get_locality_id(), sequence_number);
10✔
36
}
10✔
37

38
// task_type::two
39
void work_item2(int sequence_number)
×
40
{
41
    std::cout << hpx::util::format("locality {}: work_item2: {}\n",
×
42
        hpx::get_locality_id(), sequence_number);
×
43
}
×
44

45
// task_type::three
46
void work_item3(int sequence_number)
6✔
47
{
48
    std::cout << hpx::util::format("locality {}: work_item3: {}\n",
12✔
49
        hpx::get_locality_id(), sequence_number);
6✔
50
}
6✔
51

52
bool slave_operation(int count, task_type t)
2✔
53
{
54
    bool result = true;
2✔
55
    std::vector<hpx::future<void>> tasks;
2✔
56
    tasks.reserve(count);
2✔
57

58
    for (int i = 0; i != count; ++i)
18✔
59
    {
60
        switch (t)
16✔
61
        {
62
        case task_type::one:
63
            tasks.push_back(hpx::async(work_item1, i));
10✔
64
            break;
10✔
65

66
        case task_type::two:
67
            tasks.push_back(hpx::async(work_item2, i));
×
68
            break;
×
69

70
        case task_type::three:
71
            tasks.push_back(hpx::async(work_item3, i));
6✔
72
            break;
6✔
73

74
        default:
75
            std::cerr << hpx::util::format(
×
76
                "locality {}: unknown task type: {}\n", hpx::get_locality_id(),
×
77
                int(t));
×
78
            result = false;
×
79
            break;
×
80
        }
81
    }
16✔
82

83
    hpx::wait_all(std::move(tasks));
2✔
84
    return result;
2✔
85
}
2✔
86
HPX_PLAIN_ACTION(slave_operation)
3✔
87

88
int hpx_main(hpx::program_options::variables_map& vm)
1✔
89
{
90
    unsigned int seed = (unsigned int) std::random_device{}();
1✔
91
    if (vm.count("seed"))
1✔
92
        seed = vm["seed"].as<unsigned int>();
×
93

94
    std::cout << "using seed: " << seed << std::endl;
1✔
95
    std::mt19937 gen(seed);
1✔
96

97
    std::uniform_int_distribution<> repeat_dist(1, 3);
1✔
98
    std::uniform_int_distribution<> count_dist(1, 10);
1✔
99
    std::uniform_int_distribution<> type_dist(1, 3);
1✔
100

101
    // Submit work locally as well if there is just one locality
102
    std::vector<hpx::id_type> slave_localities = hpx::find_all_localities();
1✔
103
    if (slave_localities.size() > 1)
1✔
104
    {
105
        // submit work only remotely otherwise
106
        slave_localities = hpx::find_remote_localities();
×
107
    }
×
108

109
    // schedule random amount of slave tasks to each slave locality
110
    std::vector<hpx::future<bool>> slave_tasks;
1✔
111

112
    auto repeat = repeat_dist(gen);
1✔
113
    for (auto const& locality : slave_localities)
2✔
114
    {
115
        for (int i = 0; i != repeat; ++i)
3✔
116
        {
117
            auto count = count_dist(gen);
2✔
118
            auto type = static_cast<task_type>(type_dist(gen));
2✔
119

120
            slave_tasks.push_back(
2✔
121
                hpx::async(slave_operation_action(), locality, count, type));
2✔
122
        }
2✔
123
    }
124

125
    hpx::wait_all(slave_tasks);
1✔
126

127
    for (auto&& f : slave_tasks)
3✔
128
    {
129
        if (!f.get())
2✔
130
        {
131
            std::cerr << "One of the tasks failed!\n";
×
132
            break;
×
133
        }
134
    }
135

136
    return hpx::finalize();
1✔
137
}
1✔
138

139
int main(int argc, char* argv[])
1✔
140
{
141
    // define command line options
142
    hpx::program_options::options_description desc_commandline(
1✔
143
        "Usage: " HPX_APPLICATION_STRING " [options]");
1✔
144

145
    desc_commandline.add_options()("seed,s",
1✔
146
        hpx::program_options::value<unsigned int>(),
1✔
147
        "the random number generator seed to use for this run");
148

149
    // Initialize and run HPX
150
    hpx::init_params init_args;
1✔
151
    init_args.desc_cmdline = desc_commandline;
1✔
152

153
    return hpx::init(argc, argv, init_args);
1✔
154
}
1✔
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