https://mooseframework.inl.gov
KokkosFunctionWrapper.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
15 {
16 namespace Kokkos
17 {
18 
19 template <typename Object>
21 
26 {
27 public:
31  KOKKOS_FUNCTION FunctionWrapperDeviceBase() {}
35  KOKKOS_FUNCTION virtual ~FunctionWrapperDeviceBase() {}
36 
40  KOKKOS_FUNCTION virtual Real value(Real t, Real3 p) const = 0;
42  KOKKOS_FUNCTION virtual Real3 vectorValue(Real t, Real3 p) const = 0;
43  KOKKOS_FUNCTION virtual Real3 gradient(Real t, Real3 p) const = 0;
44  KOKKOS_FUNCTION virtual Real3 curl(Real t, Real3 p) const = 0;
45  KOKKOS_FUNCTION virtual Real div(Real t, Real3 p) const = 0;
46  KOKKOS_FUNCTION virtual Real timeDerivative(Real t, Real3 p) const = 0;
47  KOKKOS_FUNCTION virtual Real timeIntegral(Real t1, Real t2, Real3 p) const = 0;
48  KOKKOS_FUNCTION virtual Real integral() const = 0;
49  KOKKOS_FUNCTION virtual Real average() const = 0;
51 };
52 
59 template <typename Object>
61 {
62  friend class FunctionWrapperHost<Object>;
63 
64 public:
68  KOKKOS_FUNCTION FunctionWrapperDevice() {}
69 
70  KOKKOS_FUNCTION Real value(Real t, Real3 p) const override final
71  {
72  return _function->value(t, p);
73  }
74  KOKKOS_FUNCTION Real3 vectorValue(Real t, Real3 p) const override final
75  {
76  return _function->vectorValue(t, p);
77  }
78  KOKKOS_FUNCTION Real3 gradient(Real t, Real3 p) const override final
79  {
80  return _function->gradient(t, p);
81  }
82  KOKKOS_FUNCTION Real3 curl(Real t, Real3 p) const override final { return _function->curl(t, p); }
83  KOKKOS_FUNCTION Real div(Real t, Real3 p) const override final { return _function->div(t, p); }
84  KOKKOS_FUNCTION Real timeDerivative(Real t, Real3 p) const override final
85  {
86  return _function->timeDerivative(t, p);
87  }
88  KOKKOS_FUNCTION Real timeIntegral(Real t1, Real t2, Real3 p) const override final
89  {
90  return _function->timeIntegral(t1, t2, p);
91  }
92  KOKKOS_FUNCTION Real integral() const override final { return _function->integral(); }
93  KOKKOS_FUNCTION Real average() const override final { return _function->average(); }
94 
95 protected:
99  Object * _function = nullptr;
100 };
101 
106 {
107 public:
112 
117  virtual FunctionWrapperDeviceBase * allocate() = 0;
121  virtual void copyFunction() = 0;
125  virtual void freeFunction() = 0;
126 };
127 
134 template <typename Object>
135 class FunctionWrapperHost : public FunctionWrapperHostBase
136 {
137 public:
142  FunctionWrapperHost(const void * function)
143  : _function_host(*static_cast<const Object *>(function))
144  {
145  }
150 
151  FunctionWrapperDeviceBase * allocate() override final;
152  void copyFunction() override final;
153  void freeFunction() override final;
154 
155 private:
159  const Object & _function_host;
163  std::unique_ptr<Object> _function_copy;
167  Object * _function_device = nullptr;
168 };
169 
170 template <typename Object>
173 {
174  // Allocate storage for device wrapper on device
175  auto wrapper_device = static_cast<FunctionWrapperDevice<Object> *>(
176  ::Kokkos::kokkos_malloc<ExecSpace::memory_space>(sizeof(FunctionWrapperDevice<Object>)));
177 
178  // Allocate device wrapper on device using placement new to populate vtable with device pointers
179  ::Kokkos::parallel_for(
180  1, KOKKOS_LAMBDA(const int) { new (wrapper_device) FunctionWrapperDevice<Object>(); });
181 
182  // Allocate storage for function on device
184  static_cast<Object *>(::Kokkos::kokkos_malloc<ExecSpace::memory_space>(sizeof(Object)));
185 
186  // Let device wrapper point to the copy
187  ::Kokkos::Impl::DeepCopy<MemSpace, ::Kokkos::HostSpace>(
188  &(wrapper_device->_function), &_function_device, sizeof(Object *));
189 
190  return wrapper_device;
191 }
192 
193 template <typename Object>
194 void
196 {
197  // Make a copy of function on host to trigger copy constructor
198  _function_copy = std::make_unique<Object>(_function_host);
199 
200  // Copy function to device
201  ::Kokkos::Impl::DeepCopy<MemSpace, ::Kokkos::HostSpace>(
202  _function_device, _function_copy.get(), sizeof(Object));
203 }
204 
205 template <typename Object>
206 void
208 {
209  _function_copy.reset();
210 }
211 
212 template <typename Object>
214 {
215  ::Kokkos::kokkos_free<ExecSpace::memory_space>(_function_device);
216 }
217 
218 } // namespace Kokkos
219 } // namespace Moose
Device function wrapper class that provides polymorphic interfaces for a function.
KOKKOS_FUNCTION Real value(Real t, Real3 p) const override final
Virtual shims that calls the corresponding methods of the actual stored function. ...
Base class for device function wrapper.
const Object & _function_host
Reference of the function on host.
virtual KOKKOS_FUNCTION Real timeIntegral(Real t1, Real t2, Real3 p) const =0
std::unique_ptr< Object > _function_copy
Copy of the function on host.
virtual KOKKOS_FUNCTION Real3 gradient(Real t, Real3 p) const =0
virtual FunctionWrapperDeviceBase * allocate()=0
Allocate device function and wrapper.
KOKKOS_FUNCTION Real3 curl(Real t, Real3 p) const override final
Object * _function_device
Copy of the function on device.
virtual void copyFunction()=0
Copy function to device.
void freeFunction() override final
Free host and device copies of function.
virtual KOKKOS_FUNCTION Real3 vectorValue(Real t, Real3 p) const =0
KOKKOS_FUNCTION Real average() const override final
virtual KOKKOS_FUNCTION Real integral() const =0
KOKKOS_FUNCTION Real3 gradient(Real t, Real3 p) const override final
KOKKOS_FUNCTION FunctionWrapperDevice()
Constructor.
virtual KOKKOS_FUNCTION Real average() const =0
virtual void freeFunction()=0
Free host and device copies of function.
FunctionWrapperDeviceBase * allocate() override final
Allocate device function and wrapper.
virtual KOKKOS_FUNCTION Real timeDerivative(Real t, Real3 p) const =0
Host function wrapper class that allocates a function on device and creates its device wrapper...
virtual KOKKOS_FUNCTION Real div(Real t, Real3 p) const =0
KOKKOS_FUNCTION Real timeIntegral(Real t1, Real t2, Real3 p) const override final
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
FunctionWrapperHost(const void *function)
Constructor.
KOKKOS_FUNCTION Real timeDerivative(Real t, Real3 p) const override final
KOKKOS_FUNCTION Real integral() const override final
Object * _function
Pointer to the function on device.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
KOKKOS_FUNCTION FunctionWrapperDeviceBase()
Constructor.
virtual KOKKOS_FUNCTION Real value(Real t, Real3 p) const =0
Virtual shims that calls the corresponding methods of the actual stored function. ...
KOKKOS_FUNCTION Real3 vectorValue(Real t, Real3 p) const override final
virtual KOKKOS_FUNCTION Real3 curl(Real t, Real3 p) const =0
Base class for host function wrapper.
virtual ~FunctionWrapperHostBase()
Virtual destructor.
void copyFunction() override final
Copy function to device.
virtual KOKKOS_FUNCTION ~FunctionWrapperDeviceBase()
Virtual destructor.
KOKKOS_FUNCTION Real div(Real t, Real3 p) const override final