5 #ifndef GKO_PUBLIC_CORE_BASE_ARRAY_HPP_
6 #define GKO_PUBLIC_CORE_BASE_ARRAY_HPP_
12 #include <type_traits>
15 #include <ginkgo/core/base/exception.hpp>
16 #include <ginkgo/core/base/exception_helpers.hpp>
17 #include <ginkgo/core/base/executor.hpp>
18 #include <ginkgo/core/base/types.hpp>
19 #include <ginkgo/core/base/utils.hpp>
25 template <
typename ValueType>
38 template <
typename SourceType,
typename TargetType>
39 void convert_data(std::shared_ptr<const Executor> exec,
size_type size,
40 const SourceType* src, TargetType* dst);
52 template <
typename ValueType>
53 class const_array_view {
67 const_array_view(std::shared_ptr<const Executor> exec,
size_type size,
68 const ValueType* data)
69 : exec_{std::move(exec)}, size_{size}, data_{data}
76 const_array_view& operator=(
const const_array_view&) =
delete;
77 const_array_view& operator=(const_array_view&&) =
delete;
78 const_array_view(
const const_array_view&) =
delete;
83 const_array_view(const_array_view&& other)
84 : const_array_view{other.exec_, other.size_, other.data_}
87 other.data_ =
nullptr;
95 size_type get_size() const noexcept {
return size_; }
102 GKO_DEPRECATED(
"use get_size() instead")
103 size_type get_num_elems() const noexcept {
return get_size(); }
110 const value_type* get_const_data() const noexcept {
return data_; }
117 std::shared_ptr<const Executor> get_executor() const noexcept
125 bool is_owning() const noexcept {
return false; }
132 array<ValueType> copy_to_array()
const;
135 std::shared_ptr<const Executor> exec_;
137 const ValueType* data_;
141 template <
typename ValueType>
142 using ConstArrayView GKO_DEPRECATED(
"please use const_array_view") =
143 const_array_view<ValueType>;
146 template <
typename ValueType>
147 array<ValueType> array_const_cast(const_array_view<ValueType> view);
164 template <
typename ValueType>
204 explicit array(std::shared_ptr<const Executor> exec) noexcept
207 exec_(std::move(exec))
220 exec_(std::move(exec))
245 template <
typename DeleterType>
248 : size_{size}, data_(data, deleter), exec_{exec}
276 template <
typename RandomAccessIterator>
277 array(std::shared_ptr<const Executor> exec, RandomAccessIterator begin,
278 RandomAccessIterator end)
281 array tmp(exec->get_master(), std::distance(begin, end));
282 std::copy(begin, end, tmp.data_.get());
283 *
this = std::move(tmp);
296 template <
typename T>
297 array(std::shared_ptr<const Executor> exec,
298 std::initializer_list<T> init_list)
299 :
array(exec, begin(init_list), end(init_list))
311 array(std::shared_ptr<const Executor> exec,
const array& other)
338 *
this = std::move(other);
384 std::shared_ptr<const Executor> exec,
size_type size,
387 return {exec, size, data};
427 if (&other ==
this) {
430 if (exec_ ==
nullptr) {
431 exec_ = other.get_executor();
432 data_ = data_manager{
nullptr, other.data_.get_deleter()};
434 if (other.get_executor() ==
nullptr) {
442 GKO_ENSURE_COMPATIBLE_BOUNDS(other.get_size(), this->
get_size());
444 exec_->copy_from(other.get_executor(), other.get_size(),
445 other.get_const_data(), this->
get_data());
480 if (&other ==
this) {
483 if (exec_ ==
nullptr) {
484 exec_ = other.get_executor();
487 if (other.get_executor() ==
nullptr) {
491 if (exec_ == other.get_executor()) {
493 data_ = std::exchange(
494 other.data_, data_manager{nullptr, default_deleter{exec_}});
495 size_ = std::exchange(other.size_, 0);
521 template <
typename OtherValueType>
522 std::enable_if_t<!std::is_same<ValueType, OtherValueType>::value,
array>&
525 if (this->exec_ ==
nullptr) {
526 this->exec_ = other.get_executor();
529 if (other.get_executor() ==
nullptr) {
534 if (this->is_owning()) {
535 this->resize_and_reset(other.get_size());
537 GKO_ENSURE_COMPATIBLE_BOUNDS(other.get_size(), this->get_size());
540 const OtherValueType* source = other.get_const_data();
542 if (this->exec_ != other.get_executor()) {
544 source = tmp.get_const_data();
546 detail::convert_data(this->exec_, other.get_size(), source,
570 if (this->exec_ ==
nullptr) {
571 this->exec_ = other.get_executor();
574 if (other.get_executor() ==
nullptr) {
579 if (this->is_owning()) {
580 this->resize_and_reset(other.get_size());
582 GKO_ENSURE_COMPATIBLE_BOUNDS(other.get_size(), this->get_size());
584 array tmp{this->exec_};
585 const ValueType* source = other.get_const_data();
587 if (this->exec_ != other.get_executor()) {
588 tmp = other.copy_to_array();
589 source = tmp.get_const_data();
591 exec_->copy_from(other.get_executor(), other.get_size(), source,
606 data_.reset(
nullptr);
626 if (exec_ ==
nullptr) {
628 "gko::Executor (nullptr)");
630 if (!this->is_owning()) {
632 "Non owning gko::array cannot be resized.");
635 if (size > 0 && this->is_owning()) {
650 std::vector<value_type> result(this->get_size());
652 this->get_size(), result.data());
662 void fill(
const value_type value);
676 GKO_DEPRECATED(
"use get_size() instead")
677 size_type get_num_elems() const noexcept {
return get_size(); }
719 array tmp(std::move(exec));
721 exec_ = std::move(tmp.exec_);
722 data_ = std::move(tmp.data_);
744 template <
typename OtherValueType>
748 std::unique_ptr<value_type[], std::function<void(value_type[])>>;
752 std::shared_ptr<const Executor> exec_;
756 template <
typename ValueType>
757 using Array GKO_DEPRECATED(
"please use array") = array<ValueType>;
770 template <
typename ValueType>
771 ValueType reduce_add(
const array<ValueType>& input_arr,
772 const ValueType init_val = 0);
784 template <
typename ValueType>
785 void reduce_add(
const array<ValueType>& input_arr, array<ValueType>& result);
799 template <
typename ValueType>
818 template <
typename ValueType>
820 std::shared_ptr<const Executor> exec,
size_type size,
const ValueType* data)
829 template <
typename T>
830 struct temporary_clone_helper<array<T>> {
831 static std::unique_ptr<array<T>> create(
832 std::shared_ptr<const Executor> exec, array<T>* ptr,
bool copy_data)
835 return std::make_unique<array<T>>(std::move(exec), *ptr);
837 return std::make_unique<array<T>>(std::move(exec), ptr->get_size());
842 template <
typename T>
843 struct temporary_clone_helper<const
array<T>> {
844 static std::unique_ptr<const array<T>> create(
845 std::shared_ptr<const Executor> exec,
const array<T>* ptr,
bool)
847 return std::make_unique<const array<T>>(std::move(exec), *ptr);
853 template <
typename T>
854 class copy_back_deleter<
array<T>>
855 :
public copy_back_deleter_from_assignment<array<T>> {
857 using copy_back_deleter_from_assignment<
858 array<T>>::copy_back_deleter_from_assignment;
874 template <
typename ValueType>
875 array<ValueType> array_const_cast(const_array_view<ValueType> view)
877 return array<ValueType>::view(
878 view.get_executor(), view.get_size(),
879 const_cast<ValueType*>(view.get_const_data()));
883 template <
typename ValueType>
884 array<ValueType> const_array_view<ValueType>::copy_to_array()
const
886 array<ValueType> result(this->get_executor(), this->get_size());
887 result.get_executor()->copy_from(this->get_executor(), this->get_size(),
888 this->get_const_data(), result.get_data());
897 #endif // GKO_PUBLIC_CORE_BASE_ARRAY_HPP_