Add hash value typedef. (#9710)

Add a typedef for the various hash value variables. Use of a typedef conveys some additional meaning.
This commit is contained in:
Edward Chen 2021-12-15 19:07:17 -08:00 committed by GitHub
parent 4e73cc83d6
commit 3466ee45a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 70 additions and 52 deletions

View file

@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include <cstdint>
namespace onnxruntime {
/** A computed hash value. */
using HashValue = uint64_t;
} // namespace onnxruntime

View file

@ -4,13 +4,14 @@
#pragma once
#ifndef SHARED_PROVIDER
#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <memory>
#include "core/common/status.h"
#include "core/common/logging/logging.h"
#include "core/framework/tensor.h"
#include "core/common/status.h"
#include "core/framework/data_transfer.h"
#include "core/framework/tensor.h"
namespace onnxruntime {
@ -25,10 +26,11 @@ class KernelRegistryManager;
#include <memory>
#endif
#include "core/framework/provider_options.h"
#include "core/framework/func_api.h"
#include "core/framework/allocatormgr.h"
#include "core/common/basic_types.h"
#include "core/common/profiler_common.h"
#include "core/framework/allocatormgr.h"
#include "core/framework/func_api.h"
#include "core/framework/provider_options.h"
namespace onnxruntime {
@ -259,7 +261,7 @@ class IExecutionProvider {
NOTE: Ideally this would be a protected method, but to work across the EP bridge it has to be public and
virtual, and ModelMetadefIdGenerator but be defined in the header as well.
*/
virtual int GenerateMetaDefId(const onnxruntime::GraphViewer& graph_viewer, uint64_t& model_hash) const;
virtual int GenerateMetaDefId(const onnxruntime::GraphViewer& graph_viewer, HashValue& model_hash) const;
/**
Register allocators used for EP
@ -286,11 +288,11 @@ class IExecutionProvider {
// multiple sessions.
class ModelMetadefIdGenerator {
public:
int GenerateId(const onnxruntime::GraphViewer& graph_viewer, uint64_t& model_hash);
int GenerateId(const onnxruntime::GraphViewer& graph_viewer, HashValue& model_hash);
private:
std::unordered_map<uint64_t, int64_t> main_graph_hash_; // map graph instance hash to model contents hash
std::unordered_map<int64_t, int> model_metadef_id_; // current unique id for model
std::unordered_map<HashValue, HashValue> main_graph_hash_; // map graph instance hash to model contents hash
std::unordered_map<HashValue, int> model_metadef_id_; // current unique id for model
};
std::unique_ptr<ModelMetadefIdGenerator> metadef_id_generator_;

View file

@ -103,7 +103,7 @@ class KernelDef {
bool IsConflict(const KernelDef& other) const;
uint64_t GetHash() const noexcept {
HashValue GetHash() const noexcept {
// if we need to support different hash versions we can update CalculateHash to take a version number
// and calculate any non-default versions dynamically. we only use this during kernel lookup so
// it's not performance critical
@ -175,7 +175,7 @@ class KernelDef {
OrtMemType default_outputs_mem_type_{OrtMemTypeDefault};
// hash of kernel definition for lookup in minimal build
uint64_t hash_ = 0;
HashValue hash_ = 0;
};
class KernelDefBuilder {

View file

@ -8,7 +8,7 @@
namespace onnxruntime {
using KernelCreateMap = std::multimap<std::string, KernelCreateInfo>;
using KernelDefHashes = std::vector<std::pair<std::string, uint64_t>>;
using KernelDefHashes = std::vector<std::pair<std::string, HashValue>>;
/**
* Each provider has a KernelRegistry. Often, the KernelRegistry only belongs to that specific provider.
@ -48,7 +48,7 @@ class KernelRegistry {
#endif
// Try to find the kernel given a kernel def hash.
bool TryFindKernelByHash(uint64_t kernel_def_hash, const KernelCreateInfo** out) const;
bool TryFindKernelByHash(HashValue kernel_def_hash, const KernelCreateInfo** out) const;
bool IsEmpty() const { return kernel_creator_fn_map_.empty(); }
@ -97,6 +97,6 @@ class KernelRegistry {
KernelCreateMap kernel_creator_fn_map_;
// map from kernel def hash to entry in kernel_creator_fn_map_
std::unordered_map<uint64_t, KernelCreateMap::iterator> kernel_def_hash_lookup_;
std::unordered_map<HashValue, KernelCreateMap::iterator> kernel_def_hash_lookup_;
};
} // namespace onnxruntime

View file

@ -10,6 +10,8 @@
#include <memory>
#include <functional>
#include "core/common/basic_types.h"
namespace ONNX_NAMESPACE {
class ValueInfoProto;
class TensorProto;
@ -30,6 +32,7 @@ using NodeArgInfo = ONNX_NAMESPACE::ValueInfoProto;
using InitializedTensorSet = std::unordered_map<std::string, const ONNX_NAMESPACE::TensorProto*>;
using ArgNameToTypeMap = std::unordered_map<std::string, ONNX_NAMESPACE::TypeProto>;
using ProviderType = const std::string&;
// TODO - Evaluate switching the types below to support transparent comparators and enable
// lookups based on gsl::cstring_span<> and std::string_view. This would reduces allocations
// converting to std::string, but requires conversion to std::map<std::string, foo, std::less<>>
@ -38,9 +41,7 @@ using ProviderType = const std::string&;
using NodeAttributes = std::unordered_map<std::string, ONNX_NAMESPACE::AttributeProto>;
class IOnnxRuntimeOpSchemaCollection;
using IOnnxRuntimeOpSchemaCollectionPtr = std::shared_ptr<IOnnxRuntimeOpSchemaCollection>;
} // namespace onnxruntime
namespace onnxruntime {
class OpKernel;
class OpKernelInfo;

View file

@ -174,7 +174,7 @@ common::Status IExecutionProvider::Compile(const std::vector<FusedNodeAndGraph>&
#endif
int IExecutionProvider::ModelMetadefIdGenerator::GenerateId(const onnxruntime::GraphViewer& graph_viewer,
uint64_t& model_hash) {
HashValue& model_hash) {
model_hash = 0;
// find the top level graph
@ -191,7 +191,7 @@ int IExecutionProvider::ModelMetadefIdGenerator::GenerateId(const onnxruntime::G
// the same memory (unit tests prove this can occur). the raw bytes of the Graph instance should be a unique
// fingerprint for the instance that can use used as the key to the hash of the model path/contents.
MurmurHash3::x86_128(&main_graph, gsl::narrow_cast<int32_t>(sizeof(Graph)), instance_hash[0], &instance_hash);
uint64_t graph_instance_hash = instance_hash[0] | (uint64_t(instance_hash[1]) << 32);
HashValue graph_instance_hash = instance_hash[0] | (uint64_t(instance_hash[1]) << 32);
// if we've already hashed this main graph instance use the cached value
auto entry = main_graph_hash_.find(graph_instance_hash);
@ -234,7 +234,7 @@ int IExecutionProvider::ModelMetadefIdGenerator::GenerateId(const onnxruntime::G
return model_metadef_id_[model_hash]++;
}
int IExecutionProvider::GenerateMetaDefId(const onnxruntime::GraphViewer& graph_viewer, uint64_t& model_hash) const {
int IExecutionProvider::GenerateMetaDefId(const onnxruntime::GraphViewer& graph_viewer, HashValue& model_hash) const {
ORT_ENFORCE(metadef_id_generator_,
"IExecutionProvider constructor must be called with true for use_metadef_id_creator");

View file

@ -393,7 +393,7 @@ static Status PartitionOrtFormatModelImpl(Graph& graph, FuncManager& func_mgr,
KernelRegistryManager& kernel_registry_mgr,
KernelRegistry& fused_kernel_registry,
IExecutionProvider& current_ep,
std::unordered_map<std::string, uint64_t>& compiled_kernel_hashes,
std::unordered_map<std::string, HashValue>& compiled_kernel_hashes,
int& fused_node_unique_id) {
// recurse into nested graphs first to partition bottom up.
for (auto& node : graph.Nodes()) {
@ -496,7 +496,7 @@ static Status PartitionOrtFormatModelImpl(Graph& graph, FuncManager& func_mgr,
Status GraphPartitioner::PartitionOrtFormatModel(
Graph& graph, FuncManager& func_mgr,
KernelRegistry& fused_kernel_registry,
std::unordered_map<std::string, uint64_t>& compiled_kernel_hashes,
std::unordered_map<std::string, HashValue>& compiled_kernel_hashes,
int& fused_node_unique_id) const {
// process full graph with each EP
for (const auto& ep : providers_) {
@ -514,7 +514,7 @@ Status GraphPartitioner::PartitionOrtFormatModel(
}
Status GraphPartitioner::Partition(Graph& graph, bool export_dll, FuncManager& func_mgr, Mode mode,
std::unordered_map<std::string, uint64_t>* compiled_kernel_hashes) const {
std::unordered_map<std::string, HashValue>* compiled_kernel_hashes) const {
// It is a greedy partitioning algorithm per provider preferences user provided when calling ONNX RUNTIME right now.
// 1. Execution providers' capabilities are checked one by one.
// 2. All sub-graphs that an execution provider returns will be assigned to it if it's not assigned yet.

View file

@ -33,7 +33,7 @@ class GraphPartitioner {
// Run partitioning. Provide compiled_kernel_hashes if mode is kOrtFormatLoad.
Status Partition(Graph& graph, bool export_dll, FuncManager& func_mgr,
Mode mode = Mode::kNormal,
std::unordered_map<std::string, uint64_t>* compiled_kernel_hashes = nullptr) const;
std::unordered_map<std::string, HashValue>* compiled_kernel_hashes = nullptr) const;
private:
ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(GraphPartitioner);
@ -44,7 +44,7 @@ class GraphPartitioner {
#endif
Status PartitionOrtFormatModel(Graph& graph, FuncManager& func_mgr, KernelRegistry& fused_kernel_registry,
std::unordered_map<std::string, uint64_t>& compiled_kernel_hashes,
std::unordered_map<std::string, HashValue>& compiled_kernel_hashes,
int& fused_node_unique_id) const;
KernelRegistryManager& kernel_registry_mgr_;

View file

@ -268,7 +268,7 @@ Status KernelRegistry::TryFindKernel(const Node& node,
}
#endif // !defined(ORT_MINIMAL_BUILD)
bool KernelRegistry::TryFindKernelByHash(uint64_t kernel_def_hash, const KernelCreateInfo** out) const {
bool KernelRegistry::TryFindKernelByHash(HashValue kernel_def_hash, const KernelCreateInfo** out) const {
const auto hash_lookup_it = kernel_def_hash_lookup_.find(kernel_def_hash);
if (hash_lookup_it == kernel_def_hash_lookup_.end()) {
if (out) *out = nullptr;

View file

@ -104,7 +104,7 @@ Status KernelRegistryManager::SearchKernelRegistry(const onnxruntime::Node& node
}
#endif
bool KernelRegistryManager::SearchKernelRegistriesByHash(uint64_t kernel_def_hash,
bool KernelRegistryManager::SearchKernelRegistriesByHash(HashValue kernel_def_hash,
const KernelCreateInfo** kernel_create_info) const {
#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) || defined(ORT_MINIMAL_BUILD_CUSTOM_OPS)
for (const auto& registry : custom_kernel_registries_) {

View file

@ -74,7 +74,7 @@ class KernelRegistryManager {
/**
* Search the kernel registries given a kernel def hash.
*/
bool SearchKernelRegistriesByHash(uint64_t kernel_def_hash,
bool SearchKernelRegistriesByHash(HashValue kernel_def_hash,
const KernelCreateInfo** kernel_create_info) const;
std::unique_ptr<OpKernel> CreateKernel(const onnxruntime::Node& node,

View file

@ -6,7 +6,7 @@
namespace onnxruntime {
uint64_t PrePackedWeights::GetHash() const {
HashValue PrePackedWeights::GetHash() const {
// Adaptation of the hashing logic of the KernelDef class
uint32_t hash[4] = {0, 0, 0, 0};
@ -22,7 +22,7 @@ uint64_t PrePackedWeights::GetHash() const {
}
}
uint64_t returned_hash = hash[0] & 0xfffffff8; // save low 3 bits for hash version info in case we need it in the future
HashValue returned_hash = hash[0] & 0xfffffff8; // save low 3 bits for hash version info in case we need it in the future
returned_hash |= uint64_t(hash[1]) << 32;
return returned_hash;

View file

@ -5,6 +5,7 @@
#include <vector>
#include "core/common/basic_types.h"
#include "core/framework/buffer_deleter.h"
#include "core/framework/tensor_shape.h"
@ -19,7 +20,7 @@ struct PrePackedWeights final {
std::vector<size_t> buffer_sizes_; // cache sizes of pre-packed buffers (in bytes)
// Produces a hash of the buffers stored in the given instance of this class
uint64_t GetHash() const;
HashValue GetHash() const;
};
} // namespace onnxruntime

View file

@ -970,7 +970,7 @@ Status SessionState::LoadFromOrtFormat(const fbs::SessionState& fbs_session_stat
ORT_RETURN_IF_ERROR(fbs_session_state_viewer.Validate());
auto add_kernel_by_hash =
[&kernel_registry_manager, this](const Node& node, uint64_t hash) {
[&kernel_registry_manager, this](const Node& node, HashValue hash) {
const KernelCreateInfo* kci = nullptr;
ORT_RETURN_IF_NOT(kernel_registry_manager.SearchKernelRegistriesByHash(hash, &kci),
"Failed to find kernel def hash (", hash, ") in kernel registries for ",

View file

@ -295,7 +295,7 @@ class SessionState {
flatbuffers::Offset<onnxruntime::fbs::SessionState>& fbs_session_state) const;
#endif
void SetCompiledKernelHashes(std::unordered_map<std::string, uint64_t>&& compiled_kernel_hashes) {
void SetCompiledKernelHashes(std::unordered_map<std::string, HashValue>&& compiled_kernel_hashes) {
compiled_kernel_hashes_ = std::move(compiled_kernel_hashes);
}
@ -390,7 +390,7 @@ class SessionState {
#endif
// the SessionState for the main Graph contains the compiled kernel hashes for the entire model
const std::unordered_map<std::string, uint64_t>& GetCompiledKernelHashes() const {
const std::unordered_map<std::string, HashValue>& GetCompiledKernelHashes() const {
return parent_ ? parent_->GetCompiledKernelHashes() : compiled_kernel_hashes_;
}
@ -399,7 +399,7 @@ class SessionState {
// If we compile kernels in a minimal build we need a way to find the kernel using the hash.
// We populate this map when doing the kernel compilation in GraphPartitioner, and use it in LoadFromOrtFormat.
std::unordered_map<std::string, uint64_t> compiled_kernel_hashes_;
std::unordered_map<std::string, HashValue> compiled_kernel_hashes_;
// cache of the constructed kernels to avoid spending construction time per executor
std::vector<OpKernel*> session_kernels_;

View file

@ -47,7 +47,7 @@ class FbsSessionStateViewer {
struct NodeKernelInfo {
NodeIndex node_index;
uint64_t kernel_def_hash;
HashValue kernel_def_hash;
};
/**

View file

@ -64,7 +64,7 @@ an ORT format model. This also means that non-empty node indices here must be in
struct NodeIndexAndKernelDefHash {
NodeIndex node_index;
uint64_t kernel_def_hash;
HashValue kernel_def_hash;
};
/** Information for a single runtime optimization.

View file

@ -63,7 +63,7 @@ CoreMLExecutionProvider::GetCapability(const onnxruntime::GraphViewer& graph_vie
const auto supported_nodes = coreml::GetSupportedNodes(graph_viewer, logger);
const auto gen_metadef_name = [&]() {
uint64_t model_hash;
HashValue model_hash;
int metadef_id = GenerateMetaDefId(graph_viewer, model_hash);
return MakeString(COREML, "_", model_hash, "_", metadef_id);
};

View file

@ -236,7 +236,7 @@ std::vector<std::unique_ptr<ComputeCapability>> DNNLExecutionProvider::GetCapabi
}
// Assign inputs and outputs to subgraph's meta_def
uint64_t model_hash;
HashValue model_hash;
int metadef_id = GenerateMetaDefId(graph_viewer, model_hash);
auto meta_def = ::onnxruntime::IndexedSubGraph_MetaDef::Create();
meta_def->name() = "DNNL_" + std::to_string(model_hash) + "_" + std::to_string(metadef_id);
@ -271,7 +271,7 @@ std::vector<std::unique_ptr<ComputeCapability>> DNNLExecutionProvider::GetCapabi
auto model_proto = model->ToProto();
ToGraphProtoInternal(graph_viewer, *model_proto->mutable_graph());
model_proto->set_ir_version(ONNX_NAMESPACE::Version::IR_VERSION);
uint64_t model_hash;
HashValue model_hash;
int metadef_id = GenerateMetaDefId(graph_viewer, model_hash);
std::fstream dump("DNNL_" + std::to_string(model_hash) + "_" + std::to_string(metadef_id) + ".onnx", std::ios::out | std::ios::trunc | std::ios::binary);
model_proto->SerializeToOstream(dump);

View file

@ -150,7 +150,7 @@ NnapiExecutionProvider::GetCapability(const onnxruntime::GraphViewer& graph_view
};
const auto gen_metadef_name = [&]() {
uint64_t model_hash;
HashValue model_hash;
int metadef_id = GenerateMetaDefId(graph_viewer, model_hash);
return MakeString(NNAPI, "_", model_hash, "_", metadef_id);
};

View file

@ -299,7 +299,7 @@ common::Status IExecutionProvider::Compile(const std::vector<FusedNodeAndGraph>&
return g_host->IExecutionProvider__Compile(this, fused_nodes_and_graphs, node_compute_funcs);
}
int IExecutionProvider::GenerateMetaDefId(const onnxruntime::GraphViewer& graph_viewer, uint64_t& model_hash) const {
int IExecutionProvider::GenerateMetaDefId(const onnxruntime::GraphViewer& graph_viewer, HashValue& model_hash) const {
return g_host->IExecutionProvider__GenerateMetaDefId(this, graph_viewer, model_hash);
}

View file

@ -82,6 +82,7 @@ struct TensorShapeProto_Dimension_Iterator {
virtual const ONNX_NAMESPACE::TensorShapeProto_Dimension& operator*() = 0;
};
using HashValue = uint64_t;
using NodeIndex = size_t;
// We can't just reinterpret_cast this one, since it's an unordered_map of object BY VALUE (can't do anything by value on the real types)
// using NodeAttributes = std::unordered_map<std::string, ONNX_NAMESPACE::AttributeProto_Copyable>;
@ -213,7 +214,7 @@ struct ProviderHost {
virtual common::Status IExecutionProvider__Compile(IExecutionProvider* p, const std::vector<onnxruntime::Node*>& fused_nodes, std::string& dll_path) = 0;
virtual common::Status IExecutionProvider__Compile(IExecutionProvider* p, const std::vector<IExecutionProvider::FusedNodeAndGraph>& fused_nodes_and_graphs, std::vector<NodeComputeInfo>& node_compute_funcs) = 0;
virtual int IExecutionProvider__GenerateMetaDefId(const IExecutionProvider* p, const onnxruntime::GraphViewer& graph_viewer, uint64_t& model_hash) = 0;
virtual int IExecutionProvider__GenerateMetaDefId(const IExecutionProvider* p, const onnxruntime::GraphViewer& graph_viewer, HashValue& model_hash) = 0;
virtual void IExecutionProvider__RegisterAllocator(IExecutionProvider* p, std::shared_ptr<AllocatorManager> allocator_manager) = 0;
// Status

View file

@ -796,7 +796,7 @@ std::unique_ptr<IndexedSubGraph> TensorrtExecutionProvider::GetSubGraph(SubGraph
}
// Generate unique kernel name for TRT subgraph
uint64_t model_hash = 0;
HashValue model_hash = 0;
int id = GenerateMetaDefId(graph, model_hash);
std::string subgraph_id = std::to_string(model_hash) + "_" + std::to_string(id);
auto meta_def = IndexedSubGraph_MetaDef::Create();

View file

@ -1133,7 +1133,7 @@ Status PartitionOrtFormatModel(onnxruntime::Graph& graph,
const ExecutionProviders& providers,
KernelRegistryManager& kernel_registry_manager,
SessionState& session_state) {
std::unordered_map<std::string, uint64_t> compiled_kernel_hashes;
std::unordered_map<std::string, HashValue> compiled_kernel_hashes;
GraphPartitioner partitioner(kernel_registry_manager, providers);
ORT_RETURN_IF_ERROR(partitioner.Partition(graph, session_state.ExportDll(),

View file

@ -269,7 +269,7 @@ struct ProviderHostImpl : ProviderHost {
return p->IExecutionProvider::Compile(fused_nodes_and_graphs, node_compute_funcs);
}
int IExecutionProvider__GenerateMetaDefId(const IExecutionProvider* p, const onnxruntime::GraphViewer& graph_viewer, uint64_t& model_hash) override {
int IExecutionProvider__GenerateMetaDefId(const IExecutionProvider* p, const onnxruntime::GraphViewer& graph_viewer, HashValue& model_hash) override {
return p->IExecutionProvider::GenerateMetaDefId(graph_viewer, model_hash);
}

View file

@ -20,7 +20,7 @@ class TestEP : public IExecutionProvider {
public:
TestEP() : IExecutionProvider{kEPType, true} {}
int GetId(const GraphViewer& viewer, uint64_t& model_hash) {
int GetId(const GraphViewer& viewer, HashValue& model_hash) {
return GenerateMetaDefId(viewer, model_hash);
}
};
@ -36,13 +36,13 @@ TEST(ExecutionProviderTest, MetadefIdGeneratorUsingModelPath) {
GraphViewer viewer(graph);
// check for stable non-zero model_hash, and incrementing id.
uint64_t model_hash;
HashValue model_hash;
int id = ep.GetId(viewer, model_hash);
ASSERT_EQ(id, 0);
ASSERT_NE(model_hash, 0);
for (int i = 1; i < 4; ++i) {
uint64_t cur_model_hash;
HashValue cur_model_hash;
int cur_id = ep.GetId(viewer, cur_model_hash);
ASSERT_EQ(cur_id, i);
ASSERT_EQ(cur_model_hash, model_hash);
@ -67,7 +67,7 @@ TEST(ExecutionProviderTest, MetadefIdGeneratorUsingModelHashing) {
GraphViewer viewer(graph);
// get the hash for the model when loaded from file
uint64_t model_hash;
HashValue model_hash;
int id = ep.GetId(viewer, model_hash);
ASSERT_EQ(id, 0);
ASSERT_NE(model_hash, 0);
@ -84,7 +84,7 @@ TEST(ExecutionProviderTest, MetadefIdGeneratorUsingModelHashing) {
Graph& graph2 = model2->MainGraph();
GraphViewer viewer2(graph2);
uint64_t model_hash2;
HashValue model_hash2;
int id2 = ep.GetId(viewer2, model_hash2);
ASSERT_EQ(id2, 0) << "Id for new model should always start at zero";
ASSERT_NE(model_hash, model_hash2) << "Hash from model path should differ from hash based on model contents";

View file

@ -82,7 +82,7 @@ InternalTestingExecutionProvider::GetCapability(const onnxruntime::GraphViewer&
// create functor to generate a guaranteed unique metadef id
auto generate_metadef_name = [this, &graph_viewer]() {
uint64_t model_hash;
HashValue model_hash;
int metadef_id = GenerateMetaDefId(graph_viewer, model_hash);
auto meta_def = std::make_unique<::onnxruntime::IndexedSubGraph::MetaDef>();
return ep_name_ + "_" + std::to_string(model_hash) + "_" + std::to_string(metadef_id);