diff --git a/src/hasher.cc b/src/hasher.cc index 1f41ea5..a45c4ff 100644 --- a/src/hasher.cc +++ b/src/hasher.cc @@ -26,12 +26,6 @@ static void hash_bytes(const uint8_t *input, size_t input_bytes, uint8_t *output siphash(input, input_bytes, k, output, output_bytes); } -Hasher::Hasher() {} - -void Hasher::hash_type_tag(HashTypeTag type_tag) { - buffer.write(reinterpret_cast(&type_tag), sizeof(type_tag)); -} - uint64_t Hasher::result() { uint64_t result; std::string content = std::move(buffer).str(); diff --git a/src/hasher.inl b/src/hasher.inl index dbeb26e..8f504b7 100644 --- a/src/hasher.inl +++ b/src/hasher.inl @@ -13,11 +13,7 @@ * limitations under the License. */ -enum HashTypeTag { -#if defined(__GNUC__) && !defined(__clang__) - INT_TYPE_ID, - LONG_LONG_TYPE_ID, -#endif +enum HashTypeIDs { INT32_T_TYPE_ID, UINT32_T_TYPE_ID, INT64_T_TYPE_ID, @@ -28,191 +24,71 @@ enum HashTypeTag { LEGION_DOMAIN_TYPE_ID, }; -template -class HashTypeTagAdapter {}; - -template -class HashValueAdapter {}; - class Hasher { public: - Hasher(); - template - void hash(const T &value); + void hash(const T &value) { + hash_type_tag(value); + hash_value(value); + } uint64_t result(); private: - void hash_type_tag(HashTypeTag type_tag); - - template - void hash_value(const T &value); - + void hash_type_tag(int32_t value) { hash_raw(INT32_T_TYPE_ID); } + void hash_type_tag(uint32_t value) { hash_raw(UINT32_T_TYPE_ID); } + void hash_type_tag(int64_t value) { hash_raw(INT64_T_TYPE_ID); } + void hash_type_tag(uint64_t value) { hash_raw(UINT64_T_TYPE_ID); } template - void hash_value(const std::pair &value); - template - void hash_value(const std::vector &value); - - void hash_value(const Legion::DomainPoint &value); - void hash_value(const Legion::Domain &value); - -private: - std::stringstream buffer; - - template - friend class HashTypeTagAdapter; - - template - friend class HashValueAdapter; -}; - -// The only way in C++ to avoid implicit type conversion is to use an explicit -// constructor. The adapters below jump through the necessary hoops to make -// sure we don't perform implicit conversions by accident. - -#define DECLARE_TYPE_ADAPTER(W, W_TYPE_ID) \ - template <> \ - class HashTypeTagAdapter { \ - private: \ - explicit HashTypeTagAdapter(Hasher &hasher) { hasher.hash_type_tag(W_TYPE_ID); } \ - friend class Hasher; \ - template \ - friend class HashTypeTagAdapter; \ - }; - -#if defined(__GNUC__) && !defined(__clang__) -DECLARE_TYPE_ADAPTER(int, INT_TYPE_ID) -DECLARE_TYPE_ADAPTER(long long, LONG_LONG_TYPE_ID) -#endif -DECLARE_TYPE_ADAPTER(int32_t, INT32_T_TYPE_ID) -DECLARE_TYPE_ADAPTER(uint32_t, UINT32_T_TYPE_ID) -DECLARE_TYPE_ADAPTER(int64_t, INT64_T_TYPE_ID) -DECLARE_TYPE_ADAPTER(uint64_t, UINT64_T_TYPE_ID) -DECLARE_TYPE_ADAPTER(Legion::DomainPoint, LEGION_DOMAIN_POINT_TYPE_ID) -DECLARE_TYPE_ADAPTER(Legion::Domain, LEGION_DOMAIN_TYPE_ID) -#undef DECLARE_TYPE_ADAPTER - -template -class HashTypeTagAdapter> { -private: - explicit HashTypeTagAdapter(Hasher &hasher) { - hasher.hash_type_tag(STD_PAIR_TYPE_ID); - ::HashTypeTagAdapter{hasher}; - ::HashTypeTagAdapter{hasher}; + void hash_type_tag(const std::pair &value) { + hash_raw(STD_PAIR_TYPE_ID); + hash_type_tag(value.first); + hash_type_tag(value.second); } - friend class Hasher; - template - friend class HashTypeTagAdapter; -}; - -template -class HashTypeTagAdapter> { -private: - explicit HashTypeTagAdapter(Hasher &hasher) { - hasher.hash_type_tag(STD_VECTOR_TYPE_ID); - ::HashTypeTagAdapter{hasher}; + void hash_type_tag(const Legion::DomainPoint &value) { + hash_raw(LEGION_DOMAIN_POINT_TYPE_ID); } - friend class Hasher; - template - friend class HashTypeTagAdapter; -}; + void hash_type_tag(const Legion::Domain &value) { hash_raw(LEGION_DOMAIN_TYPE_ID); } -#define DECLARE_SIMPLE_VALUE_ADAPTER(W) \ - template <> \ - class HashValueAdapter { \ - private: \ - explicit HashValueAdapter(Hasher &hasher, const W &value) { \ - hasher.hash_value(value); \ - } \ - friend class Hasher; \ - template \ - friend class HashValueAdapter; \ - }; - -#if defined(__GNUC__) && !defined(__clang__) -DECLARE_SIMPLE_VALUE_ADAPTER(int) -DECLARE_SIMPLE_VALUE_ADAPTER(long long) -#endif -DECLARE_SIMPLE_VALUE_ADAPTER(int32_t) -DECLARE_SIMPLE_VALUE_ADAPTER(uint32_t) -DECLARE_SIMPLE_VALUE_ADAPTER(int64_t) -DECLARE_SIMPLE_VALUE_ADAPTER(uint64_t) -#undef DECLARE_SIMPLE_VALUE_ADAPTER - -template -class HashValueAdapter> { -private: - explicit HashValueAdapter(Hasher &hasher, const std::pair &value) { - ::HashValueAdapter{hasher, value.first}; - ::HashValueAdapter{hasher, value.second}; - } - friend class Hasher; - template - friend class HashValueAdapter; -}; - -template -class HashValueAdapter> { -private: - explicit HashValueAdapter(Hasher &hasher, const std::vector &value) { - ::HashValueAdapter{hasher, value.size()}; - for (const T &elem : value) { - ::HashValueAdapter{hasher, elem}; - } + void hash_value(int32_t value) { hash_raw(value); } + void hash_value(uint32_t value) { hash_raw(value); } + void hash_value(int64_t value) { hash_raw(value); } + void hash_value(uint64_t value) { hash_raw(value); } + template + void hash_value(const std::pair &value) { + hash_value(value.first); + hash_value(value.second); } - friend class Hasher; - template - friend class HashValueAdapter; -}; - -template <> -class HashValueAdapter { -private: - explicit HashValueAdapter(Hasher &hasher, const Legion::DomainPoint &value) { - int dim = value.get_dim(); - ::HashValueAdapter{hasher, dim}; - for (int idx = 0; idx < dim; ++idx) { - ::HashValueAdapter{hasher, value[idx]}; + void hash_value(const Legion::DomainPoint &value) { + int32_t dim = value.get_dim(); + hash_value(dim); + for (int32_t idx = 0; idx < dim; ++idx) { + hash_value(int64_t(value[idx])); } } - friend class Hasher; - template - friend class HashValueAdapter; -}; - -template <> -class HashValueAdapter { -private: - explicit HashValueAdapter(Hasher &hasher, const Legion::Domain &value) { + void hash_value(const Legion::Domain &value) { if (!value.dense()) { abort(); } - int dim = value.get_dim(); - ::HashValueAdapter{hasher, dim}; - for (int idx = 0; idx < dim; ++idx) { - ::HashValueAdapter{hasher, value.lo()[idx]}; - ::HashValueAdapter{hasher, value.hi()[idx]}; + int32_t dim = value.get_dim(); + hash_value(dim); + for (int32_t idx = 0; idx < dim; ++idx) { + hash_value(int64_t(value.lo()[idx])); + hash_value(int64_t(value.hi()[idx])); } } - friend class Hasher; - template - friend class HashValueAdapter; -}; -template -void Hasher::hash(const T &value) { - HashTypeTagAdapter{*this}; - HashValueAdapter{*this, value}; -} + template + void hash_raw(const T &value) { + // Ensure we use this only on POD types with no padding. + static_assert(std::is_trivially_copyable_v); + static_assert(std::has_unique_object_representations_v); + buffer.write(reinterpret_cast(&value), sizeof(value)); + } -template -void Hasher::hash_value(const T &value) { - // Ensure we use this only on POD types with no padding. - static_assert(std::is_trivially_copyable_v); - static_assert(std::has_unique_object_representations_v); - buffer.write(reinterpret_cast(&value), sizeof(value)); -} +private: + std::stringstream buffer; +}; template uint64_t hash(const T &value) { diff --git a/src/mapper.cc b/src/mapper.cc index d5b141c..a1d5b91 100644 --- a/src/mapper.cc +++ b/src/mapper.cc @@ -254,11 +254,11 @@ void FuzzMapper::select_steal_targets(const MapperContext ctx, const SelectStealingInput &input, SelectStealingOutput &output) {} -RngChannel FuzzMapper::make_task_channel(int mapper_call, +RngChannel FuzzMapper::make_task_channel(int32_t mapper_call, const Legion::Task &task) const { // TODO: index launches - static_assert(sizeof(MappingTagID) <= sizeof(uint64_t)); - return stream.make_channel(std::pair(mapper_call, uint64_t(task.tag))); + uint64_t tag = task.tag; + return stream.make_channel(std::pair(mapper_call, tag)); } Processor FuzzMapper::random_local_proc(RngChannel &rng) {