Ginkgo Generated from branch based on master. Ginkgo version 1.7.0
A numerical linear algebra library targeting many-core architectures
Loading...
Searching...
No Matches
workspace.hpp
1/*******************************<GINKGO LICENSE>******************************
2Copyright (c) 2017-2023, the Ginkgo authors
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions
7are met:
8
91. Redistributions of source code must retain the above copyright
10notice, this list of conditions and the following disclaimer.
11
122. Redistributions in binary form must reproduce the above copyright
13notice, this list of conditions and the following disclaimer in the
14documentation and/or other materials provided with the distribution.
15
163. Neither the name of the copyright holder nor the names of its
17contributors may be used to endorse or promote products derived from
18this software without specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31******************************<GINKGO LICENSE>*******************************/
32
33#ifndef GKO_PUBLIC_CORE_SOLVER_WORKSPACE_HPP_
34#define GKO_PUBLIC_CORE_SOLVER_WORKSPACE_HPP_
35
36
37#include <typeinfo>
38
39
40#include <ginkgo/core/matrix/dense.hpp>
41
42
43namespace gko {
44namespace solver {
45namespace detail {
46
47
51class any_array {
52public:
53 template <typename ValueType>
54 array<ValueType>& init(std::shared_ptr<const Executor> exec, size_type size)
55 {
56 auto container = std::make_unique<concrete_container<ValueType>>(
57 std::move(exec), size);
58 auto& arr = container->arr;
59 data_ = std::move(container);
60 return arr;
61 }
62
63 bool empty() const { return data_.get() == nullptr; }
64
65 template <typename ValueType>
66 bool contains() const
67 {
68 return dynamic_cast<const concrete_container<ValueType>*>(data_.get());
69 }
70
71 template <typename ValueType>
72 array<ValueType>& get()
73 {
74 GKO_ASSERT(this->template contains<ValueType>());
75 return dynamic_cast<concrete_container<ValueType>*>(data_.get())->arr;
76 }
77
78 template <typename ValueType>
79 const array<ValueType>& get() const
80 {
81 GKO_ASSERT(this->template contains<ValueType>());
82 return dynamic_cast<const concrete_container<ValueType>*>(data_.get())
83 ->arr;
84 }
85
86 void clear() { data_.reset(); }
87
88private:
89 struct generic_container {
90 virtual ~generic_container() = default;
91 };
92
93 template <typename ValueType>
94 struct concrete_container : generic_container {
95 template <typename... Args>
96 concrete_container(Args&&... args) : arr{std::forward<Args>(args)...}
97 {}
98
100 };
101
102 std::unique_ptr<generic_container> data_;
103};
104
105
106class workspace {
107public:
108 workspace(std::shared_ptr<const Executor> exec) : exec_{std::move(exec)} {}
109
110 workspace(const workspace& other) : workspace{other.get_executor()} {}
111
112 workspace(workspace&& other) : workspace{other.get_executor()}
113 {
114 other.clear();
115 }
116
117 workspace& operator=(const workspace& other) { return *this; }
118
119 workspace& operator=(workspace&& other)
120 {
121 other.clear();
122 return *this;
123 }
124
125 template <typename LinOpType, typename CreateOperation>
126 LinOpType* create_or_get_op(int op_id, CreateOperation create,
127 const std::type_info& expected_type,
128 dim<2> size, size_type stride)
129 {
130 GKO_ASSERT(op_id >= 0 && op_id < operators_.size());
131 // does the existing object have the wrong type?
132 // vector types may vary e.g. if users derive from Dense
133 auto stored_op = operators_[op_id].get();
134 LinOpType* op{};
135 if (!stored_op || typeid(*stored_op) != expected_type) {
136 auto new_op = create();
137 op = new_op.get();
138 operators_[op_id] = std::move(new_op);
139 return op;
140 }
141 // does the existing object have the wrong dimensions?
142 op = dynamic_cast<LinOpType*>(operators_[op_id].get());
143 GKO_ASSERT(op);
144 if (op->get_size() != size || op->get_stride() != stride) {
145 auto new_op = create();
146 op = new_op.get();
147 operators_[op_id] = std::move(new_op);
148 }
149 return op;
150 }
151
152 const LinOp* get_op(int op_id) const
153 {
154 GKO_ASSERT(op_id >= 0 && op_id < operators_.size());
155 return operators_[op_id].get();
156 }
157
158 template <typename ValueType>
159 array<ValueType>& init_or_get_array(int array_id)
160 {
161 GKO_ASSERT(array_id >= 0 && array_id < arrays_.size());
162 auto& array = arrays_[array_id];
163 if (array.empty()) {
164 auto& result =
165 array.template init<ValueType>(this->get_executor(), 0);
166 return result;
167 }
168 // array types should not change!
169 GKO_ASSERT(array.template contains<ValueType>());
170 return array.template get<ValueType>();
171 }
172
173 template <typename ValueType>
174 array<ValueType>& create_or_get_array(int array_id, size_type size)
175 {
177 if (result.get_num_elems() != size) {
178 result.resize_and_reset(size);
179 }
180 return result;
181 }
182
183 std::shared_ptr<const Executor> get_executor() const { return exec_; }
184
185 void set_size(int num_operators, int num_arrays)
186 {
187 operators_.resize(num_operators);
188 arrays_.resize(num_arrays);
189 }
190
191 void clear()
192 {
193 for (auto& op : operators_) {
194 op.reset();
195 }
196 for (auto& array : arrays_) {
197 array.clear();
198 }
199 }
200
201private:
202 std::shared_ptr<const Executor> exec_;
203 std::vector<std::unique_ptr<LinOp>> operators_;
204 std::vector<any_array> arrays_;
205};
206
207
208} // namespace detail
209} // namespace solver
210} // namespace gko
211
212#endif // GKO_PUBLIC_CORE_SOLVER_WORKSPACE_HPP_
The Ginkgo namespace.
Definition abstract_factory.hpp:48
constexpr T one()
Returns the multiplicative identity for T.
Definition math.hpp:803
std::size_t size_type
Integral type used for allocation quantities.
Definition types.hpp:120
@ array
The matrix should be written as dense matrix in column-major order.