createThreadIterators.hpp
Go to the documentation of this file.
1/*
2 Copyright 2025 Equinor ASA.
3
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef OPM_CREATETHREADITERATORS_HEADER_INCLUDED
21#define OPM_CREATETHREADITERATORS_HEADER_INCLUDED
22
23#include <algorithm>
24#include <cassert>
25#include <stdexcept>
26#include <string>
27#include <vector>
28
29namespace Opm
30{
31
47 template <class Range>
48 auto createChunkIterators(const Range& r,
49 const std::size_t num_elem,
50 const std::size_t num_chunks)
51 {
52 if (num_chunks < 1) {
53 throw std::logic_error("createChunkIterators() must create at least one chunk.");
54 }
55 std::vector<decltype(std::begin(r))> chunk_iterators;
56 auto it = std::begin(r);
57 const auto end = std::end(r);
58 if (num_chunks == 1) {
59 chunk_iterators.push_back(it);
60 chunk_iterators.push_back(end);
61 } else {
62 const auto chunk_size = std::max(num_elem / num_chunks, 1ul);
63 chunk_iterators.reserve(num_chunks + 1);
64 // Push evenly spaced iterators for the beginning of each chunk.
65 // We do this a number of times equal to the number of chunks.
66 for (std::size_t count = 0, num_pushed = 0; it != end; ++it, ++count) {
67 if (count % chunk_size == 0) {
68 chunk_iterators.push_back(it);
69 ++num_pushed;
70 if (num_pushed == num_chunks) {
71 // This break means that the last chunk may be bigger
72 // then the other ones.
73 break;
74 }
75 }
76 }
77 // Push sufficiently many end iterators to make the required number of chunks,
78 // there may be more than one (yielding empty chunks) if num_chunks > num_elem.
79 for (std::size_t extra = chunk_iterators.size(); extra < num_chunks + 1; ++extra) {
80 chunk_iterators.push_back(end);
81 }
82 assert(chunk_iterators.size() == num_chunks + 1);
83 }
84 return chunk_iterators;
85 }
86
87
105 template <class Range>
106 auto createThreadIterators(const Range& r,
107 const std::size_t num_elem,
108 const std::size_t num_threads,
109 const std::size_t max_chunk_size,
110 int& chunk_size)
111 {
112 if (num_threads < 1) {
113 throw std::logic_error("createThreadIterators() called with num_threads arguments = "
114 + std::to_string(num_threads));
115 }
116 std::vector<decltype(std::begin(r))> chunk_iterators;
117 auto it = std::begin(r);
118 const auto end = std::end(r);
119 if (num_threads == 1) {
120 chunk_iterators.push_back(it);
121 chunk_iterators.push_back(end);
122 } else {
123 chunk_size = static_cast<int>(std::clamp(num_elem / num_threads, 1ul, max_chunk_size));
124 chunk_iterators.reserve(num_elem / chunk_size + 2);
125 for (int count = 0; it != end; ++it, ++count) {
126 if (count % chunk_size == 0) {
127 chunk_iterators.push_back(it);
128 }
129 }
130 chunk_iterators.push_back(end);
131 }
132 return chunk_iterators;
133 }
134
135
138 template <class GridView>
139 auto createThreadIterators(const GridView& gv,
140 const std::size_t num_threads,
141 const std::size_t max_chunk_size,
142 int& chunk_size)
143 {
144 return createThreadIterators(elements(gv),
145 gv.size(0),
146 num_threads,
147 max_chunk_size,
148 chunk_size);
149 }
150
151} // namespace Opm
152
153#endif // OPM_CREATETHREADITERATORS_HEADER_INCLUDED
Holds the implementation of the CpGrid as a pimple.
Definition: CellQuadrature.hpp:26
auto createChunkIterators(const Range &r, const std::size_t num_elem, const std::size_t num_chunks)
Definition: createThreadIterators.hpp:48
auto createThreadIterators(const Range &r, const std::size_t num_elem, const std::size_t num_threads, const std::size_t max_chunk_size, int &chunk_size)
Definition: createThreadIterators.hpp:106