Ginkgo Generated from develop branch based on develop. 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
80template <typename T>
81struct temporary_clone_helper {
82 static std::unique_ptr<T> create(std::shared_ptr<const Executor> exec,
83 T* ptr, bool)
84 {
85 return gko::clone(std::move(exec), ptr);
86 }
87};
88
89
101template <typename T>
102class temporary_clone {
103public:
104 using value_type = T;
105 using pointer = T*;
106
115 explicit temporary_clone(std::shared_ptr<const Executor> exec,
116 ptr_param<T> ptr, bool copy_data = true)
117 {
118 if (ptr->get_executor()->memory_accessible(exec)) {
119 // just use the object we already have
120 handle_ = handle_type(ptr.get(), null_deleter<T>());
121 } else {
122 // clone the object to the new executor and make sure it's copied
123 // back before we delete it
124 handle_ = handle_type(temporary_clone_helper<T>::create(
125 std::move(exec), ptr.get(), copy_data)
126 .release(),
127 copy_back_deleter<T>(ptr.get()));
128 }
129 }
130
136 T* get() const { return handle_.get(); }
137
143 T* operator->() const { return handle_.get(); }
144
150 T& operator*() const { return *handle_; }
151
152private:
153 // std::function deleter allows to decide the (type of) deleter at runtime
154 using handle_type = std::unique_ptr<T, std::function<void(T*)>>;
155
156 handle_type handle_;
157};
158
159
160} // namespace detail
161
162
163template <typename T>
164struct err {};
165
178template <typename Ptr>
179detail::temporary_clone<detail::pointee<Ptr>> make_temporary_clone(
180 std::shared_ptr<const Executor> exec, Ptr&& ptr)
181{
182 using T = detail::pointee<Ptr>;
183 return detail::temporary_clone<T>(std::move(exec), std::forward<Ptr>(ptr));
184}
185
186
201template <typename Ptr>
202detail::temporary_clone<detail::pointee<Ptr>> make_temporary_output_clone(
203 std::shared_ptr<const Executor> exec, Ptr&& ptr)
204{
205 using T = detail::pointee<Ptr>;
206 static_assert(
207 !std::is_const<T>::value,
208 "make_temporary_output_clone should only be used on non-const objects");
209 return detail::temporary_clone<T>(std::move(exec), std::forward<Ptr>(ptr),
210 false);
211}
212
213
214} // namespace gko
215
216
217#endif // GKO_PUBLIC_CORE_BASE_TEMPORARY_CLONE_HPP_
The Ginkgo namespace.
Definition abstract_factory.hpp:20
constexpr T one()
Returns the multiplicative identity for T.
Definition math.hpp:775
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:202
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:179
Definition temporary_clone.hpp:164