24 #ifndef TVM_RUNTIME_CONTAINER_ARRAY_H_
25 #define TVM_RUNTIME_CONTAINER_ARRAY_H_
29 #include <type_traits>
43 size_t size()
const {
return this->size_; }
59 void clear() { ShrinkBy(size_); }
75 int64_t
size = from->size_;
76 ICHECK_GE(cap,
size) <<
"ValueError: not enough capacity";
81 for (int64_t& i = p->size_ = 0; i <
size; ++i) {
94 int64_t
size = from->size_;
95 ICHECK_GE(cap,
size) <<
"ValueError: not enough capacity";
100 for (int64_t& i = p->size_ = 0; i <
size; ++i) {
101 new (write++)
ObjectRef(std::move(*read++));
116 for (int64_t& i = p->size_ = 0; i < n; ++i) {
128 size_t GetSize()
const {
return this->size_; }
136 ObjectRef* MutableEnd()
const {
return MutableBegin() + size_; }
143 static ObjectPtr<ArrayNode> Empty(int64_t n = kInitSize) {
145 ObjectPtr<ArrayNode> p = make_inplace_array_object<ArrayNode, ObjectRef>(n);
159 template <
typename IterType>
160 ArrayNode* InitRange(int64_t idx, IterType first, IterType last) {
161 ObjectRef* itr = MutableBegin() + idx;
162 for (; first != last; ++first) {
163 ObjectRef ref = *first;
164 new (itr++) ObjectRef(std::move(ref));
176 ArrayNode* MoveElementsLeft(int64_t dst, int64_t src_begin, int64_t src_end) {
177 ObjectRef* from = MutableBegin() + src_begin;
178 ObjectRef* to = MutableBegin() + dst;
179 while (src_begin++ != src_end) {
180 *to++ = std::move(*from++);
192 ArrayNode* MoveElementsRight(int64_t dst, int64_t src_begin, int64_t src_end) {
193 ObjectRef* from = MutableBegin() + src_end;
194 ObjectRef* to = MutableBegin() + (src_end - src_begin + dst);
195 while (src_begin++ != src_end) {
196 *--to = std::move(*--from);
207 ArrayNode* EnlargeBy(int64_t delta,
const ObjectRef& val = ObjectRef(
nullptr)) {
208 ObjectRef* itr = MutableEnd();
209 while (delta-- > 0) {
210 new (itr++) ObjectRef(val);
221 ArrayNode* ShrinkBy(int64_t delta) {
222 ObjectRef* itr = MutableEnd();
223 while (delta-- > 0) {
224 (--itr)->ObjectRef::~ObjectRef();
237 static constexpr int64_t kInitSize = 4;
240 static constexpr int64_t kIncFactor = 2;
243 friend InplaceArrayBase<ArrayNode, ObjectRef>;
246 template <
typename,
typename>
259 template <
typename T,
typename IterType>
261 : std::bool_constant<std::is_base_of_v<
262 T, std::remove_cv_t<std::remove_reference_t<decltype(*std::declval<IterType>())>>>> {};
264 template <
typename T,
typename IterType>
267 template <
typename T,
typename IterType>
287 template <
typename T,
288 typename =
typename std::enable_if<std::is_base_of<ObjectRef, T>::value>::type>
303 data_ = std::move(other.data_);
326 template <
typename IterType>
327 Array(IterType first, IterType last) {
328 static_assert(is_valid_iterator_v<T, IterType>,
329 "IterType cannot be inserted into a tvm::Array<T>");
337 Array(std::initializer_list<T> init) {
338 Assign(init.begin(), init.end());
346 Assign(init.begin(), init.end());
362 data_ = std::move(other.data_);
413 ICHECK(p !=
nullptr) <<
"ValueError: cannot index a null array";
414 ICHECK(0 <= i && i < p->size_)
415 <<
"IndexError: indexing " << i <<
" on an array of size " << p->size_;
416 return DowncastNoCheck<T>(*(p->
begin() + i));
437 ICHECK(p !=
nullptr) <<
"ValueError: cannot index a null array";
438 ICHECK_GT(p->size_, 0) <<
"IndexError: cannot index an empty array";
439 return DowncastNoCheck<T>(*(p->
begin()));
445 ICHECK(p !=
nullptr) <<
"ValueError: cannot index a null array";
446 ICHECK_GT(p->size_, 0) <<
"IndexError: cannot index an empty array";
447 return DowncastNoCheck<T>(*(p->
end() - 1));
468 ICHECK(
data_ !=
nullptr) <<
"ValueError: cannot insert a null array";
469 int64_t idx = std::distance(
begin(), position);
473 ->MoveElementsRight(idx + 1, idx,
size)
484 template <
typename IterType>
486 static_assert(is_valid_iterator_v<T, IterType>,
487 "IterType cannot be inserted into a tvm::Array<T>");
492 ICHECK(
data_ !=
nullptr) <<
"ValueError: cannot insert a null array";
493 int64_t idx = std::distance(
begin(), position);
495 int64_t numel = std::distance(first, last);
498 ->MoveElementsRight(idx + numel, idx,
size)
499 ->InitRange(idx, first, last);
504 ICHECK(
data_ !=
nullptr) <<
"ValueError: cannot pop_back because array is null";
506 ICHECK_GT(
size, 0) <<
"ValueError: cannot pop_back because array is empty";
515 ICHECK(
data_ !=
nullptr) <<
"ValueError: cannot erase a null array";
516 int64_t st = std::distance(
begin(), position);
518 ICHECK(0 <= st && st <
size) <<
"ValueError: cannot erase at index " << st
519 <<
", because Array size is " <<
size;
521 ->MoveElementsLeft(st, st + 1,
size)
534 ICHECK(
data_ !=
nullptr) <<
"ValueError: cannot erase a null array";
536 int64_t st = std::distance(
begin(), first);
537 int64_t ed = std::distance(
begin(), last);
538 ICHECK_LT(st, ed) <<
"ValueError: cannot erase array in range [" << st <<
", " << ed <<
")";
539 ICHECK(0 <= st && st <=
size && 0 <= ed && ed <=
size)
540 <<
"ValueError: cannot erase array in range [" << st <<
", " << ed <<
")"
541 <<
", because array size is " <<
size;
543 ->MoveElementsLeft(st, ed,
size)
552 ICHECK_GE(n, 0) <<
"ValueError: cannot resize an Array to negative size";
553 if (
data_ ==
nullptr) {
560 }
else if (
size > n) {
577 if (
data_ !=
nullptr) {
583 template <
typename... Args>
588 template <
typename... Args>
593 template <
typename... Args>
598 template <
typename... Args>
601 template <
typename... Args>
607 template <
typename... Args>
621 void Set(int64_t i, T value) {
623 ICHECK(0 <= i && i < p->size_)
624 <<
"IndexError: indexing " << i <<
" on an array of size " << p->size_;
625 *(p->MutableBegin() + i) = std::move(value);
650 template <
typename F,
typename U = std::invoke_result_t<F, T>>
661 template <
typename F,
typename = std::enable_if_t<std::is_same_v<T, std::invoke_result_t<F, T>>>>
672 template <
typename IterType>
673 void Assign(IterType first, IterType last) {
674 int64_t cap = std::distance(first, last);
675 ICHECK_GE(cap, 0) <<
"ValueError: cannot construct an Array of negative size";
677 if (p !=
nullptr &&
data_.unique() && p->capacity_ >= cap) {
682 data_ = ArrayNode::Empty(cap);
687 for (int64_t& i = p->size_ = 0; i < cap; ++i, ++first, ++itr) {
701 if (
data_ ==
nullptr) {
702 return SwitchContainer(ArrayNode::kInitSize);
704 if (!
data_.unique()) {
718 template <
typename... Args>
736 const int64_t kInitSize = ArrayNode::kInitSize;
737 return SwitchContainer(
std::max(kInitSize, reserve_extra));
739 if (p->capacity_ >= p->size_ + reserve_extra) {
742 int64_t cap = p->capacity_ * ArrayNode::kIncFactor;
743 cap =
std::max(cap, p->size_ + reserve_extra);
744 return SwitchContainer(cap);
751 ArrayNode* SwitchContainer(int64_t
capacity) {
752 if (
data_ ==
nullptr) {
754 }
else if (
data_.unique()) {
759 return static_cast<ArrayNode*
>(
data_.get());
784 template <
typename F,
typename U = std::invoke_result_t<F, T>>
785 static ObjectPtr<Object> MapHelper(ObjectPtr<Object> data, F fmap) {
786 if (data ==
nullptr) {
790 ICHECK(data->IsInstance<ArrayNode>());
792 constexpr
bool is_same_output_type = std::is_same_v<T, U>;
794 if constexpr (is_same_output_type) {
799 auto arr =
static_cast<ArrayNode*
>(data.get());
800 for (
auto it = arr->MutableBegin(); it != arr->MutableEnd(); it++) {
801 T mapped = fmap(DowncastNoCheck<T>(std::move(*it)));
802 *it = std::move(mapped);
808 constexpr
bool compatible_types = is_valid_iterator_v<T, U*> || is_valid_iterator_v<U, T*>;
810 ObjectPtr<ArrayNode> output =
nullptr;
811 auto arr =
static_cast<ArrayNode*
>(data.get());
813 auto it = arr->begin();
814 if constexpr (compatible_types) {
821 bool all_identical =
true;
822 for (; it != arr->end(); it++) {
823 U mapped = fmap(DowncastNoCheck<T>(*it));
824 if (!mapped.same_as(*it)) {
835 all_identical =
false;
837 output->InitRange(0, arr->begin(), it);
838 output->SetItem(it - arr->begin(), std::move(mapped));
876 for (; it != arr->end(); it++) {
877 U mapped = fmap(DowncastNoCheck<T>(*it));
878 output->SetItem(it - arr->begin(), std::move(mapped));
885 template <
typename T>
888 template <
typename T>
889 inline constexpr
bool is_tvm_array<Array<T>> =
true;
897 template <
typename T,
898 typename =
typename std::enable_if<std::is_base_of<ObjectRef, T>::value>::type>
900 for (
const auto& x : rhs) {
903 return std::move(lhs);
909 return ArrayNode::Empty();
array node content in array
Definition: array.h:40
static ObjectPtr< ArrayNode > MoveFrom(int64_t cap, ArrayNode *from)
Constructs a container and move from another.
Definition: array.h:93
void SetItem(int64_t i, ObjectRef item)
Set i-th element of the array in-place.
Definition: array.h:66
const ObjectRef * begin() const
Definition: array.h:53
const ObjectRef * end() const
Definition: array.h:56
size_t size() const
Definition: array.h:43
const ObjectRef at(int64_t i) const
Read i-th element from array.
Definition: array.h:50
static constexpr const char * _type_key
Definition: array.h:123
void clear()
Release reference to all the elements.
Definition: array.h:59
static constexpr const uint32_t _type_index
Definition: array.h:122
static ObjectPtr< ArrayNode > CreateRepeated(int64_t n, const ObjectRef &val)
Constructs a container with n elements. Each element is a copy of val.
Definition: array.h:113
static ObjectPtr< ArrayNode > CopyFrom(int64_t cap, ArrayNode *from)
Constructs a container and copy from another.
Definition: array.h:74
TVM_DECLARE_FINAL_OBJECT_INFO(ArrayNode, Object)
Array, container representing a contiguous sequence of ObjectRefs.
Definition: array.h:289
void clear()
Release reference to all the elements.
Definition: array.h:576
const T back() const
Definition: array.h:443
void erase(iterator position)
Erase an element on the given position.
Definition: array.h:514
static void AgregateImpl(Array< T > &dest, Array< T > value, Args... args)
Definition: array.h:602
void reserve(int64_t n)
Make sure the list has the capacity of at least n.
Definition: array.h:569
reverse_iterator rend() const
Definition: array.h:399
T value_type
Definition: array.h:291
size_t capacity() const
Definition: array.h:426
Array(std::initializer_list< T > init)
constructor from initializer list
Definition: array.h:337
ReverseIterAdapter< ValueConverter, const ObjectRef * > reverse_iterator
Definition: array.h:384
static void AgregateImpl(Array< T > &dest, T value, Args... args)
Definition: array.h:608
const T front() const
Definition: array.h:435
ArrayNode * GetArrayNode() const
Definition: array.h:629
Array< U > Map(F fmap) const
Helper function to apply a map function onto the array.
Definition: array.h:651
Array< T > & operator=(const Array< T > &other)
copy assign operator
Definition: array.h:371
void MutateByApply(F fmutate)
Helper function to apply fmutate to mutate an array.
Definition: array.h:662
void erase(iterator first, iterator last)
Erase a given range of elements.
Definition: array.h:530
iterator end() const
Definition: array.h:390
void insert(iterator position, const T &val)
Insert an element into the given position.
Definition: array.h:467
bool empty() const
Definition: array.h:432
Array(const Array< T > &other)
copy constructor
Definition: array.h:310
Array(const size_t n, const T &val)
Constructs a container with n elements. Each element is a copy of val.
Definition: array.h:354
void resize(int64_t n)
Resize the array.
Definition: array.h:551
Array(Array< T > &&other)
move constructor
Definition: array.h:302
static void AgregateImpl(Array< T > &dest)
Definition: array.h:599
Array< T > & operator=(Array< T > &&other)
move assign operator
Definition: array.h:361
IterAdapter< ValueConverter, const ObjectRef * > iterator
Definition: array.h:383
Array(const std::vector< T > &init)
constructor from vector
Definition: array.h:345
static size_t CalcCapacityImpl(T value, Args... args)
Definition: array.h:594
void push_back(const T &item)
push a new item to the back of the list
Definition: array.h:457
void pop_back()
Remove the last item of the list.
Definition: array.h:503
Array(IterType first, IterType last)
Constructor from iterator.
Definition: array.h:327
void insert(iterator position, IterType first, IterType last)
Insert a range of elements into the given position.
Definition: array.h:485
void Set(int64_t i, T value)
set i-th element of the array.
Definition: array.h:621
void Assign(IterType first, IterType last)
reset the array to content from iterator.
Definition: array.h:673
const T operator[](int64_t i) const
Immutably read i-th element from array.
Definition: array.h:411
static Array< T > Agregate(Args... args)
Agregate arguments into a single Array<T>
Definition: array.h:719
static size_t CalcCapacityImpl()
Definition: array.h:584
ArrayNode * CopyOnWrite()
Copy on write semantics Do nothing if current handle is the unique copy of the array....
Definition: array.h:700
iterator begin() const
Definition: array.h:387
size_t size() const
Definition: array.h:420
reverse_iterator rbegin() const
Definition: array.h:393
Array(ObjectPtr< Object > n)
constructor from pointer
Definition: array.h:318
static size_t CalcCapacityImpl(Array< T > value, Args... args)
Definition: array.h:589
Array()
default constructor
Definition: array.h:296
Base template for classes with array like memory layout.
Definition: base.h:100
void * AddressOf(size_t idx) const
Return the raw pointer to the element at idx.
Definition: base.h:169
const ObjectRef & operator[](size_t idx) const
Access element at index.
Definition: base.h:107
void EmplaceInit(size_t idx, Args &&... args)
Construct a value in place with the arguments.
Definition: base.h:149
iterator adapter that adapts TIter to return another type.
Definition: base.h:188
A custom smart pointer for Object.
Definition: object.h:362
Base class of all object reference.
Definition: object.h:519
ObjectRef()=default
default constructor
ObjectPtr< Object > data_
Internal pointer that backs the reference.
Definition: object.h:605
base class of all object containers.
Definition: object.h:171
Optional container that to represent to a Nullable variant of T.
Definition: optional.h:51
iterator adapter that adapts TIter to return another type.
Definition: base.h:241
constexpr bool is_tvm_array
Definition: array.h:886
ObjectPtr< ArrayNode > make_object()
Definition: array.h:908
Array< T > Concat(Array< T > lhs, const Array< T > &rhs)
Concat two Arrays.
Definition: array.h:899
constexpr bool is_valid_iterator_v
Definition: array.h:268
runtime implementation for LibTorch/TorchScript.
Definition: analyzer.h:36
PrimExpr max(PrimExpr a, PrimExpr b, Span span=Span())
take maximum of two values
Runtime Optional container types.
T ResultType
Definition: array.h:379
static T convert(const ObjectRef &n)
Definition: array.h:380
@ kRuntimeArray
runtime::Array.
Definition: object.h:68
Helper struct for type-checking.
Definition: array.h:262