Ginkgo Generated from branch based on master. Ginkgo version 1.8.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
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
19namespace gko {
20namespace detail {
21
22
37template <typename T>
38class copy_back_deleter {
39public:
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
61private:
62 pointer original_;
63};
64
65// specialization for constant objects, no need to copy back something that
66// cannot change
67template <typename T>
68class copy_back_deleter<const T> {
69public:
70 using pointer = const T*;
71 copy_back_deleter(pointer original) : original_{original} {}
72
73 void operator()(pointer ptr) const { delete ptr; }
74
75private:
76 pointer original_;
77};
78
79
80// specialization for copy back via assignment
81template <typename T>
82class copy_back_deleter_from_assignment {
83public:
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
105private:
106 pointer original_;
107};
108
109
110template <typename T>
111struct 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
131template <typename T>
132class temporary_clone {
133public:
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
182private:
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
193template <typename T>
194struct err {};
195
208template <typename Ptr>
209detail::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
231template <typename Ptr>
232detail::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_
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:232
detail::cloned_type< Pointer > clone(const Pointer &p)
Creates a unique clone of the object pointed to by p.
Definition utils_helper.hpp:175
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
Definition temporary_clone.hpp:194