Manual for OpenFLUID 2.1.10
ware
ThreadedLoopMacros.hpp
Go to the documentation of this file.
1
/*
2
3
This file is part of OpenFLUID software
4
Copyright(c) 2007, INRA - Montpellier SupAgro
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" : ["Compute code", "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 _APPLY_UNITS_ORDERED_LOOP_THREADED_WITHID(id,unitsclass,funcptr,...) \
74
openfluid::core::UnitsList_t* _UNITSLISTID(id) = mp_SpatialData->spatialUnits(unitsclass)->list(); \
75
if (_UNITSLISTID(id) != nullptr) \
76
{ \
77
openfluid::core::UnitsList_t::iterator _UNITSLISTITERID(id) = _UNITSLISTID(id)->begin(); \
78
if (_UNITSLISTITERID(id) != _UNITSLISTID(id)->end()) \
79
{ \
80
openfluid::core::PcsOrd_t _PCSORDID(id) = _UNITSLISTITERID(id)->getProcessOrder(); \
81
while (_UNITSLISTITERID(id) != _UNITSLISTID(id)->end()) \
82
{ \
83
std::vector<std::thread> _THREADGROUPID(id); \
84
while (_UNITSLISTITERID(id) != _UNITSLISTID(id)->end() && \
85
_UNITSLISTITERID(id)->getProcessOrder() == _PCSORDID(id)) \
86
{ \
87
try \
88
{ \
89
_THREADGROUPID(id).push_back(std::thread(std::bind(&funcptr,this,\
90
&(*_UNITSLISTITERID(id)),## __VA_ARGS__))); \
91
if (_THREADGROUPID(id).size() == (unsigned int)OPENFLUID_GetSimulatorMaxThreads()) \
92
{ \
93
for (auto& _THREADID(id) : _THREADGROUPID(id)) \
94
_THREADID(id).join(); \
95
_THREADGROUPID(id).clear(); \
96
} \
97
} \
98
catch (std::system_error& E) \
99
{ \
100
throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION, \
101
"Error in threaded loop (" + std::string(E.what()) +")"); \
102
} \
103
++_UNITSLISTITERID(id); \
104
} \
105
for (auto& _THREADID(id) : _THREADGROUPID(id)) \
106
_THREADID(id).join(); \
107
_THREADGROUPID(id).clear(); \
108
if (_UNITSLISTITERID(id) != _UNITSLISTID(id)->end()) \
109
_PCSORDID(id) = _UNITSLISTITERID(id)->getProcessOrder(); \
110
} \
111
} \
112
}
113
114
/**
115
Macro for applying a threaded simulator to each unit of a class, following their process order
116
@param[in] unitsclass name of the units class
117
@param[in] funcptr member simulator name
118
@param[in] ... extra parameters to pass to the member simulator
119
120
@cond OpenFLUID:completion
121
{
122
"contexts" : ["SIMULATOR", "OBSERVER"],
123
"menupath" : ["Compute code", "Loops"],
124
"title" : "Threaded ordered loop on spatial units of a class",
125
"text" : "APPLY_UNITS_ORDERED_LOOP_THREADED(\"%%SEL_START%%UnitsClass%%SEL_END%%\",FuncPtr)"
126
}
127
@endcond
128
*/
129
#define APPLY_UNITS_ORDERED_LOOP_THREADED(unitsclass,funcptr,...) \
130
_APPLY_UNITS_ORDERED_LOOP_THREADED_WITHID(__LINE__,unitsclass,funcptr,## __VA_ARGS__)
131
132
133
// =====================================================================
134
// =====================================================================
135
136
137
#define _APPLY_ALLUNITS_ORDERED_LOOP_THREADED_WITHID(id,funcptr,...) \
138
openfluid::core::UnitsPtrList_t* _UNITSPTRLISTID(id) = mp_SpatialData->allSpatialUnits(); \
139
if (_UNITSPTRLISTID(id) != nullptr) \
140
{ \
141
openfluid::core::UnitsPtrList_t::iterator _UNITSPTRLISTITERID(id) = _UNITSPTRLISTID(id)->begin(); \
142
if (_UNITSPTRLISTITERID(id) != _UNITSPTRLISTID(id)->end()) \
143
{ \
144
openfluid::core::PcsOrd_t _PCSORDID(id) = (*_UNITSPTRLISTITERID(id))->getProcessOrder(); \
145
while (_UNITSPTRLISTITERID(id) != _UNITSPTRLISTID(id)->end()) \
146
{ \
147
std::vector<std::thread> _THREADGROUPID(id); \
148
while (_UNITSPTRLISTITERID(id) != _UNITSPTRLISTID(id)->end() && \
149
(*_UNITSPTRLISTITERID(id))->getProcessOrder() == _PCSORDID(id)) \
150
{ \
151
try \
152
{ \
153
_THREADGROUPID(id).push_back(std::thread(std::bind(&funcptr,this,\
154
(*_UNITSPTRLISTITERID(id)),## __VA_ARGS__))); \
155
if (_THREADGROUPID(id).size() == (unsigned int)OPENFLUID_GetSimulatorMaxThreads()) \
156
{ \
157
for (auto& _THREADID(id) : _THREADGROUPID(id)) \
158
_THREADID(id).join(); \
159
_THREADGROUPID(id).clear(); \
160
} \
161
}\
162
catch (std::system_error& E) \
163
{ \
164
throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION, \
165
"Error in threaded loop (" + std::string(E.what()) +")"); \
166
} \
167
++_UNITSPTRLISTITERID(id); \
168
} \
169
for (auto& _THREADID(id) : _THREADGROUPID(id)) \
170
_THREADID(id).join(); \
171
_THREADGROUPID(id).clear(); \
172
if (_UNITSPTRLISTITERID(id) != _UNITSPTRLISTID(id)->end())\
173
_PCSORDID(id) = (*_UNITSPTRLISTITERID(id))->getProcessOrder(); \
174
} \
175
} \
176
}
177
178
/**
179
Macro for applying a threaded simulator to each unit of the domain, following their process order
180
@param[in] funcptr member simulator name
181
@param[in] ... extra parameters to pass to the member simulator
182
183
@cond OpenFLUID:completion
184
{
185
"contexts" : ["SIMULATOR", "OBSERVER"],
186
"menupath" : ["Compute code", "Loops"],
187
"title" : "Threaded ordered loop on all spatial units",
188
"text" : "APPLY_ALLUNITS_ORDERED_LOOP_THREADED(%%SEL_START%%FuncPtr%%SEL_END%%)"
189
}
190
@endcond
191
*/
192
#define APPLY_ALLUNITS_ORDERED_LOOP_THREADED(funcptr,...) \
193
_APPLY_ALLUNITS_ORDERED_LOOP_THREADED_WITHID(__LINE__,funcptr,## __VA_ARGS__)
194
195
196
// =====================================================================
197
// =====================================================================
198
199
200
#endif
/* __OPENFLUID_WARE_THREADEDLOOPMACROS_HPP__ */
LoopMacros.hpp
Generated by
1.8.13