16 #include <type_traits> 21 using 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.");
59 template <
typename Operation,
typename Object>
83 ::Kokkos::parallel_for(policy, *
this);
112 template <
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;
226 template <
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);
237 template <
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>
310 template <
typename Operation>
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>>
364 template <
typename T,
typename =
void>
369 template <
typename T>
371 std::void_t<typename T::InternalRightHandSideLoop,
372 typename T::BoundaryRightHandSideLoop,
373 typename T::InternalMatrixLoop,
374 typename T::BoundaryMatrixLoop>>
379 template <
typename Object>
383 return &Object::template computeMatrixContribution<Object> !=
384 Object::template defaultMatrixContribution<Object>() ||
385 &Object::template computeNeighborMatrixContribution<Object> !=
386 Object::template defaultNeighborMatrixContribution<Object>();
389 template <
typename Object>
393 return &Object::template computeInternalMatrixContribution<Object> !=
394 Object::template defaultInternalMatrixContribution<Object>() ||
395 &Object::template computeInternalNeighborMatrixContribution<Object> !=
396 Object::template defaultInternalNeighborMatrixContribution<Object>();
399 template <
typename Object>
403 return &Object::template computeBoundaryMatrixContribution<Object> !=
404 Object::template defaultBoundaryMatrixContribution<Object>();
407 template <
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);
429 DispatcherRegistry::hasUserMethod<typename Object::MatrixLoop>(
430 objectname, hasLinearFVMatrixContribution<Object>());
441 template <
typename Object>
445 if constexpr (Object::use_precompute_hooks)
446 return &Object::template precomputeQpJacobian<Object> !=
447 Object::template defaultJacobian<Object>();
449 return &Object::template computeQpJacobian<Object> !=
450 Object::template defaultJacobian<Object>();
453 template <
typename Object>
457 if constexpr (Object::use_precompute_hooks)
458 return &Object::template precomputeQpOffDiagJacobian<Object> !=
459 Object::template defaultOffDiagJacobian<Object>();
461 return &Object::template computeQpOffDiagJacobian<Object> !=
462 Object::template defaultOffDiagJacobian<Object>();
467 #define callRegisterKokkosResidualObjectFunction(classname, objectname) \ 468 static char registerKokkosResidualObject##classname() \ 470 using namespace Moose::Kokkos; \ 472 DispatcherRegistry::addDispatcher<classname::ResidualLoop, classname>(objectname); \ 473 DispatcherRegistry::addDispatcher<classname::JacobianLoop, classname>(objectname); \ 474 DispatcherRegistry::addDispatcher<classname::OffDiagJacobianLoop, classname>(objectname); \ 475 DispatcherRegistry::hasUserMethod<classname::JacobianLoop>(objectname, \ 476 hasUserJacobianHook<classname>()); \ 477 DispatcherRegistry::hasUserMethod<classname::OffDiagJacobianLoop>( \ 478 objectname, hasUserOffDiagJacobianHook<classname>()); \ 483 [[maybe_unused]] static char combineNames(kokkos_dispatcher_residual_object_##classname, \ 485 registerKokkosResidualObject##classname() 487 #define registerKokkosResidualObject(app, classname) \ 488 registerMooseObject(app, classname); \ 489 callRegisterKokkosResidualObjectFunction(classname, #classname) 491 #define registerKokkosResidualObjectAliased(app, classname, alias) \ 492 registerMooseObjectAliased(app, classname, alias); \ 493 callRegisterKokkosResidualObjectFunction(classname, alias) 497 #define callRegisterKokkosADResidualObjectFunction(classname, objectname) \ 498 static char registerKokkosADResidualObject##classname() \ 500 using namespace Moose::Kokkos; \ 502 DispatcherRegistry::addDispatcher<classname::ResidualLoop, classname>(objectname); \ 507 [[maybe_unused]] static char combineNames(kokkos_dispatcher_ad_residual_object_##classname, \ 509 registerKokkosADResidualObject##classname() 511 #define registerKokkosADResidualObject(app, classname) \ 512 registerMooseObject(app, classname); \ 513 callRegisterKokkosADResidualObjectFunction(classname, #classname) 515 #define registerKokkosADResidualObjectAliased(app, classname, alias) \ 516 registerMooseObjectAliased(app, classname, alias); \ 517 callRegisterKokkosADResidualObjectFunction(classname, alias) 519 #define callRegisterKokkosLinearFVKernelFunction(classname, objectname) \ 520 static char registerKokkosLinearFVKernel##classname() \ 522 using namespace Moose::Kokkos; \ 524 registerLinearFVKernelDispatchers<classname>(objectname); \ 529 static char combineNames(kokkos_dispatcher_linear_fv_kernel_##classname, __COUNTER__) = \ 530 registerKokkosLinearFVKernel##classname() 532 #define registerKokkosLinearFVKernel(app, classname) \ 533 registerMooseObject(app, classname); \ 534 callRegisterKokkosLinearFVKernelFunction(classname, #classname) 536 #define registerKokkosLinearFVKernelAliased(app, classname, alias) \ 537 registerMooseObjectAliased(app, classname, alias); \ 538 callRegisterKokkosLinearFVKernelFunction(classname, alias) 540 #define callRegisterKokkosLinearFVBoundaryConditionFunction(classname, objectname) \ 541 static char registerKokkosLinearFVBoundaryCondition##classname() \ 543 using namespace Moose::Kokkos; \ 545 DispatcherRegistry::addDispatcher<classname::BoundaryValueLoop, classname>(objectname); \ 546 DispatcherRegistry::addDispatcher<classname::BoundaryNormalGradientLoop, classname>( \ 548 DispatcherRegistry::hasUserMethod<classname::BoundaryValueLoop>( \ 550 &classname::computeBoundaryValue<classname> != \ 551 classname::defaultBoundaryValue<classname>()); \ 552 DispatcherRegistry::hasUserMethod<classname::BoundaryNormalGradientLoop>( \ 554 &classname::computeBoundaryNormalGradient<classname> != \ 555 classname::defaultBoundaryNormalGradient<classname>()); \ 560 static char combineNames(kokkos_dispatcher_linear_fv_boundary_condition_##classname, \ 561 __COUNTER__) = registerKokkosLinearFVBoundaryCondition##classname() 563 #define registerKokkosLinearFVBoundaryCondition(app, classname) \ 564 registerMooseObject(app, classname); \ 565 callRegisterKokkosLinearFVBoundaryConditionFunction(classname, #classname) 567 #define registerKokkosLinearFVBoundaryConditionAliased(app, classname, alias) \ 568 registerMooseObjectAliased(app, classname, alias); \ 569 callRegisterKokkosLinearFVBoundaryConditionFunction(classname, alias) 573 #define callRegisterKokkosMaterialFunction(classname, objectname) \ 574 static char registerKokkosMaterial##classname() \ 576 using namespace Moose::Kokkos; \ 578 DispatcherRegistry::addDispatcher<classname::ElementInit, classname>(objectname); \ 579 DispatcherRegistry::addDispatcher<classname::SideInit, classname>(objectname); \ 580 DispatcherRegistry::addDispatcher<classname::NeighborInit, classname>(objectname); \ 581 DispatcherRegistry::addDispatcher<classname::ElementCompute, classname>(objectname); \ 582 DispatcherRegistry::addDispatcher<classname::SideCompute, classname>(objectname); \ 583 DispatcherRegistry::addDispatcher<classname::NeighborCompute, classname>(objectname); \ 584 DispatcherRegistry::hasUserMethod<classname::ElementInit>( \ 586 &classname::initQpStatefulProperties<classname> != \ 587 classname::defaultInitStateful<classname>()); \ 588 DispatcherRegistry::hasUserMethod<classname::SideInit>( \ 590 &classname::initQpStatefulProperties<classname> != \ 591 classname::defaultInitStateful<classname>()); \ 592 DispatcherRegistry::hasUserMethod<classname::NeighborInit>( \ 594 &classname::initQpStatefulProperties<classname> != \ 595 classname::defaultInitStateful<classname>()); \ 600 [[maybe_unused]] static char combineNames(kokkos_dispatcher_material_##classname, __COUNTER__) = \ 601 registerKokkosMaterial##classname() 603 #define registerKokkosMaterial(app, classname) \ 604 registerMooseObject(app, classname); \ 605 callRegisterKokkosMaterialFunction(classname, #classname) 607 #define registerKokkosMaterialAliased(app, classname, alias) \ 608 registerMooseObjectAliased(app, classname, alias); \ 609 callRegisterKokkosMaterialFunction(classname, alias) 613 #define callRegisterKokkosAuxKernelFunction(classname, objectname) \ 614 static char registerKokkosAuxKernel##classname() \ 616 using namespace Moose::Kokkos; \ 618 DispatcherRegistry::addDispatcher<classname::ElementLoop, classname>(objectname); \ 619 DispatcherRegistry::addDispatcher<classname::NodeLoop, classname>(objectname); \ 624 [[maybe_unused]] static char combineNames(kokkos_dispatcher_auxkernel_##classname, \ 625 __COUNTER__) = registerKokkosAuxKernel##classname() 627 #define registerKokkosAuxKernel(app, classname) \ 628 registerMooseObject(app, classname); \ 629 callRegisterKokkosAuxKernelFunction(classname, #classname) 631 #define registerKokkosAuxKernelAliased(app, classname, alias) \ 632 registerMooseObjectAliased(app, classname, alias); \ 633 callRegisterKokkosAuxKernelFunction(classname, alias) 637 #define callRegisterKokkosUserObjectFunction(classname, objectname) \ 638 static char registerKokkosUserObject##classname() \ 640 using namespace Moose::Kokkos; \ 642 DispatcherRegistry::addDispatcher<classname::DefaultLoop, classname>(objectname); \ 643 DispatcherRegistry::addReducer<classname::ReducerLoop, classname>(objectname); \ 644 DispatcherRegistry::hasUserMethod<classname::DefaultLoop>( \ 645 objectname, &classname::execute<classname> != classname::defaultExecute<classname>()); \ 646 DispatcherRegistry::hasUserMethod<classname::ReducerLoop>( \ 647 objectname, &classname::reduce<classname> != classname::defaultReduce<classname>()); \ 652 [[maybe_unused]] static char combineNames(kokkos_dispatcher_userobject_##classname, \ 653 __COUNTER__) = registerKokkosUserObject##classname() 655 #define registerKokkosUserObject(app, classname) \ 656 registerMooseObject(app, classname); \ 657 callRegisterKokkosUserObjectFunction(classname, #classname) 659 #define registerKokkosUserObjectAliased(app, classname, alias) \ 660 registerMooseObjectAliased(app, classname, alias); \ 661 callRegisterKokkosUserObjectFunction(classname, alias) 665 #define registerKokkosAdditionalOperation(classname, operation) \ 666 static char registerKokkos##classname##operation() \ 668 using namespace Moose::Kokkos; \ 670 DispatcherRegistry::addDispatcher<classname::operation, classname>(#classname); \ 675 [[maybe_unused]] static char combineNames(kokkos_##classname##_##operation, __COUNTER__) = \ 676 registerKokkos##classname##operation() std::string name(const ElemQuality q)
KOKKOS_FUNCTION void join(value_type result, const value_type source) const
Functions required by the reducer concept of Kokkos.
std::unique_ptr< DispatcherBase > build(const void *object) const override final
Build a dispatcher for this operation and functor.
bool hasUserOffDiagJacobianHook()
Class that dispatches a parallel loop operation of a Kokkos functor.
static bool hasUserMethod(const std::string &name)
Get whether the user has overriden the hook method associated with an operation of a functor...
Reducer(const void *object)
Constructor.
static void addDispatcher(const std::string &name)
Register a dispatcher of an operation of a functor.
std::unique_ptr< DispatcherBase > build(const void *object) const override final
Build a dispatcher for this operation and functor.
DispatcherRegistry & operator=(DispatcherRegistry const &)=delete
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
::Kokkos::View< Real * >::size_type size_type
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_FUNCTION void operator()(const ThreadID tid) const
The parallel computation entry function called by Kokkos::parallel_for.
const Object _functor_device
Copy of the functor on device.
static auto & getDispatcher(const std::string &name)
Get the dispatcher shell of an operation of a functor.
bool hasInternalLinearFVFluxMatrixContribution()
virtual void parallelFor(const Policy &)
Dispatch this functor with Kokkos parallel_for() given a Kokkos execution policy. ...
Class that stores the information of a dispatcher and builds it.
::Kokkos::RangePolicy< ExecSpace, ::Kokkos::IndexType< ThreadID > > Policy
Base class for dispatcher registry entry.
void registerLinearFVKernelDispatchers(const std::string &objectname)
bool hasLinearFVMatrixContribution()
bool hasUserJacobianHook()
MOOSE_KOKKOS_INDEX_TYPE ThreadID
virtual ~DispatcherRegistryEntryBase()
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...
static void addReducer(const std::string &name)
Register a reducer of an operation of a functor.
KOKKOS_FUNCTION void init(value_type result) const
static std::unique_ptr< DispatcherBase > build(const void *object, const std::string &name)
Build and get a dispatcher of an operation of a functor.
bool _has_user_method
Flag whether the user has overriden the hook method associated with this operation.
bool hasUserMethod() const
Get 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.
DispatcherRegistry()=default
Base class for Kokkos functor dispatcher.
const Object & _functor_host
Reference of the functor on host.
Dispatcher(const void *object)
Constructor.
const Object _functor_device
Copy of the functor on device.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void parallelFor(const Policy &policy) override final
Dispatch this functor with Kokkos parallel_for() given a Kokkos execution policy. ...
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...
KOKKOS_FUNCTION void operator()(const ThreadID tid, value_type result) const
The parallel computation entry function called by Kokkos::parallel_reduce.
bool hasBoundaryLinearFVFluxMatrixContribution()
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...
Class that registers dispatchers of all Kokkos functors.
Class that dispatches a parallel reduction operation of a Kokkos functor.
static DispatcherRegistry & getRegistry()
Get the registry singleton.
virtual std::unique_ptr< DispatcherBase > build(const void *object) const =0
Build a dispatcher for this operation and functor.
const Object & _functor_host
Reference of the functor on host.
Reducer(const Reducer &functor)
Copy constructor for parallel dispatch.
Dispatcher(const Dispatcher &functor)
Copy constructor for parallel dispatch.
virtual ~DispatcherBase()