Ginkgo  Generated from tags/v1.0.0^0 branch based on master. Ginkgo version 1.0.0
A numerical linear algebra library targeting many-core architectures
array.hpp
1 /*******************************<GINKGO LICENSE>******************************
2 Copyright (c) 2017-2019, the Ginkgo authors
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 
16 3. Neither the name of the copyright holder nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 ******************************<GINKGO LICENSE>*******************************/
32 
33 #ifndef GKO_CORE_BASE_ARRAY_H_
34 #define GKO_CORE_BASE_ARRAY_H_
35 
36 
37 #include <memory>
38 #include <utility>
39 
40 
41 #include <ginkgo/core/base/exception.hpp>
42 #include <ginkgo/core/base/executor.hpp>
43 #include <ginkgo/core/base/types.hpp>
44 #include <ginkgo/core/base/utils.hpp>
45 
46 
47 namespace gko {
48 
49 
62 template <typename ValueType>
63 class Array {
64 public:
68  using value_type = ValueType;
69 
74 
79 
93  Array() noexcept
94  : num_elems_(0),
95  data_(nullptr, default_deleter{nullptr}),
96  exec_(nullptr)
97  {}
98 
104  Array(std::shared_ptr<const Executor> exec) noexcept
105  : num_elems_(0),
106  data_(nullptr, default_deleter{exec}),
107  exec_(std::move(exec))
108  {}
109 
117  Array(std::shared_ptr<const Executor> exec, size_type num_elems)
118  : num_elems_(num_elems),
119  data_(nullptr, default_deleter{exec}),
120  exec_(std::move(exec))
121  {
122  if (num_elems > 0) {
123  data_.reset(exec_->alloc<value_type>(num_elems));
124  }
125  }
126 
145  template <typename DeleterType>
146  Array(std::shared_ptr<const Executor> exec, size_type num_elems,
147  value_type *data, DeleterType deleter)
148  : num_elems_{num_elems}, data_(data, deleter), exec_{exec}
149  {}
150 
161  Array(std::shared_ptr<const Executor> exec, size_type num_elems,
162  value_type *data)
163  : Array(exec, num_elems, data, default_deleter{exec})
164  {}
165 
176  template <typename RandomAccessIterator>
177  Array(std::shared_ptr<const Executor> exec, RandomAccessIterator begin,
178  RandomAccessIterator end)
179  : Array(exec)
180  {
181  Array tmp(exec->get_master(), end - begin);
182  int i = 0;
183  for (auto it = begin; it != end; ++it, ++i) {
184  tmp.data_[i] = *it;
185  }
186  *this = std::move(tmp);
187  }
188 
199  template <typename T>
200  Array(std::shared_ptr<const Executor> exec,
201  std::initializer_list<T> init_list)
202  : Array(exec, begin(init_list), end(init_list))
203  {}
204 
214  Array(std::shared_ptr<const Executor> exec, const Array &other)
215  : Array(exec)
216  {
217  *this = other;
218  }
219 
228  Array(const Array &other) : Array(other.get_executor(), other) {}
229 
239  Array(std::shared_ptr<const Executor> exec, Array &&other) : Array(exec)
240  {
241  *this = std::move(other);
242  }
243 
252  Array(Array &&other) : Array(other.get_executor(), std::move(other)) {}
253 
266  static Array view(std::shared_ptr<const Executor> exec, size_type num_elems,
267  value_type *data)
268  {
269  return Array{exec, num_elems, data, view_deleter{}};
270  }
271 
285  Array &operator=(const Array &other)
286  {
287  if (&other == this) {
288  return *this;
289  }
290  if (exec_ == nullptr) {
291  exec_ = other.get_executor();
292  data_ = data_manager{nullptr, other.data_.get_deleter()};
293  }
294  if (other.get_executor() == nullptr) {
295  this->resize_and_reset(0);
296  return *this;
297  }
298  this->resize_and_reset(other.get_num_elems());
299  exec_->copy_from(other.get_executor().get(), num_elems_,
300  other.get_const_data(), this->get_data());
301  return *this;
302  }
303 
318  {
319  if (&other == this) {
320  return *this;
321  }
322  if (exec_ == nullptr) {
323  exec_ = other.get_executor();
324  data_ = data_manager{nullptr, other.data_.get_deleter()};
325  }
326  if (other.get_executor() == nullptr) {
327  this->resize_and_reset(0);
328  return *this;
329  }
330  if (exec_ == other.get_executor() &&
331  data_.get_deleter().target_type() != typeid(view_deleter)) {
332  // same device and not a view, only move the pointer
333  using std::swap;
334  swap(data_, other.data_);
335  swap(num_elems_, other.num_elems_);
336  } else {
337  // different device or a view, copy the data
338  *this = other;
339  }
340  return *this;
341  }
342 
350  void clear() noexcept
351  {
352  num_elems_ = 0;
353  data_.reset(nullptr);
354  }
355 
366  void resize_and_reset(size_type num_elems)
367  {
368  if (num_elems == num_elems_) {
369  return;
370  }
371  if (exec_ == nullptr) {
372  throw gko::NotSupported(__FILE__, __LINE__, __func__,
373  "gko::Executor (nullptr)");
374  }
375  num_elems_ = num_elems;
376  if (num_elems > 0) {
377  data_.reset(exec_->alloc<value_type>(num_elems));
378  } else {
379  data_.reset(nullptr);
380  }
381  }
382 
388  size_type get_num_elems() const noexcept { return num_elems_; }
389 
397  value_type *get_data() noexcept { return data_.get(); }
398 
406  const value_type *get_const_data() const noexcept { return data_.get(); }
407 
413  std::shared_ptr<const Executor> get_executor() const noexcept
414  {
415  return exec_;
416  }
417 
424  void set_executor(std::shared_ptr<const Executor> exec)
425  {
426  if (exec == exec_) {
427  // moving to the same executor, no-op
428  return;
429  }
430  Array tmp(std::move(exec));
431  tmp = *this;
432  exec_ = std::move(tmp.exec_);
433  data_ = std::move(tmp.data_);
434  }
435 
436 private:
437  using data_manager =
438  std::unique_ptr<value_type[], std::function<void(value_type[])>>;
439 
440  size_type num_elems_;
441  data_manager data_;
442  std::shared_ptr<const Executor> exec_;
443 };
444 
445 
446 } // namespace gko
447 
448 
449 #endif // GKO_CORE_BASE_ARRAY_H_
size_type get_num_elems() const noexcept
Returns the number of elements in the Array.
Definition: array.hpp:388
Array(std::shared_ptr< const Executor > exec, const Array &other)
Creates a copy of another array on a different executor.
Definition: array.hpp:214
null_deleter< value_type[]> view_deleter
The deleter type used for views.
Definition: array.hpp:78
Array & operator=(const Array &other)
Copies data from another array.
Definition: array.hpp:285
STL namespace.
Array(std::shared_ptr< const Executor > exec, Array &&other)
Moves another array to a different executor.
Definition: array.hpp:239
This is a deleter that uses an executor&#39;s free method to deallocate the data.
Definition: executor.hpp:628
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:94
Array & operator=(Array &&other)
Moves data from another array.
Definition: array.hpp:317
std::shared_ptr< const Executor > get_executor() const noexcept
Returns the Executor associated with the array.
Definition: array.hpp:413
const value_type * get_const_data() const noexcept
Returns a constant pointer to the block of memory used to store the elements of the Array...
Definition: array.hpp:406
The Ginkgo namespace.
Definition: abstract_factory.hpp:45
index_type value_type
The type of elements stored in the array.
Definition: array.hpp:68
Array(std::shared_ptr< const Executor > exec, size_type num_elems, value_type *data)
Creates an Array from existing memory.
Definition: array.hpp:161
Array() noexcept
Creates an empty Array not tied to any executor.
Definition: array.hpp:93
Array(Array &&other)
Moves another array.
Definition: array.hpp:252
Array(std::shared_ptr< const Executor > exec, RandomAccessIterator begin, RandomAccessIterator end)
Creates an array on the specified Executor and initializes it with values.
Definition: array.hpp:177
Array(std::shared_ptr< const Executor > exec, size_type num_elems)
Creates an Array on the specified Executor.
Definition: array.hpp:117
This is a deleter that does not delete the object.
Definition: utils.hpp:325
An Array is a container which encapsulates fixed-sized arrays, stored on the Executor tied to the Arr...
Definition: array.hpp:63
void resize_and_reset(size_type num_elems)
Resizes the array so it is able to hold the specified number of elements.
Definition: array.hpp:366
Array(std::shared_ptr< const Executor > exec) noexcept
Creates an empty Array tied to the specified Executor.
Definition: array.hpp:104
Array(std::shared_ptr< const Executor > exec, std::initializer_list< T > init_list)
Creates an array on the specified Executor and initializes it with values.
Definition: array.hpp:200
Array(const Array &other)
Creates a copy of another array.
Definition: array.hpp:228
value_type * get_data() noexcept
Returns a pointer to the block of memory used to store the elements of the Array. ...
Definition: array.hpp:397
Array(std::shared_ptr< const Executor > exec, size_type num_elems, value_type *data, DeleterType deleter)
Creates an Array from existing memory.
Definition: array.hpp:146
void clear() noexcept
Deallocates all data used by the Array.
Definition: array.hpp:350
NotSupported is thrown in case it is not possible to perform the requested operation on the given obj...
Definition: exception.hpp:153
void set_executor(std::shared_ptr< const Executor > exec)
Changes the Executor of the Array, moving the allocated data to the new Executor. ...
Definition: array.hpp:424
static Array view(std::shared_ptr< const Executor > exec, size_type num_elems, value_type *data)
Creates an Array from existing memory.
Definition: array.hpp:266