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;
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; }
86 ForLoopOneExecStat*
execStat()
const {
return m_exec_stat; }
90 std::optional<ParallelLoopOptions> m_options;
92 ForLoopOneExecStat* m_exec_stat =
nullptr;
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)
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>
181 typedef void (InstanceType::*FunctorType)(
const TaskContext& tc);
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;
263 virtual void initialize(Int32 nb_thread) =0;
269 virtual void terminate() =0;
330 friend TaskFactoryInternal;
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();
583 static
void setVerboseLevel(Integer v) { m_verbose_level = v; }
591 ARCANE_DEPRECATED_REASON(
"Y2024: This method is internal to Arcane. "
592 "Use TaskFactoryInternal::setImplementation() instead")
598 static Int32 m_verbose_level;
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);
675 TaskFactory::executeParallelFor(loop_ranges,run_info,&ipf);
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.
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.
Fabrique pour les tâches.
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 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é
Vue constante d'un tableau de type T.
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 -*-
void arcaneSequentialFor(LoopBoundType< 1, IndexType > bounds, const Lambda &func, ReducerArgs... reducer_args)
Applique le fonctor func sur une boucle 1D.