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 (USE_FALLBACK_STL_MAP != 0) 44 class MapNode :
public Object {
51 using ContainerType = std::unordered_map<ObjectRef, ObjectRef, ObjectHash, ObjectEqual>;
53 using iterator = ContainerType::iterator;
55 using const_iterator = ContainerType::const_iterator;
57 using KVType = ContainerType::value_type;
59 static_assert(std::is_standard_layout<KVType>::value,
"KVType is not standard layout");
60 static_assert(
sizeof(
KVType) == 16 ||
sizeof(
KVType) == 8,
"sizeof(KVType) incorrect");
63 static constexpr
const char*
_type_key =
"Map";
70 size_t size()
const {
return data_.size(); }
76 size_t count(
const key_type& key)
const {
return data_.count(key); }
90 iterator
begin() {
return data_.begin(); }
92 const_iterator
begin()
const {
return data_.begin(); }
94 iterator
end() {
return data_.end(); }
96 const_iterator
end()
const {
return data_.end(); }
102 const_iterator
find(
const key_type& key)
const {
return data_.find(key); }
108 iterator
find(
const key_type& key) {
return data_.find(key); }
113 void erase(
const iterator& position) { data_.erase(position); }
123 static ObjectPtr<MapNode>
Empty() {
return make_object<MapNode>(); }
133 template <
typename IterType>
134 static ObjectPtr<Object>
CreateFromRange(IterType first, IterType last) {
135 ObjectPtr<MapNode> p = make_object<MapNode>();
136 p->data_ = ContainerType(first, last);
145 MapNode* map_node =
static_cast<MapNode*
>(map->get());
146 map_node->data_[kv.first] = kv.second;
153 static ObjectPtr<MapNode>
CopyFrom(MapNode* from) {
154 ObjectPtr<MapNode> p = make_object<MapNode>();
155 p->data_ = ContainerType(from->data_.begin(), from->data_.end());
160 template <
typename,
typename,
typename,
typename>
174 using KVType = std::pair<ObjectRef, ObjectRef>;
178 static_assert(std::is_standard_layout<KVType>::value,
"KVType is not standard layout");
179 static_assert(
sizeof(
KVType) == 16 ||
sizeof(
KVType) == 8,
"sizeof(KVType) incorrect");
240 return index == other.
index &&
self == other.
self;
290 template <
typename IterType>
309 template <
typename,
typename,
typename,
typename>
317 static constexpr uint64_t kInitSize = 2;
318 static constexpr uint64_t kMaxSize = 4;
339 ICHECK(itr.
index <
size_) <<
"IndexError: key is not in Map";
349 ICHECK(itr.
index <
size_) <<
"IndexError: key is not in Map";
363 for (uint64_t i = 0; i <
size_; ++i, ++ptr) {
381 void Erase(
const uint64_t index) {
382 if (index >=
size_) {
387 if (index + 1 ==
size_) {
388 last->first.ObjectRef::~ObjectRef();
389 last->second.ObjectRef::~ObjectRef();
391 *(begin + index) = std::move(*last);
415 template <
typename IterType>
419 for (; first != last; ++first, ++p->size_) {
420 new (ptr++)
KVType(*first);
443 itr->second = kv.second;
452 uint64_t next_size =
std::max(map_node->
slots_ * 2, uint64_t(kInitSize));
453 next_size =
std::min(next_size, uint64_t(kMaxSize));
454 ICHECK_GT(next_size, map_node->
slots_);
457 *map = std::move(new_map);
464 uint64_t IncItr(uint64_t index)
const {
return index + 1 <
size_ ? index + 1 :
size_; }
470 uint64_t DecItr(uint64_t index)
const {
return index > 0 ? index - 1 :
size_; }
476 KVType* DeRefItr(uint64_t index)
const {
return static_cast<KVType*
>(AddressOf(index)); }
478 uint64_t GetSize()
const {
return size_; }
547 static constexpr
int kBlockCap = 16;
549 static constexpr
double kMaxLoadFactor = 0.99;
551 static constexpr uint8_t kEmptySlot = uint8_t(0b11111111);
553 static constexpr uint8_t kProtectedSlot = uint8_t(0b11111110);
555 static constexpr
int kNumJumpDists = 126;
560 uint8_t bytes[kBlockCap + kBlockCap *
sizeof(
KVType)];
562 static_assert(
sizeof(Block) == kBlockCap * (
sizeof(
KVType) + 1),
"sizeof(Block) incorrect");
563 static_assert(std::is_standard_layout<Block>::value,
"Block is not standard layout");
592 ListNode node = Search(key);
593 return node.IsNone() ?
end() :
iterator(node.index,
this);
600 uint64_t index = position.
index;
601 if (position.
self !=
nullptr && index <= this->
slots_) {
602 Erase(ListNode(index,
this));
610 for (uint64_t index = 0; index <=
slots_; ++index) {
611 if (!ListNode(index,
this).IsEmpty()) {
626 ListNode Search(
const key_type& key)
const {
627 if (this->
size_ == 0) {
630 for (ListNode iter = GetListHead(
ObjectHash()(key)); !iter.IsNone(); iter.MoveToNext(
this)) {
643 ListNode iter = Search(key);
644 ICHECK(!iter.IsNone()) <<
"IndexError: key is not in Map";
653 bool TryInsert(
const key_type& key, ListNode* result) {
658 ListNode iter = IndexFromHash(
ObjectHash()(key));
661 if (iter.IsEmpty()) {
668 if (!iter.IsHead()) {
670 return IsFull() ? false : TrySpareListHead(iter, key, result);
675 ListNode next = iter;
684 }
while (next.MoveToNext(
this));
692 if (!iter.GetNextEmpty(
this, &jump, result)) {
712 bool TrySpareListHead(ListNode target,
const key_type& key, ListNode* result) {
723 ListNode w = target.FindPrev(
this);
725 bool is_first =
true;
726 uint8_t r_meta, jump;
731 if (!w.GetNextEmpty(
this, &jump, &empty)) {
735 empty.NewTail(std::move(r.Data()));
748 }
while (r.MoveToNext(
this, r_meta));
760 void Erase(
const ListNode& iter) {
762 if (!iter.HasNext()) {
764 if (!iter.IsHead()) {
766 iter.FindPrev(
this).SetJump(0);
768 iter.Data().KVType::~KVType();
771 ListNode last = iter, prev = iter;
772 for (last.MoveToNext(
this); last.HasNext(); prev = last, last.MoveToNext(
this)) {
774 iter.Data() = std::move(last.Data());
781 uint64_t n_blocks = CalcNumBlocks(this->
slots_);
782 for (uint64_t bi = 0; bi < n_blocks; ++bi) {
783 uint8_t* meta_ptr = data_[bi].bytes;
784 KVType* data_ptr =
reinterpret_cast<KVType*
>(data_[bi].bytes + kBlockCap);
785 for (
int j = 0; j < kBlockCap; ++j, ++meta_ptr, ++data_ptr) {
786 uint8_t& meta = *meta_ptr;
787 if (meta != uint8_t(kProtectedSlot) && meta != uint8_t(kEmptySlot)) {
788 meta = uint8_t(kEmptySlot);
789 data_ptr->KVType::~KVType();
797 void ReleaseMemory() {
811 ICHECK_GT(n_slots, uint64_t(SmallMapNode::kMaxSize));
813 uint64_t n_blocks = CalcNumBlocks(n_slots - 1);
814 Block* block = p->data_ =
new Block[n_blocks];
815 p->slots_ = n_slots - 1;
817 p->fib_shift_ = fib_shift;
818 for (uint64_t i = 0; i < n_blocks; ++i, ++block) {
819 std::fill(block->bytes, block->bytes + kBlockCap, uint8_t(kEmptySlot));
830 uint64_t n_blocks = CalcNumBlocks(from->
slots_);
831 p->data_ =
new Block[n_blocks];
833 p->size_ = from->
size_;
835 for (uint64_t bi = 0; bi < n_blocks; ++bi) {
836 uint8_t* meta_ptr_from = from->
data_[bi].bytes;
837 KVType* data_ptr_from =
reinterpret_cast<KVType*
>(from->
data_[bi].bytes + kBlockCap);
838 uint8_t* meta_ptr_to = p->data_[bi].bytes;
839 KVType* data_ptr_to =
reinterpret_cast<KVType*
>(p->data_[bi].bytes + kBlockCap);
840 for (
int j = 0; j < kBlockCap;
841 ++j, ++meta_ptr_from, ++data_ptr_from, ++meta_ptr_to, ++data_ptr_to) {
842 uint8_t& meta = *meta_ptr_to = *meta_ptr_from;
843 ICHECK(meta != kProtectedSlot);
844 if (meta != uint8_t(kEmptySlot)) {
845 new (data_ptr_to)
KVType(*data_ptr_from);
860 if (map_node->TryInsert(kv.first, &iter)) {
861 iter.Val() = kv.second;
864 ICHECK_GT(map_node->
slots_, uint64_t(SmallMapNode::kMaxSize));
869 uint64_t n_blocks = CalcNumBlocks(map_node->
slots_);
871 for (uint64_t bi = 0; bi < n_blocks; ++bi) {
872 uint8_t* meta_ptr = map_node->
data_[bi].bytes;
873 KVType* data_ptr =
reinterpret_cast<KVType*
>(map_node->
data_[bi].bytes + kBlockCap);
874 for (
int j = 0; j < kBlockCap; ++j, ++meta_ptr, ++data_ptr) {
875 uint8_t& meta = *meta_ptr;
876 if (meta != uint8_t(kProtectedSlot) && meta != uint8_t(kEmptySlot)) {
877 meta = uint8_t(kEmptySlot);
878 KVType kv = std::move(*data_ptr);
883 map_node->ReleaseMemory();
890 bool IsFull()
const {
return size_ + 1 > (
slots_ + 1) * kMaxLoadFactor; }
896 uint64_t IncItr(uint64_t index)
const {
897 for (++index; index <=
slots_; ++index) {
898 if (!ListNode(index,
this).IsEmpty()) {
909 uint64_t DecItr(uint64_t index)
const {
912 if (!ListNode(index,
this).IsEmpty()) {
923 KVType* DeRefItr(uint64_t index)
const {
return &ListNode(index,
this).Data(); }
925 ListNode IndexFromHash(uint64_t hash_value)
const {
926 return ListNode(FibHash(hash_value, fib_shift_),
this);
929 ListNode GetListHead(uint64_t hash_value)
const {
930 ListNode node = IndexFromHash(hash_value);
931 return node.IsHead() ? node : ListNode();
934 static uint64_t CalcNumBlocks(uint64_t n_slots_m1) {
935 uint64_t n_slots = n_slots_m1 > 0 ? n_slots_m1 + 1 : 0;
936 return (n_slots + kBlockCap - 1) / kBlockCap;
944 static void CalcTableSize(uint64_t cap, uint32_t* fib_shift, uint64_t* n_slots) {
947 for (uint64_t c = cap; c; c >>= 1) {
951 ICHECK_GT(slots, cap);
952 if (slots < cap * 2) {
953 *fib_shift = shift - 1;
954 *n_slots = slots << 1;
967 static uint64_t FibHash(uint64_t hash_value, uint32_t fib_shift) {
968 constexpr uint64_t coeff = 11400714819323198485ull;
969 return (coeff * hash_value) >> fib_shift;
974 ListNode() : index(0), block(
nullptr) {}
977 : index(index), block(self->data_ + (index / kBlockCap)) {}
979 uint8_t& Meta()
const {
return *(block->bytes + index % kBlockCap); }
982 return *(
reinterpret_cast<KVType*
>(block->bytes + kBlockCap +
983 (index % kBlockCap) *
sizeof(
KVType)));
986 key_type& Key()
const {
return Data().first; }
990 bool IsHead()
const {
return (Meta() & 0b10000000) == 0b00000000; }
992 bool IsNone()
const {
return block ==
nullptr; }
994 bool IsEmpty()
const {
return Meta() == uint8_t(kEmptySlot); }
996 bool IsProtected()
const {
return Meta() == uint8_t(kProtectedSlot); }
998 void SetEmpty()
const { Meta() = uint8_t(kEmptySlot); }
1000 void SetProtected()
const { Meta() = uint8_t(kProtectedSlot); }
1002 void SetJump(uint8_t jump)
const { (Meta() &= 0b10000000) |= jump; }
1004 void NewHead(
KVType v)
const {
1005 Meta() = 0b00000000;
1006 new (&Data())
KVType(std::move(v));
1009 void NewTail(
KVType v)
const {
1010 Meta() = 0b10000000;
1011 new (&Data())
KVType(std::move(v));
1014 bool HasNext()
const {
return kNextProbeLocation[Meta() & 0b01111111] != 0; }
1016 bool MoveToNext(
const DenseMapNode*
self, uint8_t meta) {
1017 uint64_t offset = kNextProbeLocation[meta & 0b01111111];
1023 index = (index + offset) & (self->slots_);
1024 block =
self->data_ + (index / kBlockCap);
1028 bool MoveToNext(
const DenseMapNode*
self) {
return MoveToNext(
self, Meta()); }
1032 ListNode next =
self->IndexFromHash(
ObjectHash()(Key()));
1034 ListNode prev = next;
1035 for (next.MoveToNext(
self); index != next.index; prev = next, next.MoveToNext(
self)) {
1040 bool GetNextEmpty(
const DenseMapNode*
self, uint8_t* jump, ListNode* result)
const {
1041 for (uint8_t idx = 1; idx < kNumJumpDists; ++idx) {
1042 ListNode candidate((index + kNextProbeLocation[idx]) & (self->slots_),
self);
1043 if (candidate.IsEmpty()) {
1045 *result = candidate;
1064 TVM_DLL
static constexpr uint64_t kNextProbeLocation[kNumJumpDists] {
1065 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1070 21, 28, 36, 45, 55, 66, 78, 91, 105, 120,
1071 136, 153, 171, 190, 210, 231, 253, 276, 300, 325,
1072 351, 378, 406, 435, 465, 496, 528, 561, 595, 630,
1073 666, 703, 741, 780, 820, 861, 903, 946, 990, 1035,
1074 1081, 1128, 1176, 1225, 1275, 1326, 1378, 1431, 1485, 1540,
1075 1596, 1653, 1711, 1770, 1830, 1891, 1953, 2016, 2080, 2145,
1076 2211, 2278, 2346, 2415, 2485, 2556, 2628,
1078 8515, 19110, 42778, 96141, 216153,
1079 486591, 1092981, 2458653, 5532801, 12442566,
1080 27993903, 62983476, 141717030, 318844378, 717352503,
1081 1614057336, 3631522476, 8170957530, 18384510628, 41364789378,
1082 93070452520, 209408356380, 471168559170, 1060128894105, 2385289465695,
1083 5366898840628, 12075518705635, 27169915244790, 61132312065111, 137547689707000,
1084 309482283181501, 696335127828753, 1566753995631385, 3525196511162271, 7931691992677701,
1085 17846306936293605, 40154190677507445, 90346928918121501, 203280589587557251, 457381325854679626,
1086 1029107982097042876, 2315492959180353330, 5209859154120846435,
1092 #define TVM_DISPATCH_MAP(base, var, body) \ 1094 using TSmall = SmallMapNode*; \ 1095 using TDense = DenseMapNode*; \ 1096 uint64_t slots = base->slots_; \ 1097 if (slots <= SmallMapNode::kMaxSize) { \ 1098 TSmall var = static_cast<TSmall>(base); \ 1101 TDense var = static_cast<TDense>(base); \ 1106 #define TVM_DISPATCH_MAP_CONST(base, var, body) \ 1108 using TSmall = const SmallMapNode*; \ 1109 using TDense = const DenseMapNode*; \ 1110 uint64_t slots = base->slots_; \ 1111 if (slots <= SmallMapNode::kMaxSize) { \ 1112 TSmall var = static_cast<TSmall>(base); \ 1115 TDense var = static_cast<TDense>(base); \ 1126 index = p->IncItr(index);
1133 index = p->DecItr(index);
1166 #undef TVM_DISPATCH_MAP 1167 #undef TVM_DISPATCH_MAP_CONST 1172 if (from->slots_ <= SmallMapNode::kMaxSize) {
1173 return SmallMapNode::CopyFrom(static_cast<SmallMapNode*>(from));
1175 return DenseMapNode::CopyFrom(static_cast<DenseMapNode*>(from));
1179 template <
typename IterType>
1181 int64_t _cap = std::distance(first, last);
1185 uint64_t cap =
static_cast<uint64_t
>(_cap);
1186 if (cap < SmallMapNode::kMaxSize) {
1187 return SmallMapNode::CreateFromRange(cap, first, last);
1191 DenseMapNode::CalcTableSize(cap, &fib_shift, &n_slots);
1193 for (; first != last; ++first) {
1195 DenseMapNode::InsertMaybeReHash(kv, &obj);
1201 constexpr uint64_t kSmallMapMaxSize = SmallMapNode::kMaxSize;
1203 if (base->slots_ < kSmallMapMaxSize) {
1204 SmallMapNode::InsertMaybeReHash(kv, map);
1205 }
else if (base->slots_ == kSmallMapMaxSize) {
1206 if (base->size_ < base->slots_) {
1207 SmallMapNode::InsertMaybeReHash(kv, map);
1210 DenseMapNode::InsertMaybeReHash(kv, &new_map);
1211 *map = std::move(new_map);
1214 DenseMapNode::InsertMaybeReHash(kv, map);
1232 template <
typename K,
typename V,
1233 typename =
typename std::enable_if<std::is_base_of<ObjectRef, K>::value>::type,
1234 typename =
typename std::enable_if<std::is_base_of<ObjectRef, V>::value>::type>
1260 data_ = std::move(other.data_);
1269 data_ = other.
data_;
1283 template <
typename IterType>
1291 Map(std::initializer_list<std::pair<K, V>> init) {
1298 template <
typename Hash,
typename Equal>
1299 Map(
const std::unordered_map<K, V, Hash, Equal>& init) {
1307 const V
at(
const K& key)
const {
return DowncastNoCheck<V>(GetMapNode()->at(key)); }
1317 return n ==
nullptr ? 0 : n->size();
1322 return n ==
nullptr ? 0 : GetMapNode()->count(key);
1338 void Set(
const K& key,
const V& value) {
1343 iterator
begin()
const {
return iterator(GetMapNode()->
begin()); }
1345 iterator
end()
const {
return iterator(GetMapNode()->
end()); }
1347 iterator
find(
const K& key)
const {
return iterator(GetMapNode()->
find(key)); }
1351 if (iter == GetMapNode()->
end()) {
1354 return DowncastNoCheck<V>(iter->second);
1356 void erase(
const K& key) { CopyOnWrite()->erase(key); }
1367 if (data_.get() ==
nullptr) {
1369 }
else if (!data_.unique()) {
1372 return GetMapNode();
1393 pointer operator->()
const =
delete;
1397 return std::make_pair(DowncastNoCheck<K>(kv.first), DowncastNoCheck<V>(kv.second));
1415 template <
typename,
typename,
typename,
typename>
1423 MapNode* GetMapNode()
const {
return static_cast<MapNode*
>(data_.get()); }
1432 template <
typename K,
typename V,
1433 typename =
typename std::enable_if<std::is_base_of<ObjectRef, K>::value>::type,
1434 typename =
typename std::enable_if<std::is_base_of<ObjectRef, V>::value>::type>
1436 for (
const auto& p : rhs) {
1437 lhs.
Set(p.first, p.second);
1439 return std::move(lhs);
1449 #endif // TVM_RUNTIME_CONTAINER_MAP_H_ value_type * pointer
Definition: map.h:1383
String-aware ObjectRef hash functor.
Definition: base.h:50
static constexpr const char * _type_key
Definition: map.h:182
runtime::Map.
Definition: object.h:70
Block * data_
array of data blocks
Definition: map.h:1061
std::bidirectional_iterator_tag iterator_category
Definition: map.h:1380
std::forward_iterator_tag iterator_category
Definition: map.h:231
PrimExpr min(PrimExpr a, PrimExpr b, Span span=Span())
take minimum of two values
int64_t difference_type
Definition: map.h:232
Map< K, V > & operator=(const Map< K, V > &other)
move assign operator
Definition: map.h:1268
A custom smart pointer for Object.
Definition: object.h:356
Runtime Optional container types.
const V operator[](const K &key) const
Read element from map.
Definition: map.h:1313
ObjectRef key_type
Type of the keys in the hash map.
Definition: map.h:170
iterator begin() const
Definition: map.h:1150
uint64_t slots_
number of slots minus 1
Definition: map.h:305
Map()
default constructor
Definition: map.h:1243
const std::pair< K, V > value_type
Definition: map.h:1382
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:337
bool operator!=(const iterator &other) const
Compare iterators.
Definition: map.h:243
bool operator!=(const iterator &other) const
Compare iterators.
Definition: map.h:1391
void erase(const iterator &position)
Erase the entry associated with the iterator.
Definition: map.h:374
iterator end() const
Definition: map.h:355
#define TVM_DISPATCH_MAP(base, var, body)
Definition: map.h:1092
mapped_type & at(const key_type &key)
Index value associated with a key, throw exception if the key does not exist.
Definition: map.h:585
Map< K, V > & operator=(Map< K, V > &&other)
copy assign operator
Definition: map.h:1259
Performance counters for profiling via the PAPI library.
Definition: analyzer.h:36
static void InsertMaybeReHash(const KVType &kv, ObjectPtr< Object > *map)
InsertMaybeReHash an entry into the given hash map.
Definition: map.h:1200
iterator()
Default constructor.
Definition: map.h:237
Object()
Definition: object.h:239
bool operator==(const iterator &other) const
Compare iterators.
Definition: map.h:1389
iterator begin() const
Definition: map.h:353
uint32_t fib_shift_
fib shift in Fibonacci Hashing
Definition: map.h:1059
iterator & operator++()
Prefix self increment, e.g. ++iter.
Definition: map.h:1124
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:1366
ObjectRef mapped_type
Type of the values in the hash map.
Definition: map.h:172
size_t size() const
Number of elements in the SmallMapNode.
Definition: map.h:189
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:579
TVM_DECLARE_FINAL_OBJECT_INFO(MapNode, Object)
Iteration Variable, represents an iteration over an integer interval.
Definition: var.h:297
Map(const std::unordered_map< K, V, Hash, Equal > &init)
constructor from unordered_map
Definition: map.h:1299
iterator & operator++()
Prefix self increment, e.g. ++iter.
Definition: map.h:1400
static ObjectPtr< MapNode > Empty()
Create an empty container.
Definition: map.h:1169
iterator operator++(int)
Suffix self increment.
Definition: map.h:253
bool empty() const
Definition: map.h:1325
Optional< V > Get(const K &key) const
Definition: map.h:1349
Base utilities for common POD(plain old data) container types.
Map(IterType begin, IterType end)
constructor from iterator
Definition: map.h:1284
Map(ObjectPtr< Object > n)
constructor from pointer
Definition: map.h:1276
iterator end() const
Definition: map.h:1154
iterator find(const key_type &key) const
Index value associated with a key.
Definition: map.h:361
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:165
~DenseMapNode()
Destroy the DenseMapNode.
Definition: map.h:571
A specialization of small-sized hash map.
Definition: map.h:314
iterator(uint64_t index, const MapNode *self)
Construct by value.
Definition: map.h:267
void erase(const K &key)
Definition: map.h:1356
Map(const Map< K, V > &other)
copy constructor
Definition: map.h:1253
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:1171
size_t count(const key_type &key) const
Count the number of times a key exists in the SmallMapNode.
Definition: map.h:331
static ObjectPtr< Object > CreateFromRange(IterType first, IterType last)
Create the map using contents from the given iterators.
Definition: map.h:1180
iterator begin() const
Definition: map.h:606
iterator find(const key_type &key) const
Index value associated with a key.
Definition: map.h:591
iterator end() const
Definition: map.h:618
Map(std::initializer_list< std::pair< K, V >> init)
constructor from initializer list
Definition: map.h:1291
int64_t difference_type
Definition: map.h:1381
size_t count(const key_type &key) const
Definition: map.h:573
iterator find(const K &key) const
Definition: map.h:1347
size_t count(const K &key) const
Definition: map.h:1320
ObjectPtr< Object > data_
Internal pointer that backs the reference.
Definition: object.h:567
pointer operator->() const
De-reference iterators.
Definition: map.h:1120
PrimExpr max(PrimExpr a, PrimExpr b, Span span=Span())
take maximum of two values
iterator begin() const
Definition: map.h:1343
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:181
#define TVM_DISPATCH_MAP_CONST(base, var, body)
Definition: map.h:1106
const MapNode * self
The container it points to.
Definition: map.h:271
KVType value_type
Definition: map.h:233
KVType & reference
Definition: map.h:235
A specialization of hash map that implements the idea of array-based hash map. Another reference impl...
Definition: map.h:544
Base class of all object reference.
Definition: object.h:504
iterator & operator--()
Prefix self decrement, e.g. –iter.
Definition: map.h:1131
Shared content of all specializations of hash map.
Definition: map.h:167
T * get() const
Definition: object.h:409
iterator operator--(int)
Suffix self decrement.
Definition: map.h:259
iterator end() const
Definition: map.h:1345
const V at(const K &key) const
Read element from map.
Definition: map.h:1307
Map(Map< K, V > &&other)
move constructor
Definition: map.h:1248
iterator find(const key_type &key) const
Index value associated with a key.
Definition: map.h:1158
reference operator*() const
De-reference iterators.
Definition: map.h:247
size_t size() const
Definition: map.h:1315
Map< K, V > Merge(Map< K, V > lhs, const Map< K, V > &rhs)
Merge two Maps.
Definition: map.h:1435
void erase(const iterator &position)
Erase the entry associated with the iterator.
Definition: map.h:599
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:1235
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:227
mapped_type & at(const key_type &key)
Index value associated with a key, throw exception if the key does not exist.
Definition: map.h:347
bool operator==(const iterator &other) const
Compare iterators.
Definition: map.h:239
friend class Map
Definition: map.h:310
KVType * pointer
Definition: map.h:234
value_type reference
Definition: map.h:1384
void Set(const K &key, const V &value)
set the Map.
Definition: map.h:1338
reference operator*() const
De-reference iterators.
Definition: map.h:1395
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:1138
void clear()
Release reference to all the elements.
Definition: map.h:1327
iterator()
Definition: map.h:1386
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:1142
iterator operator++(int)
Suffix self increment.
Definition: map.h:1405
Additional scheduable attributes about IterVar.
Definition: schedule.h:425
std::pair< ObjectRef, ObjectRef > KVType
Type of value stored in the hash map.
Definition: map.h:174
uint64_t size_
number of entries in the container
Definition: map.h:307
void erase(const iterator &position)
Erase the entry associated with the iterator.
Definition: map.h:1162
Iterator of the hash map.
Definition: map.h:1378
uint64_t index
The position on the array.
Definition: map.h:269