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

STEllAR-GROUP / hpx / #862

10 Jan 2023 05:30PM UTC coverage: 86.582% (-0.05%) from 86.634%
#862

push

StellarBot
Merge #6130

6130: Remove the mutex lock in the critical path of get_partitioner. r=hkaiser a=JiakunYan

Remove the mutex lock in the critical path of hpx::resource::detail::get_partitioner.

The protected variable `partitioner_ref` is only set once during initialization.

Co-authored-by: Jiakun Yan <jiakunyan1998@gmail.com>

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

174767 of 201851 relevant lines covered (86.58%)

2069816.07 hits per line

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

98.89
/libs/core/iterator_support/include/hpx/iterator_support/zip_iterator.hpp
1
//  Copyright (c) 2007-2022 Hartmut Kaiser
2
//  Copyright (c) 2014 Agustin Berge
3
//
4
//  SPDX-License-Identifier: BSL-1.0
5
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
6
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7

8
#pragma once
9

10
#include <hpx/config.hpp>
11
#include <hpx/datastructures/tuple.hpp>
12
#include <hpx/functional/invoke_result.hpp>
13
#include <hpx/iterator_support/detail/minimum_category.hpp>
14
#include <hpx/iterator_support/iterator_facade.hpp>
15
#include <hpx/iterator_support/traits/is_iterator.hpp>
16
#include <hpx/serialization/serialization_fwd.hpp>
17
#include <hpx/type_support/pack.hpp>
18

19
#include <cstddef>
20
#include <iterator>
21
#include <type_traits>
22
#include <utility>
23

