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> 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() 46 #endif // TVM_LOG_DEBUG 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");
245 iterator() : state_marker(0), index(0), self(nullptr) {}
248 #endif // TVM_LOG_DEBUG 252 return index == other.
index &&
self == other.
self;
261 return *((*this).operator->());
284 uint64_t state_marker;
287 : state_marker(self->state_marker), index(index),
self(
self) {}
291 #endif // TVM_LOG_DEBUG 308 uint64_t state_marker;
309 #endif // TVM_LOG_DEBUG 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);
442 template <
typename IterType>
446 for (; first != last; ++first, ++p->size_) {
447 new (ptr++)
KVType(*first);
470 itr->second = kv.second;
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_);
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_; }
503 KVType* DeRefItr(uint64_t index)
const {
return static_cast<KVType*
>(AddressOf(index)); }
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()) {
695 if (!iter.IsHead()) {
697 return IsFull() ? false : TrySpareListHead(iter, key, result);
702 ListNode next = iter;
711 }
while (next.MoveToNext(
this));
719 if (!iter.GetNextEmpty(
this, &jump, result)) {
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));
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() {
838 ICHECK_GT(n_slots, uint64_t(SmallMapNode::kMaxSize));
840 uint64_t n_blocks = CalcNumBlocks(n_slots - 1);
841 Block* block = p->data_ =
new Block[n_blocks];
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));
857 uint64_t n_blocks = CalcNumBlocks(from->
slots_);
858 p->data_ =
new Block[n_blocks];
860 p->size_ = from->
size_;
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);
887 if (map_node->TryInsert(kv.first, &iter)) {
888 iter.Val() = kv.second;
891 ICHECK_GT(map_node->
slots_, uint64_t(SmallMapNode::kMaxSize));
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);
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 kNextProbeLocation[Meta() & 0b01111111] != 0; }
1043 bool MoveToNext(
const DenseMapNode*
self, uint8_t meta) {
1044 uint64_t offset = kNextProbeLocation[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 + kNextProbeLocation[idx]) & (self->slots_),
self);
1070 if (candidate.IsEmpty()) {
1072 *result = candidate;
1091 TVM_DLL
static constexpr uint64_t kNextProbeLocation[kNumJumpDists] {
1092 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1097 21, 28, 36, 45, 55, 66, 78, 91, 105, 120,
1098 136, 153, 171, 190, 210, 231, 253, 276, 300, 325,
1099 351, 378, 406, 435, 465, 496, 528, 561, 595, 630,
1100 666, 703, 741, 780, 820, 861, 903, 946, 990, 1035,
1101 1081, 1128, 1176, 1225, 1275, 1326, 1378, 1431, 1485, 1540,
1102 1596, 1653, 1711, 1770, 1830, 1891, 1953, 2016, 2080, 2145,
1103 2211, 2278, 2346, 2415, 2485, 2556, 2628,
1105 8515, 19110, 42778, 96141, 216153,
1106 486591, 1092981, 2458653, 5532801, 12442566,
1107 27993903, 62983476, 141717030, 318844378, 717352503,
1108 1614057336, 3631522476, 8170957530, 18384510628, 41364789378,
1109 93070452520, 209408356380, 471168559170, 1060128894105, 2385289465695,
1110 5366898840628, 12075518705635, 27169915244790, 61132312065111, 137547689707000,
1111 309482283181501, 696335127828753, 1566753995631385, 3525196511162271, 7931691992677701,
1112 17846306936293605, 40154190677507445, 90346928918121501, 203280589587557251, 457381325854679626,
1113 1029107982097042876, 2315492959180353330, 5209859154120846435,
1119 #define TVM_DISPATCH_MAP(base, var, body) \ 1121 using TSmall = SmallMapNode*; \ 1122 using TDense = DenseMapNode*; \ 1123 uint64_t slots = base->slots_; \ 1124 if (slots <= SmallMapNode::kMaxSize) { \ 1125 TSmall var = static_cast<TSmall>(base); \ 1128 TDense var = static_cast<TDense>(base); \ 1133 #define TVM_DISPATCH_MAP_CONST(base, var, body) \ 1135 using TSmall = const SmallMapNode*; \ 1136 using TDense = const DenseMapNode*; \ 1137 uint64_t slots = base->slots_; \ 1138 if (slots <= SmallMapNode::kMaxSize) { \ 1139 TSmall var = static_cast<TSmall>(base); \ 1142 TDense var = static_cast<TDense>(base); \ 1155 index = p->IncItr(index);
1163 index = p->DecItr(index);
1196 #undef TVM_DISPATCH_MAP 1197 #undef TVM_DISPATCH_MAP_CONST 1202 if (from->slots_ <= SmallMapNode::kMaxSize) {
1203 return SmallMapNode::CopyFrom(static_cast<SmallMapNode*>(from));
1205 return DenseMapNode::CopyFrom(static_cast<DenseMapNode*>(from));
1209 template <
typename IterType>
1211 int64_t _cap = std::distance(first, last);
1215 uint64_t cap =
static_cast<uint64_t
>(_cap);
1216 if (cap < SmallMapNode::kMaxSize) {
1217 return SmallMapNode::CreateFromRange(cap, first, last);
1221 DenseMapNode::CalcTableSize(cap, &fib_shift, &n_slots);
1223 for (; first != last; ++first) {
1225 DenseMapNode::InsertMaybeReHash(kv, &obj);
1231 constexpr uint64_t kSmallMapMaxSize = SmallMapNode::kMaxSize;
1234 base->state_marker++;
1235 #endif // TVM_LOG_DEBUG 1236 if (base->slots_ < kSmallMapMaxSize) {
1237 SmallMapNode::InsertMaybeReHash(kv, map);
1238 }
else if (base->slots_ == kSmallMapMaxSize) {
1239 if (base->size_ < base->slots_) {
1240 SmallMapNode::InsertMaybeReHash(kv, map);
1243 DenseMapNode::InsertMaybeReHash(kv, &new_map);
1244 *map = std::move(new_map);
1247 DenseMapNode::InsertMaybeReHash(kv, map);
1265 template <
typename K,
typename V,
1266 typename =
typename std::enable_if<std::is_base_of<ObjectRef, K>::value>::type,
1267 typename =
typename std::enable_if<std::is_base_of<ObjectRef, V>::value>::type>
1293 data_ = std::move(other.data_);
1302 data_ = other.
data_;
1316 template <
typename IterType>
1324 Map(std::initializer_list<std::pair<K, V>> init) {
1331 template <
typename Hash,
typename Equal>
1332 Map(
const std::unordered_map<K, V, Hash, Equal>& init) {
1340 const V
at(
const K& key)
const {
return DowncastNoCheck<V>(GetMapNode()->at(key)); }
1350 return n ==
nullptr ? 0 : n->size();
1355 return n ==
nullptr ? 0 : GetMapNode()->count(key);
1371 void Set(
const K& key,
const V& value) {
1376 iterator
begin()
const {
return iterator(GetMapNode()->
begin()); }
1378 iterator
end()
const {
return iterator(GetMapNode()->
end()); }
1380 iterator
find(
const K& key)
const {
return iterator(GetMapNode()->
find(key)); }
1384 if (iter == GetMapNode()->
end()) {
1387 return DowncastNoCheck<V>(iter->second);
1389 void erase(
const K& key) { CopyOnWrite()->erase(key); }
1400 if (data_.get() ==
nullptr) {
1402 }
else if (!data_.unique()) {
1405 return GetMapNode();
1426 pointer operator->()
const =
delete;
1430 return std::make_pair(DowncastNoCheck<K>(kv.first), DowncastNoCheck<V>(kv.second));
1448 template <
typename,
typename,
typename,
typename>
1456 MapNode* GetMapNode()
const {
return static_cast<MapNode*
>(data_.get()); }
1465 template <
typename K,
typename V,
1466 typename =
typename std::enable_if<std::is_base_of<ObjectRef, K>::value>::type,
1467 typename =
typename std::enable_if<std::is_base_of<ObjectRef, V>::value>::type>
1469 for (
const auto& p : rhs) {
1470 lhs.
Set(p.first, p.second);
1472 return std::move(lhs);
1482 #endif // TVM_RUNTIME_CONTAINER_MAP_H_ value_type * pointer
Definition: map.h:1416
String-aware ObjectRef hash functor.
Definition: base.h:50
static constexpr const char * _type_key
Definition: map.h:189
runtime::Map.
Definition: object.h:70
Block * data_
array of data blocks
Definition: map.h:1088
std::bidirectional_iterator_tag iterator_category
Definition: map.h:1413
std::forward_iterator_tag iterator_category
Definition: map.h:238
PrimExpr min(PrimExpr a, PrimExpr b, Span span=Span())
take minimum of two values
int64_t difference_type
Definition: map.h:239
Map< K, V > & operator=(const Map< K, V > &other)
move assign operator
Definition: map.h:1301
A custom smart pointer for Object.
Definition: object.h:358
Runtime Optional container types.
const V operator[](const K &key) const
Read element from map.
Definition: map.h:1346
ObjectRef key_type
Type of the keys in the hash map.
Definition: map.h:177
iterator begin() const
Definition: map.h:1180
uint64_t slots_
number of slots minus 1
Definition: map.h:332
Map()
default constructor
Definition: map.h:1276
const std::pair< K, V > value_type
Definition: map.h:1415
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
bool operator!=(const iterator &other) const
Compare iterators.
Definition: map.h:255
bool operator!=(const iterator &other) const
Compare iterators.
Definition: map.h:1424
void erase(const iterator &position)
Erase the entry associated with the iterator.
Definition: map.h:401
iterator end() const
Definition: map.h:382
#define TVM_DISPATCH_MAP(base, var, body)
Definition: map.h:1119
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
Map< K, V > & operator=(Map< K, V > &&other)
copy assign operator
Definition: map.h:1292
runtime implementation for LibTorch/TorchScript.
Definition: analyzer.h:36
static void InsertMaybeReHash(const KVType &kv, ObjectPtr< Object > *map)
InsertMaybeReHash an entry into the given hash map.
Definition: map.h:1230
iterator()
Default constructor.
Definition: map.h:247
Object()
Definition: object.h:241
bool operator==(const iterator &other) const
Compare iterators.
Definition: map.h:1422
iterator begin() const
Definition: map.h:380
uint32_t fib_shift_
fib shift in Fibonacci Hashing
Definition: map.h:1086
iterator & operator++()
Prefix self increment, e.g. ++iter.
Definition: map.h:1152
MapNode * CopyOnWrite()
copy on write semantics Do nothing if current handle is the unique copy of the array. Otherwise make a new copy of the array to ensure the current handle hold a unique copy.
Definition: map.h:1399
ObjectRef mapped_type
Type of the values in the hash map.
Definition: map.h:179
size_t size() const
Number of elements in the SmallMapNode.
Definition: map.h:196
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
TVM_DECLARE_FINAL_OBJECT_INFO(MapNode, Object)
Iteration Variable, represents an iteration over an integer interval.
Definition: var.h:301
Map(const std::unordered_map< K, V, Hash, Equal > &init)
constructor from unordered_map
Definition: map.h:1332
iterator & operator++()
Prefix self increment, e.g. ++iter.
Definition: map.h:1433
static ObjectPtr< MapNode > Empty()
Create an empty container.
Definition: map.h:1199
iterator operator++(int)
Suffix self increment.
Definition: map.h:268
bool empty() const
Definition: map.h:1358
Optional< V > Get(const K &key) const
Definition: map.h:1382
Base utilities for common POD(plain old data) container types.
Map(IterType begin, IterType end)
constructor from iterator
Definition: map.h:1317
Map(ObjectPtr< Object > n)
constructor from pointer
Definition: map.h:1309
iterator end() const
Definition: map.h:1184
iterator find(const key_type &key) const
Index value associated with a key.
Definition: map.h:388
ObjectPtr< ArrayType > make_inplace_array_object(size_t num_elems, Args &&... args)
Definition: memory.h:200
base class of all object containers.
Definition: object.h:167
~DenseMapNode()
Destroy the DenseMapNode.
Definition: map.h:598
A specialization of small-sized hash map.
Definition: map.h:341
iterator(uint64_t index, const MapNode *self)
Definition: map.h:290
void erase(const K &key)
Definition: map.h:1389
Map(const Map< K, V > &other)
copy constructor
Definition: map.h:1286
Base template for classes with array like memory layout.
Definition: base.h:100
static ObjectPtr< MapNode > CopyFrom(MapNode *from)
Create an empty container with elements copying from another SmallMapNode.
Definition: map.h:1201
size_t count(const key_type &key) const
Count the number of times a key exists in the SmallMapNode.
Definition: map.h:358
static ObjectPtr< Object > CreateFromRange(IterType first, IterType last)
Create the map using contents from the given iterators.
Definition: map.h:1210
iterator begin() const
Definition: map.h:633
iterator find(const key_type &key) const
Index value associated with a key.
Definition: map.h:618
iterator end() const
Definition: map.h:645
Map(std::initializer_list< std::pair< K, V >> init)
constructor from initializer list
Definition: map.h:1324
int64_t difference_type
Definition: map.h:1414
size_t count(const key_type &key) const
Definition: map.h:600
iterator find(const K &key) const
Definition: map.h:1380
size_t count(const K &key) const
Definition: map.h:1353
ObjectPtr< Object > data_
Internal pointer that backs the reference.
Definition: object.h:574
pointer operator->() const
De-reference iterators.
Definition: map.h:1147
PrimExpr max(PrimExpr a, PrimExpr b, Span span=Span())
take maximum of two values
iterator begin() const
Definition: map.h:1376
String-aware ObjectRef equal functor.
Definition: base.h:40
void * AddressOf(size_t idx) const
Return the raw pointer to the element at idx.
Definition: base.h:169
static constexpr const uint32_t _type_index
Definition: map.h:188
#define TVM_DISPATCH_MAP_CONST(base, var, body)
Definition: map.h:1133
#define TVM_MAP_FAIL_IF_CHANGED()
Definition: map.h:45
const MapNode * self
The container it points to.
Definition: map.h:295
KVType value_type
Definition: map.h:240
KVType & reference
Definition: map.h:242
A specialization of hash map that implements the idea of array-based hash map. Another reference impl...
Definition: map.h:571
Base class of all object reference.
Definition: object.h:511
iterator & operator--()
Prefix self decrement, e.g. –iter.
Definition: map.h:1160
Shared content of all specializations of hash map.
Definition: map.h:174
T * get() const
Definition: object.h:411
iterator operator--(int)
Suffix self decrement.
Definition: map.h:275
iterator end() const
Definition: map.h:1378
const V at(const K &key) const
Read element from map.
Definition: map.h:1340
Map(Map< K, V > &&other)
move constructor
Definition: map.h:1281
iterator find(const key_type &key) const
Index value associated with a key.
Definition: map.h:1188
reference operator*() const
De-reference iterators.
Definition: map.h:259
size_t size() const
Definition: map.h:1348
Map< K, V > Merge(Map< K, V > lhs, const Map< K, V > &rhs)
Merge two Maps.
Definition: map.h:1468
void erase(const iterator &position)
Erase the entry associated with the iterator.
Definition: map.h:626
Map container of NodeRef->NodeRef in DSL graph. Map implements copy on write semantics, which means map is mutable but copy will happen when array is referenced in more than two places.
Definition: map.h:1268
Optional container that to represent to a Nullable variant of T.
Definition: optional.h:51
void erase(const key_type &key)
Erase the entry associated with the key, do nothing if not exists.
Definition: map.h:234
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
bool operator==(const iterator &other) const
Compare iterators.
Definition: map.h:250
friend class Map
Definition: map.h:337
KVType * pointer
Definition: map.h:241
value_type reference
Definition: map.h:1417
void Set(const K &key, const V &value)
set the Map.
Definition: map.h:1371
reference operator*() const
De-reference iterators.
Definition: map.h:1428
Helper to represent nullptr for optional.
Definition: optional.h:35
size_t count(const key_type &key) const
Count the number of times a key exists in the hash map.
Definition: map.h:1168
void clear()
Release reference to all the elements.
Definition: map.h:1360
iterator()
Definition: map.h:1419
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:1172
iterator operator++(int)
Suffix self increment.
Definition: map.h:1438
Additional scheduable attributes about IterVar.
Definition: schedule.h:466
std::pair< ObjectRef, ObjectRef > KVType
Type of value stored in the hash map.
Definition: map.h:181
uint64_t size_
number of entries in the container
Definition: map.h:334
void erase(const iterator &position)
Erase the entry associated with the iterator.
Definition: map.h:1192
Iterator of the hash map.
Definition: map.h:1411
uint64_t index
The position on the array.
Definition: map.h:293