Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
Concurrency.h
Go to the documentation of this file.
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* Concurrency.h (C) 2000-2025 */
9/* */
10/* Classes managing concurrency (tasks, parallel loops, ...) */
11/*---------------------------------------------------------------------------*/
12#ifndef ARCANE_CORE_CONCURRENCY_H
13#define ARCANE_CORE_CONCURRENCY_H
14/*---------------------------------------------------------------------------*/
15/*---------------------------------------------------------------------------*/
16
18
19#include "arcane/core/Item.h"
20#include "arcane/core/ItemFunctor.h"
21#include "arcane/core/ItemGroup.h"
22
23#include "arcane/core/materials/MatItem.h"
24
25#include <algorithm>
26
27/*---------------------------------------------------------------------------*/
28/*---------------------------------------------------------------------------*/
29
30namespace Arcane::impl
31{
32inline Int32
33adaptGrainSize(const ForLoopRunInfo& run_info)
34{
35 const std::optional<ParallelLoopOptions>& options = run_info.options();
36 Int32 grain_size = AbstractItemRangeFunctor::DEFAULT_GRAIN_SIZE;
37 if (options.has_value())
38 if (options.value().hasGrainSize())
39 grain_size = options.value().grainSize();
40 return grain_size;
41}
42} // namespace Arcane::impl
43
44namespace Arcane
45{
46
47/*---------------------------------------------------------------------------*/
48/*---------------------------------------------------------------------------*/
49
50/*!
51 * \ingroup Concurrency
52 *
53 * \brief Applies the method \a function of the instance
54 * \a instance concurrently on the view \a items_view with the options \a options.
55 */
56template <typename InstanceType, typename ItemType> inline void
57arcaneParallelForeach(const ItemVectorView& items_view, const ForLoopRunInfo& run_info,
58 InstanceType* instance, void (InstanceType::*function)(ItemVectorViewT<ItemType> items))
59{
60 Int32 grain_size = impl::adaptGrainSize(run_info);
61 ItemRangeFunctorT<InstanceType, ItemType> ipf(items_view, instance, function, grain_size);
62
63 ForLoopRunInfo adapted_run_info(run_info);
64 ParallelLoopOptions loop_opt(run_info.options().value_or(TaskFactory::defaultParallelLoopOptions()));
65 loop_opt.setGrainSize(ipf.blockGrainSize());
66 adapted_run_info.addOptions(loop_opt);
67
68 ParallelFor1DLoopInfo loop_info(0, ipf.nbBlock(), &ipf, adapted_run_info);
70}
71
72/*---------------------------------------------------------------------------*/
73/*---------------------------------------------------------------------------*/
74
75/*!
76 * \brief Applies the lambda function \a lambda_function
77 * \a instance concurrently on the view \a items_view with the options \a options
78 * \ingroup Concurrency
79 */
80template <typename LambdaType> inline void
81arcaneParallelForeach(const ItemVectorView& items_view, const ForLoopRunInfo& run_info,
82 const LambdaType& lambda_function)
83{
84 Int32 grain_size = impl::adaptGrainSize(run_info);
85 LambdaItemRangeFunctorT<LambdaType> ipf(items_view, lambda_function, grain_size);
86
87 ForLoopRunInfo adapted_run_info(run_info);
88 ParallelLoopOptions loop_opt(run_info.options().value_or(TaskFactory::defaultParallelLoopOptions()));
89 loop_opt.setGrainSize(ipf.blockGrainSize());
90 adapted_run_info.addOptions(loop_opt);
91
92 ParallelFor1DLoopInfo loop_info(0, ipf.nbBlock(), &ipf, adapted_run_info);
94}
95
96/*---------------------------------------------------------------------------*/
97/*---------------------------------------------------------------------------*/
98
99/*!
100 * \ingroup Concurrency
101 *
102 * \brief Applies the method \a function of the instance
103 * \a instance concurrently on the view \a items_view with the options \a options.
104 */
105template <typename InstanceType, typename ItemType> inline void
107 InstanceType* instance, void (InstanceType::*function)(ItemVectorViewT<ItemType> items))
108{
109 arcaneParallelForeach(items_view, ForLoopRunInfo(options), instance, function);
110}
111
112/*!
113 * \ingroup Concurrency
114 *
115 * \brief Applies the method \a function of the instance
116 * \a instance concurrently on the group \a items with the options \a options.
117 */
118template <typename InstanceType, typename ItemType> inline void
119arcaneParallelForeach(const ItemGroup& items, const ForLoopRunInfo& run_info,
120 InstanceType* instance, void (InstanceType::*function)(ItemVectorViewT<ItemType> items))
121{
122 arcaneParallelForeach(items._paddedView(), run_info, instance, function);
123}
124
125/*!
126 * \ingroup Concurrency
127 * \brief Applies the method \a function of the instance
128 * \a instance concurrently on the view \a items_view.
129 */
130template <typename InstanceType, typename ItemType> inline void
132 InstanceType* instance, void (InstanceType::*function)(ItemVectorViewT<ItemType> items))
133{
134 arcaneParallelForeach(items_view, ForLoopRunInfo(), instance, function);
135}
136
137/*!
138 * \ingroup Concurrency
139 * \brief Applies the method \a function of the instance
140 * \a instance concurrently on the group \a items.
141 */
142template <typename InstanceType, typename ItemType> inline void
144 InstanceType* instance, void (InstanceType::*function)(ItemVectorViewT<ItemType> items))
145{
146 arcaneParallelForeach(items._paddedView(), ForLoopRunInfo(), instance, function);
147}
148
149/*!
150 * \brief Applies the lambda function \a lambda_function
151 * \a instance concurrently on the view \a items_view with the options \a options
152 * \ingroup Concurrency
153 */
154template <typename LambdaType> inline void
156 const LambdaType& lambda_function)
157{
158 arcaneParallelForeach(items_view, ForLoopRunInfo(options), lambda_function);
159}
160
161/*!
162 * \brief Applies the lambda function \a lambda_function
163 * concurrently on the group \a items with the options \a options
164 * \ingroup Concurrency
165 */
166template <typename LambdaType> inline void
168 const LambdaType& lambda_function)
169{
170 arcaneParallelForeach(items._paddedView(), ForLoopRunInfo(options), lambda_function);
171}
172
173/*!
174 * \ingroup Concurrency
175 * \brief Applies the lambda function \a lambda_function
176 * \a instance concurrently on the view \a items_view.
177 */
178template <typename LambdaType> inline void
179arcaneParallelForeach(const ItemVectorView& items_view, const LambdaType& lambda_function)
180{
181 arcaneParallelForeach(items_view, ForLoopRunInfo(), lambda_function);
182}
183
184/*!
185 * \ingroup Concurrency
186 * \brief Applies the lambda function \a lambda_function
187 * concurrently on the group \a items.
188 */
189template <typename LambdaType> inline void
190arcaneParallelForeach(const ItemGroup& items, const LambdaType& lambda_function)
191{
192 arcaneParallelForeach(items._paddedView(), lambda_function);
193}
194
195/*---------------------------------------------------------------------------*/
196/*---------------------------------------------------------------------------*/
197/*!
198 * \ingroup Concurrency
199 * \brief Applies the lambda function \a lambda_function
200 * concurrently over the iteration range [i0,i0+size].
201 */
202template <typename InstanceType> inline void
203arcaneParallelFor(Integer i0, Integer size, InstanceType* itype,
204 void (InstanceType::*lambda_function)(Integer i0, Integer size))
205{
206 RangeFunctorT<InstanceType> ipf(itype, lambda_function);
207 ParallelFor1DLoopInfo loop_info(i0, size, &ipf);
209}
210
211/*!
212 * \ingroup Concurrency
213 * \brief Applies the lambda function \a lambda_function
214 * concurrently over the iteration range [i0,i0+size] with the options \a options.
215 */
216template <typename LambdaType> inline void
218 const LambdaType& lambda_function)
219{
220 LambdaRangeFunctorT<LambdaType> ipf(lambda_function);
221 ParallelFor1DLoopInfo loop_info(i0, size, &ipf, options);
223}
224
225/*!
226 * \ingroup Concurrency
227 * \brief Applies the lambda function \a lambda_function
228 * concurrently over the iteration range [i0,i0+size] with the options \a options.
229 */
230template <typename LambdaType> inline void
232 const LambdaType& lambda_function)
233{
234 arcaneParallelFor(i0, size, ForLoopRunInfo(options), lambda_function);
235}
236
237/*!
238 * \brief Applies the lambda function \a lambda_function
239 * concurrently over the iteration range [i0,i0+size]
240 */
241template <typename LambdaType> inline void
242arcaneParallelFor(Integer i0, Integer size, const LambdaType& lambda_function)
243{
244 LambdaRangeFunctorT<LambdaType> ipf(lambda_function);
245 ParallelFor1DLoopInfo loop_info(i0, size, &ipf);
247}
248
249/*---------------------------------------------------------------------------*/
250/*---------------------------------------------------------------------------*/
251
252/*!
253 * \brief Applies the lambda function \a lambda_function
254 * \a instance concurrently on the container views \a views with the options \a options
255 * \ingroup Concurrency
256 */
257template <typename LambdaType, typename... Views> inline void
258arcaneParallelForVa(const ForLoopRunInfo& run_info, const LambdaType& lambda_function, Views... views)
259{
260 // Asserting every views have the size
261 typename std::tuple_element_t<0, std::tuple<Views...>>::size_type sizes[] = { views.size()... };
262 if (!std::all_of(std::begin(sizes), std::end(sizes), [&sizes](auto cur) { return cur == sizes[0]; }))
263 ARCANE_FATAL("Every views must have the same size");
264
265 LambdaRangeFunctorTVa<LambdaType, Views...> ipf(views..., lambda_function);
266
267 ParallelFor1DLoopInfo loop_info(0, sizes[0], &ipf, run_info);
269}
270
271/*---------------------------------------------------------------------------*/
272/*---------------------------------------------------------------------------*/
273
274/*!
275 * \brief Concurrency implementation.
276 * * The methods in this namespace are obsolete and must be replaced
277 * by equivalent methods in the Arcane namespace.
278 * For example, Arcane::Parallel::For() must be replaced by Arcane::arcaneParallelFor()
279 * and Arcane::Parallel::Foreach() by Arcane::arcaneParallelForeach().
280 */
281namespace Parallel
282{
283 /*!
284 * \deprecated Use Arcane::arcaneParallelForeach() instead.
285 */
286 template <typename InstanceType, typename ItemType>
287 [[deprecated("Year2021: Use Arcane::arcaneParallelForeach() instead")]] inline void
288 Foreach(const ItemVectorView& items_view, const ParallelLoopOptions& options,
289 InstanceType* instance, void (InstanceType::*function)(ItemVectorViewT<ItemType> items))
290 {
291 ItemRangeFunctorT<InstanceType, ItemType> ipf(items_view, instance, function, options.grainSize());
292 // Recopie \a options et utilise la valeur de 'grain_size' retournée par \a ifp
293 ParallelLoopOptions loop_opt(options);
294 loop_opt.setGrainSize(ipf.blockGrainSize());
295 TaskFactory::executeParallelFor(0, ipf.nbBlock(), loop_opt, &ipf);
296 }
297
298 /*!
299 * \deprecated Use Arcane::arcaneParallelForeach() instead.
300 */
301 template <typename InstanceType, typename ItemType>
302 [[deprecated("Year2021: Use Arcane::arcaneParallelForeach() instead")]] inline void
303 Foreach(const ItemGroup& items, const ParallelLoopOptions& options, InstanceType* instance,
304 void (InstanceType::*function)(ItemVectorViewT<ItemType> items))
305 {
306 Foreach(items._paddedView(), options, instance, function);
307 }
308
309 /*!
310 * \deprecated Use Arcane::arcaneParallelForeach() instead.
311 */
312 template <typename InstanceType, typename ItemType>
313 [[deprecated("Year2021: Use Arcane::arcaneParallelForeach() instead")]] inline void
314 Foreach(const ItemVectorView& items_view, InstanceType* instance, void (InstanceType::*function)(ItemVectorViewT<ItemType> items))
315 {
316 ItemRangeFunctorT<InstanceType, ItemType> ipf(items_view, instance, function);
318 }
319
320 /*!
321 * \deprecated Use Arcane::arcaneParallelForeach() instead.
322 */
323 template <typename InstanceType, typename ItemType>
324 [[deprecated("Year2021: Use Arcane::arcaneParallelForeach() instead")]] inline void
325 Foreach(const ItemGroup& items, InstanceType* instance, void (InstanceType::*function)(ItemVectorViewT<ItemType> items))
326 {
327 Foreach(items._paddedView(), instance, function);
328 }
329
330 /*!
331 * \deprecated Use Arcane::arcaneParallelForeach() instead.
332 */
333 template <typename LambdaType>
334 [[deprecated("Year2021: Use Arcane::arcaneParallelForeach() instead")]] inline void
335 Foreach(const ItemVectorView& items_view, const ParallelLoopOptions& options, const LambdaType& lambda_function)
336 {
337 LambdaItemRangeFunctorT<LambdaType> ipf(items_view, lambda_function, options.grainSize());
338 // Recopie \a options et utilise la valeur de 'grain_size' retournée par \a ifp
339 ParallelLoopOptions loop_opt(options);
340 loop_opt.setGrainSize(ipf.blockGrainSize());
341 TaskFactory::executeParallelFor(0, ipf.nbBlock(), loop_opt, &ipf);
342 }
343
344 /*!
345 * \deprecated Use Arcane::arcaneParallelForeach() instead.
346 */
347 template <typename LambdaType>
348 [[deprecated("Year2021: Use Arcane::arcaneParallelForeach() instead")]] inline void
349 Foreach(const ItemGroup& items, const ParallelLoopOptions& options, const LambdaType& lambda_function)
350 {
351 Foreach(items._paddedView(), options, lambda_function);
352 }
353
354 /*!
355 * \deprecated Use Arcane::arcaneParallelForeach() instead.
356 */
357 template <typename LambdaType>
358 [[deprecated("Year2021: Use Arcane::arcaneParallelForeach() instead")]] inline void
359 Foreach(const ItemVectorView& items_view, const LambdaType& lambda_function)
360 {
361 LambdaItemRangeFunctorT<LambdaType> ipf(items_view, lambda_function);
363 }
364
365 /*!
366 * \deprecated Use Arcane::arcaneParallelForeach() instead.
367 */
368 template <typename LambdaType>
369 [[deprecated("Year2021: Use Arcane::arcaneParallelForeach() instead")]] inline void
370 Foreach(const ItemGroup& items, const LambdaType& lambda_function)
371 {
372 Foreach(items._paddedView(), lambda_function);
373 }
374
375 /*!
376 * \deprecated Use the For overload with ParallelLoopOptions as an argument.
377 */
378 template <typename InstanceType> ARCANE_DEPRECATED_122 inline void
379 For(Integer i0, Integer size, Integer grain_size, InstanceType* itype,
380 void (InstanceType::*lambda_function)(Integer i0, Integer size))
381 {
382 RangeFunctorT<InstanceType> ipf(itype, lambda_function);
383 TaskFactory::executeParallelFor(i0, size, grain_size, &ipf);
384 }
385
386 /*!
387 * \deprecated Use Arcane::arcaneParallelFor() instead.
388 */
389 template <typename InstanceType>
390 [[deprecated("Year2021: Use Arcane::arcaneParallelFor() instead")]] inline void
391 For(Integer i0, Integer size, const ParallelLoopOptions& options, InstanceType* itype,
392 void (InstanceType::*lambda_function)(Integer i0, Integer size))
393 {
394 RangeFunctorT<InstanceType> ipf(itype, lambda_function);
395 TaskFactory::executeParallelFor(i0, size, options, &ipf);
396 }
397
398 /*!
399 * \deprecated Use the For overload with ParallelLoopOptions as an argument.
400 */
401 template <typename LambdaType> ARCANE_DEPRECATED_122 inline void
402 For(Integer i0, Integer size, Integer grain_size, const LambdaType& lambda_function)
403 {
404 LambdaRangeFunctorT<LambdaType> ipf(lambda_function);
405 TaskFactory::executeParallelFor(i0, size, grain_size, &ipf);
406 }
407
408 /*!
409 * \deprecated Use Arcane::arcaneParallelFor() instead.
410 */
411 template <typename InstanceType>
412 [[deprecated("Year2021: Use Arcane::arcaneParallelFor() instead")]] inline void
413 For(Integer i0, Integer size, InstanceType* itype,
414 void (InstanceType::*lambda_function)(Integer i0, Integer size))
415 {
416 RangeFunctorT<InstanceType> ipf(itype, lambda_function);
417 TaskFactory::executeParallelFor(i0, size, &ipf);
418 }
419
420 /*!
421 * \deprecated Use Arcane::arcaneParallelFor() instead.
422 */
423 template <typename LambdaType>
424 [[deprecated("Year2021: Use Arcane::arcaneParallelFor() instead")]] inline void
425 For(Integer i0, Integer size, const ParallelLoopOptions& options, const LambdaType& lambda_function)
426 {
427 LambdaRangeFunctorT<LambdaType> ipf(lambda_function);
428 TaskFactory::executeParallelFor(i0, size, options, &ipf);
429 }
430
431 /*!
432 * \deprecated Use Arcane::arcaneParallelFor() instead.
433 */
434 template <typename LambdaType>
435 [[deprecated("Year2021: Use Arcane::arcaneParallelFor() instead")]] inline void
436 For(Integer i0, Integer size, const LambdaType& lambda_function)
437 {
438 LambdaRangeFunctorT<LambdaType> ipf(lambda_function);
439 TaskFactory::executeParallelFor(i0, size, &ipf);
440 }
441
442} // End namespace Parallel
443
444/*---------------------------------------------------------------------------*/
445/*---------------------------------------------------------------------------*/
446
447} // End namespace Arcane
448
449/*---------------------------------------------------------------------------*/
450/*---------------------------------------------------------------------------*/
451
452#endif
#define ARCANE_FATAL(...)
Macro throwing a FatalErrorException.
Classes, Types, and macros for managing concurrency.
Int32 nbBlock() const
Number of blocks.
Definition ItemFunctor.h:53
Int32 blockGrainSize() const
Desired size of an iteration interval.
Definition ItemFunctor.h:56
Loop execution information.
Mesh entity group.
Definition ItemGroup.h:51
ItemVectorView _paddedView() const
View of the group entities with padding for vectorization.
Definition ItemGroup.cc:589
Functor for iterating over a list of entities.
Definition ItemFunctor.h:81
View on a typed array of entities.
View on a vector of entities.
Functor on an iteration interval instantiated via a lambda function.
Functor over an iteration interval instantiated via a lambda function.
Functor over an iteration interval instantiated via a lambda function.
Characteristics of a multi-thread 1D loop.
Definition ParallelFor.h:35
Execution options for a parallel loop in multi-threading.
Integer grainSize() const
Size of an iteration interval.
void setGrainSize(Integer v)
Sets the size (approximate) of an iteration interval.
Functor over an iteration interval.
static const ParallelLoopOptions & defaultParallelLoopOptions()
Default parallel loop execution options.
static void executeParallelFor(Integer begin, Integer size, const ParallelLoopOptions &options, IRangeFunctor *f)
Executes the functor f in parallel.
Definition TaskFactory.h:97
void arcaneParallelForeach(const ItemVectorView &items_view, const ForLoopRunInfo &run_info, InstanceType *instance, void(InstanceType::*function)(ItemVectorViewT< ItemType > items))
Applies the method function of the instance instance concurrently on the view items_view with the opt...
Definition Concurrency.h:57
void arcaneParallelForVa(const ForLoopRunInfo &run_info, const LambdaType &lambda_function, Views... views)
Applies the lambda function lambda_function instance concurrently on the container views views with t...
void arcaneParallelFor(Integer i0, Integer size, InstanceType *itype, void(InstanceType::*lambda_function)(Integer i0, Integer size))
Applies the lambda function lambda_function concurrently over the iteration range [i0,...
Concurrency implementation.
void Foreach(const ItemVectorView &items_view, const ParallelLoopOptions &options, InstanceType *instance, void(InstanceType::*function)(ItemVectorViewT< ItemType > items))
ARCANE_DEPRECATED_122 void For(Integer i0, Integer size, Integer grain_size, InstanceType *itype, void(InstanceType::*lambda_function)(Integer i0, Integer size))
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
std::int32_t Int32
Signed integer type of 32 bits.