24
namespace hpx::util {
25

26
    namespace detail {
27

28
        ///////////////////////////////////////////////////////////////////////
29
        template <typename IteratorTuple>
30
        struct zip_iterator_value;
31

32
        template <typename... Ts>
33
        struct zip_iterator_value<hpx::tuple<Ts...>>
34
        {
35
            using type =
36
                hpx::tuple<typename std::iterator_traits<Ts>::value_type...>;
37
        };
38

39
        ///////////////////////////////////////////////////////////////////////
40
        template <typename IteratorTuple>
41
        struct zip_iterator_reference;
42

43
        template <typename... Ts>
44
        struct zip_iterator_reference<hpx::tuple<Ts...>>
45
        {
46
            using type =
47
                hpx::tuple<typename std::iterator_traits<Ts>::reference...>;
48
        };
49

50
        ///////////////////////////////////////////////////////////////////////
51
        template <typename IteratorTuple, typename Enable = void>
52
        struct zip_iterator_category;
53

54
        template <typename T>
55
        struct zip_iterator_category<hpx::tuple<T>,
56
            std::enable_if_t<hpx::tuple_size<hpx::tuple<T>>::value == 1>>
57
        {
58
            using type = typename std::iterator_traits<T>::iterator_category;
59
        };
60

61
        template <typename T, typename U>
62
        struct zip_iterator_category<hpx::tuple<T, U>,
63
            std::enable_if_t<hpx::tuple_size<hpx::tuple<T, U>>::value == 2>>
64
          : minimum_category<
65
                typename std::iterator_traits<T>::iterator_category,
66
                typename std::iterator_traits<U>::iterator_category>
67
        {
68
        };
69

70
        template <typename T, typename U, typename... Tail>
71
        struct zip_iterator_category<hpx::tuple<T, U, Tail...>,
72
            std::enable_if_t<(
73
                hpx::tuple_size<hpx::tuple<T, U, Tail...>>::value > 2)>>
74
          : minimum_category<
75
                typename minimum_category<
76
                    typename std::iterator_traits<T>::iterator_category,
77
                    typename std::iterator_traits<U>::iterator_category>::type,
78
                typename zip_iterator_category<hpx::tuple<Tail...>>::type>
79
        {
80
        };
81

82
        ///////////////////////////////////////////////////////////////////////
83
        template <typename IteratorTuple>
84
        struct dereference_iterator;
85

86
        template <typename... Ts>
87
        struct dereference_iterator<hpx::tuple<Ts...>>
88
        {
89
            template <std::size_t... Is>
90
            HPX_HOST_DEVICE static constexpr
91
                typename zip_iterator_reference<hpx::tuple<Ts...>>::type
92
                call(
446,389,481✔
93
                    util::index_pack<Is...>, hpx::tuple<Ts...> const& iterators)
94
            {
95
                return hpx::forward_as_tuple(*hpx::get<Is>(iterators)...);
446,369,605✔
96
            }
97
        };
98

99
        struct increment_iterator
100
        {
101
            template <typename T>
102
            HPX_HOST_DEVICE constexpr void operator()(T& iter) const
100,298,288✔
103
                noexcept(noexcept(++std::declval<T&>()))
104
            {
105
                ++iter;
100,455,690✔
106
            }
100,455,690✔
107
        };
108

109
        struct decrement_iterator
110
        {
111
            template <typename T>
112
            HPX_HOST_DEVICE constexpr void operator()(T& iter) const
8,306,570✔
113
                noexcept(noexcept(--std::declval<T&>()))
114
            {
115
                --iter;
8,306,570✔
116
            }
8,306,570✔
117
        };
118

119
        struct advance_iterator
120
        {
121
            explicit constexpr advance_iterator(std::ptrdiff_t n) noexcept
219,078,398✔
122
              : n_(n)
219,155,311✔
123
            {
124
            }
219,155,311✔
125

126
            template <typename T>
127
            HPX_HOST_DEVICE constexpr void operator()(T& iter) const noexcept(
442,015,298✔
128
                noexcept(std::declval<T&>() += std::declval<std::ptrdiff_t>()))
129
            {
130
                iter += n_;
442,077,509✔
131
            }
442,077,509✔
132

133
            std::ptrdiff_t n_;
134
        };
135

136
        ///////////////////////////////////////////////////////////////////////
137
        template <typename IteratorTuple, typename Derived>
138
        class zip_iterator_base
5,270,611✔
139
          : public hpx::util::iterator_facade<Derived,
140
                typename zip_iterator_value<IteratorTuple>::type,
141
                typename zip_iterator_category<IteratorTuple>::type,
142
                typename zip_iterator_reference<IteratorTuple>::type>
143
        {
144
            using base_type = hpx::util::iterator_facade<
145
                zip_iterator_base<IteratorTuple, Derived>,
146
                typename zip_iterator_value<IteratorTuple>::type,
147
                typename zip_iterator_category<IteratorTuple>::type,
148
                typename zip_iterator_reference<IteratorTuple>::type>;
149

150
        public:
151
            HPX_HOST_DEVICE constexpr zip_iterator_base() noexcept {}
8✔
152

153
            HPX_HOST_DEVICE explicit constexpr zip_iterator_base(
154
                IteratorTuple const& iterators)
155
              : iterators_(iterators)
156
            {
157
            }
158
            HPX_HOST_DEVICE explicit constexpr zip_iterator_base(
10,039✔
159
                IteratorTuple&& iterators) noexcept
160
              : iterators_(HPX_MOVE(iterators))
10,039✔
161
            {
10,039✔
162
            }
10,039✔
163

164
            HPX_HOST_DEVICE
165
            constexpr zip_iterator_base& operator=(
166
                IteratorTuple const& iterators)
167
            {
168
                iterators_ = iterators;
169
                return *this;
170
            }
171

172
            HPX_HOST_DEVICE
173
            constexpr zip_iterator_base& operator=(
174
                IteratorTuple&& iterators) noexcept
175
            {
176
                iterators_ = HPX_MOVE(iterators);
177
                return *this;
178
            }
179

180
            using iterator_tuple_type = IteratorTuple;
181

182
            HPX_HOST_DEVICE constexpr iterator_tuple_type const&
183
            get_iterator_tuple() const& noexcept
88,544,052✔
184
            {
185
                return iterators_;
88,545,864✔
186
            }
187

188
            HPX_HOST_DEVICE constexpr iterator_tuple_type&&
189
            get_iterator_tuple() && noexcept
190
            {
191
                return HPX_MOVE(iterators_);
192
            }
193

194
        private:
195
            friend class hpx::util::iterator_core_access;
196

197
            HPX_HOST_DEVICE constexpr bool equal(
4,892,744✔
198
                zip_iterator_base const& other) const
199
                noexcept(noexcept(std::declval<IteratorTuple>() ==
200
                    std::declval<IteratorTuple>()))
201
            {
202
                return iterators_ == other.iterators_;
4,892,744✔
203
            }
204

205
            HPX_HOST_DEVICE constexpr typename base_type::reference
206
            dereference() const
445,937,500✔
207
            {
208
                return dereference_iterator<IteratorTuple>::call(
445,777,913✔
209
                    util::make_index_pack_t<
210
                        hpx::tuple_size<IteratorTuple>::value>(),
211
                    iterators_);
445,777,913✔
212
            }
213

214
            HPX_HOST_DEVICE void increment()
46,616,680✔
215
            {
216
                this->apply(increment_iterator());
46,679,548✔
217
            }
46,679,548✔
218

219
            HPX_HOST_DEVICE void decrement()
4,153,285✔
220
            {
221
                this->apply(decrement_iterator());
4,153,285✔
222
            }
4,153,285✔
223

224
            HPX_HOST_DEVICE void advance(std::ptrdiff_t n)
219,535,850✔
225
            {
226
                this->apply(advance_iterator(n));
219,544,946✔
227
            }
219,544,946✔
228

229
            HPX_HOST_DEVICE
230
            std::ptrdiff_t distance_to(zip_iterator_base const& other) const
1,016,722✔
231
            {
232
                return hpx::get<0>(other.iterators_) - hpx::get<0>(iterators_);
1,016,722✔
233
            }
234

235
        private:
236
            template <typename F, std::size_t... Is>
237
            HPX_HOST_DEVICE void apply(F&& f, util::index_pack<Is...>)
270,660,549✔
238
            {
239
                (f(hpx::get<Is>(iterators_)), ...);
270,715,692✔
240
            }
270,715,692✔
241

242
            template <typename F>
243
            HPX_HOST_DEVICE void apply(F&& f)
270,274,073✔
244
            {
245
                return apply(HPX_FORWARD(F, f),
540,548,146✔
246
                    util::make_index_pack<
270,418,466✔
247
                        hpx::tuple_size<IteratorTuple>::value>());
248
            }
249

250
        private:
251
            friend class hpx::serialization::access;
252

253
            template <typename Archive>
254
            void serialize(Archive& ar, unsigned)
56✔
255
            {
256
                // clang-format off
257
                ar & iterators_;
56✔
258
                // clang-format on
259
            }
56✔
260

261
        private:
262
            IteratorTuple iterators_;
263
        };
264
    }    // namespace detail
265

266
    template <typename... Ts>
267
    class zip_iterator
87,178✔
268
      : public detail::zip_iterator_base<hpx::tuple<Ts...>, zip_iterator<Ts...>>
269
    {
270
        static_assert(
271
            sizeof...(Ts) != 0, "zip_iterator must wrap at least one iterator");
272

273
        using base_type =
274
            detail::zip_iterator_base<hpx::tuple<Ts...>, zip_iterator<Ts...>>;
275

276
    public:
277
        HPX_HOST_DEVICE constexpr zip_iterator() noexcept
8✔
278
          : base_type()
8✔
279
        {
8✔
280
        }
8✔
281

282
        HPX_HOST_DEVICE explicit constexpr zip_iterator(
9,475✔
283
            Ts const&... vs) noexcept
284
          : base_type(hpx::tie(vs...))
9,475✔
285
        {
9,475✔
286
        }
9,475✔
287

288
        HPX_HOST_DEVICE explicit constexpr zip_iterator(
156✔
289
            hpx::tuple<Ts...>&& t) noexcept
290
          : base_type(HPX_MOVE(t))
156✔
291
        {
156✔
292
        }
156✔
293

294
        HPX_HOST_DEVICE constexpr zip_iterator(
3,436,535✔
295
            zip_iterator const& other) = default;
6,873,070✔
296
        HPX_HOST_DEVICE constexpr zip_iterator(
24,727✔
297
            zip_iterator&& other) noexcept = default;
38,837✔
298

299
        HPX_HOST_DEVICE zip_iterator& operator=(
1,654,115✔
300
            zip_iterator const& other) = default;
1,654,115✔
301
        HPX_HOST_DEVICE zip_iterator& operator=(
100,731✔
302
            zip_iterator&& other) noexcept = default;
100,731✔
303

304
        template <typename... Ts_>
305
        HPX_HOST_DEVICE std::enable_if_t<
306
            std::is_assignable_v<typename zip_iterator::iterator_tuple_type&,
307
                typename zip_iterator<Ts_...>::iterator_tuple_type&&>,
308
            zip_iterator&>
309
        operator=(zip_iterator<Ts_...> const& other)
310
        {
311
            base_type::operator=(other.get_iterator_tuple());
312
            return *this;
313
        }
314

315
        template <typename... Ts_>
316
        HPX_HOST_DEVICE std::enable_if_t<
317
            std::is_assignable_v<typename zip_iterator::iterator_tuple_type&,
318
                typename zip_iterator<Ts_...>::iterator_tuple_type&&>,
319
            zip_iterator&>
320
        operator=(zip_iterator<Ts_...>&& other) noexcept
321
        {
322
            base_type::operator=(HPX_MOVE(other).get_iterator_tuple());
323
            return *this;
324
        }
325
    };
326

327
    template <typename... Ts>
328
    zip_iterator(Ts const&... vs) -> zip_iterator<Ts...>;
329

330
    template <typename... Ts>
331
    zip_iterator(hpx::tuple<Ts...>&& vs) -> zip_iterator<Ts...>;
332

333
    template <typename... Ts>
334
    HPX_DEPRECATED_V(1, 9,
335
        "hpx::util::make_zip_iterator is deprecated, use "
336
        "hpx::util::zip_iterator instead")
337
    HPX_HOST_DEVICE
338
        constexpr zip_iterator<std::decay_t<Ts>...> make_zip_iterator(
339
            Ts&&... vs)
340
    {
341
        using result_type = zip_iterator<std::decay_t<Ts>...>;
342
        return result_type(HPX_FORWARD(Ts, vs)...);
343
    }
344

345
    ///////////////////////////////////////////////////////////////////////////
346
    template <typename... Ts>
347
    class zip_iterator<hpx::tuple<Ts...>>
348
      : public detail::zip_iterator_base<hpx::tuple<Ts...>,
349
            zip_iterator<hpx::tuple<Ts...>>>
350
    {
351
        static_assert(
352
            sizeof...(Ts) != 0, "zip_iterator must wrap at least one iterator");
353

354
        using base_type = detail::zip_iterator_base<hpx::tuple<Ts...>,
355
            zip_iterator<hpx::tuple<Ts...>>>;
356

357
    public:
358
        HPX_HOST_DEVICE constexpr zip_iterator() noexcept
359
          : base_type()
360
        {
361
        }
362

363
        HPX_HOST_DEVICE explicit constexpr zip_iterator(
1✔
364
            Ts const&... vs) noexcept
365
          : base_type(hpx::tie(vs...))
1✔
366
        {
1✔
367
        }
1✔
368

369
        HPX_HOST_DEVICE explicit constexpr zip_iterator(
6✔
370
            hpx::tuple<Ts...>&& t) noexcept
371
          : base_type(HPX_MOVE(t))
6✔
372
        {
6✔
373
        }
6✔
374

375
        HPX_HOST_DEVICE constexpr zip_iterator(
376
            zip_iterator const& other) = default;
377
        HPX_HOST_DEVICE constexpr zip_iterator(
378
            zip_iterator&& other) noexcept = default;
379

380
        HPX_HOST_DEVICE zip_iterator& operator=(
1✔
381
            zip_iterator const& other) = default;
1✔
382
        HPX_HOST_DEVICE zip_iterator& operator=(
2✔
383
            zip_iterator&& other) noexcept = default;
2✔
384

385
        template <typename... Ts_>
386
        HPX_HOST_DEVICE std::enable_if_t<
387
            std::is_assignable_v<typename zip_iterator::iterator_tuple_type&,
388
                typename zip_iterator<Ts_...>::iterator_tuple_type&&>,
389
            zip_iterator&>
390
        operator=(zip_iterator<Ts_...> const& other)
1✔
391
        {
392
            base_type::operator=(base_type(other.get_iterator_tuple()));
1✔
393
            return *this;
1✔
394
        }
395

396
        template <typename... Ts_>
397
        HPX_HOST_DEVICE std::enable_if_t<
398
            std::is_assignable_v<typename zip_iterator::iterator_tuple_type&,
399
                typename zip_iterator<Ts_...>::iterator_tuple_type&&>,
400
            zip_iterator&>
401
        operator=(zip_iterator<Ts_...>&& other) noexcept
402
        {
403
            base_type::operator=(
404
                base_type(HPX_MOVE(other).get_iterator_tuple()));
405
            return *this;
406
        }
407
    };
408

409
    ///////////////////////////////////////////////////////////////////////////
410
    template <typename ZipIter>
411
    struct zip_iterator_category
412
      : detail::zip_iterator_category<typename ZipIter::iterator_tuple_type>
413
    {
414
    };
415
}    // namespace hpx::util
416

