opm-common
Toggle main menu visibility
Loading...
Searching...
No Matches
ThreadSafeMapBuilder.hpp
1
/*
2
This file is part of the Open Porous Media project (OPM).
3
4
Copyright 2025 SINTEF Digital
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
Consult the COPYING file in the top-level source directory of this
20
module for the precise wording of the license and the list of
21
copyright holders.
22
*/
23
#ifndef OPM_THREAD_SAFE_MAP_BUILDER_HPP
24
#define OPM_THREAD_SAFE_MAP_BUILDER_HPP
25
26
#include <algorithm>
27
#include <cassert>
28
#include <cstddef>
29
#include <list>
30
#include <map>
31
#include <numeric>
32
#include <vector>
33
34
#if _OPENMP
35
#include <omp.h>
36
#endif
37
38
namespace
Opm
{
39
53
55
enum class
MapBuilderInsertionMode
{
56
Emplace,
// Use first inserted value encountered
57
Insert_Or_Assign
// Use last inserted value encountered (last thread wins)
58
};
59
60
template
<
class
Map>
61
class
ThreadSafeMapBuilder
62
{
64
template
<
class
T>
65
struct
is_ordered
66
{
67
constexpr
static
bool
value =
false
;
68
};
69
70
template
<
class
Key,
class
T,
class
Compare,
class
Allocator>
71
struct
is_ordered<std::map<Key,T,Compare,Allocator>>
72
{
73
constexpr
static
bool
value =
true
;
74
};
75
76
public
:
77
using
Key =
typename
Map::key_type;
78
using
Value =
typename
Map::mapped_type;
79
81
ThreadSafeMapBuilder
(Map& map,
const
int
num_threads,
82
const
MapBuilderInsertionMode
mode)
83
: map_(map), num_threads_(num_threads), mode_(mode)
84
{
85
if
(num_threads_ > 1) {
86
thread_values_.resize(num_threads_);
87
}
88
}
89
91
~ThreadSafeMapBuilder
()
92
{
93
finalize
();
94
}
95
97
template
<
class
M>
98
void
insert_or_assign
(
const
Key& key, M&& value)
99
{
100
assert(mode_ == MapBuilderInsertionMode::Insert_Or_Assign);
101
#if _OPENMP
102
if
(num_threads_ > 1) {
103
thread_values_[omp_get_thread_num()].
104
emplace_back(key, std::forward<M>(value));
105
}
else
106
#endif
// _OPENMP
107
{
108
map_.insert_or_assign(key, std::forward<M>(value));
109
}
110
}
111
113
template
<
class
... Args>
114
void
emplace
(Args&&... args)
115
{
116
assert(mode_ == MapBuilderInsertionMode::Emplace);
117
#if _OPENMP
118
if
(num_threads_ > 1) {
119
thread_values_[omp_get_thread_num()].
120
emplace_back(std::forward<Args>(args)...);
121
}
else
122
#endif
// _OPENMP
123
{
124
map_.emplace(std::forward<Args>(args)...);
125
}
126
}
127
129
void
finalize
()
130
{
131
if
(num_threads_ > 1 && !thread_values_.empty()) {
132
if
constexpr
(!is_ordered<Map>::value) {
133
const
std::size_t size =
134
std::accumulate(thread_values_.begin(),
135
thread_values_.end(), std::size_t(0),
136
[](std::size_t s,
const
auto
& v) { return s + v.size(); });
137
map_.reserve(size);
138
}
139
for
(
int
i = 0; i < num_threads_; ++i) {
140
for
(
const
auto
& it : thread_values_[i]) {
141
if
(mode_== MapBuilderInsertionMode::Insert_Or_Assign) {
142
map_.insert_or_assign(std::move(it.first), std::move(it.second));
143
}
else
{
144
map_.emplace(std::move(it.first), std::move(it.second));
145
}
146
}
147
}
148
}
149
thread_values_.clear();
150
}
151
152
private
:
153
std::vector<std::list<std::pair<Key,Value>>> thread_values_;
154
Map& map_;
155
int
num_threads_;
156
MapBuilderInsertionMode
mode_;
157
};
158
159
}
160
161
#endif
// OPM_THREAD_SAFE_MAP_BUILDER_HPP
Opm::ThreadSafeMapBuilder::~ThreadSafeMapBuilder
~ThreadSafeMapBuilder()
The destructor (optionally) assembles the final map.
Definition
ThreadSafeMapBuilder.hpp:91
Opm::ThreadSafeMapBuilder::insert_or_assign
void insert_or_assign(const Key &key, M &&value)
Insert a value into the map.
Definition
ThreadSafeMapBuilder.hpp:98
Opm::ThreadSafeMapBuilder::ThreadSafeMapBuilder
ThreadSafeMapBuilder(Map &map, const int num_threads, const MapBuilderInsertionMode mode)
Constructor for a given map and number of threads.
Definition
ThreadSafeMapBuilder.hpp:81
Opm::ThreadSafeMapBuilder::emplace
void emplace(Args &&... args)
Insert a value into the map.
Definition
ThreadSafeMapBuilder.hpp:114
Opm::ThreadSafeMapBuilder::finalize
void finalize()
Assembles the final map.
Definition
ThreadSafeMapBuilder.hpp:129
Opm
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition
Exceptions.hpp:30
Opm::MapBuilderInsertionMode
MapBuilderInsertionMode
Utility class for adding multi-threading to loops that are building maps.
Definition
ThreadSafeMapBuilder.hpp:55
opm
common
utility
ThreadSafeMapBuilder.hpp
Generated by
1.17.0