Ginkgo  Generated from pipelines/1330831941 branch based on master. Ginkgo version 1.8.0
A numerical linear algebra library targeting many-core architectures
temporary_clone.hpp
1 // SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 #ifndef GKO_PUBLIC_CORE_BASE_TEMPORARY_CLONE_HPP_
6 #define GKO_PUBLIC_CORE_BASE_TEMPORARY_CLONE_HPP_
7 
8 
9 #include <functional>
10 #include <memory>
11 #include <type_traits>
12 
13 
14 #include <ginkgo/core/base/exception_helpers.hpp>
15 #include <ginkgo/core/base/executor.hpp>
16 #include <ginkgo/core/base/utils_helper.hpp>
17 
18 
19 namespace gko {
20 namespace detail {
21 
22 
37 template <typename T>
38 class copy_back_deleter {
39 public:
40  using pointer = T*;
41 
48  copy_back_deleter(pointer original) : original_{original} {}
49 
55  void operator()(pointer ptr) const
56  {
57  original_->copy_from(ptr);
58  delete ptr;
59  }
60 
61 private:
62  pointer original_;
63 };
64 
65 // specialization for constant objects, no need to copy back something that
66 // cannot change
67 template <typename T>
68 class copy_back_deleter<const T> {
69 public:
70  using pointer = const T*;
71  copy_back_deleter(pointer original) : original_{original} {}
72 
73  void operator()(pointer ptr) const { delete ptr; }
74 
75 private:
76  pointer original_;
77 };
78 
79 
80 // specialization for copy back via assignment
81 template <typename T>
82 class copy_back_deleter_from_assignment {
83 public:
84  using pointer = T*;
85 
92  copy_back_deleter_from_assignment(pointer original) : original_{original} {}
93 
99  void operator()(pointer ptr) const
100  {
101  *original_ = *ptr;
102  delete ptr;
103  }
104 
105 private:
106  pointer original_;
107 };
108 
109 
110 template <typename T>
111 struct temporary_clone_helper {
112  static std::unique_ptr<T> create(std::shared_ptr<const Executor> exec,
113  T* ptr, bool)
114  {
115  return gko::clone(std::move(exec), ptr);
116  }
117 };
118 
119 
131 template <typename T>
132 class temporary_clone {
133 public:
134  using value_type = T;
135  using pointer = T*;
136 
145  explicit temporary_clone(std::shared_ptr<const Executor> exec,
146  ptr_param<T> ptr, bool copy_data = true)
147  {
148  if (ptr->get_executor()->memory_accessible(exec)) {
149  // just use the object we already have
150  handle_ = handle_type(ptr.get(), null_deleter<T>());
151  } else {
152  // clone the object to the new executor and make sure it's copied
153  // back before we delete it
154  handle_ = handle_type(temporary_clone_helper<T>::create(
155  std::move(exec), ptr.get(), copy_data)
156  .release(),
157  copy_back_deleter<T>(ptr.get()));
158  }
159  }
160 
166  T* get() const { return handle_.get(); }
167 
173  T* operator->() const { return handle_.get(); }
174 
180  T& operator*() const { return *handle_; }
181 
182 private:
183  // std::function deleter allows to decide the (type of) deleter at runtime
184  using handle_type = std::unique_ptr<T, std::function<void(T*)>>;
185 
186  handle_type handle_;
187 };
188 
189 
190 } // namespace detail
191 
192 
193 template <typename T>
194 struct err {};
195 
208 template <typename Ptr>
209 detail::temporary_clone<detail::pointee<Ptr>> make_temporary_clone(
210  std::shared_ptr<const Executor> exec, Ptr&& ptr)
211 {
212  using T = detail::pointee<Ptr>;
213  return detail::temporary_clone<T>(std::move(exec), std::forward<Ptr>(ptr));
214 }
215 
216 
231 template <typename Ptr>
232 detail::temporary_clone<detail::pointee<Ptr>> make_temporary_output_clone(
233  std::shared_ptr<const Executor> exec, Ptr&& ptr)
234 {
235  using T = detail::pointee<Ptr>;
236  static_assert(
237  !std::is_const<T>::value,
238  "make_temporary_output_clone should only be used on non-const objects");
239  return detail::temporary_clone<T>(std::move(exec), std::forward<Ptr>(ptr),
240  false);
241 }
242 
243 
244 } // namespace gko
245 
246 
247 #endif // GKO_PUBLIC_CORE_BASE_TEMPORARY_CLONE_HPP_
gko::make_temporary_output_clone
detail::temporary_clone< detail::pointee< Ptr > > make_temporary_output_clone(std::shared_ptr< const Executor > exec, Ptr &&ptr)
Creates a uninitialized temporary_clone that will be copied back to the input afterwards.
Definition: temporary_clone.hpp:232
gko::clone
detail::cloned_type< Pointer > clone(const Pointer &p)
Creates a unique clone of the object pointed to by p.
Definition: utils_helper.hpp:175
gko
The Ginkgo namespace.
Definition: abstract_factory.hpp:20
gko::err
Definition: temporary_clone.hpp:194
gko::make_temporary_clone
detail::temporary_clone< detail::pointee< Ptr > > make_temporary_clone(std::shared_ptr< const Executor > exec, Ptr &&ptr)
Creates a temporary_clone.
Definition: temporary_clone.hpp:209