Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[SMPI] Add code to support std::tuple for std::unordered_map
authorChristian Heinrich <franz-christian.heinrich@inria.fr>
Fri, 13 Apr 2018 07:26:54 +0000 (09:26 +0200)
committerChristian Heinrich <franz-christian.heinrich@inria.fr>
Fri, 13 Apr 2018 08:28:14 +0000 (10:28 +0200)
This is currently in the replay file because it's only needed there.
I hope that a better solution can be proposed (or we should move
this to a header file).

The reason for adding this code here is that it will be used in
future commits (for identifying replay send/recv actions through
triplets, (src,dst,tag)).

This commit has been split from others to make the commits smaller.

src/smpi/internals/smpi_replay.cpp

index de58629..7eb9815 100644 (file)
 
 using simgrid::s4u::Actor;
 
+#include <tuple>
+// From https://stackoverflow.com/questions/7110301/generic-hash-for-tuples-in-unordered-map-unordered-set
+// This is all just to make std::unordered_map work with std::tuple. If we need this in other places,
+// this could go into a header file.
+namespace hash_tuple{
+    template <typename TT>
+    struct hash
+    {
+        size_t
+        operator()(TT const& tt) const
+        {
+            return std::hash<TT>()(tt);
+        }
+    };
+
+    template <class T>
+    inline void hash_combine(std::size_t& seed, T const& v)
+    {
+        seed ^= hash_tuple::hash<T>()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
+    }
+
+    // Recursive template code derived from Matthieu M.
+    template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1>
+    struct HashValueImpl
+    {
+      static void apply(size_t& seed, Tuple const& tuple)
+      {
+        HashValueImpl<Tuple, Index-1>::apply(seed, tuple);
+        hash_combine(seed, std::get<Index>(tuple));
+      }
+    };
+
+    template <class Tuple>
+    struct HashValueImpl<Tuple,0>
+    {
+      static void apply(size_t& seed, Tuple const& tuple)
+      {
+        hash_combine(seed, std::get<0>(tuple));
+      }
+    };
+
+    template <typename ... TT>
+    struct hash<std::tuple<TT...>>
+    {
+        size_t
+        operator()(std::tuple<TT...> const& tt) const
+        {
+            size_t seed = 0;
+            HashValueImpl<std::tuple<TT...> >::apply(seed, tt);
+            return seed;
+        }
+    };
+}
+
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_replay,smpi,"Trace Replay with SMPI");
 
 static std::unordered_map<int, std::vector<MPI_Request>*> reqq;