diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 941ecf28f0..603cc75fe2 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -121,9 +121,6 @@ option(onnxruntime_EXTENDED_MINIMAL_BUILD "onnxruntime_MINIMAL_BUILD with suppor option(onnxruntime_MINIMAL_BUILD_CUSTOM_OPS "Add custom operator kernels support to a minimal build." OFF) option(onnxruntime_REDUCED_OPS_BUILD "Reduced set of kernels are registered in build via modification of the kernel registration source files." OFF) option(onnxruntime_DISABLE_EXTERNAL_INITIALIZERS "Don't allow models to load external data" OFF) -cmake_dependent_option(onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD - "Enable runtime graph optimizations for ORT format models in an extended minimal build." - OFF "onnxruntime_EXTENDED_MINIMAL_BUILD" OFF) #A special option just for debugging and sanitize check. Please do not enable in option in retail builds. #The option has no effect on Windows. @@ -347,11 +344,6 @@ if (onnxruntime_MINIMAL_BUILD) if (onnxruntime_EXTENDED_MINIMAL_BUILD) # enable EPs that compile kernels at runtime add_compile_definitions(ORT_EXTENDED_MINIMAL_BUILD) - # enable runtime optimizations. These are required for NNAPI. - # TODO remove onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD since these optimzations are now - # enabled for all extended minimal builds. - SET(onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD ON) - add_compile_definitions(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) endif() if (onnxruntime_MINIMAL_BUILD_CUSTOM_OPS) diff --git a/cmake/onnxruntime_optimizer.cmake b/cmake/onnxruntime_optimizer.cmake index 8fa9b9a0dd..d86ffa0c10 100644 --- a/cmake/onnxruntime_optimizer.cmake +++ b/cmake/onnxruntime_optimizer.cmake @@ -11,45 +11,45 @@ if (onnxruntime_MINIMAL_BUILD) "${ONNXRUNTIME_ROOT}/core/optimizer/graph_transformer.cc" ) - if (onnxruntime_EXTENDED_MINIMAL_BUILD AND onnxruntime_USE_NNAPI_BUILTIN) + if (onnxruntime_EXTENDED_MINIMAL_BUILD) list(APPEND onnxruntime_optimizer_src_patterns - "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/shared/utils.h" - "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/shared/utils.cc" - "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h" - "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc" - "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/qdq_util.h" - "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/qdq_util.cc" - "${ONNXRUNTIME_ROOT}/core/optimizer/initializer.h" - "${ONNXRUNTIME_ROOT}/core/optimizer/initializer.cc" - "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/helpers.h" - "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/helpers.cc" - "${ONNXRUNTIME_ROOT}/core/optimizer/utils.h" - "${ONNXRUNTIME_ROOT}/core/optimizer/utils.cc" - ) - endif() - - if (onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) - list(APPEND onnxruntime_optimizer_src_patterns - "${ONNXRUNTIME_ROOT}/core/optimizer/conv_activation_fusion.h" - "${ONNXRUNTIME_ROOT}/core/optimizer/conv_activation_fusion.cc" "${ONNXRUNTIME_INCLUDE_DIR}/core/optimizer/graph_transformer_utils.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/conv_activation_fusion.cc" + "${ONNXRUNTIME_ROOT}/core/optimizer/conv_activation_fusion.h" "${ONNXRUNTIME_ROOT}/core/optimizer/graph_transformer_utils.cc" - "${ONNXRUNTIME_ROOT}/core/optimizer/initializer.h" "${ONNXRUNTIME_ROOT}/core/optimizer/initializer.cc" - "${ONNXRUNTIME_ROOT}/core/optimizer/nhwc_transformer.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/initializer.h" "${ONNXRUNTIME_ROOT}/core/optimizer/nhwc_transformer.cc" - "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/qdq_final_cleanup.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/nhwc_transformer.h" "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/qdq_final_cleanup.cc" - "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/qdq_util.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/qdq_final_cleanup.h" "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/qdq_util.cc" - "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/*.h" - "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/*.cc" - "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/*.h" - "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/*.cc" - "${ONNXRUNTIME_ROOT}/core/optimizer/transpose_optimizer/*.h" - "${ONNXRUNTIME_ROOT}/core/optimizer/transpose_optimizer/*.cc" - "${ONNXRUNTIME_ROOT}/core/optimizer/utils.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/qdq_util.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/qdq_actions.cc" + "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/qdq_actions.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.cc" + "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/qdq_selector_action_transformer.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.cc" + "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/qdq_selectors.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/shared/utils.cc" + "${ONNXRUNTIME_ROOT}/core/optimizer/qdq_transformer/selectors_actions/shared/utils.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/actions.cc" + "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/actions.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/helpers.cc" + "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/helpers.cc" + "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/helpers.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/helpers.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/selector_action_transformer_apply_contexts.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/selector_action_transformer.cc" + "${ONNXRUNTIME_ROOT}/core/optimizer/selectors_actions/selector_action_transformer.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/transpose_optimizer/optimizer_api_impl.cc" + "${ONNXRUNTIME_ROOT}/core/optimizer/transpose_optimizer/optimizer_api.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/transpose_optimizer/optimizer_utils.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/transpose_optimizer/ort_transpose_optimizer.cc" + "${ONNXRUNTIME_ROOT}/core/optimizer/transpose_optimizer/ort_transpose_optimizer.h" + "${ONNXRUNTIME_ROOT}/core/optimizer/transpose_optimizer/transpose_optimizer.cc" "${ONNXRUNTIME_ROOT}/core/optimizer/utils.cc" + "${ONNXRUNTIME_ROOT}/core/optimizer/utils.h" ) endif() else() @@ -70,10 +70,6 @@ else() ) endif() -# handle the overlap between the NNAPI files and the runtime optimization files -# TODO: simplify this setup -list(REMOVE_DUPLICATES onnxruntime_optimizer_src_patterns) - if (onnxruntime_ENABLE_TRAINING) list(APPEND onnxruntime_optimizer_src_patterns "${ORTTRAINING_SOURCE_DIR}/core/optimizer/*.h" diff --git a/cmake/onnxruntime_unittests.cmake b/cmake/onnxruntime_unittests.cmake index 8615982519..3de416f980 100644 --- a/cmake/onnxruntime_unittests.cmake +++ b/cmake/onnxruntime_unittests.cmake @@ -236,7 +236,7 @@ else() # minimal and/or reduced ops build endif() endif() -if((NOT onnxruntime_MINIMAL_BUILD OR onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +if((NOT onnxruntime_MINIMAL_BUILD OR onnxruntime_EXTENDED_MINIMAL_BUILD) AND NOT onnxruntime_REDUCED_OPS_BUILD) list(APPEND onnxruntime_test_optimizer_src "${TEST_SRC_DIR}/optimizer/runtime_optimization/graph_runtime_optimization_test.cc") diff --git a/include/onnxruntime/core/graph/graph.h b/include/onnxruntime/core/graph/graph.h index 15313383a6..a389c407fc 100644 --- a/include/onnxruntime/core/graph/graph.h +++ b/include/onnxruntime/core/graph/graph.h @@ -53,7 +53,7 @@ struct IndexedSubGraph; class Model; class OpSignature; -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) class RuntimeOptimizationRecordContainer; #endif @@ -391,10 +391,10 @@ class Node { /** Gets the Node's attributes. */ const NodeAttributes& GetAttributes() const noexcept { return attributes_; } -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) /** Remove the specified attribute from this Node */ bool ClearAttribute(const std::string& attr_name); -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) #if !defined(ORT_MINIMAL_BUILD) /** Gets the Node's mutable attributes. */ @@ -868,13 +868,13 @@ class Graph { return *(result.first->second); } -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) /** Generate a unique name in this Graph for a NodeArg */ std::string GenerateNodeArgName(const std::string& base_name); /** Generate a unique name in this Graph for a Node */ std::string GenerateNodeName(const std::string& base_name); -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) #if !defined(ORT_MINIMAL_BUILD) /** Copy a Node and add it to this Graph. @@ -1159,7 +1159,7 @@ class Graph { #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) /** Sets the type of a NodeArg, replacing existing type/shape if any */ void SetNodeArgType(NodeArg& arg, const ONNX_NAMESPACE::TypeProto& type_proto); @@ -1194,7 +1194,7 @@ class Graph { void RemoveConsumerNode(const std::string& node_arg_name, Node* consumer) { node_arg_to_consumer_nodes_[node_arg_name].erase(consumer->Index()); } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) #if !defined(ORT_MINIMAL_BUILD) std::vector GetMutableConsumerNodes(const std::string& node_arg_name) { @@ -1299,7 +1299,7 @@ class Graph { Graph& parent_graph, const Node& parent_node, const logging::Logger& logger, std::unique_ptr& graph); -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) const RuntimeOptimizationRecordContainer& RuntimeOptimizations() const { return runtime_optimizations_; } @@ -1321,7 +1321,7 @@ class Graph { RuntimeOptimizationReplayContext& MutableRuntimeOptimizationReplayCtx() { return runtime_optimization_replay_context_; } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) // This friendship relationship should only be used to call Graph::Graph and // Graph::LoadGraph All other access should be via the public API. @@ -1476,7 +1476,7 @@ class Graph { #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) Status PopulateNodeArgToProducerConsumerLookupsFromNodes(); template @@ -1503,9 +1503,7 @@ class Graph { } return nullptr; } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) gsl::not_null AllocateNode(); // Release the node. @@ -1513,7 +1511,7 @@ class Graph { bool ReleaseNode(NodeIndex node_index); Node& CreateFusedSubGraphNode(const IndexedSubGraph& sub_graph, const std::string& fused_node_name); -#endif +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) Node* NodeAtIndexImpl(NodeIndex node_index) const { // if we are trying to access a node that doesn't exist there's (most @@ -1543,14 +1541,14 @@ class Graph { std::hash, std::equal_to> sparse_tensor_names_; -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) // Runtime optimization storage. // Note: runtime_optimizations_ == *runtime_optimizations_ptr_ and must be initialized std::unique_ptr runtime_optimizations_ptr_; RuntimeOptimizationRecordContainer& runtime_optimizations_; RuntimeOptimizationReplayContext runtime_optimization_replay_context_; -#endif +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) #if !defined(ORT_MINIMAL_BUILD) IOnnxRuntimeOpSchemaCollectionPtr schema_registry_; @@ -1559,7 +1557,7 @@ class Graph { std::vector> function_container_; std::unordered_map model_local_functions_; -#endif +#endif // !defined(ORT_MINIMAL_BUILD) // Graph nodes. // Element in may be nullptr due to graph optimization. @@ -1603,7 +1601,7 @@ class Graph { // All node args owned by <*this> graph. Key is node arg name. std::unordered_map> node_args_; -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) int name_generator_ = 0; // Strings which have been used as node names. @@ -1619,7 +1617,7 @@ class Graph { // node arg to its consumer nodes std::unordered_map> node_arg_to_consumer_nodes_; -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) const std::unordered_map domain_to_version_; diff --git a/include/onnxruntime/core/graph/node_arg.h b/include/onnxruntime/core/graph/node_arg.h index 7c575fed95..921bff59fb 100644 --- a/include/onnxruntime/core/graph/node_arg.h +++ b/include/onnxruntime/core/graph/node_arg.h @@ -63,7 +63,7 @@ class NodeArg { @returns true if NodeArg is a normal tensor with a non-empty shape or a scalar with an empty shape. Otherwise, returns false. */ bool HasTensorOrScalarShape() const; -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) /** Sets the shape. @remarks Shape can only be set if the TypeProto was provided to the ctor, or #SetType has been called, @@ -74,7 +74,7 @@ class NodeArg { @remarks If there is a mismatch during shape inferencing that can't be resolved the shape info may be removed. */ void ClearShape(); -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) #if !defined(ORT_MINIMAL_BUILD) @@ -118,9 +118,9 @@ class NodeArg { private: ORT_DISALLOW_COPY_AND_ASSIGNMENT(NodeArg); void SetType(const std::string* p_type); -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) void SetType(const ONNX_NAMESPACE::TypeProto& type_proto); -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) // Node arg PType. const std::string* type_; diff --git a/include/onnxruntime/core/optimizer/graph_transformer_utils.h b/include/onnxruntime/core/optimizer/graph_transformer_utils.h index a92896a32f..e609745b5e 100644 --- a/include/onnxruntime/core/optimizer/graph_transformer_utils.h +++ b/include/onnxruntime/core/optimizer/graph_transformer_utils.h @@ -16,7 +16,7 @@ #include "core/optimizer/rewrite_rule.h" #endif -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) #include "core/optimizer/selectors_actions/selector_action_transformer_apply_contexts.h" #endif @@ -53,7 +53,7 @@ InlinedVector> GenerateTransformers( #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) /** Generates all predefined transformers which can be used to provide runtime optimizations for this level in a minimal build. @@ -80,7 +80,7 @@ InlinedVector> GenerateTransformersForMinimalB const IExecutionProvider& cpu_execution_provider, const InlinedHashSet& rules_and_transformers_to_disable = {}); -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) } // namespace optimizer_utils } // namespace onnxruntime diff --git a/onnxruntime/core/framework/graph_partitioner.cc b/onnxruntime/core/framework/graph_partitioner.cc index 57b5d6c7f8..a3f026eb84 100644 --- a/onnxruntime/core/framework/graph_partitioner.cc +++ b/onnxruntime/core/framework/graph_partitioner.cc @@ -74,7 +74,7 @@ static Status ValidateGraphPartitioning(const Graph& graph) { return Status::OK(); } -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) /// /// Check if a node can be placed on a specific provider. If yes, then set the nodes execution provider. @@ -100,7 +100,7 @@ static void AssignNodes(Graph& graph, const IndexedSubGraph& capability, } } -#endif //! defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) static Status GetCapabilityForEP(Graph& graph, KernelRegistryManager& kernel_registry_mgr, IExecutionProvider& current_ep, GraphPartitioner::Mode mode, std::vector>& capabilities, @@ -110,7 +110,7 @@ static Status GetCapabilityForEP(Graph& graph, KernelRegistryManager& kernel_reg capabilities = current_ep.GetCapability(graph_viewer, kernel_registry_mgr.GetKernelRegistriesByProviderType(current_ep.Type())); } -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) // Run layout transformer only for EPs other than CPU EP and provided the preferred layout is NHWC // CPU EP layout transformation happens later when level 3 transformers are run. if (mode != GraphPartitioner::Mode::kAssignOnly && @@ -136,7 +136,7 @@ static Status GetCapabilityForEP(Graph& graph, KernelRegistryManager& kernel_reg capabilities = current_ep.GetCapability(graph_viewer, kernel_registry_mgr.GetKernelRegistriesByProviderType(current_ep.Type())); } } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) return Status::OK(); } diff --git a/onnxruntime/core/framework/session_state.cc b/onnxruntime/core/framework/session_state.cc index 70adb4b159..139cbd6d22 100644 --- a/onnxruntime/core/framework/session_state.cc +++ b/onnxruntime/core/framework/session_state.cc @@ -990,9 +990,9 @@ Status SessionState::LoadFromOrtFormat(const fbs::SessionState& fbs_session_stat const bool original_nodes_should_exist = compiled_kernel_hashes.empty() -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) && graph_.RuntimeOptimizationReplayCtx().num_replayed_optimizations == 0 -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) ; // process the nodes that existed when the model was created @@ -1011,7 +1011,7 @@ Status SessionState::LoadFromOrtFormat(const fbs::SessionState& fbs_session_stat ORT_RETURN_IF_ERROR(add_kernel_by_hash(*node, node_kernel_info.kernel_def_hash)); } -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) // process the nodes that were added by replaying any loaded runtime optimizations for (const auto& [node_index, kernel_def_hash] : graph_.RuntimeOptimizationReplayCtx().produced_node_index_to_kernel_def_hash) { @@ -1050,7 +1050,7 @@ Status SessionState::LoadFromOrtFormat(const fbs::SessionState& fbs_session_stat } } } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) if (!subgraph_session_states_.empty()) { for (const auto& [node_idx, session_states] : subgraph_session_states_) { @@ -1262,11 +1262,11 @@ Status SessionState::FinalizeSessionStateImpl(const std::basic_string unused_initializer_names; for (const auto& [name, tensor_proto] : graph_.GetAllInitializedTensors()) { @@ -1281,7 +1281,7 @@ Status SessionState::FinalizeSessionStateImpl(const std::basic_string valid_outer_scope_node_args; diff --git a/onnxruntime/core/graph/graph.cc b/onnxruntime/core/graph/graph.cc index 8db620b04b..81c44b91f5 100644 --- a/onnxruntime/core/graph/graph.cc +++ b/onnxruntime/core/graph/graph.cc @@ -290,7 +290,7 @@ bool NodeArg::HasTensorOrScalarShape() const { } } -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) void NodeArg::SetShape(const TensorShapeProto& shape) { const auto type_case = node_arg_info_.type().value_case(); switch (type_case) { @@ -354,7 +354,7 @@ void NodeArg::ClearShape() { } } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) #if !defined(ORT_MINIMAL_BUILD) @@ -509,14 +509,14 @@ void NodeArg::SetType(DataType p_type) { #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) void NodeArg::SetType(const TypeProto& type_proto) { type_ = DataTypeUtils::ToType(type_proto); *(node_arg_info_.mutable_type()) = type_proto; } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) bool NodeArg::Exists() const noexcept { return exists_; @@ -973,13 +973,13 @@ ADD_ATTR_MOVE_IMPL(SparseTensorProto, AttributeProto_AttributeType::AttributePro ADD_LIST_ATTR_IMPL(SparseTensorProto, AttributeProto_AttributeType::AttributeProto_AttributeType_SPARSE_TENSORS, sparse_tensors) #endif -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) bool Node::ClearAttribute(const std::string& attr_name) { graph_->SetGraphResolveNeeded(); graph_->SetGraphProtoSyncNeeded(); return attributes_.erase(attr_name) > 0; } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) #if !defined(ORT_MINIMAL_BUILD) Status Node::UpdateInputArgCount() { @@ -1138,7 +1138,7 @@ Graph::Graph(const Model& owning_model, const logging::Logger& logger) : owning_model_(owning_model), graph_proto_(graph_proto), -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) runtime_optimizations_ptr_(std::make_unique()), runtime_optimizations_(*runtime_optimizations_ptr_), #endif @@ -3183,7 +3183,7 @@ common::Status Graph::SaveToOrtFormat(flatbuffers::FlatBufferBuilder& builder, auto nodes = builder.CreateVector(nodes_vec); auto node_edges = builder.CreateVector(node_edges_vec); -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) auto runtime_optimizations = flatbuffers::Offset{}; // null value if (!RuntimeOptimizations().IsEmpty()) { flatbuffers::Offset @@ -3204,7 +3204,7 @@ common::Status Graph::SaveToOrtFormat(flatbuffers::FlatBufferBuilder& builder, #if !defined(DISABLE_SPARSE_TENSORS) gb.add_sparse_initializers(sparse_initializers); #endif -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) gb.add_runtime_optimizations(runtime_optimizations); #endif fbs_graph = gb.Finish(); @@ -3212,7 +3212,7 @@ common::Status Graph::SaveToOrtFormat(flatbuffers::FlatBufferBuilder& builder, } #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) std::string Graph::GenerateNodeArgName(const std::string& base_name) { std::string new_name = base_name; // Check if new_name has been used in as any of node_args_' names. @@ -3268,9 +3268,7 @@ std::string Graph::GenerateNodeName(const std::string& base_name) { return new_name; } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) Node& Graph::AddNode(const std::string& name, const std::string& op_type, const std::string& description, @@ -3826,7 +3824,7 @@ bool Graph::SetOpSchemaFromRegistryForNode(Node& node) { } #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) Status Graph::PopulateNodeArgToProducerConsumerLookupsFromNodes() { node_arg_to_producer_node_.clear(); node_arg_to_consumer_nodes_.clear(); @@ -3843,9 +3841,7 @@ Status Graph::PopulateNodeArgToProducerConsumerLookupsFromNodes() { return Status::OK(); } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) // calling private ctor GSL_SUPPRESS(r .11) gsl::not_null Graph::AllocateNode() { @@ -4174,12 +4170,12 @@ void Graph::SetOutputs(gsl::span outputs) { #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) void Graph::SetNodeArgType(NodeArg& arg, const ONNX_NAMESPACE::TypeProto& type_proto) { arg.SetType(type_proto); GraphResolveNeeded(true); } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) Graph::~Graph() { // nothing to do, but we put it here so we don't need to fully define types in Graph that are held in unique_ptr @@ -4308,7 +4304,7 @@ Graph::Graph(const Model& owning_model, const logging::Logger& logger) : owning_model_(owning_model), graph_proto_(&deserialized_proto_data_), -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) runtime_optimizations_ptr_(std::make_unique()), runtime_optimizations_(*runtime_optimizations_ptr_), #endif @@ -4455,7 +4451,7 @@ common::Status Graph::LoadFromOrtFormat(const onnxruntime::fbs::Graph& fbs_graph ORT_RETURN_IF_ERROR(add_node_args(fbs_graph.outputs(), graph_outputs_)); -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) // populate NodeArg lookups after loading Nodes and NodeArgs ORT_RETURN_IF_ERROR(PopulateNodeArgToProducerConsumerLookupsFromNodes()); @@ -4465,7 +4461,7 @@ common::Status Graph::LoadFromOrtFormat(const onnxruntime::fbs::Graph& fbs_graph ORT_RETURN_IF_ERROR(MutableRuntimeOptimizations().LoadFromOrtFormat(*fbs_runtime_optimization_records)); } } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) return Status::OK(); } diff --git a/onnxruntime/core/graph/graph_utils.cc b/onnxruntime/core/graph/graph_utils.cc index 6d4234dec5..cc97364d34 100644 --- a/onnxruntime/core/graph/graph_utils.cc +++ b/onnxruntime/core/graph/graph_utils.cc @@ -2,9 +2,11 @@ // Licensed under the MIT License. #include "core/graph/graph_utils.h" + +#include + #include "core/graph/graph.h" #include "core/common/logging/logging.h" -#include namespace onnxruntime { @@ -14,6 +16,20 @@ namespace graph_utils { //--- local helpers --- //--------------------- +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) + +static int GetIndexFromName(const Node& node, const std::string& name, bool is_input) { + const auto& node_args = is_input ? node.InputDefs() : node.OutputDefs(); + auto itr = std::find_if(node_args.begin(), node_args.end(), + [&name](const NodeArg* node_arg) { return node_arg->Name() == name; }); + ORT_ENFORCE(itr != node_args.end(), + "Attempting to get index by a name which does not exist:", name, "for node: ", node.Name()); + auto index = std::distance(node_args.begin(), itr); + return static_cast(index); +} + +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) + #if !defined(ORT_MINIMAL_BUILD) // check if an output edge provides an implicit input to the destination node @@ -190,17 +206,9 @@ static void MoveAllNodeOutputs(Graph& graph, Node& src_node, Node& target_node) #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) - -static int GetIndexFromName(const Node& node, const std::string& name, bool is_input) { - const auto& node_args = is_input ? node.InputDefs() : node.OutputDefs(); - auto itr = std::find_if(node_args.begin(), node_args.end(), - [&name](const NodeArg* node_arg) { return node_arg->Name() == name; }); - ORT_ENFORCE(itr != node_args.end(), - "Attempting to get index by a name which does not exist:", name, "for node: ", node.Name()); - auto index = std::distance(node_args.begin(), itr); - return static_cast(index); -} +//---------------------------- +//--- end of local helpers --- +//---------------------------- bool MatchesOpSinceVersion(const Node& node, std::initializer_list versions) { return std::find(versions.begin(), versions.end(), node.SinceVersion()) != versions.end(); @@ -225,13 +233,179 @@ bool IsSupportedOptypeVersionAndDomain(const Node& node, #endif MatchesOpSinceVersion(node, versions) && MatchesOpSetDomain(node, domain)); } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) -//---------------------------- -//--- end of local helpers --- -//---------------------------- +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) + +const ONNX_NAMESPACE::AttributeProto* GetNodeAttribute(const Node& node, const std::string& attr_name) { + const auto& attrs = node.GetAttributes(); + const auto iter = attrs.find(attr_name); + return iter == attrs.end() ? nullptr : &iter->second; +} + +NodeArg& AddInitializer(Graph& graph, const ONNX_NAMESPACE::TensorProto& new_initializer) { + // sanity check as AddInitializedTensor silently ignores attempts to add a duplicate initializer + const ONNX_NAMESPACE::TensorProto* existing = nullptr; + ORT_ENFORCE(!graph.GetInitializedTensor(new_initializer.name(), existing), + "Initializer with same name exists. Name:", new_initializer.name()); + + graph.AddInitializedTensor(new_initializer); + + ONNX_NAMESPACE::TypeProto new_type; + auto* typeproto_tensor = new_type.mutable_tensor_type(); + typeproto_tensor->set_elem_type(new_initializer.data_type()); + + auto* shape = typeproto_tensor->mutable_shape(); + for (auto dim : new_initializer.dims()) { + shape->add_dim()->set_dim_value(dim); + } + + return graph.GetOrCreateNodeArg(new_initializer.name(), &new_type); +} + +int GetNodeOutputIndexFromOutputName(const Node& node, const std::string& output_name) { + return GetIndexFromName(node, output_name, false); +} + +std::vector FindParentsByType(const Node& node, const std::string& parent_type) { + // find parents and sort them by destination argument index + // as there is at most one input edge for each input argument, + // there is no need of extra work like FindChildrenByType + std::vector parents(node.InputDefs().size(), nullptr); + for (auto it = node.InputEdgesBegin(); it != node.InputEdgesEnd(); it++) { + if (it->GetNode().OpType().compare(parent_type) == 0) { + parents[it->GetDstArgIndex()] = &(it->GetNode()); + } + } + + // remove unmatched nodes + parents.erase(std::remove(parents.begin(), parents.end(), nullptr), parents.end()); + return parents; +} + +std::vector FindChildrenByType(const Node& node, const std::string& child_type) { + // find children and sort them by source argument index: + // Create a 2D vector to hold the result. + // 1st dimension index is output index, + // and the 2nd dimension stores the edges from the output. + std::vector> children(node.OutputDefs().size(), std::vector()); + for (auto it = node.OutputEdgesBegin(); it != node.OutputEdgesEnd(); it++) { + if (it->GetNode().OpType().compare(child_type) == 0) { + children[it->GetSrcArgIndex()].push_back(&(it->GetNode())); + } + } + + // aggregate children + std::vector agg_res; + for (size_t output_idx = 0; output_idx < children.size(); output_idx++) { + agg_res.insert(agg_res.end(), children[output_idx].begin(), children[output_idx].end()); + } + return agg_res; +} + +const std::string& GetNodeInputName(const Node& node, int index) { + const auto& inputs = node.InputDefs(); + ORT_ENFORCE(index >= 0 && static_cast(index) < inputs.size(), + "Attempting to get an input that does not exist."); + return inputs[index]->Name(); +} + +const std::string& GetNodeOutputName(const Node& node, int index) { + const auto& outputs = node.OutputDefs(); + ORT_ENFORCE(index >= 0 && static_cast(index) < outputs.size(), + "Attempting to get an output that does not exist."); + return outputs[index]->Name(); +} + +size_t RemoveNodeOutputEdges(Graph& graph, Node& node) { + std::vector output_edges = GraphEdge::GetNodeOutputEdges(node); + GraphEdge::RemoveGraphEdges(graph, output_edges); + + return output_edges.size(); +} + +size_t RemoveNodeOutputEdges(Graph& graph, Node& node, int output_idx) { + std::vector output_edges = GraphEdge::GetNodeOutputEdges(node, output_idx); + GraphEdge::RemoveGraphEdges(graph, output_edges); + + return output_edges.size(); +} + +const ONNX_NAMESPACE::TensorProto* GetConstantInitializer(const Graph& graph, const std::string& initializer_name, + bool check_outer_scope) { + return graph.GetConstantInitializer(initializer_name, check_outer_scope); +} + +GraphEdge::GraphEdge(NodeIndex src_node, + NodeIndex dst_node, + int src_arg_index, + int dst_arg_index, + const std::string& arg_name) : src_node(src_node), + dst_node(dst_node), + src_arg_index(src_arg_index), + dst_arg_index(dst_arg_index), + arg_name(arg_name) {} + +// Constructs a GraphEdge given a node, an edge_end, and a boolean for the edge direction. +GraphEdge GraphEdge::CreateGraphEdge(const Node& node, const Node::EdgeEnd& edge_end, bool is_input_edge) { + return is_input_edge + ? GraphEdge(edge_end.GetNode().Index(), + node.Index(), + edge_end.GetSrcArgIndex(), + edge_end.GetDstArgIndex(), + GetNodeInputName(node, edge_end.GetDstArgIndex())) + : GraphEdge(node.Index(), + edge_end.GetNode().Index(), + edge_end.GetSrcArgIndex(), + edge_end.GetDstArgIndex(), + GetNodeOutputName(node, edge_end.GetSrcArgIndex())); +} + +/** Returns a vector of the input GraphEdges of a node. */ +std::vector GraphEdge::GetNodeInputEdges(const Node& node) { + std::vector input_edges; + for (auto it = node.InputEdgesBegin(), end = node.InputEdgesEnd(); it != end; ++it) { + input_edges.push_back(GraphEdge::CreateGraphEdge(node, *it, true)); + } + + return input_edges; +} + +/** Returns a vector of the output GraphEdges of a node. */ +std::vector GraphEdge::GetNodeOutputEdges(const Node& node) { + std::vector output_edges; + for (auto it = node.OutputEdgesBegin(), end = node.OutputEdgesEnd(); it != end; ++it) { + output_edges.push_back(GraphEdge::CreateGraphEdge(node, *it, false)); + } + + return output_edges; +} + +/** Returns a vector of output GraphEdges of a node for the provided output index. */ +std::vector GraphEdge::GetNodeOutputEdges(const Node& node, size_t index) { + std::vector output_edges; + for (auto it = node.OutputEdgesBegin(), end = node.OutputEdgesEnd(); it != end; ++it) { + if (static_cast(it->GetSrcArgIndex()) == index) { + output_edges.push_back(GraphEdge::CreateGraphEdge(node, *it, false)); + } + } + + return output_edges; +} + +/** Removes a set of GraphEdges from the graph. */ +void GraphEdge::RemoveGraphEdges(Graph& graph, const std::vector& edges) { + for (const auto& edge_to_remove : edges) { + graph.RemoveEdge(edge_to_remove.src_node, + edge_to_remove.dst_node, + edge_to_remove.src_arg_index, + edge_to_remove.dst_arg_index); + } +} + +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) #if !defined(ORT_MINIMAL_BUILD) + bool MatchesOpSinceVersion(const Node& node, gsl::span versions) { return std::find(versions.begin(), versions.end(), node.SinceVersion()) != versions.end(); } @@ -706,179 +880,5 @@ NodeArg& CreateNodeArg(Graph& graph, const NodeArg& base_arg) { #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) - -std::vector FindParentsByType(const Node& node, const std::string& parent_type) { - // find parents and sort them by destination argument index - // as there is at most one input edge for each input argument, - // there is no need of extra work like FindChildrenByType - std::vector parents(node.InputDefs().size(), nullptr); - for (auto it = node.InputEdgesBegin(); it != node.InputEdgesEnd(); it++) { - if (it->GetNode().OpType().compare(parent_type) == 0) { - parents[it->GetDstArgIndex()] = &(it->GetNode()); - } - } - - // remove unmatched nodes - parents.erase(std::remove(parents.begin(), parents.end(), nullptr), parents.end()); - return parents; -} - -std::vector FindChildrenByType(const Node& node, const std::string& child_type) { - // find children and sort them by source argument index: - // Create a 2D vector to hold the result. - // 1st dimension index is output index, - // and the 2nd dimension stores the edges from the output. - std::vector> children(node.OutputDefs().size(), std::vector()); - for (auto it = node.OutputEdgesBegin(); it != node.OutputEdgesEnd(); it++) { - if (it->GetNode().OpType().compare(child_type) == 0) { - children[it->GetSrcArgIndex()].push_back(&(it->GetNode())); - } - } - - // aggregate children - std::vector agg_res; - for (size_t output_idx = 0; output_idx < children.size(); output_idx++) { - agg_res.insert(agg_res.end(), children[output_idx].begin(), children[output_idx].end()); - } - return agg_res; -} - -const std::string& GetNodeInputName(const Node& node, int index) { - const auto& inputs = node.InputDefs(); - ORT_ENFORCE(index >= 0 && static_cast(index) < inputs.size(), - "Attempting to get an input that does not exist."); - return inputs[index]->Name(); -} - -const std::string& GetNodeOutputName(const Node& node, int index) { - const auto& outputs = node.OutputDefs(); - ORT_ENFORCE(index >= 0 && static_cast(index) < outputs.size(), - "Attempting to get an output that does not exist."); - return outputs[index]->Name(); -} - -size_t RemoveNodeOutputEdges(Graph& graph, Node& node) { - std::vector output_edges = GraphEdge::GetNodeOutputEdges(node); - GraphEdge::RemoveGraphEdges(graph, output_edges); - - return output_edges.size(); -} - -size_t RemoveNodeOutputEdges(Graph& graph, Node& node, int output_idx) { - std::vector output_edges = GraphEdge::GetNodeOutputEdges(node, output_idx); - GraphEdge::RemoveGraphEdges(graph, output_edges); - - return output_edges.size(); -} - -const ONNX_NAMESPACE::TensorProto* GetConstantInitializer(const Graph& graph, const std::string& initializer_name, - bool check_outer_scope) { - return graph.GetConstantInitializer(initializer_name, check_outer_scope); -} - -GraphEdge::GraphEdge(NodeIndex src_node, - NodeIndex dst_node, - int src_arg_index, - int dst_arg_index, - const std::string& arg_name) : src_node(src_node), - dst_node(dst_node), - src_arg_index(src_arg_index), - dst_arg_index(dst_arg_index), - arg_name(arg_name) {} - -// Constructs a GraphEdge given a node, an edge_end, and a boolean for the edge direction. -GraphEdge GraphEdge::CreateGraphEdge(const Node& node, const Node::EdgeEnd& edge_end, bool is_input_edge) { - return is_input_edge - ? GraphEdge(edge_end.GetNode().Index(), - node.Index(), - edge_end.GetSrcArgIndex(), - edge_end.GetDstArgIndex(), - GetNodeInputName(node, edge_end.GetDstArgIndex())) - : GraphEdge(node.Index(), - edge_end.GetNode().Index(), - edge_end.GetSrcArgIndex(), - edge_end.GetDstArgIndex(), - GetNodeOutputName(node, edge_end.GetSrcArgIndex())); -} - -/** Returns a vector of the input GraphEdges of a node. */ -std::vector GraphEdge::GetNodeInputEdges(const Node& node) { - std::vector input_edges; - for (auto it = node.InputEdgesBegin(), end = node.InputEdgesEnd(); it != end; ++it) { - input_edges.push_back(GraphEdge::CreateGraphEdge(node, *it, true)); - } - - return input_edges; -} - -/** Returns a vector of the output GraphEdges of a node. */ -std::vector GraphEdge::GetNodeOutputEdges(const Node& node) { - std::vector output_edges; - for (auto it = node.OutputEdgesBegin(), end = node.OutputEdgesEnd(); it != end; ++it) { - output_edges.push_back(GraphEdge::CreateGraphEdge(node, *it, false)); - } - - return output_edges; -} - -/** Returns a vector of output GraphEdges of a node for the provided output index. */ -std::vector GraphEdge::GetNodeOutputEdges(const Node& node, size_t index) { - std::vector output_edges; - for (auto it = node.OutputEdgesBegin(), end = node.OutputEdgesEnd(); it != end; ++it) { - if (static_cast(it->GetSrcArgIndex()) == index) { - output_edges.push_back(GraphEdge::CreateGraphEdge(node, *it, false)); - } - } - - return output_edges; -} - -/** Removes a set of GraphEdges from the graph. */ -void GraphEdge::RemoveGraphEdges(Graph& graph, const std::vector& edges) { - for (const auto& edge_to_remove : edges) { - graph.RemoveEdge(edge_to_remove.src_node, - edge_to_remove.dst_node, - edge_to_remove.src_arg_index, - edge_to_remove.dst_arg_index); - } -} - -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) - -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) - -const ONNX_NAMESPACE::AttributeProto* GetNodeAttribute(const Node& node, const std::string& attr_name) { - const auto& attrs = node.GetAttributes(); - const auto iter = attrs.find(attr_name); - return iter == attrs.end() ? nullptr : &iter->second; -} - -NodeArg& AddInitializer(Graph& graph, const ONNX_NAMESPACE::TensorProto& new_initializer) { - // sanity check as AddInitializedTensor silently ignores attempts to add a duplicate initializer - const ONNX_NAMESPACE::TensorProto* existing = nullptr; - ORT_ENFORCE(!graph.GetInitializedTensor(new_initializer.name(), existing), - "Initializer with same name exists. Name:", new_initializer.name()); - - graph.AddInitializedTensor(new_initializer); - - ONNX_NAMESPACE::TypeProto new_type; - auto* typeproto_tensor = new_type.mutable_tensor_type(); - typeproto_tensor->set_elem_type(new_initializer.data_type()); - - auto* shape = typeproto_tensor->mutable_shape(); - for (auto dim : new_initializer.dims()) { - shape->add_dim()->set_dim_value(dim); - } - - return graph.GetOrCreateNodeArg(new_initializer.name(), &new_type); -} - -int GetNodeOutputIndexFromOutputName(const Node& node, const std::string& output_name) { - return GetIndexFromName(node, output_name, false); -} - -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) - } // namespace graph_utils } // namespace onnxruntime diff --git a/onnxruntime/core/graph/graph_utils.h b/onnxruntime/core/graph/graph_utils.h index f88ada7897..301bf83a5e 100644 --- a/onnxruntime/core/graph/graph_utils.h +++ b/onnxruntime/core/graph/graph_utils.h @@ -10,15 +10,20 @@ #endif #include "onnx/onnx_pb.h" #include "onnx/onnx-operators_pb.h" -#include "core/graph/graph.h" #include "core/common/inlined_containers.h" +#include "core/graph/graph.h" namespace onnxruntime { - namespace graph_utils { -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +/** Checks if the operator's type, version, and domain of the given node match the given values. */ +bool IsSupportedOptypeVersionAndDomain(const Node& node, + std::string_view op_type, + std::initializer_list versions, + std::string_view domain = kOnnxDomainAlias); + +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) /** Returns the attribute of a Node with a given name. */ const ONNX_NAMESPACE::AttributeProto* GetNodeAttribute(const Node& node, const std::string& attr_name); @@ -33,13 +38,63 @@ NodeArg& AddInitializer(Graph& graph, const ONNX_NAMESPACE::TensorProto& new_ini /** Gets the index of an output arg with the specified output arg name. */ int GetNodeOutputIndexFromOutputName(const Node& node, const std::string& output_name); -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +/** Find node parents by op types. + @returns The matched parents are sorted by destination argument index of their corresponding edge. +**/ +std::vector FindParentsByType(const Node& node, const std::string& parent_type); -/** Checks if the operator's type, version, and domain of the given node match the given values. */ -bool IsSupportedOptypeVersionAndDomain(const Node& node, - std::string_view op_type, - std::initializer_list versions, - std::string_view domain = kOnnxDomainAlias); +/** Find node children by op types. + @returns The matched children are sorted by source argument index of their corresponding edge. +**/ +std::vector FindChildrenByType(const Node& node, const std::string& child_type); + +/** Gets the name of the incoming NodeArg with the specified index for the given node. */ +const std::string& GetNodeInputName(const Node& node, int index); + +/** Gets the name of the outgoing NodeArg with the specified index for the given node. */ +const std::string& GetNodeOutputName(const Node& node, int index); + +/** Removes all output edges from the given Node of the Graph. + This should probably be elevated to the Graph API eventually. */ +size_t RemoveNodeOutputEdges(Graph& graph, Node& node); + +/** Removes output edges from the specific output_idx for the given Node of the Graph. */ +size_t RemoveNodeOutputEdges(Graph& graph, Node& node, int output_idx); + +/** returns the initializer's TensorProto if 'name' is an initializer, is constant and +cannot be overridden at runtime. If the initializer is not found or is not constant, a nullptr is returned. +@param check_outer_scope If true and the graph is a subgraph, check ancestor graph/s for 'name' if not found in 'graph'. +*/ +const ONNX_NAMESPACE::TensorProto* GetConstantInitializer(const Graph& graph, const std::string& name, + bool check_outer_scope = true); + +// A class helps handle graph edges +struct GraphEdge { + NodeIndex src_node; + NodeIndex dst_node; + int src_arg_index; + int dst_arg_index; + std::string arg_name; + + GraphEdge(NodeIndex src_node, NodeIndex dst_node, int src_arg_index, int dst_arg_index, const std::string& arg_name); + + // Constructs a GraphEdge given a node, an edge_end, and a boolean for the edge direction. + static GraphEdge CreateGraphEdge(const Node& node, const Node::EdgeEnd& edge_end, bool is_input_edge); + + /** Returns a vector of the input GraphEdges of a node. */ + static std::vector GetNodeInputEdges(const Node& node); + + /** Returns a vector of the output GraphEdges of a node. */ + static std::vector GetNodeOutputEdges(const Node& node); + + /** Returns a vector of output GraphEdges of a node for the provided output index. */ + static std::vector GetNodeOutputEdges(const Node& node, size_t index); + + /** Removes a set of GraphEdges from the graph. */ + static void RemoveGraphEdges(Graph& graph, const std::vector& edges); +}; + +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) #if !defined(ORT_MINIMAL_BUILD) /** Checks if the node has the same operator since version as the given one. */ @@ -322,65 +377,5 @@ NodeArg& CreateNodeArg(Graph& graph, const NodeArg& base_arg); #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) - -/** Find node parents by op types. - @returns The matched parents are sorted by destination argument index of their corresponding edge. -**/ -std::vector FindParentsByType(const Node& node, const std::string& parent_type); - -/** Find node children by op types. - @returns The matched children are sorted by source argument index of their corresponding edge. -**/ -std::vector FindChildrenByType(const Node& node, const std::string& child_type); - -/** Gets the name of the incoming NodeArg with the specified index for the given node. */ -const std::string& GetNodeInputName(const Node& node, int index); - -/** Gets the name of the outgoing NodeArg with the specified index for the given node. */ -const std::string& GetNodeOutputName(const Node& node, int index); - -/** Removes all output edges from the given Node of the Graph. - This should probably be elevated to the Graph API eventually. */ -size_t RemoveNodeOutputEdges(Graph& graph, Node& node); - -/** Removes output edges from the specific output_idx for the given Node of the Graph. */ -size_t RemoveNodeOutputEdges(Graph& graph, Node& node, int output_idx); - -/** returns the initializer's TensorProto if 'name' is an initializer, is constant and -cannot be overridden at runtime. If the initializer is not found or is not constant, a nullptr is returned. -@param check_outer_scope If true and the graph is a subgraph, check ancestor graph/s for 'name' if not found in 'graph'. -*/ -const ONNX_NAMESPACE::TensorProto* GetConstantInitializer(const Graph& graph, const std::string& name, - bool check_outer_scope = true); - -// A class helps handle graph edges -struct GraphEdge { - NodeIndex src_node; - NodeIndex dst_node; - int src_arg_index; - int dst_arg_index; - std::string arg_name; - - GraphEdge(NodeIndex src_node, NodeIndex dst_node, int src_arg_index, int dst_arg_index, const std::string& arg_name); - - // Constructs a GraphEdge given a node, an edge_end, and a boolean for the edge direction. - static GraphEdge CreateGraphEdge(const Node& node, const Node::EdgeEnd& edge_end, bool is_input_edge); - - /** Returns a vector of the input GraphEdges of a node. */ - static std::vector GetNodeInputEdges(const Node& node); - - /** Returns a vector of the output GraphEdges of a node. */ - static std::vector GetNodeOutputEdges(const Node& node); - - /** Returns a vector of output GraphEdges of a node for the provided output index. */ - static std::vector GetNodeOutputEdges(const Node& node, size_t index); - - /** Removes a set of GraphEdges from the graph. */ - static void RemoveGraphEdges(Graph& graph, const std::vector& edges); -}; - -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) - } // namespace graph_utils } // namespace onnxruntime diff --git a/onnxruntime/core/graph/runtime_optimization_record_container.cc b/onnxruntime/core/graph/runtime_optimization_record_container.cc index 35707db8e8..342ca11bc8 100644 --- a/onnxruntime/core/graph/runtime_optimization_record_container.cc +++ b/onnxruntime/core/graph/runtime_optimization_record_container.cc @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) #include "core/graph/runtime_optimization_record_container.h" @@ -183,4 +183,4 @@ Status RuntimeOptimizationRecordContainer::LoadFromOrtFormat( } // namespace onnxruntime -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) diff --git a/onnxruntime/core/graph/runtime_optimization_record_container.h b/onnxruntime/core/graph/runtime_optimization_record_container.h index 35d2509c5b..278425cc04 100644 --- a/onnxruntime/core/graph/runtime_optimization_record_container.h +++ b/onnxruntime/core/graph/runtime_optimization_record_container.h @@ -3,7 +3,7 @@ #pragma once -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) #include #include @@ -60,4 +60,4 @@ class RuntimeOptimizationRecordContainer { } // namespace onnxruntime -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) diff --git a/onnxruntime/core/optimizer/graph_transformer_utils.cc b/onnxruntime/core/optimizer/graph_transformer_utils.cc index 605f3d970b..ab23df4dba 100644 --- a/onnxruntime/core/optimizer/graph_transformer_utils.cc +++ b/onnxruntime/core/optimizer/graph_transformer_utils.cc @@ -277,7 +277,7 @@ InlinedVector> GenerateTransformers( #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) InlinedVector> GenerateTransformersForMinimalBuild( TransformerLevel level, @@ -336,6 +336,6 @@ InlinedVector> GenerateTransformersForMinimalB return transformers; } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) } // namespace onnxruntime::optimizer_utils diff --git a/onnxruntime/core/optimizer/qdq_transformer/qdq_util.cc b/onnxruntime/core/optimizer/qdq_transformer/qdq_util.cc index daba73df26..6297a45c42 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/qdq_util.cc +++ b/onnxruntime/core/optimizer/qdq_transformer/qdq_util.cc @@ -98,7 +98,7 @@ bool QOrDQNodeHasConstantScalarScaleAndZeroPoint( return true; } -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) bool MatchQNode(const Node& node) { return graph_utils::IsSupportedOptypeVersionAndDomain(node, QOpName, {10, 13}); @@ -108,6 +108,6 @@ bool MatchDQNode(const Node& node) { return graph_utils::IsSupportedOptypeVersionAndDomain(node, DQOpName, {10, 13}); } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) } // namespace onnxruntime::QDQ diff --git a/onnxruntime/core/optimizer/qdq_transformer/qdq_util.h b/onnxruntime/core/optimizer/qdq_transformer/qdq_util.h index b6eaf69288..bb0bf9438c 100644 --- a/onnxruntime/core/optimizer/qdq_transformer/qdq_util.h +++ b/onnxruntime/core/optimizer/qdq_transformer/qdq_util.h @@ -51,12 +51,12 @@ bool QOrDQNodeHasConstantScalarScaleAndZeroPoint( const GetConstantInitializerFn& get_const_initializer, bool& zero_point_exists); -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) // Check Q node op type, version, and domain. bool MatchQNode(const Node& node); // Check DQ node op type, version, and domain. bool MatchDQNode(const Node& node); -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) } // namespace QDQ } // namespace onnxruntime diff --git a/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.cc b/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.cc index fc32c47884..85d2b0ebe0 100644 --- a/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.cc +++ b/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.cc @@ -189,7 +189,7 @@ Status SelectorActionTransformer::ApplySelectorsAndActions( #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) static Status RegisterProducedNodesWithGraph(NodeIndex pre_action_max_num_nodes, NodeIndex post_action_max_num_nodes, const RuntimeOptimizationRecord& record, @@ -270,17 +270,17 @@ Status SelectorActionTransformer::ApplySavedRuntimeOptimizations( return Status::OK(); } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) Status SelectorActionTransformer::ApplyImpl(Graph& graph, bool& modified, int graph_level, const logging::Logger& logger) const { if (std::holds_alternative(apply_context_)) { -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) return ApplySavedRuntimeOptimizations(graph, modified, graph_level, logger); -#else // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#else return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Loading runtime optimizations is not enabled in this build."); -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif } assert(std::holds_alternative(apply_context_) || @@ -289,10 +289,10 @@ Status SelectorActionTransformer::ApplyImpl(Graph& graph, bool& modified, int gr #if !defined(ORT_MINIMAL_BUILD) const auto* save_context = std::get_if(&apply_context_); return ApplySelectorsAndActions(graph, modified, graph_level, logger, save_context); -#else // !defined(ORT_MINIMAL_BUILD) +#else return ORT_MAKE_STATUS(ONNXRUNTIME, FAIL, "Running both selectors and actions is not enabled in this build."); -#endif // !defined(ORT_MINIMAL_BUILD) +#endif } } // namespace onnxruntime diff --git a/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.h b/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.h index 7887fef455..7eb162cc69 100644 --- a/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.h +++ b/onnxruntime/core/optimizer/selectors_actions/selector_action_transformer.h @@ -131,11 +131,11 @@ class SelectorActionTransformer : public GraphTransformer { #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) // apply optimizations by replaying saved runtime optimizations Status ApplySavedRuntimeOptimizations(Graph& graph, bool& modified, int graph_level, const logging::Logger& logger) const; -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) SelectorActionRegistry selector_action_registry_; diff --git a/onnxruntime/core/session/inference_session.cc b/onnxruntime/core/session/inference_session.cc index 07cf583831..0fe1972ab8 100644 --- a/onnxruntime/core/session/inference_session.cc +++ b/onnxruntime/core/session/inference_session.cc @@ -707,12 +707,12 @@ common::Status InferenceSession::Load(const std::basic_string& model_uri) { #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) common::Status InferenceSession::FilterEnabledOptimizers(InlinedHashSet&& optimizers_to_disable) { optimizers_to_disable_ = std::move(optimizers_to_disable); return Status::OK(); } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) common::Status InferenceSession::Load(const std::string& model_uri) { std::string model_type = session_options_.config_options.GetConfigOrDefault(kOrtSessionOptionsConfigLoadModelFormat, ""); @@ -1177,7 +1177,7 @@ Status PartitionOrtFormatModel(onnxruntime::Graph& graph, return Status::OK(); } -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) + Status ApplyOrtFormatModelRuntimeOptimizations( onnxruntime::Graph& graph, const logging::Logger& logger, const SessionOptions& session_options, const InlinedHashSet& optimizers_to_disable, const IExecutionProvider& cpu_ep) { @@ -1197,7 +1197,6 @@ Status ApplyOrtFormatModelRuntimeOptimizations( return Status::OK(); } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) #endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) Status AssignNodesToEpsFromHashesImpl(Graph& graph, const fbs::SessionState& fbs_session_state, @@ -1237,7 +1236,7 @@ Status AssignNodesToEpsFromHashesImpl(Graph& graph, const fbs::SessionState& fbs ORT_RETURN_IF_ERROR(set_node_ep(node_kernel_info.node_index, node_kernel_info.kernel_def_hash)); } -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) for (const auto& [node_index, kernel_def_hash] : graph.RuntimeOptimizationReplayCtx().produced_node_index_to_kernel_def_hash) { ORT_RETURN_IF_ERROR(set_node_ep(node_index, kernel_def_hash)); @@ -1253,7 +1252,7 @@ Status AssignNodesToEpsFromHashesImpl(Graph& graph, const fbs::SessionState& fbs } } } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) return Status::OK(); } @@ -1474,14 +1473,12 @@ common::Status InferenceSession::Initialize() { ORT_RETURN_IF_ERROR(PartitionOrtFormatModel(graph, execution_providers_, kernel_registry_manager_, *session_state_)); } -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) const auto& cpu_ep = *execution_providers_.Get(onnxruntime::kCpuExecutionProvider); ORT_RETURN_IF_ERROR_SESSIONID_( ApplyOrtFormatModelRuntimeOptimizations(graph, *session_logger_, session_options_, optimizers_to_disable_, cpu_ep)); -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) ORT_RETURN_IF_ERROR(AssignNodesToEpsFromHashes(graph, *serialized_session_state, kernel_registry_manager_, *session_logger_)); diff --git a/onnxruntime/core/session/inference_session.h b/onnxruntime/core/session/inference_session.h index 1a0dd085f1..1f8b26cbe5 100644 --- a/onnxruntime/core/session/inference_session.h +++ b/onnxruntime/core/session/inference_session.h @@ -184,7 +184,7 @@ class InferenceSession { #endif // !defined(ORT_MINIMAL_BUILD) -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) /** * Filter the enabled optimizers (either transformer or rewrite rule) using optimizers_to_disable. * For an optimizer to be enabled, it must be allowed at the current optimization level (as specified in @@ -196,7 +196,7 @@ class InferenceSession { * @return OK if success. */ common::Status FilterEnabledOptimizers(InlinedHashSet&& optimizers_to_disable); -#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#endif // !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) #if !defined(ORT_MINIMAL_BUILD) || defined(ORT_MINIMAL_BUILD_CUSTOM_OPS) /** diff --git a/onnxruntime/python/onnxruntime_pybind_state.cc b/onnxruntime/python/onnxruntime_pybind_state.cc index ab0cd38773..c1f3d99b83 100644 --- a/onnxruntime/python/onnxruntime_pybind_state.cc +++ b/onnxruntime/python/onnxruntime_pybind_state.cc @@ -829,7 +829,7 @@ void InitializeSession(InferenceSession* sess, ep_registration_fn(sess, provider_types, provider_options_map); -#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD) +#if !defined(ORT_MINIMAL_BUILD) || defined(ORT_EXTENDED_MINIMAL_BUILD) if (!disabled_optimizer_names.empty()) { OrtPybindThrowIfError(sess->FilterEnabledOptimizers({disabled_optimizer_names.cbegin(), disabled_optimizer_names.cend()})); } diff --git a/tools/ci_build/github/azure-pipelines/linux-cpu-minimal-build-ci-pipeline.yml b/tools/ci_build/github/azure-pipelines/linux-cpu-minimal-build-ci-pipeline.yml index 644e5b40bf..4dd6620f20 100644 --- a/tools/ci_build/github/azure-pipelines/linux-cpu-minimal-build-ci-pipeline.yml +++ b/tools/ci_build/github/azure-pipelines/linux-cpu-minimal-build-ci-pipeline.yml @@ -11,7 +11,7 @@ # 4. Build minimal ORT with type reduction from a globally allowed types list. # This step uses a hard-coded list of types which may not include the types needed by the models # in /onnxruntime/test/testdata/, so the tests for those models are skipped. -# 5. Build extended minimal ORT with runtime optimization replay enabled. +# 5. Build extended minimal ORT and run tests. # 6. Build with all optional features disabled and no kernels. # 6a: regular build with python enabled checks that the exclusions don't break code paths in a full build. # 6b: minimal build with exceptions and python disabled checks that the exclusions don't break code paths in a @@ -154,7 +154,7 @@ jobs: workingDirectory: $(Build.SourcesDirectory) - task: CmdLine@2 - displayName: 5. Build extended minimal onnxruntime with runtime optimization replay enabled + displayName: 5. Build extended minimal onnxruntime and run tests inputs: script: | docker run --rm \ @@ -170,8 +170,7 @@ jobs: --skip_submodule_sync \ --build_shared_lib \ --parallel \ - --minimal_build extended \ - --cmake_extra_defines onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD=ON + --minimal_build extended workingDirectory: $(Build.SourcesDirectory) - task: CmdLine@2 @@ -251,7 +250,7 @@ jobs: --skip_submodule_sync \ --build_shared_lib \ --parallel \ - --minimal_build extended\ + --minimal_build extended \ --disable_exceptions \ --disable_ml_ops \ --skip_tests \ @@ -259,7 +258,6 @@ jobs: --include_ops_by_config /home/onnxruntimedev/.test_data/include_no_operators.config \ --cmake_extra_defines onnxruntime_DISABLE_SPARSE_TENSORS=ON \ onnxruntime_DISABLE_OPTIONAL_TYPE=ON \ - onnxruntime_ENABLE_RUNTIME_OPTIMIZATION_IN_MINIMAL_BUILD=OFF \ onnxruntime_BUILD_UNIT_TESTS=OFF workingDirectory: $(Build.SourcesDirectory)