12#ifndef ARCANE_UTILS_CONCURRENCYUTILS_H
13#define ARCANE_UTILS_CONCURRENCYUTILS_H
18#include "arcane/utils/RangeFunctor.h"
19#include "arcane/utils/FatalErrorException.h"
20#include "arcane/utils/ForLoopTraceInfo.h"
21#include "arcane/utils/ParallelLoopOptions.h"
34class TaskFactoryInternal;
55class ARCANE_UTILS_EXPORT ForLoopRunInfo
59 using ThatClass = ForLoopRunInfo;
63 ForLoopRunInfo() =
default;
65 : m_options(options) {}
67 : m_options(options), m_trace_info(trace_info) {}
69 : m_trace_info(trace_info) {}
73 std::optional<ParallelLoopOptions> options()
const {
return m_options; }
76 ThatClass& addTraceInfo(
const ForLoopTraceInfo& v) { m_trace_info = v;
return (*
this); }
90 std::optional<ParallelLoopOptions> m_options;
101class ARCANE_UTILS_EXPORT TaskContext
104 explicit TaskContext(
ITask* atask) : m_task(atask) {}
119class ARCANE_UTILS_EXPORT ITaskFunctor
122 virtual ~ITaskFunctor() =
default;
124 ITaskFunctor(
const ITaskFunctor&) =
default;
125 ITaskFunctor() =
default;
129 virtual ITaskFunctor* clone(
void* buffer,
Integer size) =0;
139template<
typename InstanceType>
144 typedef void (InstanceType::*FunctorType)();
146 TaskFunctor(InstanceType* instance,FunctorType func)
147 : m_instance(instance), m_function(func)
150 TaskFunctor(
const TaskFunctor& rhs) =
default;
151 TaskFunctor& operator=(
const TaskFunctor& rhs) =
delete;
156 (m_instance->*m_function)();
160 if (
sizeof(*
this)>(
size_t)size)
161 ARCANE_FATAL(
"INTERNAL: task functor buffer is too small");
165 InstanceType* m_instance;
166 FunctorType m_function;
176template<
typename InstanceType>
177class TaskFunctorWithContext
181 typedef void (InstanceType::*FunctorType)(
const TaskContext& tc);
183 TaskFunctorWithContext(InstanceType* instance,FunctorType func)
184 : ITaskFunctor(), m_instance(instance), m_function(func)
191 (m_instance->*m_function)(tc);
195 if (
sizeof(*
this)>(
size_t)size)
196 ARCANE_FATAL(
"INTERNAL: task functor buffer is too small");
200 InstanceType* m_instance;
201 FunctorType m_function;
214 friend class TaskFactory;
263 virtual void initialize(
Int32 nb_thread) =0;
269 virtual void terminate() =0;
328class ARCANE_UTILS_EXPORT TaskFactory
330 friend TaskFactoryInternal;
334 TaskFactory() =
delete;
343 template<
typename InstanceType>
static ITask*
347 return m_impl->createRootTask(&functor);
355 template<
typename InstanceType>
static ITask*
356 createTask(InstanceType* instance,
void (InstanceType::*function)())
359 return m_impl->createRootTask(&functor);
368 template<
typename InstanceType>
static ITask*
373 return parent_task->_createChildTask(&functor);
382 template<
typename InstanceType>
static ITask*
387 return parent_task->_createChildTask(&functor);
393 m_impl->executeParallelFor(begin,size,options,f);
399 m_impl->executeParallelFor(begin,size,block_size,f);
405 m_impl->executeParallelFor(begin,size,f);
411 m_impl->executeParallelFor(loop_info);
419 m_impl->executeParallelFor(loop_ranges,
ForLoopRunInfo(options),functor);
427 m_impl->executeParallelFor(loop_ranges,run_info,functor);
435 m_impl->executeParallelFor(loop_ranges,
ForLoopRunInfo(options),functor);
443 m_impl->executeParallelFor(loop_ranges,run_info,functor);
451 m_impl->executeParallelFor(loop_ranges,
ForLoopRunInfo(options),functor);
459 m_impl->executeParallelFor(loop_ranges,run_info,functor);
467 m_impl->executeParallelFor(loop_ranges,
ForLoopRunInfo(options),functor);
475 m_impl->executeParallelFor(loop_ranges,run_info,functor);
481 return m_impl->nbAllowedThread();
493 return m_impl->currentTaskThreadIndex();
511 return m_impl->currentTaskIndex();
519 m_default_loop_options = v;
525 return m_default_loop_options;
537 return m_impl->isActive();
548 return m_impl->printInfos(o);
559 ARCANE_DEPRECATED_REASON(
"Y2024: This method is internal to Arcane. Do not use it")
570 ARCANE_DEPRECATED_REASON(
"Y2024: This method is internal to Arcane. Do not use it")
578 static
void terminate();
591 ARCANE_DEPRECATED_REASON(
"Y2024: This method is internal to Arcane. "
592 "Use TaskFactoryInternal::setImplementation() instead")
598 static
Int32 m_verbose_level;
610class ARCANE_UTILS_EXPORT ParallelFor1DLoopInfo
614 using ThatClass = ParallelFor1DLoopInfo;
619 : m_begin(begin), m_size(size), m_functor(functor) {}
621 : m_run_info(run_info), m_begin(begin), m_size(size), m_functor(functor) {}
623 : m_begin(begin), m_size(size), m_functor(functor)
627 m_run_info.addOptions(opts);
632 Int32 beginIndex()
const {
return m_begin; }
633 Int32 size()
const {
return m_size; }
652template<
int RankValue,
typename LambdaType,
typename... ReducerArgs>
inline void
655 const LambdaType& lambda_function,
656 const ReducerArgs&... reducer_args)
670 using Type =
typename std::remove_reference<LambdaType>::type;
671 Type private_lambda(lambda_function);
684template<
int RankValue,
typename LambdaType,
typename... ReducerArgs>
inline void
687 const LambdaType& lambda_function,
688 const ReducerArgs&... reducer_args)
699template <
int RankValue,
typename LambdaType,
typename... ReducerArgs>
inline void
702 const LambdaType& lambda_function,
703 const ReducerArgs&... reducer_args)
706 arcaneParallelFor(complex_loop_ranges, run_info, lambda_function, reducer_args...);
715template <
int RankValue,
typename LambdaType,
typename... ReducerArgs>
inline void
718 const LambdaType& lambda_function,
719 const ReducerArgs&... reducer_args)
731template<
int RankValue,
typename LambdaType>
inline void
733 const LambdaType& lambda_function)
745template<
int RankValue,
typename LambdaType>
inline void
747 const LambdaType& lambda_function)
#define ARCANE_CHECK_POINTER(ptr)
Macro retournant le pointeur ptr s'il est non nul ou lancant une exception s'il est nul.
#define ARCANE_FATAL(...)
Macro envoyant une exception FatalErrorException.
Déclarations des types utilisés dans Arcane.
Vue constante d'un tableau de type T.
Classe pour gérer le profiling d'une seule exécution d'une boucle.
Informations d'exécution d'une boucle.
ForLoopOneExecStat * execStat() const
Pointeur contenant les statistiques d'exécution.
void setExecStat(ForLoopOneExecStat *v)
Positionne le pointeur conservant les statistiques d'exécution.
Informations de trace pour une boucle 'for'.
Interface d'un fonctor sur un interval d'itération multi-dimensionnel de dimension RankValue.
Interface d'un observable.
Interface d'un fonctor sur un interval d'itération.
virtual void executeFunctor(const TaskContext &tc)=0
Exécute la méthode associé
virtual void executeParallelFor(Integer begin, Integer size, const ParallelLoopOptions &options, IRangeFunctor *f)=0
Exécute le fonctor f en concurrence.
virtual void executeParallelFor(Integer begin, Integer size, IRangeFunctor *f)=0
Exécute le fonctor f en concurrence.
virtual void executeParallelFor(const ParallelFor1DLoopInfo &loop_info)=0
Exécute la boucle loop_info en concurrence.
virtual Int32 nbAllowedThread() const =0
Nombre de threads utilisés au maximum pour gérer les tâches.
virtual void executeParallelFor(const ComplexForLoopRanges< 2 > &loop_ranges, const ForLoopRunInfo &run_info, IMDRangeFunctor< 2 > *functor)=0
Exécute une boucle 2D en concurrence.
virtual void executeParallelFor(Integer begin, Integer size, Integer block_size, IRangeFunctor *f)=0
Exécute le fonctor f en concurrence.
virtual void executeParallelFor(const ComplexForLoopRanges< 3 > &loop_ranges, const ForLoopRunInfo &run_info, IMDRangeFunctor< 3 > *functor)=0
Exécute une boucle 3D en concurrence.
virtual ITask * createRootTask(ITaskFunctor *f)=0
Créé une tâche racine. L'implémentation doit recopier la valeur de f qui est soit un TaskFunctor,...
virtual Int32 currentTaskIndex() const =0
Implémentation de TaskFactory::currentTaskIndex()
virtual bool isActive() const =0
Indique si l'implémentation est active.
virtual void executeParallelFor(const ComplexForLoopRanges< 4 > &loop_ranges, const ForLoopRunInfo &run_info, IMDRangeFunctor< 4 > *functor)=0
Exécute une boucle 4D en concurrence.
virtual void executeParallelFor(const ComplexForLoopRanges< 1 > &loop_ranges, const ForLoopRunInfo &run_info, IMDRangeFunctor< 1 > *functor)=0
Exécute une boucle 1D en concurrence.
virtual void printInfos(std::ostream &o) const =0
Affiche les informations sur le runtime utilisé
virtual Int32 currentTaskThreadIndex() const =0
Implémentation de TaskFactory::currentTaskThreadIndex()
Interface d'une tâche concourante.
virtual void launchAndWait()=0
Lance la tâche et bloque jusqu'à ce qu'elle se termine.
virtual void launchAndWait(ConstArrayView< ITask * > tasks)=0
Lance les tâches filles tasks et bloque jusqu'à ce qu'elles se terminent.
Fonctor sur un interval d'itération instancié via une lambda fonction.
Caractéristiques d'un boucle 1D multi-thread.
Options d'exécution d'une boucle parallèle en multi-thread.
void setGrainSize(Integer v)
Positionne la taille (approximative) d'un intervalle d'itération.
Interval d'itération simple.
Contexte d'éxecution d'une tâche.
ITask * task() const
Tâche courante.
static Int32 currentTaskIndex()
Indice (entre 0 et nbAllowedThread()-1) de la tâche actuelle.
static void executeParallelFor(const ParallelFor1DLoopInfo &loop_info)
Exécute la boucle loop_info en concurrence.
static void setVerboseLevel(Integer v)
Positionne le niveau de verbosité (0 pour pas d'affichage qui est le défaut)
static Int32 nbAllowedThread()
Nombre de threads utilisés au maximum pour gérer les tâches.
static void executeParallelFor(Integer begin, Integer size, IRangeFunctor *f)
Exécute le fonctor f en concurrence.
static ITask * createTask(InstanceType *instance, void(InstanceType::*function)())
Créé une tâche. Lors de l'exécution, la tâche appellera la méthode function via l'instance instance.
static const ParallelLoopOptions & defaultParallelLoopOptions()
Valeurs par défaut d'exécution d'une boucle parallèle.
static void executeParallelFor(const ComplexForLoopRanges< 1 > &loop_ranges, const ParallelLoopOptions &options, IMDRangeFunctor< 1 > *functor)
Exécute une boucle simple.
static void executeParallelFor(const ComplexForLoopRanges< 1 > &loop_ranges, const ForLoopRunInfo &run_info, IMDRangeFunctor< 1 > *functor)
Exécute une boucle simple.
static void executeParallelFor(const ComplexForLoopRanges< 2 > &loop_ranges, const ForLoopRunInfo &run_info, IMDRangeFunctor< 2 > *functor)
Exécute une boucle 2D.
static Integer verboseLevel()
Niveau de verbosité
static void executeParallelFor(const ComplexForLoopRanges< 4 > &loop_ranges, const ParallelLoopOptions &options, IMDRangeFunctor< 4 > *functor)
Exécute une boucle 4D.
static void executeParallelFor(const ComplexForLoopRanges< 2 > &loop_ranges, const ParallelLoopOptions &options, IMDRangeFunctor< 2 > *functor)
Exécute une boucle 2D.
static void setDefaultParallelLoopOptions(const ParallelLoopOptions &v)
Positionne les valeurs par défaut d'exécution d'une boucle parallèle.
static void executeParallelFor(Integer begin, Integer size, const ParallelLoopOptions &options, IRangeFunctor *f)
Exécute le fonctor f en concurrence.
static void executeParallelFor(Integer begin, Integer size, Integer block_size, IRangeFunctor *f)
Exécute le fonctor f en concurrence.
static void executeParallelFor(const ComplexForLoopRanges< 3 > &loop_ranges, const ParallelLoopOptions &options, IMDRangeFunctor< 3 > *functor)
Exécute une boucle 3D.
static ITask * createChildTask(ITask *parent_task, InstanceType *instance, void(InstanceType::*function)(const TaskContext &tc))
Créé une tâche fille.
static Int32 currentTaskThreadIndex()
Indice (entre 0 et nbAllowedThread()-1) du thread exécutant la tâche actuelle.
static ITask * createChildTask(ITask *parent_task, InstanceType *instance, void(InstanceType::*function)())
Créé une tâche fille.
static bool isActive()
Indique si les tâches sont actives. Les tâches sont actives si une implémentation est disponible et s...
static ITask * createTask(InstanceType *instance, void(InstanceType::*function)(const TaskContext &tc))
Créé une tâche. Lors de l'exécution, la tâche appellera la méthode function via l'instance instance.
static void executeParallelFor(const ComplexForLoopRanges< 4 > &loop_ranges, const ForLoopRunInfo &run_info, IMDRangeFunctor< 4 > *functor)
Exécute une boucle 4D.
static void printInfos(std::ostream &o)
Affiche les informations sur l'implémentation.
static void executeParallelFor(const ComplexForLoopRanges< 3 > &loop_ranges, const ForLoopRunInfo &run_info, IMDRangeFunctor< 3 > *functor)
Exécute une boucle 3D.
void executeFunctor(const TaskContext &tc) override
Exécute la méthode associé
void executeFunctor(const TaskContext &) override
Exécute la méthode associé
void arcaneParallelFor(Integer i0, Integer size, InstanceType *itype, void(InstanceType::*lambda_function)(Integer i0, Integer size))
Applique en concurrence la fonction lambda lambda_function sur l'intervalle d'itération [i0,...
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.
void arcaneSequentialFor(LoopBoundType< 1, IndexType > bounds, const Lambda &func, ReducerArgs... reducer_args)
Applique le fonctor func sur une boucle 1D.
std::int32_t Int32
Type entier signé sur 32 bits.