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::Kokkos
15 {
16 
17 template <typename Object>
19 
24 {
25 public:
29  KOKKOS_FUNCTION FunctionWrapperDeviceBase() {}
33  KOKKOS_FUNCTION virtual ~FunctionWrapperDeviceBase() {}
34 
38  KOKKOS_FUNCTION virtual Real value(Real t, Real3 p) const = 0;
40  KOKKOS_FUNCTION virtual Real3 vectorValue(Real t, Real3 p) const = 0;
41  KOKKOS_FUNCTION virtual Real3 gradient(Real t, Real3 p) const = 0;
42  KOKKOS_FUNCTION virtual Real3 curl(Real t, Real3 p) const = 0;
43  KOKKOS_FUNCTION virtual Real div(Real t, Real3 p) const = 0;
44  KOKKOS_FUNCTION virtual Real timeDerivative(Real t, Real3 p) const = 0;
45  KOKKOS_FUNCTION virtual Real timeIntegral(Real t1, Real t2, Real3 p) const = 0;
46  KOKKOS_FUNCTION virtual Real integral() const = 0;
47  KOKKOS_FUNCTION virtual Real average() const = 0;
49 };
50 
57 template <typename Object>
59 {
60  friend class FunctionWrapperHost<Object>;
61 
62 public:
66  KOKKOS_FUNCTION FunctionWrapperDevice() {}
67 
68  KOKKOS_FUNCTION Real value(Real t, Real3 p) const override final
69  {
70  return _function->value(t, p);
71  }
72  KOKKOS_FUNCTION Real3 vectorValue(Real t, Real3 p) const override final
73  {
74  return _function->vectorValue(t, p);
75  }
76  KOKKOS_FUNCTION Real3 gradient(Real t, Real3 p) const override final
77  {
78  return _function->gradient(t, p);
79  }
80  KOKKOS_FUNCTION Real3 curl(Real t, Real3 p) const override final { return _function->curl(t, p); }
81  KOKKOS_FUNCTION Real div(Real t, Real3 p) const override final { return _function->div(t, p); }
82  KOKKOS_FUNCTION Real timeDerivative(Real t, Real3 p) const override final
83  {
84  return _function->timeDerivative(t, p);
85  }
86  KOKKOS_FUNCTION Real timeIntegral(Real t1, Real t2, Real3 p) const override final
87  {
88  return _function->timeIntegral(t1, t2, p);
89  }
90  KOKKOS_FUNCTION Real integral() const override final { return _function->integral(); }
91  KOKKOS_FUNCTION Real average() const override final { return _function->average(); }
92 
93 protected:
97  Object * _function = nullptr;
98 };
99 
104 {
105 public:
110 
115  virtual FunctionWrapperDeviceBase * allocate() = 0;
119  virtual void copyFunction() = 0;
123  virtual void freeFunction() = 0;
124 };
125 
132 template <typename Object>
133 class FunctionWrapperHost : public FunctionWrapperHostBase
134 {
135 public:
140  FunctionWrapperHost(const void * function)
141  : _function_host(*static_cast<const Object *>(function))
142  {
143  }
148 
149  FunctionWrapperDeviceBase * allocate() override final;
150  void copyFunction() override final;
151  void freeFunction() override final;
152 
153 private:
157  const Object & _function_host;
161  std::unique_ptr<Object> _function_copy;
165  Object * _function_device = nullptr;
166 };
167 
168 template <typename Object>
171 {
172  // Allocate storage for device wrapper on device
173  auto wrapper_device = static_cast<FunctionWrapperDevice<Object> *>(
174  ::Kokkos::kokkos_malloc<ExecSpace::memory_space>(sizeof(FunctionWrapperDevice<Object>)));
175 
176  // Allocate device wrapper on device using placement new to populate vtable with device pointers
177  ::Kokkos::parallel_for(
178  1, KOKKOS_LAMBDA(const int) { new (wrapper_device) FunctionWrapperDevice<Object>(); });
179 
180  // Allocate storage for function on device
182  static_cast<Object *>(::Kokkos::kokkos_malloc<ExecSpace::memory_space>(sizeof(Object)));
183 
184  // Let device wrapper point to the copy
185  ::Kokkos::Impl::DeepCopy<MemSpace, ::Kokkos::HostSpace>(
186  &(wrapper_device->_function), &_function_device, sizeof(Object *));
187 
188  return wrapper_device;
189 }
190 
191 template <typename Object>
192 void
194 {
195  // Make a copy of function on host to trigger copy constructor
196  _function_copy = std::make_unique<Object>(_function_host);
197 
198  // Copy function to device
199  ::Kokkos::Impl::DeepCopy<MemSpace, ::Kokkos::HostSpace>(
200  _function_device, _function_copy.get(), sizeof(Object));
201 }
202 
203 template <typename Object>
204 void
206 {
207  _function_copy.reset();
208 }
209 
210 template <typename Object>
212 {
213  ::Kokkos::kokkos_free<ExecSpace::memory_space>(_function_device);
214 }
215 
216 } // namespace Moose::Kokkos
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.
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