You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by mo...@apache.org on 2021/04/07 04:19:52 UTC
[tvm] branch main updated: [FIX] Make HashCombine stable across
platforms (#7801)
This is an automated email from the ASF dual-hosted git repository.
moreau 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 3ce74f0 [FIX] Make HashCombine stable across platforms (#7801)
3ce74f0 is described below
commit 3ce74f00a5168473578d7e420c3824eed91a1f62
Author: Tristan Konolige <tr...@gmail.com>
AuthorDate: Tue Apr 6 21:19:34 2021 -0700
[FIX] Make HashCombine stable across platforms (#7801)
* [FIX] Make HashCombine stable across platforms
PR #7605 inadvertatly broke cross platform hashing when when it switched
size_t to uint64_t. This cause a different specialization of HashCombine
to be used. Unfortunately the new specialization used std::hash which is
implementation dependent. I've added tests to make sure this doesn't
happen again.
* fix template specialization issues
---
src/support/utils.h | 19 ++++++++-----------
tests/cpp/support_test.cc | 13 +++++++++++++
2 files changed, 21 insertions(+), 11 deletions(-)
diff --git a/src/support/utils.h b/src/support/utils.h
index 91b9c13..2f55d40 100644
--- a/src/support/utils.h
+++ b/src/support/utils.h
@@ -165,22 +165,19 @@ inline int Execute(std::string cmd, std::string* err_msg) {
#endif // __hexagon__
/*!
- * \brief Combine two hash values into a single one.
+ * \brief hash an object and combines uint64_t key with previous keys
+ *
+ * This hash function is stable across platforms.
+ *
* \param key The left operand.
* \param value The right operand.
* \return the combined result.
*/
-inline size_t HashCombine(size_t key, size_t value) {
- return key ^ (value + 0x9e3779b9 + (key << 6) + (key >> 2));
-}
-
-/*!
- * \brief hash an object and combines uint64_t key with previous keys
- */
-template <typename T>
+template <typename T, std::enable_if_t<std::is_convertible<T, uint64_t>::value, bool> = true>
inline uint64_t HashCombine(uint64_t key, const T& value) {
- std::hash<T> hash_func;
- return key ^ (hash_func(value) + 0x9e3779b9 + (key << 6) + (key >> 2));
+ // XXX: do not use std::hash in this function. This hash must be stable
+ // across different platforms and std::hash is implementation dependent.
+ return key ^ (uint64_t(value) + 0x9e3779b9 + (key << 6) + (key >> 2));
}
} // namespace support
diff --git a/tests/cpp/support_test.cc b/tests/cpp/support_test.cc
index bc9b944..7d523fe 100644
--- a/tests/cpp/support_test.cc
+++ b/tests/cpp/support_test.cc
@@ -21,6 +21,7 @@
#include <gtest/gtest.h>
#include "../../src/support/hexdump.h"
+#include "../../src/support/utils.h"
namespace tvm {
namespace test {
@@ -43,6 +44,18 @@ TEST(HexDumpTests, Unaligned) {
"\x01\x23\x45\x67\x89\xab\xcd\xef\x01"));
}
+TEST(HashTests, HashStability) {
+ size_t a = 345292;
+ int b = 795620;
+ EXPECT_EQ(::tvm::support::HashCombine(a, b), 2677237020);
+ uint64_t c = 12345;
+ int d = 987654432;
+ EXPECT_EQ(::tvm::support::HashCombine(c, d), 3642871070);
+ size_t e = 1010101;
+ size_t f = 3030303;
+ EXPECT_EQ(::tvm::support::HashCombine(e, f), 2722928432);
+}
+
} // namespace test
} // namespace tvm