Documentation for OpenFLUID
2.2.2
Loading...
Searching...
No Matches
ThreadedLoopMacros.hpp
Go to the documentation of this file.
1
/*
2
3
This file is part of OpenFLUID software
4
Copyright(c) 2021-2026, INRAE
5
6
7
== GNU General Public License Usage ==
8
9
OpenFLUID is free software: you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation, either version 3 of the License, or
12
(at your option) any later version.
13
14
OpenFLUID is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
GNU General Public License for more details.
18
19
You should have received a copy of the GNU General Public License
20
along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21
22
23
== Other Usage ==
24
25
Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26
license, and requires a written agreement between You and INRA.
27
Licensees for Other Usage of OpenFLUID may use this file in accordance
28
with the terms contained in the written agreement between You and INRA.
29
30
*/
31
32
33
/**
34
@file ThreadedLoopMacros.hpp
35
36
@author Jean-Christophe FABRE <jean-christophe.fabre@inra.fr>
37
38
@cond OpenFLUID:completion
39
{
40
"contexts" : ["SIMULATOR", "OBSERVER"],
41
"menupath" : ["Fortran integration"],
42
"title" : "Include ThreadedLoopMacros header",
43
"text" : "#include <openfluid/ware/ThreadedLoopMacros.hpp>"
44
}
45
@endcond
46
*/
47
48
49
#ifndef __OPENFLUID_WARE_THREADEDLOOPMACROS_HPP__
50
#define __OPENFLUID_WARE_THREADEDLOOPMACROS_HPP__
51
52
53
#include <functional>
54
#include <thread>
55
#include <vector>
56
#include <system_error>
57
58
#include <
openfluid/ware/LoopMacros.hpp
>
59
60
61
// =====================================================================
62
// =====================================================================
63
64
65
#define _THREADGROUPID(_id) _M_##_id##_ThreadGroup
66
#define _THREADID(_id) _M_##_id##_Thread
67
68
69
// =====================================================================
70
// =====================================================================
71
72
73
#define _RUN_UNIT_GROUP_THREADED(id,iter,end,unitptr,funcptr,cond,...) \
74
std::vector<std::thread> _THREADGROUPID(id); \
75
while ((iter) != (end) && (cond)) \
76
{ \
77
try \
78
{ \
79
_THREADGROUPID(id).push_back(std::thread(std::bind(&funcptr,this,unitptr,## __VA_ARGS__))); \
80
if (_THREADGROUPID(id).size() == (unsigned int)OPENFLUID_GetSimulatorMaxThreads()) \
81
{ \
82
for (auto& _THREADID(id) : _THREADGROUPID(id)) \
83
_THREADID(id).join(); \
84
_THREADGROUPID(id).clear(); \
85
} \
86
} \
87
catch (std::system_error& E) \
88
{ \
89
throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION, \
90
"Error in threaded loop (" + std::string(E.what()) + ")"); \
91
} \
92
++(iter); \
93
} \
94
for (auto& _THREADID(id) : _THREADGROUPID(id)) \
95
_THREADID(id).join(); \
96
97
98
// =====================================================================
99
// =====================================================================
100
101
102
#define _APPLY_UNITS_ORDERED_LOOP_THREADED_WITHID(id,unitsclass,funcptr,...) \
103
openfluid::core::UnitsList_t* _UNITSLISTID(id) = mp_SpatialData->spatialUnits(unitsclass)->list(); \
104
if (_UNITSLISTID(id) != nullptr) \
105
{ \
106
openfluid::core::UnitsList_t::iterator _UNITSLISTITERID(id) = _UNITSLISTID(id)->begin(); \
107
while (_UNITSLISTITERID(id) != _UNITSLISTID(id)->end()) \
108
{ \
109
openfluid::core::PcsOrd_t _PCSORDID(id) = _UNITSLISTITERID(id)->getProcessOrder(); \
110
_RUN_UNIT_GROUP_THREADED(id,_UNITSLISTITERID(id),_UNITSLISTID(id)->end(), &(*_UNITSLISTITERID(id)), funcptr, \
111
_UNITSLISTITERID(id)->getProcessOrder() == _PCSORDID(id), ## __VA_ARGS__); \
112
} \
113
}
114
115
/**
116
Macro for applying a threaded simulator to each unit of a class, following their process order
117
@param[in] unitsclass name of the units class
118
@param[in] funcptr member simulator name
119
@param[in] ... extra parameters to pass to the member simulator
120
121
@cond OpenFLUID:completion
122
{
123
"contexts" : ["SIMULATOR", "OBSERVER"],
124
"menupath" : ["Loops"],
125
"title" : "Threaded ordered loop on spatial units of a class",
126
"text" : "APPLY_UNITS_ORDERED_LOOP_THREADED(\"%%SEL_START%%UnitsClass%%SEL_END%%\",FuncPtr)"
127
}
128
@endcond
129
*/
130
#define APPLY_UNITS_ORDERED_LOOP_THREADED(unitsclass,funcptr,...) \
131
_APPLY_UNITS_ORDERED_LOOP_THREADED_WITHID(__LINE__,unitsclass,funcptr,## __VA_ARGS__)
132
133
134
// =====================================================================
135
// =====================================================================
136
137
138
#define _APPLY_UNITS_UNORDERED_LOOP_THREADED_WITHID(id,unitsclass,funcptr,...) \
139
openfluid::core::UnitsList_t* _UNITSLISTID(id) = mp_SpatialData->spatialUnits(unitsclass)->list(); \
140
if (_UNITSLISTID(id) != nullptr) \
141
{ \
142
openfluid::core::UnitsList_t::iterator _UNITSLISTITERID(id) = _UNITSLISTID(id)->begin(); \
143
_RUN_UNIT_GROUP_THREADED(id,_UNITSLISTITERID(id),_UNITSLISTID(id)->end(),&(*_UNITSLISTITERID(id)),funcptr, \
144
true,## __VA_ARGS__); \
145
}
146
147
/**
148
Macro for applying a threaded simulator to each unit of a class, without considering process order
149
@param[in] unitsclass name of the units class
150
@param[in] funcptr member simulator name
151
@param[in] ... extra parameters to pass to the member simulator
152
153
@cond OpenFLUID:completion
154
{
155
"contexts" : ["SIMULATOR", "OBSERVER"],
156
"menupath" : ["Loops"],
157
"title" : "Threaded loop on spatial units of a class",
158
"text" : "APPLY_UNITS_LOOP_THREADED(\"%%SEL_START%%UnitsClass%%SEL_END%%\",FuncPtr)"
159
}
160
@endcond
161
*/
162
#define APPLY_UNITS_UNORDERED_LOOP_THREADED(unitsclass,funcptr,...) \
163
_APPLY_UNITS_UNORDERED_LOOP_THREADED_WITHID(__LINE__,unitsclass,funcptr,## __VA_ARGS__)
164
165
166
// =====================================================================
167
// =====================================================================
168
169
170
/* TODO May factorize UnitsPtrList_t to UnitsList_t ? */
171
#define _APPLY_ALLUNITS_ORDERED_LOOP_THREADED_WITHID(id,funcptr,...) \
172
openfluid::core::UnitsPtrList_t* _UNITSPTRLISTID(id) = mp_SpatialData->allSpatialUnits(); \
173
if (_UNITSPTRLISTID(id) != nullptr) \
174
{ \
175
openfluid::core::UnitsPtrList_t::iterator _UNITSPTRLISTITERID(id) = _UNITSPTRLISTID(id)->begin(); \
176
while (_UNITSPTRLISTITERID(id) != _UNITSPTRLISTID(id)->end()) \
177
{ \
178
openfluid::core::PcsOrd_t _PCSORDID(id) = (*_UNITSPTRLISTITERID(id))->getProcessOrder(); \
179
_RUN_UNIT_GROUP_THREADED(id,_UNITSPTRLISTITERID(id),_UNITSPTRLISTID(id)->end(),(*_UNITSPTRLISTITERID(id)), \
180
funcptr,(*_UNITSPTRLISTITERID(id))->getProcessOrder() == _PCSORDID(id), ## __VA_ARGS__); \
181
} \
182
}
183
184
/**
185
Macro for applying a threaded simulator to each unit of the domain, following their process order
186
@param[in] funcptr member simulator name
187
@param[in] ... extra parameters to pass to the member simulator
188
189
@cond OpenFLUID:completion
190
{
191
"contexts" : ["SIMULATOR", "OBSERVER"],
192
"menupath" : ["Loops"],
193
"title" : "Threaded ordered loop on all spatial units",
194
"text" : "APPLY_ALLUNITS_ORDERED_LOOP_THREADED(%%SEL_START%%FuncPtr%%SEL_END%%)"
195
}
196
@endcond
197
*/
198
#define APPLY_ALLUNITS_ORDERED_LOOP_THREADED(funcptr,...) \
199
_APPLY_ALLUNITS_ORDERED_LOOP_THREADED_WITHID(__LINE__,funcptr,## __VA_ARGS__)
200
201
202
// =====================================================================
203
// =====================================================================
204
205
206
#define _APPLY_ALLUNITS_UNORDERED_LOOP_THREADED_WITHID(id,funcptr,...) \
207
openfluid::core::UnitsPtrList_t* _UNITSPTRLISTID(id) = mp_SpatialData->allSpatialUnits(); \
208
if (_UNITSPTRLISTID(id) != nullptr) \
209
{ \
210
openfluid::core::UnitsPtrList_t::iterator _UNITSPTRLISTITERID(id) = _UNITSPTRLISTID(id)->begin(); \
211
_RUN_UNIT_GROUP_THREADED(id,_UNITSPTRLISTITERID(id),_UNITSPTRLISTID(id)->end(),(*_UNITSPTRLISTITERID(id)), \
212
funcptr,true,## __VA_ARGS__); \
213
}
214
215
/**
216
Macro for applying a threaded simulator to each unit of the domain, without considering process order
217
@param[in] funcptr member simulator name
218
@param[in] ... extra parameters to pass to the member simulator
219
220
@cond OpenFLUID:completion
221
{
222
"contexts" : ["SIMULATOR", "OBSERVER"],
223
"menupath" : ["Loops"],
224
"title" : "Threaded ordered loop on all spatial units",
225
"text" : "APPLY_ALLUNITS_LOOP_THREADED(%%SEL_START%%FuncPtr%%SEL_END%%)"
226
}
227
@endcond
228
*/
229
#define APPLY_ALLUNITS_UNORDERED_LOOP_THREADED(funcptr,...) \
230
_APPLY_ALLUNITS_UNORDERED_LOOP_THREADED_WITHID(__LINE__,funcptr,## __VA_ARGS__)
231
232
233
#endif
/* __OPENFLUID_WARE_THREADEDLOOPMACROS_HPP__ */
LoopMacros.hpp
ware
ThreadedLoopMacros.hpp
Generated by
1.9.8