24 #ifndef TVM_RUNTIME_CONTAINER_MAP_H_
25 #define TVM_RUNTIME_CONTAINER_MAP_H_
27 #ifndef USE_FALLBACK_STL_MAP
28 #define USE_FALLBACK_STL_MAP 0
32 #include <unordered_map>
41 #if TVM_DEBUG_WITH_ABI_CHANGE
42 #define TVM_MAP_FAIL_IF_CHANGED() \
43 ICHECK(state_marker == self->state_marker) << "Concurrent modification of the Map";
45 #define TVM_MAP_FAIL_IF_CHANGED()
48 #if (USE_FALLBACK_STL_MAP != 0)
51 class MapNode :
public Object {
58 using ContainerType = std::unordered_map<ObjectRef, ObjectRef, ObjectHash, ObjectEqual>;
60 using iterator = ContainerType::iterator;
62 using const_iterator = ContainerType::const_iterator;
64 using KVType = ContainerType::value_type;
66 static_assert(std::is_standard_layout<KVType>::value,
"KVType is not standard layout");
67 static_assert(
sizeof(
KVType) == 16 ||
sizeof(
KVType) == 8,
"sizeof(KVType) incorrect");
70 static constexpr
const char*
_type_key =
"Map";
77 size_t size()
const {
return data_.size(); }
83 size_t count(
const key_type& key)
const {
return data_.count(key); }
97 iterator
begin() {
return data_.begin(); }
99 const_iterator
begin()
const {
return data_.begin(); }
101 iterator
end() {
return data_.end(); }
103 const_iterator
end()
const {
return data_.end(); }
109 const_iterator
find(
const key_type& key)
const {
return data_.find(key); }
115 iterator
find(
const key_type& key) {
return data_.find(key); }
120 void erase(
const iterator& position) { data_.erase(position); }
130 static ObjectPtr<MapNode>
Empty() {
return make_object<MapNode>(); }
140 template <
typename IterType>
141 static ObjectPtr<Object>
CreateFromRange(IterType first, IterType last) {
142 ObjectPtr<MapNode> p = make_object<MapNode>();
143 p->data_ = ContainerType(first, last);
152 MapNode* map_node =
static_cast<MapNode*
>(map->get());
153 map_node->data_[kv.first] = kv.second;
160 static ObjectPtr<MapNode>
CopyFrom(MapNode* from) {
161 ObjectPtr<MapNode> p = make_object<MapNode>();
162 p->data_ = ContainerType(from->data_.begin(), from->data_.end());
167 template <
typename,
typename,
typename,
typename>
181 using KVType = std::pair<ObjectRef, ObjectRef>;
185 static_assert(std::is_standard_layout<KVType>::value,
"KVType is not standard layout");
186 static_assert(
sizeof(
KVType) == 16 ||
sizeof(
KVType) == 8,
"sizeof(KVType) incorrect");
216 iterator
begin()
const;
218 iterator
end()
const;
229 void erase(
const iterator& position);
244 #if TVM_DEBUG_WITH_ABI_CHANGE
250 bool operator==(const iterator& other) const {
255 bool operator!=(const
iterator& other)
const {
return !(*
this == other); }
261 return *((*this).operator->());
283 #if TVM_DEBUG_WITH_ABI_CHANGE
284 uint64_t state_marker;
307 #if TVM_DEBUG_WITH_ABI_CHANGE
308 uint64_t state_marker;
317 template <typename IterType>
336 template <
typename,
typename,
typename,
typename>
344 static constexpr uint64_t kInitSize = 2;
345 static constexpr uint64_t kMaxSize = 4;
366 ICHECK(itr.
index <
size_) <<
"IndexError: key is not in Map";
376 ICHECK(itr.
index <
size_) <<
"IndexError: key is not in Map";
390 for (uint64_t i = 0; i <
size_; ++i, ++ptr) {
408 void Erase(
const uint64_t index) {
409 if (index >=
size_) {
414 if (index + 1 ==
size_) {
415 last->first.ObjectRef::~ObjectRef();
416 last->second.ObjectRef::~ObjectRef();
418 *(
begin + index) = std::move(*last);
427 static ObjectPtr<SmallMapNode>
Empty(uint64_t n = kInitSize) {
429 ObjectPtr<SmallMapNode> p = make_inplace_array_object<SmallMapNode, KVType>(n);
442 template <
typename IterType>
443 static ObjectPtr<SmallMapNode> CreateFromRange(uint64_t n, IterType first, IterType last) {
444 ObjectPtr<SmallMapNode> p =
Empty(n);
446 for (; first != last; ++first, ++p->size_) {
447 new (ptr++)
KVType(*first);
456 static ObjectPtr<SmallMapNode> CopyFrom(SmallMapNode* from) {
457 KVType* first =
static_cast<KVType*
>(from->AddressOf(0));
458 KVType* last = first + from->size_;
459 return CreateFromRange(from->size_, first, last);
466 static void InsertMaybeReHash(
const KVType& kv, ObjectPtr<Object>* map) {
467 SmallMapNode* map_node =
static_cast<SmallMapNode*
>(map->get());
468 iterator itr = map_node->find(kv.first);
469 if (itr.index < map_node->size_) {
470 itr->second = kv.second;
473 if (map_node->size_ < map_node->slots_) {
474 KVType* ptr =
static_cast<KVType*
>(map_node->AddressOf(map_node->size_));
479 uint64_t next_size =
std::max(map_node->slots_ * 2, uint64_t(kInitSize));
480 next_size =
std::min(next_size, uint64_t(kMaxSize));
481 ICHECK_GT(next_size, map_node->slots_);
482 ObjectPtr<Object> new_map = CreateFromRange(next_size, map_node->begin(), map_node->end());
483 InsertMaybeReHash(kv, &new_map);
484 *map = std::move(new_map);
491 uint64_t IncItr(uint64_t index)
const {
return index + 1 <
size_ ? index + 1 :
size_; }
497 uint64_t DecItr(uint64_t index)
const {
return index > 0 ? index - 1 :
size_; }
505 uint64_t GetSize()
const {
return size_; }
574 static constexpr
int kBlockCap = 16;
576 static constexpr
double kMaxLoadFactor = 0.99;
578 static constexpr uint8_t kEmptySlot = uint8_t(0b11111111);
580 static constexpr uint8_t kProtectedSlot = uint8_t(0b11111110);
582 static constexpr
int kNumJumpDists = 126;
587 uint8_t bytes[kBlockCap + kBlockCap *
sizeof(
KVType)];
589 static_assert(
sizeof(
Block) == kBlockCap * (
sizeof(
KVType) + 1),
"sizeof(Block) incorrect");
590 static_assert(std::is_standard_layout<Block>::value,
"Block is not standard layout");
619 ListNode node = Search(key);
620 return node.IsNone() ?
end() :
iterator(node.index,
this);
627 uint64_t index = position.
index;
628 if (position.
self !=
nullptr && index <= this->
slots_) {
629 Erase(ListNode(index,
this));
637 for (uint64_t index = 0; index <=
slots_; ++index) {
638 if (!ListNode(index,
this).IsEmpty()) {
653 ListNode Search(
const key_type& key)
const {
654 if (this->
size_ == 0) {
657 for (ListNode iter = GetListHead(
ObjectHash()(key)); !iter.IsNone(); iter.MoveToNext(
this)) {
670 ListNode iter = Search(key);
671 ICHECK(!iter.IsNone()) <<
"IndexError: key is not in Map";
680 bool TryInsert(
const key_type& key, ListNode* result) {
685 ListNode iter = IndexFromHash(ObjectHash()(key));
688 if (iter.IsEmpty()) {
689 iter.NewHead(
KVType(key, ObjectRef(
nullptr)));
695 if (!iter.IsHead()) {
697 return IsFull() ? false : TrySpareListHead(iter, key, result);
702 ListNode next = iter;
705 if (ObjectEqual()(key, next.Key())) {
711 }
while (next.MoveToNext(
this));
719 if (!iter.GetNextEmpty(
this, &jump, result)) {
722 result->NewTail(
KVType(key, ObjectRef(
nullptr)));
739 bool TrySpareListHead(ListNode target,
const key_type& key, ListNode* result) {
750 ListNode w = target.FindPrev(
this);
752 bool is_first =
true;
753 uint8_t r_meta, jump;
758 if (!w.GetNextEmpty(
this, &jump, &empty)) {
762 empty.NewTail(std::move(r.Data()));
775 }
while (r.MoveToNext(
this, r_meta));
778 target.NewHead(
KVType(key, ObjectRef(
nullptr)));
787 void Erase(
const ListNode& iter) {
789 if (!iter.HasNext()) {
791 if (!iter.IsHead()) {
793 iter.FindPrev(
this).SetJump(0);
795 iter.Data().KVType::~KVType();
798 ListNode last = iter, prev = iter;
799 for (last.MoveToNext(
this); last.HasNext(); prev = last, last.MoveToNext(
this)) {
801 iter.Data() = std::move(last.Data());
808 uint64_t n_blocks = CalcNumBlocks(this->
slots_);
809 for (uint64_t bi = 0; bi < n_blocks; ++bi) {
810 uint8_t* meta_ptr = data_[bi].bytes;
811 KVType* data_ptr =
reinterpret_cast<KVType*
>(data_[bi].bytes + kBlockCap);
812 for (
int j = 0; j < kBlockCap; ++j, ++meta_ptr, ++data_ptr) {
813 uint8_t& meta = *meta_ptr;
814 if (meta != uint8_t(kProtectedSlot) && meta != uint8_t(kEmptySlot)) {
815 meta = uint8_t(kEmptySlot);
816 data_ptr->KVType::~KVType();
824 void ReleaseMemory() {
837 static ObjectPtr<DenseMapNode>
Empty(uint32_t fib_shift, uint64_t n_slots) {
838 ICHECK_GT(n_slots, uint64_t(SmallMapNode::kMaxSize));
839 ObjectPtr<DenseMapNode> p = make_object<DenseMapNode>();
840 uint64_t n_blocks = CalcNumBlocks(n_slots - 1);
842 p->slots_ = n_slots - 1;
844 p->fib_shift_ = fib_shift;
845 for (uint64_t i = 0; i < n_blocks; ++i, ++block) {
846 std::fill(block->bytes, block->bytes + kBlockCap, uint8_t(kEmptySlot));
855 static ObjectPtr<DenseMapNode> CopyFrom(
DenseMapNode* from) {
856 ObjectPtr<DenseMapNode> p = make_object<DenseMapNode>();
857 uint64_t n_blocks = CalcNumBlocks(from->slots_);
858 p->data_ =
new Block[n_blocks];
859 p->slots_ = from->slots_;
860 p->size_ = from->size_;
861 p->fib_shift_ = from->fib_shift_;
862 for (uint64_t bi = 0; bi < n_blocks; ++bi) {
863 uint8_t* meta_ptr_from = from->
data_[bi].bytes;
864 KVType* data_ptr_from =
reinterpret_cast<KVType*
>(from->data_[bi].bytes + kBlockCap);
865 uint8_t* meta_ptr_to = p->data_[bi].bytes;
866 KVType* data_ptr_to =
reinterpret_cast<KVType*
>(p->data_[bi].bytes + kBlockCap);
867 for (
int j = 0; j < kBlockCap;
868 ++j, ++meta_ptr_from, ++data_ptr_from, ++meta_ptr_to, ++data_ptr_to) {
869 uint8_t& meta = *meta_ptr_to = *meta_ptr_from;
870 ICHECK(meta != kProtectedSlot);
871 if (meta != uint8_t(kEmptySlot)) {
872 new (data_ptr_to)
KVType(*data_ptr_from);
883 static void InsertMaybeReHash(
const KVType& kv, ObjectPtr<Object>* map) {
887 if (map_node->TryInsert(kv.first, &iter)) {
888 iter.Val() = kv.second;
891 ICHECK_GT(map_node->slots_, uint64_t(SmallMapNode::kMaxSize));
893 ObjectPtr<Object> p =
Empty(map_node->fib_shift_ - 1, map_node->slots_ * 2 + 2);
895 InsertMaybeReHash(kv, &p);
896 uint64_t n_blocks = CalcNumBlocks(map_node->slots_);
898 for (uint64_t bi = 0; bi < n_blocks; ++bi) {
899 uint8_t* meta_ptr = map_node->data_[bi].bytes;
900 KVType* data_ptr =
reinterpret_cast<KVType*
>(map_node->data_[bi].bytes + kBlockCap);
901 for (
int j = 0; j < kBlockCap; ++j, ++meta_ptr, ++data_ptr) {
902 uint8_t& meta = *meta_ptr;
903 if (meta != uint8_t(kProtectedSlot) && meta != uint8_t(kEmptySlot)) {
904 meta = uint8_t(kEmptySlot);
905 KVType kv = std::move(*data_ptr);
906 InsertMaybeReHash(kv, &p);
910 map_node->ReleaseMemory();
917 bool IsFull()
const {
return size_ + 1 > (
slots_ + 1) * kMaxLoadFactor; }
923 uint64_t IncItr(uint64_t index)
const {
924 for (++index; index <=
slots_; ++index) {
925 if (!ListNode(index,
this).IsEmpty()) {
936 uint64_t DecItr(uint64_t index)
const {
939 if (!ListNode(index,
this).IsEmpty()) {
950 KVType* DeRefItr(uint64_t index)
const {
return &ListNode(index,
this).Data(); }
952 ListNode IndexFromHash(uint64_t hash_value)
const {
953 return ListNode(FibHash(hash_value, fib_shift_),
this);
956 ListNode GetListHead(uint64_t hash_value)
const {
957 ListNode node = IndexFromHash(hash_value);
958 return node.IsHead() ? node : ListNode();
961 static uint64_t CalcNumBlocks(uint64_t n_slots_m1) {
962 uint64_t n_slots = n_slots_m1 > 0 ? n_slots_m1 + 1 : 0;
963 return (n_slots + kBlockCap - 1) / kBlockCap;
971 static void CalcTableSize(uint64_t cap, uint32_t* fib_shift, uint64_t* n_slots) {
974 for (uint64_t c = cap; c; c >>= 1) {
978 ICHECK_GT(slots, cap);
979 if (slots < cap * 2) {
980 *fib_shift = shift - 1;
981 *n_slots = slots << 1;
994 static uint64_t FibHash(uint64_t hash_value, uint32_t fib_shift) {
995 constexpr uint64_t coeff = 11400714819323198485ull;
996 return (coeff * hash_value) >> fib_shift;
1001 ListNode() : index(0), block(nullptr) {}
1004 : index(index), block(self->data_ + (index / kBlockCap)) {}
1006 uint8_t& Meta()
const {
return *(block->bytes + index % kBlockCap); }
1009 return *(
reinterpret_cast<KVType*
>(block->bytes + kBlockCap +
1010 (index % kBlockCap) *
sizeof(
KVType)));
1013 key_type& Key()
const {
return Data().first; }
1015 mapped_type& Val()
const {
return Data().second; }
1017 bool IsHead()
const {
return (Meta() & 0b10000000) == 0b00000000; }
1019 bool IsNone()
const {
return block ==
nullptr; }
1021 bool IsEmpty()
const {
return Meta() == uint8_t(kEmptySlot); }
1023 bool IsProtected()
const {
return Meta() == uint8_t(kProtectedSlot); }
1025 void SetEmpty()
const { Meta() = uint8_t(kEmptySlot); }
1027 void SetProtected()
const { Meta() = uint8_t(kProtectedSlot); }
1029 void SetJump(uint8_t jump)
const { (Meta() &= 0b10000000) |= jump; }
1031 void NewHead(
KVType v)
const {
1032 Meta() = 0b00000000;
1033 new (&Data())
KVType(std::move(v));
1036 void NewTail(
KVType v)
const {
1037 Meta() = 0b10000000;
1038 new (&Data())
KVType(std::move(v));
1041 bool HasNext()
const {
return NextProbeLocation(Meta() & 0b01111111) != 0; }
1043 bool MoveToNext(
const DenseMapNode*
self, uint8_t meta) {
1044 uint64_t offset = NextProbeLocation(meta & 0b01111111);
1050 index = (index + offset) & (self->slots_);
1051 block =
self->data_ + (index / kBlockCap);
1055 bool MoveToNext(
const DenseMapNode*
self) {
return MoveToNext(
self, Meta()); }
1059 ListNode next =
self->IndexFromHash(ObjectHash()(Key()));
1061 ListNode prev = next;
1062 for (next.MoveToNext(
self); index != next.index; prev = next, next.MoveToNext(
self)) {
1067 bool GetNextEmpty(
const DenseMapNode*
self, uint8_t* jump, ListNode* result)
const {
1068 for (uint8_t idx = 1; idx < kNumJumpDists; ++idx) {
1069 ListNode candidate((index + NextProbeLocation(idx)) & (self->slots_),
self);
1070 if (candidate.IsEmpty()) {
1072 *result = candidate;
1092 static const uint64_t kNextProbeLocation[kNumJumpDists] {
1093 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1098 21, 28, 36, 45, 55, 66, 78, 91, 105, 120,
1099 136, 153, 171, 190, 210, 231, 253, 276, 300, 325,
1100 351, 378, 406, 435, 465, 496, 528, 561, 595, 630,
1101 666, 703, 741, 780, 820, 861, 903, 946, 990, 1035,
1102 1081, 1128, 1176, 1225, 1275, 1326, 1378, 1431, 1485, 1540,
1103 1596, 1653, 1711, 1770, 1830, 1891, 1953, 2016, 2080, 2145,
1104 2211, 2278, 2346, 2415, 2485, 2556, 2628,
1106 8515, 19110, 42778, 96141, 216153,
1107 486591, 1092981, 2458653, 5532801, 12442566,
1108 27993903, 62983476, 141717030, 318844378, 717352503,
1109 1614057336, 3631522476, 8170957530, 18384510628, 41364789378,
1110 93070452520, 209408356380, 471168559170, 1060128894105, 2385289465695,
1111 5366898840628, 12075518705635, 27169915244790, 61132312065111, 137547689707000,
1112 309482283181501, 696335127828753, 1566753995631385, 3525196511162271, 7931691992677701,
1113 17846306936293605, 40154190677507445, 90346928918121501, 203280589587557251,
1114 457381325854679626, 1029107982097042876, 2315492959180353330, 5209859154120846435,
1117 return kNextProbeLocation[index];
1122 #define TVM_DISPATCH_MAP(base, var, body) \
1124 using TSmall = SmallMapNode*; \
1125 using TDense = DenseMapNode*; \
1126 uint64_t slots = base->slots_; \
1127 if (slots <= SmallMapNode::kMaxSize) { \
1128 TSmall var = static_cast<TSmall>(base); \
1131 TDense var = static_cast<TDense>(base); \
1136 #define TVM_DISPATCH_MAP_CONST(base, var, body) \
1138 using TSmall = const SmallMapNode*; \
1139 using TDense = const DenseMapNode*; \
1140 uint64_t slots = base->slots_; \
1141 if (slots <= SmallMapNode::kMaxSize) { \
1142 TSmall var = static_cast<TSmall>(base); \
1145 TDense var = static_cast<TDense>(base); \
1158 index = p->IncItr(index);
1166 index = p->DecItr(index);
1199 #undef TVM_DISPATCH_MAP
1200 #undef TVM_DISPATCH_MAP_CONST
1205 if (from->slots_ <= SmallMapNode::kMaxSize) {
1206 return SmallMapNode::CopyFrom(
static_cast<SmallMapNode*
>(from));
1208 return DenseMapNode::CopyFrom(
static_cast<DenseMapNode*
>(from));
1212 template <
typename IterType>
1214 int64_t _cap = std::distance(first, last);
1218 uint64_t cap =
static_cast<uint64_t
>(_cap);
1219 if (cap < SmallMapNode::kMaxSize) {
1220 return SmallMapNode::CreateFromRange(cap, first, last);
1224 DenseMapNode::CalcTableSize(cap, &fib_shift, &n_slots);
1226 for (; first != last; ++first) {
1228 DenseMapNode::InsertMaybeReHash(kv, &obj);
1234 constexpr uint64_t kSmallMapMaxSize = SmallMapNode::kMaxSize;
1236 #if TVM_DEBUG_WITH_ABI_CHANGE
1237 base->state_marker++;
1239 if (base->slots_ < kSmallMapMaxSize) {
1240 SmallMapNode::InsertMaybeReHash(kv, map);
1241 }
else if (base->slots_ == kSmallMapMaxSize) {
1242 if (base->size_ < base->slots_) {
1243 SmallMapNode::InsertMaybeReHash(kv, map);
1246 DenseMapNode::InsertMaybeReHash(kv, &new_map);
1247 *map = std::move(new_map);
1250 DenseMapNode::InsertMaybeReHash(kv, map);
1268 template <
typename K,
typename V,
1269 typename =
typename std::enable_if<std::is_base_of<ObjectRef, K>::value>::type,
1270 typename =
typename std::enable_if<std::is_base_of<ObjectRef, V>::value>::type>
1296 data_ = std::move(other.data_);
1305 data_ = other.
data_;
1319 template <
typename IterType>
1327 Map(std::initializer_list<std::pair<K, V>> init) {
1334 template <
typename Hash,
typename Equal>
1335 Map(
const std::unordered_map<K, V, Hash, Equal>& init) {
1343 const V
at(
const K& key)
const {
return DowncastNoCheck<V>(GetMapNode()->
at(key)); }
1353 return n ==
nullptr ? 0 : n->size();
1358 return n ==
nullptr ? 0 : GetMapNode()->count(key);
1374 void Set(
const K& key,
const V& value) {
1387 if (iter == GetMapNode()->
end()) {
1390 return DowncastNoCheck<V>(iter->second);
1392 void erase(
const K& key) { CopyOnWrite()->erase(key); }
1403 if (data_.get() ==
nullptr) {
1405 }
else if (!data_.unique()) {
1408 return GetMapNode();
1433 return std::make_pair(DowncastNoCheck<K>(kv.first), DowncastNoCheck<V>(kv.second));
1451 template <
typename,
typename,
typename,
typename>
1459 MapNode* GetMapNode()
const {
return static_cast<MapNode*
>(data_.get()); }
1468 template <
typename K,
typename V,
1469 typename =
typename std::enable_if<std::is_base_of<ObjectRef, K>::value>::type,
1470 typename =
typename std::enable_if<std::is_base_of<ObjectRef, V>::value>::type>
1472 for (
const auto& p : rhs) {
1473 lhs.
Set(p.first, p.second);
1475 return std::move(lhs);
1482 using runtime::MapNode;
A specialization of hash map that implements the idea of array-based hash map. Another reference impl...
Definition: map.h:571
iterator begin() const
Definition: map.h:633
void erase(const iterator &position)
Erase the entry associated with the iterator.
Definition: map.h:626
iterator end() const
Definition: map.h:645
Block * data_
array of data blocks
Definition: map.h:1088
const mapped_type & at(const key_type &key) const
Index value associated with a key, throw exception if the key does not exist.
Definition: map.h:606
iterator find(const key_type &key) const
Index value associated with a key.
Definition: map.h:618
mapped_type & at(const key_type &key)
Index value associated with a key, throw exception if the key does not exist.
Definition: map.h:612
~DenseMapNode()
Destroy the DenseMapNode.
Definition: map.h:598
size_t count(const key_type &key) const
Definition: map.h:600
static uint64_t NextProbeLocation(size_t index)
Definition: map.h:1089
uint32_t fib_shift_
fib shift in Fibonacci Hashing
Definition: map.h:1086
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
iterator & operator--()
Prefix self decrement, e.g. –iter.
Definition: map.h:1163
KVType * pointer
Definition: map.h:241
uint64_t index
The position on the array.
Definition: map.h:293
iterator operator++(int)
Suffix self increment.
Definition: map.h:268
const MapNode * self
The container it points to.
Definition: map.h:295
std::forward_iterator_tag iterator_category
Definition: map.h:238
iterator(uint64_t index, const MapNode *self)
Definition: map.h:290
iterator & operator++()
Prefix self increment, e.g. ++iter.
Definition: map.h:1155
KVType & reference
Definition: map.h:242
iterator operator--(int)
Suffix self decrement.
Definition: map.h:275
reference operator*() const
De-reference iterators.
Definition: map.h:259
iterator()
Default constructor.
Definition: map.h:247
int64_t difference_type
Definition: map.h:239
pointer operator->() const
De-reference iterators.
Definition: map.h:1150
KVType value_type
Definition: map.h:240
Shared content of all specializations of hash map.
Definition: map.h:174
uint64_t size_
number of entries in the container
Definition: map.h:334
ObjectRef key_type
Type of the keys in the hash map.
Definition: map.h:177
static ObjectPtr< MapNode > CopyFrom(MapNode *from)
Create an empty container with elements copying from another SmallMapNode.
Definition: map.h:1204
void erase(const key_type &key)
Erase the entry associated with the key, do nothing if not exists.
Definition: map.h:234
const mapped_type & at(const key_type &key) const
Index value associated with a key, throw exception if the key does not exist.
Definition: map.h:1175
ObjectRef mapped_type
Type of the values in the hash map.
Definition: map.h:179
std::pair< ObjectRef, ObjectRef > KVType
Type of value stored in the hash map.
Definition: map.h:181
size_t size() const
Number of elements in the SmallMapNode.
Definition: map.h:196
size_t count(const key_type &key) const
Count the number of times a key exists in the hash map.
Definition: map.h:1171
static ObjectPtr< Object > CreateFromRange(IterType first, IterType last)
Create the map using contents from the given iterators.
Definition: map.h:1213
static void InsertMaybeReHash(const KVType &kv, ObjectPtr< Object > *map)
InsertMaybeReHash an entry into the given hash map.
Definition: map.h:1233
static constexpr const uint32_t _type_index
Definition: map.h:188
iterator end() const
Definition: map.h:1187
iterator find(const key_type &key) const
Index value associated with a key.
Definition: map.h:1191
static constexpr const char * _type_key
Definition: map.h:189
uint64_t slots_
number of slots minus 1
Definition: map.h:332
TVM_DECLARE_FINAL_OBJECT_INFO(MapNode, Object)
friend class Map
Definition: map.h:337
iterator begin() const
Definition: map.h:1183
static ObjectPtr< MapNode > Empty()
Create an empty container.
Definition: map.h:1202
void erase(const iterator &position)
Erase the entry associated with the iterator.
Definition: map.h:1195
Iterator of the hash map.
Definition: map.h:1414
std::bidirectional_iterator_tag iterator_category
Definition: map.h:1416
pointer operator->() const =delete
De-reference iterators is not allowed.
bool operator!=(const iterator &other) const
Compare iterators.
Definition: map.h:1427
value_type * pointer
Definition: map.h:1419
const std::pair< K, V > value_type
Definition: map.h:1418
reference operator*() const
De-reference iterators.
Definition: map.h:1431
iterator & operator++()
Prefix self increment, e.g. ++iter.
Definition: map.h:1436
int64_t difference_type
Definition: map.h:1417
iterator operator++(int)
Suffix self increment.
Definition: map.h:1441
iterator()
Definition: map.h:1422
bool operator==(const iterator &other) const
Compare iterators.
Definition: map.h:1425
value_type reference
Definition: map.h:1420
Map container of NodeRef->NodeRef in DSL graph. Map implements copy on write semantics,...
Definition: map.h:1271
void clear()
Release reference to all the elements.
Definition: map.h:1363
MapNode * CopyOnWrite()
copy on write semantics Do nothing if current handle is the unique copy of the array....
Definition: map.h:1402
size_t size() const
Definition: map.h:1351
K key_type
Definition: map.h:1273
Map(ObjectPtr< Object > n)
constructor from pointer
Definition: map.h:1312
iterator end() const
Definition: map.h:1381
void erase(const K &key)
Definition: map.h:1392
Map< K, V > & operator=(const Map< K, V > &other)
move assign operator
Definition: map.h:1304
const V at(const K &key) const
Read element from map.
Definition: map.h:1343
V mapped_type
Definition: map.h:1274
const V operator[](const K &key) const
Read element from map.
Definition: map.h:1349
Map(IterType begin, IterType end)
constructor from iterator
Definition: map.h:1320
Map(std::initializer_list< std::pair< K, V >> init)
constructor from initializer list
Definition: map.h:1327
Map(Map< K, V > &&other)
move constructor
Definition: map.h:1284
size_t count(const K &key) const
Definition: map.h:1356
iterator begin() const
Definition: map.h:1379
Map()
default constructor
Definition: map.h:1279
iterator find(const K &key) const
Definition: map.h:1383
Map(const std::unordered_map< K, V, Hash, Equal > &init)
constructor from unordered_map
Definition: map.h:1335
Map< K, V > & operator=(Map< K, V > &&other)
copy assign operator
Definition: map.h:1295
void Set(const K &key, const V &value)
set the Map.
Definition: map.h:1374
Map(const Map< K, V > &other)
copy constructor
Definition: map.h:1289
Optional< V > Get(const K &key) const
Definition: map.h:1385
bool empty() const
Definition: map.h:1361
A custom smart pointer for Object.
Definition: object.h:362
T * get() const
Definition: object.h:415
Base class of all object reference.
Definition: object.h:519
ObjectPtr< Object > data_
Internal pointer that backs the reference.
Definition: object.h:605
base class of all object containers.
Definition: object.h:171
Object()
Definition: object.h:245
Optional container that to represent to a Nullable variant of T.
Definition: optional.h:51
A specialization of small-sized hash map.
Definition: map.h:342
const mapped_type & at(const key_type &key) const
Index value associated with a key, throw exception if the key does not exist.
Definition: map.h:364
friend class DenseMapNode
Definition: map.h:509
iterator begin() const
Definition: map.h:380
~SmallMapNode()=default
Defaults to the destructor of InplaceArrayBase.
std::pair< ObjectRef, ObjectRef > KVType
Type of value stored in the hash map.
Definition: map.h:181
mapped_type & at(const key_type &key)
Index value associated with a key, throw exception if the key does not exist.
Definition: map.h:374
iterator end() const
Definition: map.h:382
size_t count(const key_type &key) const
Count the number of times a key exists in the SmallMapNode.
Definition: map.h:358
void erase(const iterator &position)
Erase the entry associated with the iterator.
Definition: map.h:401
friend class MapNode
Definition: map.h:508
iterator find(const key_type &key) const
Index value associated with a key.
Definition: map.h:388
#define TVM_DISPATCH_MAP_CONST(base, var, body)
Definition: map.h:1136
#define TVM_MAP_FAIL_IF_CHANGED()
Definition: map.h:45
#define TVM_DISPATCH_MAP(base, var, body)
Definition: map.h:1122
ObjectPtr< ArrayType > make_inplace_array_object(size_t num_elems, Args &&... args)
Definition: memory.h:200
Map< K, V > Merge(Map< K, V > lhs, const Map< K, V > &rhs)
Merge two Maps.
Definition: map.h:1471
BlockFrame Block(String name, bool no_realize=false)
The block declaration statement.
runtime implementation for LibTorch/TorchScript.
Definition: analyzer.h:36
PrimExpr max(PrimExpr a, PrimExpr b, Span span=Span())
take maximum of two values
PrimExpr min(PrimExpr a, PrimExpr b, Span span=Span())
take minimum of two values
Runtime Optional container types.
Helper to represent nullptr for optional.
Definition: optional.h:35
String-aware ObjectRef hash functor.
Definition: base.h:50
String-aware ObjectRef equal functor.
Definition: base.h:40
@ kRuntimeMap
runtime::Map.
Definition: object.h:70