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