21using Policy = ::Kokkos::RangePolicy<ExecSpace, ::Kokkos::IndexType<ThreadID>>;
38 mooseError(
"parallelFor() called for an instance that is not a dispatcher.");
47 ::Kokkos::View<Real *, ::Kokkos::HostSpace> & )
49 mooseError(
"parallelReduce() called for an instance that is not a reducer.");
59template <
typename Operation,
typename Object>
83 ::Kokkos::parallel_for(policy, *
this);
112template <
typename Operation,
typename Object>
137 ::Kokkos::View<Real *, ::Kokkos::HostSpace> & result)
override final
141 ::Kokkos::parallel_reduce(policy, *
this, result);
197 virtual std::unique_ptr<DispatcherBase>
build(
const void *
object)
const = 0;
227template <
typename Operation,
typename Object>
231 std::unique_ptr<DispatcherBase>
build(
const void *
object)
const override final
233 return std::make_unique<Dispatcher<Operation, Object>>(object);
237template <
typename Operation,
typename Object>
241 std::unique_ptr<DispatcherBase>
build(
const void *
object)
const override final
243 return std::make_unique<Reducer<Operation, Object>>(object);
268 template <
typename Operation,
typename Object>
271 auto operation = std::type_index(
typeid(Operation));
274 std::make_unique<DispatcherRegistryEntry<Operation, Object>>();
283 template <
typename Operation,
typename Object>
286 auto operation = std::type_index(
typeid(Operation));
289 std::make_unique<ReducerRegistryEntry<Operation, Object>>();
298 template <
typename Operation>
301 getDispatcher<Operation>(name)->hasUserMethod(flag);
310 template <
typename Operation>
313 return getDispatcher<Operation>(name)->hasUserMethod();
323 template <
typename Operation>
324 static std::unique_ptr<DispatcherBase>
build(
const void *
object,
const std::string & name)
326 return getDispatcher<Operation>(name)->build(
object);
342 template <
typename Operation>
345 auto operation = std::type_index(
typeid(Operation));
349 mooseError(
"Kokkos functor dispatcher not registered for object type '",
351 "'. Double check that you used Kokkos-specific registration macro.");
360 std::map<std::pair<std::type_index, std::string>, std::unique_ptr<DispatcherRegistryEntryBase>>
364template <
typename T,
typename =
void>
371 std::void_t<typename T::InternalRightHandSideLoop,
372 typename T::BoundaryRightHandSideLoop,
373 typename T::InternalMatrixLoop,
374 typename T::BoundaryMatrixLoop>>
379template <
typename Object>
383 return &Object::template computeMatrixContribution<Object> !=
384 Object::template defaultMatrixContribution<Object>() ||
385 &Object::template computeNeighborMatrixContribution<Object> !=
386 Object::template defaultNeighborMatrixContribution<Object>();
389template <
typename Object>
393 return &Object::template computeInternalMatrixContribution<Object> !=
394 Object::template defaultInternalMatrixContribution<Object>() ||
395 &Object::template computeInternalNeighborMatrixContribution<Object> !=
396 Object::template defaultInternalNeighborMatrixContribution<Object>();
399template <
typename Object>
403 return &Object::template computeBoundaryMatrixContribution<Object> !=
404 Object::template defaultBoundaryMatrixContribution<Object>();
407template <
typename Object>
413 DispatcherRegistry::addDispatcher<typename Object::InternalRightHandSideLoop, Object>(
415 DispatcherRegistry::addDispatcher<typename Object::BoundaryRightHandSideLoop, Object>(
417 DispatcherRegistry::addDispatcher<typename Object::InternalMatrixLoop, Object>(objectname);
418 DispatcherRegistry::addDispatcher<typename Object::BoundaryMatrixLoop, Object>(objectname);
420 DispatcherRegistry::hasUserMethod<typename Object::InternalMatrixLoop>(
421 objectname, hasInternalLinearFVFluxMatrixContribution<Object>());
422 DispatcherRegistry::hasUserMethod<typename Object::BoundaryMatrixLoop>(
423 objectname, hasBoundaryLinearFVFluxMatrixContribution<Object>());
427 DispatcherRegistry::addDispatcher<typename Object::RightHandSideLoop, Object>(objectname);
428 DispatcherRegistry::addDispatcher<typename Object::MatrixLoop, Object>(objectname);
430 DispatcherRegistry::hasUserMethod<typename Object::MatrixLoop>(
431 objectname, hasLinearFVMatrixContribution<Object>());
442template <
typename Object>
448 DispatcherRegistry::addDispatcher<typename Object::ResidualLoop, Object>(objectname);
449 DispatcherRegistry::addDispatcher<typename Object::JacobianLoop, Object>(objectname);
450 DispatcherRegistry::addDispatcher<typename Object::OffDiagJacobianLoop, Object>(objectname);
452 if constexpr (Object::uses_precompute_hooks)
454 DispatcherRegistry::hasUserMethod<typename Object::JacobianLoop>(
456 &Object::template precomputeQpJacobian<Object> !=
457 Object::template defaultJacobian<Object>());
458 DispatcherRegistry::hasUserMethod<typename Object::OffDiagJacobianLoop>(
460 &Object::template precomputeQpOffDiagJacobian<Object> !=
461 Object::template defaultOffDiagJacobian<Object>());
465 DispatcherRegistry::hasUserMethod<typename Object::JacobianLoop>(
467 &Object::template computeQpJacobian<Object> != Object::template defaultJacobian<Object>());
468 DispatcherRegistry::hasUserMethod<typename Object::OffDiagJacobianLoop>(
470 &Object::template computeQpOffDiagJacobian<Object> !=
471 Object::template defaultOffDiagJacobian<Object>());
474 if constexpr (Object::supports_scalar_jacobian)
476 DispatcherRegistry::addDispatcher<typename Object::OffDiagJacobianScalarLoop, Object>(
478 DispatcherRegistry::hasUserMethod<typename Object::OffDiagJacobianScalarLoop>(
480 &Object::template computeQpOffDiagJacobianScalar<Object> !=
481 Object::template defaultOffDiagJacobianScalar<Object>());
487#define callRegisterKokkosResidualObjectFunction(classname, objectname) \
488 static char registerKokkosResidualObject##classname() \
490 using namespace Moose::Kokkos; \
492 registerResidualObjectDispatchers<classname>(objectname); \
497 [[maybe_unused]] static char combineNames(kokkos_dispatcher_residual_object_##classname, \
499 registerKokkosResidualObject##classname()
501#define registerKokkosResidualObject(app, classname) \
502 registerMooseObject(app, classname); \
503 callRegisterKokkosResidualObjectFunction(classname, #classname)
505#define registerKokkosResidualObjectAliased(app, classname, alias) \
506 registerMooseObjectAliased(app, classname, alias); \
507 callRegisterKokkosResidualObjectFunction(classname, alias)
511#define callRegisterKokkosADResidualObjectFunction(classname, objectname) \
512 static char registerKokkosADResidualObject##classname() \
514 using namespace Moose::Kokkos; \
516 DispatcherRegistry::addDispatcher<classname::ResidualLoop, classname>(objectname); \
521 [[maybe_unused]] static char combineNames(kokkos_dispatcher_ad_residual_object_##classname, \
523 registerKokkosADResidualObject##classname()
525#define registerKokkosADResidualObject(app, classname) \
526 registerMooseObject(app, classname); \
527 callRegisterKokkosADResidualObjectFunction(classname, #classname)
529#define registerKokkosADResidualObjectAliased(app, classname, alias) \
530 registerMooseObjectAliased(app, classname, alias); \
531 callRegisterKokkosADResidualObjectFunction(classname, alias)
533#define callRegisterKokkosLinearFVKernelFunction(classname, objectname) \
534 static char registerKokkosLinearFVKernel##classname() \
536 using namespace Moose::Kokkos; \
538 registerLinearFVKernelDispatchers<classname>(objectname); \
543 static char combineNames(kokkos_dispatcher_linear_fv_kernel_##classname, __COUNTER__) = \
544 registerKokkosLinearFVKernel##classname()
546#define registerKokkosLinearFVKernel(app, classname) \
547 registerMooseObject(app, classname); \
548 callRegisterKokkosLinearFVKernelFunction(classname, #classname)
550#define registerKokkosLinearFVKernelAliased(app, classname, alias) \
551 registerMooseObjectAliased(app, classname, alias); \
552 callRegisterKokkosLinearFVKernelFunction(classname, alias)
554#define callRegisterKokkosLinearFVBoundaryConditionFunction(classname, objectname) \
555 static char registerKokkosLinearFVBoundaryCondition##classname() \
557 using namespace Moose::Kokkos; \
559 DispatcherRegistry::addDispatcher<classname::BoundaryValueLoop, classname>(objectname); \
560 DispatcherRegistry::addDispatcher<classname::BoundaryNormalGradientLoop, classname>( \
563 DispatcherRegistry::hasUserMethod<classname::BoundaryValueLoop>( \
565 &classname::computeBoundaryValue<classname> != \
566 classname::defaultBoundaryValue<classname>()); \
567 DispatcherRegistry::hasUserMethod<classname::BoundaryNormalGradientLoop>( \
569 &classname::computeBoundaryNormalGradient<classname> != \
570 classname::defaultBoundaryNormalGradient<classname>()); \
575 static char combineNames(kokkos_dispatcher_linear_fv_boundary_condition_##classname, \
576 __COUNTER__) = registerKokkosLinearFVBoundaryCondition##classname()
578#define registerKokkosLinearFVBoundaryCondition(app, classname) \
579 registerMooseObject(app, classname); \
580 callRegisterKokkosLinearFVBoundaryConditionFunction(classname, #classname)
582#define registerKokkosLinearFVBoundaryConditionAliased(app, classname, alias) \
583 registerMooseObjectAliased(app, classname, alias); \
584 callRegisterKokkosLinearFVBoundaryConditionFunction(classname, alias)
588#define callRegisterKokkosMaterialFunction(classname, objectname) \
589 static char registerKokkosMaterial##classname() \
591 using namespace Moose::Kokkos; \
593 DispatcherRegistry::addDispatcher<classname::ElementInit, classname>(objectname); \
594 DispatcherRegistry::addDispatcher<classname::SideInit, classname>(objectname); \
595 DispatcherRegistry::addDispatcher<classname::NeighborInit, classname>(objectname); \
596 DispatcherRegistry::addDispatcher<classname::ElementCompute, classname>(objectname); \
597 DispatcherRegistry::addDispatcher<classname::SideCompute, classname>(objectname); \
598 DispatcherRegistry::addDispatcher<classname::NeighborCompute, classname>(objectname); \
600 DispatcherRegistry::hasUserMethod<classname::ElementInit>( \
602 &classname::initQpStatefulProperties<classname> != \
603 classname::defaultInitStateful<classname>()); \
604 DispatcherRegistry::hasUserMethod<classname::SideInit>( \
606 &classname::initQpStatefulProperties<classname> != \
607 classname::defaultInitStateful<classname>()); \
608 DispatcherRegistry::hasUserMethod<classname::NeighborInit>( \
610 &classname::initQpStatefulProperties<classname> != \
611 classname::defaultInitStateful<classname>()); \
616 [[maybe_unused]] static char combineNames(kokkos_dispatcher_material_##classname, __COUNTER__) = \
617 registerKokkosMaterial##classname()
619#define registerKokkosMaterial(app, classname) \
620 registerMooseObject(app, classname); \
621 callRegisterKokkosMaterialFunction(classname, #classname)
623#define registerKokkosMaterialAliased(app, classname, alias) \
624 registerMooseObjectAliased(app, classname, alias); \
625 callRegisterKokkosMaterialFunction(classname, alias)
629#define callRegisterKokkosAuxKernelFunction(classname, objectname) \
630 static char registerKokkosAuxKernel##classname() \
632 using namespace Moose::Kokkos; \
634 DispatcherRegistry::addDispatcher<classname::ElementLoop, classname>(objectname); \
635 DispatcherRegistry::addDispatcher<classname::NodeLoop, classname>(objectname); \
640 [[maybe_unused]] static char combineNames(kokkos_dispatcher_auxkernel_##classname, \
641 __COUNTER__) = registerKokkosAuxKernel##classname()
643#define registerKokkosAuxKernel(app, classname) \
644 registerMooseObject(app, classname); \
645 callRegisterKokkosAuxKernelFunction(classname, #classname)
647#define registerKokkosAuxKernelAliased(app, classname, alias) \
648 registerMooseObjectAliased(app, classname, alias); \
649 callRegisterKokkosAuxKernelFunction(classname, alias)
653#define callRegisterKokkosUserObjectFunction(classname, objectname) \
654 static char registerKokkosUserObject##classname() \
656 using namespace Moose::Kokkos; \
658 DispatcherRegistry::addDispatcher<classname::DefaultLoop, classname>(objectname); \
659 DispatcherRegistry::addReducer<classname::ReducerLoop, classname>(objectname); \
661 DispatcherRegistry::hasUserMethod<classname::DefaultLoop>( \
662 objectname, &classname::execute<classname> != classname::defaultExecute<classname>()); \
663 DispatcherRegistry::hasUserMethod<classname::ReducerLoop>( \
664 objectname, &classname::reduce<classname> != classname::defaultReduce<classname>()); \
669 [[maybe_unused]] static char combineNames(kokkos_dispatcher_userobject_##classname, \
670 __COUNTER__) = registerKokkosUserObject##classname()
672#define registerKokkosUserObject(app, classname) \
673 registerMooseObject(app, classname); \
674 callRegisterKokkosUserObjectFunction(classname, #classname)
676#define registerKokkosUserObjectAliased(app, classname, alias) \
677 registerMooseObjectAliased(app, classname, alias); \
678 callRegisterKokkosUserObjectFunction(classname, alias)
682#define registerKokkosAdditionalOperation(classname, operation) \
683 static char registerKokkos##classname##operation() \
685 using namespace Moose::Kokkos; \
687 DispatcherRegistry::addDispatcher<classname::operation, classname>(#classname); \
692 [[maybe_unused]] static char combineNames(kokkos_##classname##_##operation, __COUNTER__) = \
693 registerKokkos##classname##operation()
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Base class for Kokkos functor dispatcher.
virtual void parallelFor(const Policy &)
Dispatch this functor with Kokkos parallel_for() given a Kokkos execution policy.
virtual void parallelReduce(const Policy &, ::Kokkos::View< Real *, ::Kokkos::HostSpace > &)
Dispatch this functor with Kokkos parallel_reduce() given a Kokkos execution policy and result buffer...
virtual ~DispatcherBase()
Base class for dispatcher registry entry.
virtual ~DispatcherRegistryEntryBase()
bool hasUserMethod() const
Get whether the user has overriden the hook method associated with this operation.
bool _has_user_method
Flag whether the user has overriden the hook method associated with this operation.
void hasUserMethod(bool flag)
Set whether the user has overriden the hook method associated with this operation.
virtual std::unique_ptr< DispatcherBase > build(const void *object) const =0
Build a dispatcher for this operation and functor.
Class that stores the information of a dispatcher and builds it.
std::unique_ptr< DispatcherBase > build(const void *object) const override final
Build a dispatcher for this operation and functor.
Class that registers dispatchers of all Kokkos functors.
std::map< std::pair< std::type_index, std::string >, std::unique_ptr< DispatcherRegistryEntryBase > > _dispatchers
Map containing the dispatcher shells with the key being the pair of function tag type index and regis...
static auto & getDispatcher(const std::string &name)
Get the dispatcher shell of an operation of a functor.
DispatcherRegistry & operator=(DispatcherRegistry const &)=delete
DispatcherRegistry()=default
DispatcherRegistry(DispatcherRegistry &&)=delete
static void hasUserMethod(const std::string &name, const bool flag)
Set whether the user has overriden the hook method associated with an operation of a functor.
static std::unique_ptr< DispatcherBase > build(const void *object, const std::string &name)
Build and get a dispatcher of an operation of a functor.
DispatcherRegistry(DispatcherRegistry const &)=delete
DispatcherRegistry & operator=(DispatcherRegistry &&)=delete
static bool hasUserMethod(const std::string &name)
Get whether the user has overriden the hook method associated with an operation of a functor.
static void addDispatcher(const std::string &name)
Register a dispatcher of an operation of a functor.
static DispatcherRegistry & getRegistry()
Get the registry singleton.
static void addReducer(const std::string &name)
Register a reducer of an operation of a functor.
Class that dispatches a parallel loop operation of a Kokkos functor.
Dispatcher(const void *object)
Constructor.
const Object _functor_device
Copy of the functor on device.
KOKKOS_FUNCTION void operator()(const ThreadID tid) const
The parallel computation entry function called by Kokkos::parallel_for.
const Object & _functor_host
Reference of the functor on host.
void parallelFor(const Policy &policy) override final
Dispatch this functor with Kokkos parallel_for() given a Kokkos execution policy.
Dispatcher(const Dispatcher &functor)
Copy constructor for parallel dispatch.
std::unique_ptr< DispatcherBase > build(const void *object) const override final
Build a dispatcher for this operation and functor.
Class that dispatches a parallel reduction operation of a Kokkos functor.
const Object & _functor_host
Reference of the functor on host.
KOKKOS_FUNCTION void init(value_type result) const
KOKKOS_FUNCTION void join(value_type result, const value_type source) const
Functions required by the reducer concept of Kokkos.
Reducer(const void *object)
Constructor.
const Object _functor_device
Copy of the functor on device.
Reducer(const Reducer &functor)
Copy constructor for parallel dispatch.
void parallelReduce(const Policy &policy, ::Kokkos::View< Real *, ::Kokkos::HostSpace > &result) override final
Dispatch this functor with Kokkos parallel_reduce() given a Kokkos execution policy and result buffer...
::Kokkos::View< Real * >::size_type size_type
KOKKOS_FUNCTION void operator()(const ThreadID tid, value_type result) const
The parallel computation entry function called by Kokkos::parallel_reduce.
void registerResidualObjectDispatchers(const std::string &objectname)
bool hasBoundaryLinearFVFluxMatrixContribution()
::Kokkos::RangePolicy< ExecSpace, ::Kokkos::IndexType< ThreadID > > Policy
bool hasLinearFVMatrixContribution()
bool hasInternalLinearFVFluxMatrixContribution()
MOOSE_KOKKOS_INDEX_TYPE ThreadID
void registerLinearFVKernelDispatchers(const std::string &objectname)