https://mooseframework.inl.gov
KokkosFunctorWrapper.h
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #pragma once
11 
12 #include "KokkosTypes.h"
13 
14 namespace Moose::Kokkos
15 {
16 
17 template <typename Object>
19 
24 {
25 public:
29  KOKKOS_FUNCTION FunctorWrapperDeviceBase() {}
33  KOKKOS_FUNCTION virtual ~FunctorWrapperDeviceBase() {}
34 };
35 
42 template <typename Object>
44 {
45  friend class FunctorWrapperHost<Object>;
46 
47 public:
51  KOKKOS_FUNCTION FunctorWrapperDevice() {}
52 
53 protected:
57  Object * _functor = nullptr;
58 };
59 
64 {
65 public:
70 
75  virtual FunctorWrapperDeviceBase * allocate() = 0;
79  virtual void copyFunctor() = 0;
83  virtual void freeFunctor() = 0;
84 };
85 
92 template <typename Object>
93 class FunctorWrapperHost : public FunctorWrapperHostBase
94 {
95 public:
100  FunctorWrapperHost(const void * functor) : _functor_host(*static_cast<const Object *>(functor)) {}
105 
106  FunctorWrapperDeviceBase * allocate() override final;
107  void copyFunctor() override final;
108  void freeFunctor() override final;
109 
110 private:
114  const Object & _functor_host;
118  std::unique_ptr<Object> _functor_copy;
122  Object * _functor_device = nullptr;
123 };
124 
125 template <typename Object>
128 {
129  // Allocate storage for device wrapper on device
130  auto wrapper_device = static_cast<FunctorWrapperDevice<Object> *>(
131  ::Kokkos::kokkos_malloc<ExecSpace::memory_space>(sizeof(FunctorWrapperDevice<Object>)));
132 
133  // Allocate device wrapper on device using placement new to populate vtable with device pointers
134  ::Kokkos::parallel_for(
135  1, KOKKOS_LAMBDA(const int) { new (wrapper_device) FunctorWrapperDevice<Object>(); });
136 
137  // Allocate storage for functor on device
139  static_cast<Object *>(::Kokkos::kokkos_malloc<ExecSpace::memory_space>(sizeof(Object)));
140 
141  // Let device wrapper point to the copy
142  ::Kokkos::Impl::DeepCopy<MemSpace, ::Kokkos::HostSpace>(
143  &(wrapper_device->_functor), &_functor_device, sizeof(Object *));
144 
145  return wrapper_device;
146 }
147 
148 template <typename Object>
149 void
151 {
152  // Make a copy of functor on host to trigger copy constructor
153  _functor_copy = std::make_unique<Object>(_functor_host);
154 
155  // Copy functor to device
156  ::Kokkos::Impl::DeepCopy<MemSpace, ::Kokkos::HostSpace>(
157  _functor_device, _functor_copy.get(), sizeof(Object));
158 }
159 
160 template <typename Object>
161 void
163 {
164  _functor_copy.reset();
165 }
166 
167 template <typename Object>
169 {
170  ::Kokkos::kokkos_free<ExecSpace::memory_space>(_functor_device);
171 }
172 
173 } // namespace Moose::Kokkos
void copyFunctor() override final
Copy functor to device.
virtual ~FunctorWrapperHostBase()
Virtual destructor.
Object * _functor_device
Copy of the functor on device.
virtual KOKKOS_FUNCTION ~FunctorWrapperDeviceBase()
Virtual destructor.
Base class for host functor wrapper.
virtual void copyFunctor()=0
Copy functor to device.
Device functor wrapper class that provides polymorphic interfaces for a functor.
virtual FunctorWrapperDeviceBase * allocate()=0
Allocate device functor and wrapper.
Object * _functor
Pointer to the functor on device.
FunctorWrapperDeviceBase * allocate() override final
Allocate device functor and wrapper.
virtual void freeFunctor()=0
Free host and device copies of functor.
std::unique_ptr< Object > _functor_copy
Copy of the functor on host.
KOKKOS_FUNCTION FunctorWrapperDevice()
Constructor.
FunctorWrapperHost(const void *functor)
Constructor.
KOKKOS_FUNCTION FunctorWrapperDeviceBase()
Constructor.
Base class for device functor wrapper.
void freeFunctor() override final
Free host and device copies of functor.
const Object & _functor_host
Reference of the functor on host.
Host functor wrapper class that allocates a functor on device and creates its device wrapper...