This is an automated email from the ASF dual-hosted git repository.

ruihangl pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/main by this push:
     new 5a54d969e8 [FFI] Fix SmallMapInit with duplicated keys (#18178)
5a54d969e8 is described below

commit 5a54d969e82230b617904688f3e0f154d287b2ca
Author: Tianqi Chen <[email protected]>
AuthorDate: Thu Jul 31 14:48:10 2025 -0400

    [FFI] Fix SmallMapInit with duplicated keys (#18178)
    
    This PR fixes Small map init when there are duplicated keys
---
 ffi/include/tvm/ffi/container/map.h | 30 ++++++++++++++++++++----------
 ffi/tests/cpp/test_map.cc           |  7 +++++++
 2 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/ffi/include/tvm/ffi/container/map.h 
b/ffi/include/tvm/ffi/container/map.h
index fc94ab15a8..7892e20085 100644
--- a/ffi/include/tvm/ffi/container/map.h
+++ b/ffi/include/tvm/ffi/container/map.h
@@ -1264,17 +1264,27 @@ inline ObjectPtr<Object> 
MapObj::CreateFromRange(IterType first, IterType last)
   }
   uint64_t cap = static_cast<uint64_t>(_cap);
   if (cap < SmallMapObj::kMaxSize) {
-    return SmallMapObj::CreateFromRange(cap, first, last);
-  }
-  uint32_t fib_shift;
-  uint64_t n_slots;
-  DenseMapObj::CalcTableSize(cap, &fib_shift, &n_slots);
-  ObjectPtr<Object> obj = DenseMapObj::Empty(fib_shift, n_slots);
-  for (; first != last; ++first) {
-    KVType kv(*first);
-    DenseMapObj::InsertMaybeReHash(std::move(kv), &obj);
+    if (cap < 2) {
+      return SmallMapObj::CreateFromRange(cap, first, last);
+    }
+    // need to insert to avoid duplicate keys
+    ObjectPtr<Object> obj = SmallMapObj::Empty(cap);
+    for (; first != last; ++first) {
+      KVType kv(*first);
+      SmallMapObj::InsertMaybeReHash(std::move(kv), &obj);
+    }
+    return obj;
+  } else {
+    uint32_t fib_shift;
+    uint64_t n_slots;
+    DenseMapObj::CalcTableSize(cap, &fib_shift, &n_slots);
+    ObjectPtr<Object> obj = DenseMapObj::Empty(fib_shift, n_slots);
+    for (; first != last; ++first) {
+      KVType kv(*first);
+      DenseMapObj::InsertMaybeReHash(std::move(kv), &obj);
+    }
+    return obj;
   }
-  return obj;
 }
 
 inline void MapObj::InsertMaybeReHash(KVType&& kv, ObjectPtr<Object>* map) {
diff --git a/ffi/tests/cpp/test_map.cc b/ffi/tests/cpp/test_map.cc
index b7c977fd34..98d8427c23 100644
--- a/ffi/tests/cpp/test_map.cc
+++ b/ffi/tests/cpp/test_map.cc
@@ -356,4 +356,11 @@ TEST(Map, EmptyIter) {
   // now m0 is dense map with all empty slots
   EXPECT_EQ(m0.begin(), m0.end());
 }
+
+TEST(Map, DuplicatedKeysInit) {
+  std::vector<std::pair<String, int>> data = {{"a", 1}, {"a", 2}, {"a", 3}};
+  Map<String, int> map(data.begin(), data.end());
+  EXPECT_EQ(map.size(), 1);
+  EXPECT_EQ(map["a"], 3);
+}
 }  // namespace

Reply via email to