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 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;
1237 base->state_marker++;
1238 #endif // TVM_LOG_DEBUG 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) {
1379 iterator
begin()
const {
return iterator(GetMapNode()->
begin()); }
1381 iterator
end()
const {
return iterator(GetMapNode()->
end()); }
1383 iterator
find(
const K& key)
const {
return iterator(GetMapNode()->
find(key)); }
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();
1429 pointer operator->()
const =
delete;
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);
1485 #endif // TVM_RUNTIME_CONTAINER_MAP_H_ value_type * pointer
Definition: map.h:1419
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:1416
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:1304
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:1349
ObjectRef key_type
Type of the keys in the hash map.
Definition: map.h:177
iterator begin() const
Definition: map.h:1183
uint64_t slots_
number of slots minus 1
Definition: map.h:332
Map()
default constructor
Definition: map.h:1279
const std::pair< K, V > value_type
Definition: map.h:1418
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:1427
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:1122
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:1295
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:1233
iterator()
Default constructor.
Definition: map.h:247
static uint64_t NextProbeLocation(size_t index)
Definition: map.h:1089
Object()
Definition: object.h:241
bool operator==(const iterator &other) const
Compare iterators.
Definition: map.h:1425
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:1155
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:1402
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:308
Map(const std::unordered_map< K, V, Hash, Equal > &init)
constructor from unordered_map
Definition: map.h:1335
iterator & operator++()
Prefix self increment, e.g. ++iter.
Definition: map.h:1436
static ObjectPtr< MapNode > Empty()
Create an empty container.
Definition: map.h:1202
iterator operator++(int)
Suffix self increment.
Definition: map.h:268
bool empty() const
Definition: map.h:1361
Optional< V > Get(const K &key) const
Definition: map.h:1385
Base utilities for common POD(plain old data) container types.
Map(IterType begin, IterType end)
constructor from iterator
Definition: map.h:1320
Map(ObjectPtr< Object > n)
constructor from pointer
Definition: map.h:1312
iterator end() const
Definition: map.h:1187
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:1392
Map(const Map< K, V > &other)
copy constructor
Definition: map.h:1289
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:1204
size_t count(const key_type &key) const
Count the number of times a key exists in the SmallMapNode.
Definition: map.h:358
BlockFrame Block(String name, bool no_realize=false)
The block declaration statement.
static ObjectPtr< Object > CreateFromRange(IterType first, IterType last)
Create the map using contents from the given iterators.
Definition: map.h:1213
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:1327
int64_t difference_type
Definition: map.h:1417
size_t count(const key_type &key) const
Definition: map.h:600
iterator find(const K &key) const
Definition: map.h:1383
size_t count(const K &key) const
Definition: map.h:1356
ObjectPtr< Object > data_
Internal pointer that backs the reference.
Definition: object.h:574
pointer operator->() const
De-reference iterators.
Definition: map.h:1150
PrimExpr max(PrimExpr a, PrimExpr b, Span span=Span())
take maximum of two values
iterator begin() const
Definition: map.h:1379
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:1136
#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:1163
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:1381
const V at(const K &key) const
Read element from map.
Definition: map.h:1343
Map(Map< K, V > &&other)
move constructor
Definition: map.h:1284
iterator find(const key_type &key) const
Index value associated with a key.
Definition: map.h:1191
reference operator*() const
De-reference iterators.
Definition: map.h:259
size_t size() const
Definition: map.h:1351
Map< K, V > Merge(Map< K, V > lhs, const Map< K, V > &rhs)
Merge two Maps.
Definition: map.h:1471
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:1271
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:1420
void Set(const K &key, const V &value)
set the Map.
Definition: map.h:1374
reference operator*() const
De-reference iterators.
Definition: map.h:1431
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:1171
void clear()
Release reference to all the elements.
Definition: map.h:1363
iterator()
Definition: map.h:1422
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
iterator operator++(int)
Suffix self increment.
Definition: map.h:1441
Additional scheduable attributes about IterVar.
Definition: schedule.h:487
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:1195
Iterator of the hash map.
Definition: map.h:1414
uint64_t index
The position on the array.
Definition: map.h:293