• 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

97.89
/libs/core/algorithms/tests/unit/container_algorithms/test_utils.hpp
1
//  Copyright (c) 2014-2015 Hartmut Kaiser
2
//  Copyright (c)      2018 Taeguk Kwon
3
//  Copyright (c)      2020 ETH Zurich
4
//
5
//  SPDX-License-Identifier: BSL-1.0
6
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
7
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8

9
#pragma once
10

11
#include <hpx/concepts/concepts.hpp>
12
#include <hpx/local/execution.hpp>
13
#include <hpx/local/runtime.hpp>
14
#include <hpx/modules/iterator_support.hpp>
15

16
#include <atomic>
17
#include <cstddef>
18
#include <iostream>
19
#include <numeric>
20
#include <random>
21
#include <utility>
22
#include <vector>
23

24
namespace test {
25
    ///////////////////////////////////////////////////////////////////////////
26
    // Sentinel constructed from an Iterator just for the purpose of the
27
    // overloads tests
28
    template <typename IterType,
29
        HPX_CONCEPT_REQUIRES_(hpx::traits::is_iterator<IterType>::value)>
30
    struct sentinel_from_iterator
31
    {
32
        explicit sentinel_from_iterator(IterType end_iter)
84✔
33
          : end(end_iter)
84✔
34
        {
35
        }
84✔
36

37
        IterType get()
467,529✔
38
        {
39
            return end;
467,529✔
40
        }
41

42
        friend bool operator==(IterType i, sentinel_from_iterator<IterType> s)
40,096✔
43
        {
44
            return i == s.get();
40,096✔
45
        }
46

47
        friend bool operator==(sentinel_from_iterator<IterType> s, IterType i)
48
        {
49
            return i == s.get();
50
        }
51

52
        friend bool operator!=(IterType i, sentinel_from_iterator<IterType> s)
427,433✔
53
        {
54
            return i != s.get();
427,433✔
55
        }
56

57
        friend bool operator!=(sentinel_from_iterator<IterType> s, IterType i)
58
        {
59
            return i != s.get();
60
        }
61

62
    private:
63
        IterType end;
64
    };
65

66
    ///////////////////////////////////////////////////////////////////////////
67
    template <typename BaseIterator, typename IteratorTag>
68
    struct test_iterator
69
      : hpx::util::iterator_adaptor<test_iterator<BaseIterator, IteratorTag>,
70
            BaseIterator, void, IteratorTag>
71
    {
72
    private:
73
        typedef hpx::util::iterator_adaptor<
74
            test_iterator<BaseIterator, IteratorTag>, BaseIterator, void,
75
            IteratorTag>
76
            base_type;
77

78
    public:
79
        test_iterator()
704✔
80
          : base_type()
704✔
81
        {
704✔
82
        }
704✔
83
        test_iterator(BaseIterator base)
4,627✔
84
          : base_type(base)
4,627✔
85
        {
4,627✔
86
        }
4,627✔
87
    };
88

89
    ///////////////////////////////////////////////////////////////////////////
90
    template <typename BaseContainer, typename IteratorTag>
91
    struct test_container : BaseContainer
334✔
92
    {
93
        template <typename... Ts>
94
        test_container(Ts&&... ts)
334✔
95
          : BaseContainer(std::forward<Ts>(ts)...)
334✔
96
        {
334✔
97
        }
334✔
98

99
        BaseContainer& base()
684✔
100
        {
101
            return *this;
684✔
102
        }
103
        BaseContainer const& base() const
104
        {
105
            return *this;
106
        }
107

108
        typedef test_iterator<typename BaseContainer::iterator, IteratorTag>
109
            iterator;
110
        typedef test_iterator<typename BaseContainer::const_iterator,
111
            IteratorTag>
112
            const_iterator;
113

114
        iterator begin()
648✔
115
        {
116
            return iterator(this->BaseContainer::begin());
648✔
117
        }
118
        const_iterator begin() const
119
        {
120
            return const_iterator(this->BaseContainer::begin());
121
        }
122
        const_iterator cbegin() const
123
        {
124
            return const_iterator(this->BaseContainer::cbegin());
125
        }
126

127
        iterator end()
760✔
128
        {
129
            return iterator(this->BaseContainer::end());
760✔
130
        }
131
        const_iterator end() const
132
        {
133
            return const_iterator(this->BaseContainer::end());
134
        }
135
        const_iterator cend() const
136
        {
137
            return const_iterator(this->BaseContainer::cend());
138
        }
139
    };
140

141
    ///////////////////////////////////////////////////////////////////////////
142
    template <typename BaseIterator, typename IteratorTag>
143
    struct decorated_iterator
880,744✔
144
      : hpx::util::iterator_adaptor<
145
            decorated_iterator<BaseIterator, IteratorTag>, BaseIterator, void,
146
            IteratorTag>
147
    {
148
    private:
149
        typedef hpx::util::iterator_adaptor<
150
            decorated_iterator<BaseIterator, IteratorTag>, BaseIterator, void,
151
            IteratorTag>
152
            base_type;
153

154
    public:
155
        decorated_iterator() {}
156

157
        decorated_iterator(BaseIterator base)
640✔
158
          : base_type(base)
640✔
159
        {
640✔
160
        }
640✔
161

162
        decorated_iterator(BaseIterator base, std::function<void()> f)
784✔
163
          : base_type(base)
784✔
164
          , m_callback(f)
784✔
165
        {
784✔
166
        }
784✔
167

168
    private:
169
        friend class hpx::util::iterator_core_access;
170

171
        typename base_type::reference dereference() const
335,684✔
172
        {
173
            if (m_callback)
335,282✔
174
                m_callback();
225,300✔
175
            return *(this->base());
350,148✔
176
        }
177

178
    private:
179
        std::function<void()> m_callback;
180
    };
181

182
    ///////////////////////////////////////////////////////////////////////////
183
    template <typename T>
184
    struct count_instances_v
185
    {
186
        count_instances_v()
360,252✔
187
        {
188
            ++instance_count;
360,252✔
189
            ++max_instance_count;
360,252✔
190
        }
360,252✔
191
        count_instances_v(T value)
192
          : value_(value)
193
        {
194
            ++instance_count;
195
            ++max_instance_count;
196
        }
197

198
        count_instances_v(count_instances_v const& rhs)
199
          : value_(rhs.value_)
200
        {
201
            ++instance_count;
202
        }
203
        count_instances_v(count_instances_v&& rhs)
204
          : value_(rhs.value_)
205
        {
206
            ++instance_count;
207
        }
208

209
        count_instances_v& operator=(count_instances_v const& rhs)
210
        {
211
            value_ = rhs.value_;
212
            return *this;
213
        }
214
        count_instances_v& operator=(count_instances_v&& rhs)
215
        {
216
            value_ = rhs.value_;
217
            return *this;
218
        }
219

220
        ~count_instances_v()
219,369✔
221
        {
222
            --instance_count;
219,376✔
223
        }
219,376✔
224

225
        T value_;
226
        static std::atomic<std::size_t> instance_count;
227
        static std::atomic<std::size_t> max_instance_count;
228
    };
229

230
    template <typename T>
231
    std::atomic<std::size_t> count_instances_v<T>::instance_count(0);
232

233
    template <typename T>
234
    std::atomic<std::size_t> count_instances_v<T>::max_instance_count(0);
235

236
    using count_instances = count_instances_v<std::size_t>;
237

238
    ///////////////////////////////////////////////////////////////////////////
239
    template <typename ExPolicy>
240
    struct test_num_exceptions_base
241
    {
242
        static void call(ExPolicy, hpx::exception_list const& e)
480✔
243
        {
244
            // The static partitioner uses four times the number of
245
            // threads/cores for the number chunks to create.
246
            HPX_TEST_LTE(e.size(), 4 * hpx::get_num_worker_threads());
480✔
247
        }
480✔
248
    };
249

250
    template <>
251
    struct test_num_exceptions_base<hpx::execution::sequenced_policy>
252
    {
253
        static void call(hpx::execution::sequenced_policy const&,
172✔
254
            hpx::exception_list const& e)
255
        {
256
            HPX_TEST_EQ(e.size(), 1u);
172✔
257
        }
172✔
258
    };
259

260
    template <typename ExPolicy, typename IteratorTag>
261
    struct test_num_exceptions : test_num_exceptions_base<ExPolicy>
262
    {
263
    };
264

265
    template <typename ExPolicy>
266
    struct test_num_exceptions<ExPolicy, std::input_iterator_tag>
267
    {
268
        static void call(ExPolicy, hpx::exception_list const& e)
269
        {
270
            HPX_TEST_EQ(e.size(), 1u);
271
        }
272
    };
273

274
    ///////////////////////////////////////////////////////////////////////////
275
    inline std::vector<std::size_t> iota(std::size_t size, std::size_t start)
276
    {
277
        std::vector<std::size_t> c(size);
278
        std::iota(std::begin(c), std::end(c), start);
279
        return c;
280
    }
281

282
    inline std::vector<std::size_t> random_iota(std::size_t size)
168✔
283
    {
284
        std::vector<std::size_t> c(size);
168✔
285
        std::iota(std::begin(c), std::end(c), 0);
168✔
286
        std::random_device rd;
168✔
287
        std::mt19937 g(rd());
168✔
288
        std::shuffle(std::begin(c), std::end(c), g);
168✔
289
        return c;
168✔
290
    }
168✔
291

292
    template <typename T>
293
    inline std::vector<T> random_iota(std::size_t size)
24✔
294
    {
295
        std::vector<T> c(size);
24✔
296
        std::iota(std::begin(c), std::end(c), 0);
24✔
297
        std::random_device rd;
24✔
298
        std::mt19937 g(rd());
24✔
299
        std::shuffle(std::begin(c), std::end(c), g);
24✔
300
        return c;
24✔
301
    }
24✔
302

303
    inline std::vector<std::size_t> random_fill(std::size_t size)
352✔
304
    {
305
        std::vector<std::size_t> c(size);
352✔
306
        std::generate(std::begin(c), std::end(c), std::rand);
352✔
307
        return c;
352✔
308
    }
352✔
309

310
    ///////////////////////////////////////////////////////////////////////////
311
    inline void make_ready(std::vector<hpx::promise<std::size_t>>& p,
312
        std::vector<std::size_t>& idx)
313
    {
314
        std::for_each(std::begin(idx), std::end(idx),
315
            [&p](std::size_t i) { p[i].set_value(i); });
316
    }
317

318
    inline std::vector<hpx::future<std::size_t>> fill_with_futures(
319
        std::vector<hpx::promise<std::size_t>>& p)
320
    {
321
        std::vector<hpx::future<std::size_t>> f;
322
        std::transform(std::begin(p), std::end(p), std::back_inserter(f),
323
            [](hpx::promise<std::size_t>& pr) { return pr.get_future(); });
324

325
        return f;
326
    }
327

328
    ///////////////////////////////////////////////////////////////////////////
329
    inline std::vector<std::size_t> fill_all_any_none(
378✔
330
        std::size_t size, std::size_t num_filled)
331
    {
332
        if (num_filled == 0)
378✔
333
            return std::vector<std::size_t>(size, 0);
126✔
334

335
        if (num_filled == size)
252✔
336
            return std::vector<std::size_t>(size, 1);
126✔
337

338
        std::vector<std::size_t> c(size, 0);
126✔
339
        for (std::size_t i = 0; i < num_filled; /**/)
2,672✔
340
        {
341
            std::size_t pos = std::rand() % c.size();    //-V104
2,546✔
342
            if (c[pos])
2,546✔
343
                continue;
×
344

345
            c[pos] = 1;
2,546✔
346
            ++i;
2,546✔
347
        }
348
        return c;
126✔
349
    }
378✔
350

351
    ///////////////////////////////////////////////////////////////////////////
352
    template <typename InputIter1, typename InputIter2>
353
    bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2,
146✔
354
        InputIter2 last2)
355
    {
356
        if (std::distance(first1, last1) != std::distance(first2, last2))
146✔
357
            return false;
×
358

359
        return std::equal(first1, last1, first2);
146✔
360
    }
146✔
361
}    // namespace test
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