417
namespace hpx::traits {
418

419
    namespace functional {
420

421
        ///////////////////////////////////////////////////////////////////////
422
        template <typename F, typename T>
423
        struct element_result_of : util::invoke_result<F, T>
424
        {
425
        };
426

427
        template <typename F, typename Iter>
428
        struct lift_zipped_iterators;
429

430
        template <typename F, typename... Ts>
431
        struct lift_zipped_iterators<F, util::zip_iterator<Ts...>>
432
        {
433
            using tuple_type =
434
                typename util::zip_iterator<Ts...>::iterator_tuple_type;
435
            using result_type = hpx::tuple<typename element_result_of<
436
                typename F::template apply<Ts>, Ts>::type...>;
437

438
            template <std::size_t... Is, typename... Ts_>
439
            static result_type call(
152✔
440
                util::index_pack<Is...>, hpx::tuple<Ts_...> const& t)
441
            {
442
                return hpx::make_tuple(
152✔
443
                    typename F::template apply<Ts>()(hpx::get<Is>(t))...);
152✔
444
            }
×
445

446
            template <typename... Ts_>
447
            static result_type call(util::zip_iterator<Ts_...> const& iter)
152✔
448
            {
449
                using hpx::util::make_index_pack_t;
450
                return call(make_index_pack_t<sizeof...(Ts)>(),
152✔
451
                    iter.get_iterator_tuple());
152✔
452
            }
453
        };
454
    }    // namespace functional
455

456
    ///////////////////////////////////////////////////////////////////////////
457
    template <typename... Iter>
458
    struct is_zip_iterator<hpx::util::zip_iterator<Iter...>> : std::true_type
459
    {
460
    };
461
}    // namespace hpx::traits
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