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
15 {
16 namespace Kokkos
17 {
18 
19 template <typename Object>
21 
26 {
27 public:
31  KOKKOS_FUNCTION FunctorWrapperDeviceBase() {}
35  KOKKOS_FUNCTION virtual ~FunctorWrapperDeviceBase() {}
36 };
37 
44 template <typename Object>
46 {
47  friend class FunctorWrapperHost<Object>;
48 
49 public:
53  KOKKOS_FUNCTION FunctorWrapperDevice() {}
54 
55 protected:
59  Object * _functor = nullptr;
60 };
61 
66 {
67 public:
72 
77  virtual FunctorWrapperDeviceBase * allocate() = 0;
81  virtual void copyFunctor() = 0;
85  virtual void freeFunctor() = 0;
86 };
87 
94 template <typename Object>
95 class FunctorWrapperHost : public FunctorWrapperHostBase
96 {
97 public:
102  FunctorWrapperHost(const void * functor) : _functor_host(*static_cast<const Object *>(functor)) {}
107 
108  FunctorWrapperDeviceBase * allocate() override final;
109  void copyFunctor() override final;
110  void freeFunctor() override final;
111 
112 private:
116  const Object & _functor_host;
120  std::unique_ptr<Object> _functor_copy;
124  Object * _functor_device = nullptr;
125 };
126 
127 template <typename Object>
130 {
131  // Allocate storage for device wrapper on device
132  auto wrapper_device = static_cast<FunctorWrapperDevice<Object> *>(
133  ::Kokkos::kokkos_malloc<ExecSpace::memory_space>(sizeof(FunctorWrapperDevice<Object>)));
134 
135  // Allocate device wrapper on device using placement new to populate vtable with device pointers
136  ::Kokkos::parallel_for(
137  1, KOKKOS_LAMBDA(const int) { new (wrapper_device) FunctorWrapperDevice<Object>(); });
138 
139  // Allocate storage for functor on device
141  static_cast<Object *>(::Kokkos::kokkos_malloc<ExecSpace::memory_space>(sizeof(Object)));
142 
143  // Let device wrapper point to the copy
144  ::Kokkos::Impl::DeepCopy<MemSpace, ::Kokkos::HostSpace>(
145  &(wrapper_device->_functor), &_functor_device, sizeof(Object *));
146 
147  return wrapper_device;
148 }
149 
150 template <typename Object>
151 void
153 {
154  // Make a copy of functor on host to trigger copy constructor
155  _functor_copy = std::make_unique<Object>(_functor_host);
156 
157  // Copy functor to device
158  ::Kokkos::Impl::DeepCopy<MemSpace, ::Kokkos::HostSpace>(
159  _functor_device, _functor_copy.get(), sizeof(Object));
160 }
161 
162 template <typename Object>
163 void
165 {
166  _functor_copy.reset();
167 }
168 
169 template <typename Object>
171 {
172  ::Kokkos::kokkos_free<ExecSpace::memory_space>(_functor_device);
173 }
174 
175 } // namespace Kokkos
176 } // namespace Moose
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.
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
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...