diff --git a/docs/ContribOperators.md b/docs/ContribOperators.md index f22190e029..45b2f8da5f 100644 --- a/docs/ContribOperators.md +++ b/docs/ContribOperators.md @@ -33,6 +33,7 @@ Do not modify directly.* * com.microsoft.FusedConv * com.microsoft.FusedGemm * com.microsoft.FusedMatMul + * com.microsoft.FusedMatMulActivation * com.microsoft.GatedRelativePositionBias * com.microsoft.GatherND * com.microsoft.Gelu @@ -1797,6 +1798,63 @@ This version of the operator has been available since version 1 of the 'com.micr +### **com.microsoft.FusedMatMulActivation** + + Executes the same operation as FusedMatMul, but also has an activation function fused to its output. + +#### Version + +This version of the operator has been available since version 1 of the 'com.microsoft' operator set. + +#### Attributes + +
+
activation : string (required)
+
+
activation_alpha : float
+
+
activation_axis : int
+
+
activation_beta : float
+
+
activation_gamma : float
+
+
alpha : float
+
Scalar multiplier for the product of the input tensors.
+
transA : int
+
Whether A should be transposed on the last two dimensions before doing multiplication
+
transB : int
+
Whether B should be transposed on the last two dimensions before doing multiplication
+
transBatchA : int
+
Whether A should be transposed on the 1st dimension and batch dimensions (dim-1 to dim-rank-2) before doing multiplication
+
transBatchB : int
+
Whether B should be transposed on the 1st dimension and batch dimensions (dim-1 to dim-rank-2) before doing multiplication
+
+ +#### Inputs + +
+
A : T
+
N-dimensional matrix A
+
B : T
+
N-dimensional matrix B
+
+ +#### Outputs + +
+
Y : T
+
Matrix multiply results
+
+ +#### Type Constraints + +
+
T : tensor(float16), tensor(float), tensor(double), tensor(bfloat16)
+
Constrain input and output types to float tensors.
+
+ + ### **com.microsoft.GatedRelativePositionBias** query_layer = (query_layer + query_bias).reshape(batch_size, seq_len, num_heads, head_size).transpose(1, 2) diff --git a/docs/OperatorKernels.md b/docs/OperatorKernels.md index f99c8b0c42..840a68b5aa 100644 --- a/docs/OperatorKernels.md +++ b/docs/OperatorKernels.md @@ -1180,6 +1180,7 @@ Do not modify directly.* |DequantizeLinear|*in* x:**T1**
*in* x_scale:**T2**
*in* x_zero_point:**T1**
*out* y:**T2**|1+|**T1** = tensor(float)
**T2** = tensor(uint8)| |EmbedLayerNormalization|*in* input_ids:**T1**
*in* segment_ids:**T1**
*in* word_embedding:**T**
*in* position_embedding:**T**
*in* segment_embedding:**T**
*in* gamma:**T**
*in* beta:**T**
*in* mask:**T1**
*in* position_ids:**T1**
*out* output:**T**
*out* mask_index:**T1**
*out* embedding_sum:**T**|1+|**T** = tensor(float), tensor(float16)| |FusedMatMul|*in* A:**T**
*in* B:**T**
*out* Y:**T**|1+|**T** = tensor(float), tensor(float16)| +|FusedMatMulActivation|*in* A:**T**
*in* B:**T**
*out* Y:**T**|1+|**T** = tensor(float), tensor(float16)| |Gelu|*in* X:**T**
*out* Y:**T**|1+|**T** = tensor(float), tensor(float16)| |GroupNorm|*in* X:**T**
*in* gamma:**M**
*in* beta:**M**
*out* Y:**T**|1+|**M** = tensor(float), tensor(float16)
**T** = tensor(float), tensor(float16)| |NhwcConv|*in* X:**T**
*in* W:**T**
*in* B:**T**
*out* Y:**T**|1+|**T** = tensor(float), tensor(float16)| diff --git a/onnxruntime/core/graph/contrib_ops/contrib_defs.cc b/onnxruntime/core/graph/contrib_ops/contrib_defs.cc index 637600dcaf..4a2a925cb1 100644 --- a/onnxruntime/core/graph/contrib_ops/contrib_defs.cc +++ b/onnxruntime/core/graph/contrib_ops/contrib_defs.cc @@ -1695,6 +1695,10 @@ constexpr const char* FusedMatMul_doc = R"DOC( Matrix product that behaves like numpy.matmul: https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.matmul.html )DOC"; +constexpr const char* FusedMatMulActivation_doc = R"DOC( +Executes the same operation as FusedMatMul, but also has an activation function fused to its output. +)DOC"; + ONNX_MS_OPERATOR_SET_SCHEMA(TransposeMatMul, 1, OpSchema() .Input(0, "A", "N-dimensional matrix A", "T") @@ -1747,6 +1751,53 @@ ONNX_MS_OPERATOR_SET_SCHEMA(FusedMatMul, 1, .SetDoc(FusedMatMul_doc) .TypeAndShapeInferenceFunction([](ONNX_NAMESPACE::InferenceContext& ctx) { FusedMatMulShapeInference(ctx); })); +ONNX_MS_OPERATOR_SET_SCHEMA(FusedMatMulActivation, 1, + OpSchema() + .Input(0, "A", "N-dimensional matrix A", "T") + .Input(1, "B", "N-dimensional matrix B", "T") + .Attr("alpha", "Scalar multiplier for the product of the input tensors.", AttributeProto::FLOAT, 1.0f) + .Attr("transA", "Whether A should be transposed on the last two dimensions before doing multiplication", + AttributeProto::INT, static_cast(0)) + .Attr("transB", "Whether B should be transposed on the last two dimensions before doing multiplication", + AttributeProto::INT, static_cast(0)) + .Attr("transBatchA", + "Whether A should be transposed on the 1st dimension and batch dimensions (dim-1 to dim-rank-2) before " + "doing multiplication", + AttributeProto::INT, static_cast(0)) + .Attr("transBatchB", + "Whether B should be transposed on the 1st dimension and batch dimensions (dim-1 to dim-rank-2) before " + "doing multiplication", + AttributeProto::INT, static_cast(0)) + .Attr( + "activation", + "", + AttributeProto::STRING) + .Attr( + "activation_alpha", + "", + AttributeProto::FLOAT, + OPTIONAL_VALUE) + .Attr( + "activation_beta", + "", + AttributeProto::FLOAT, + OPTIONAL_VALUE) + .Attr( + "activation_gamma", + "", + AttributeProto::FLOAT, + OPTIONAL_VALUE) + .Attr( + "activation_axis", + "", + AttributeProto::INT, + OPTIONAL_VALUE) + .Output(0, "Y", "Matrix multiply results", "T") + .TypeConstraint("T", {"tensor(float16)", "tensor(float)", "tensor(double)", "tensor(bfloat16)"}, + "Constrain input and output types to float tensors.") + .SetDoc(FusedMatMulActivation_doc) + .TypeAndShapeInferenceFunction([](ONNX_NAMESPACE::InferenceContext& ctx) { FusedMatMulShapeInference(ctx); })); + ONNX_MS_OPERATOR_SET_SCHEMA(SparseToDenseMatMul, 1, OpSchema() .Input(0, "A", "2-dimensional sparse matrix A. Either COO or CSR format", "T") diff --git a/onnxruntime/core/graph/contrib_ops/ms_opset.h b/onnxruntime/core/graph/contrib_ops/ms_opset.h index 210c0d5aa2..cc821ea3d3 100644 --- a/onnxruntime/core/graph/contrib_ops/ms_opset.h +++ b/onnxruntime/core/graph/contrib_ops/ms_opset.h @@ -67,6 +67,7 @@ class ONNX_OPERATOR_SET_SCHEMA_CLASS_NAME(Microsoft, 1, FastGelu); class ONNX_OPERATOR_SET_SCHEMA_CLASS_NAME(Microsoft, 1, FusedConv); class ONNX_OPERATOR_SET_SCHEMA_CLASS_NAME(Microsoft, 1, FusedGemm); class ONNX_OPERATOR_SET_SCHEMA_CLASS_NAME(Microsoft, 1, FusedMatMul); +class ONNX_OPERATOR_SET_SCHEMA_CLASS_NAME(Microsoft, 1, FusedMatMulActivation); class ONNX_OPERATOR_SET_SCHEMA_CLASS_NAME(Microsoft, 1, GatherND); class ONNX_OPERATOR_SET_SCHEMA_CLASS_NAME(Microsoft, 1, Gelu); class ONNX_OPERATOR_SET_SCHEMA_CLASS_NAME(Microsoft, 1, QuickGelu); @@ -161,6 +162,7 @@ class OpSet_Microsoft_ver1 { fn(GetOpSchema()); fn(GetOpSchema()); fn(GetOpSchema()); + fn(GetOpSchema()); fn(GetOpSchema()); fn(GetOpSchema()); fn(GetOpSchema()); diff --git a/onnxruntime/core/optimizer/graph_transformer_utils.cc b/onnxruntime/core/optimizer/graph_transformer_utils.cc index cce11c4795..d1452eb47b 100644 --- a/onnxruntime/core/optimizer/graph_transformer_utils.cc +++ b/onnxruntime/core/optimizer/graph_transformer_utils.cc @@ -45,6 +45,7 @@ #include "core/optimizer/identical_children_consolidation.h" #include "core/optimizer/identity_elimination.h" #include "core/optimizer/layer_norm_fusion.h" +#include "core/optimizer/matmul_activation_fusion.h" #include "core/optimizer/matmul_add_fusion.h" #include "core/optimizer/matmul_integer_to_float.h" #include "core/optimizer/matmul_scale_fusion.h" @@ -183,6 +184,7 @@ InlinedVector> GenerateTransformers( #ifndef DISABLE_CONTRIB_OPS const InlinedHashSet cpu_ep = {onnxruntime::kCpuExecutionProvider}; #endif + const InlinedHashSet dml_ep = {onnxruntime::kDmlExecutionProvider}; switch (level) { case TransformerLevel::Level1: { // RewriteRule optimizations are the simplest (they generally remove unnecessary nodes and are cheap to run) @@ -200,7 +202,7 @@ InlinedVector> GenerateTransformers( // Put ConstantSharing before CommonSubexpressionElimination by intention as it can create more opportunities for // CSE. For example, if A and B nodes both do Add operation with a same value but different initializers, by // default, CSE will not merge them, because the different initializers are represented by different NodeArg. - if (session_options.config_options.GetConfigOrDefault(kOrtSessionOptionsDisableDoubleQDQRemover, "0") == "0"){ + if (session_options.config_options.GetConfigOrDefault(kOrtSessionOptionsDisableDoubleQDQRemover, "0") == "0") { transformers.emplace_back(std::make_unique()); } transformers.emplace_back(std::make_unique()); @@ -302,6 +304,7 @@ InlinedVector> GenerateTransformers( transformers.emplace_back(std::make_unique(cpu_cuda_dml_rocm_eps)); transformers.emplace_back(std::make_unique(cpu_cuda_dml_rocm_eps)); + transformers.emplace_back(std::make_unique(dml_ep)); // GeluApproximation has side effects which may change results. It needs to be manually enabled, // or alternatively the model can be updated offline using a model conversion script diff --git a/onnxruntime/core/optimizer/matmul_activation_fusion.cc b/onnxruntime/core/optimizer/matmul_activation_fusion.cc new file mode 100644 index 0000000000..2c6cf83ea4 --- /dev/null +++ b/onnxruntime/core/optimizer/matmul_activation_fusion.cc @@ -0,0 +1,83 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "core/optimizer/initializer.h" +#include "core/optimizer/matmul_activation_fusion.h" +#include "core/graph/graph_utils.h" + +using namespace ONNX_NAMESPACE; +using namespace ::onnxruntime::common; +namespace onnxruntime { + +namespace { +// Don't check if the op is Deprecated. In ONNX Runtime's world, there is no deprecation. +bool IsSupportedOptypeVersionAndDomain(const Node& node, const std::string& op_type, + std::initializer_list versions, + std::string_view domain) { + return (node.OpType() == op_type && graph_utils::MatchesOpSinceVersion(node, versions) && + graph_utils::MatchesOpSetDomain(node, domain)); +} + +// If the op has multiple versions, here we require it must have a single implementation that can work across all the +// versions. Because in the fusion, we discarded the op version information. +bool IsFusableActivation(const Node& node) { + return IsSupportedOptypeVersionAndDomain(node, "Softmax", {1, 11, 13}, kOnnxDomain); +} +} // namespace + +Status MatMulActivationFusion::ApplyImpl(Graph& graph, bool& modified, int graph_level, + const logging::Logger& logger) const { + GraphViewer graph_viewer(graph); + const auto& order = graph_viewer.GetNodesInTopologicalOrder(); + + for (auto index : order) { + auto* node_ptr = graph.GetNode(index); + if (!node_ptr) + continue; // node was removed + + auto& node = *node_ptr; + ORT_RETURN_IF_ERROR(Recurse(node, modified, graph_level, logger)); + + if (!graph_utils::IsSupportedOptypeVersionAndDomain(node, "FusedMatMul", {1}, kMSDomain) || + !graph_utils::IsSupportedProvider(node, GetCompatibleExecutionProviders()) || node.GetOutputEdgesCount() != 1) { + continue; + } + + const Node& next_node = *(node.OutputNodesBegin()); + if (!IsFusableActivation(next_node) || next_node.GetExecutionProviderType() != node.GetExecutionProviderType()) { + continue; + } + + if (graph.NodeProducesGraphOutput(node)) { + continue; + } + + Node& act_node = *graph.GetNode(next_node.Index()); // get mutable reference + + Node& fused_node = graph.AddNode(graph.GenerateNodeName(node.Name() + "_FusedActivation"), "FusedMatMulActivation", + node.Description() + " with activation " + act_node.OpType(), + node.MutableInputDefs(), {}, &node.GetAttributes(), kMSDomain); + + // Add a new attribute to specify the activation type + fused_node.AddAttribute("activation", act_node.OpType()); + + // Assign provider to this new node. Provider should be same as the provider for old node. + fused_node.SetExecutionProviderType(node.GetExecutionProviderType()); + + // Add optional attributes for activations + const NodeAttributes& attrs = act_node.GetAttributes(); + for (const auto& attr : attrs) { + AttributeProto fused_node_attr(attr.second); + fused_node_attr.set_name("activation_" + attr.first); + fused_node.AddAttributeProto(std::move(fused_node_attr)); + } + + // move output definitions and edges from act_node to fused_node. delete node and act_node. + graph_utils::FinalizeNodeFusion(graph, {node, act_node}, fused_node); + + modified = true; + } + + return Status::OK(); +} +} // namespace onnxruntime diff --git a/onnxruntime/core/optimizer/matmul_activation_fusion.h b/onnxruntime/core/optimizer/matmul_activation_fusion.h new file mode 100644 index 0000000000..b1f9d6f47f --- /dev/null +++ b/onnxruntime/core/optimizer/matmul_activation_fusion.h @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#pragma once + +#include "core/optimizer/graph_transformer.h" + +namespace onnxruntime { + +class MatMulActivationFusion : public GraphTransformer { + public: + MatMulActivationFusion(const InlinedHashSet& compatible_execution_providers = {}) noexcept + : GraphTransformer("MatMulActivationFusion", compatible_execution_providers) {} + + Status ApplyImpl(Graph& graph, bool& modified, int graph_level, const logging::Logger& logger) const override; +}; + +} // namespace onnxruntime diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorFusedMatMul.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorFusedMatMul.cpp index 10a98ac48c..0bc543c56f 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorFusedMatMul.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorFusedMatMul.cpp @@ -57,8 +57,8 @@ public: std::vector inputDescs = GetDmlInputDescs(); std::vector outputDescs = GetDmlOutputDescs(); - std::optional fusedActivation = FusionHelpers::TryGetFusedActivationDesc(kernelInfo); - DML_OPERATOR_DESC fusedActivationDmlDesc = fusedActivation ? fusedActivation->GetDmlDesc() : DML_OPERATOR_DESC(); + std::optional fusedActivation = FusionHelpers::TryGetGraphFusedActivationDesc(kernelInfo); + DML_OPERATOR_DESC fusedActivationDmlDesc = fusedActivation ? fusedActivation->desc.GetDmlDesc() : DML_OPERATOR_DESC(); const float alpha = kernelInfo.GetOptionalAttribute(AttrName::Alpha, 1.0f); @@ -79,5 +79,6 @@ public: }; DML_OP_DEFINE_CREATION_FUNCTION(FusedMatMul, DmlOperatorFusedMatMul); +DML_OP_DEFINE_CREATION_FUNCTION(FusedMatMulActivation, DmlOperatorFusedMatMul); } // namespace Dml diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorRegistration.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorRegistration.cpp index 4484ac9d06..be5a56007a 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorRegistration.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorRegistration.cpp @@ -312,6 +312,7 @@ DML_OP_EXTERN_CREATION_FUNCTION(Affine); DML_OP_EXTERN_CREATION_FUNCTION(Dropout); DML_OP_EXTERN_CREATION_FUNCTION(MatMul); DML_OP_EXTERN_CREATION_FUNCTION(FusedMatMul); +DML_OP_EXTERN_CREATION_FUNCTION(FusedMatMulActivation); DML_OP_EXTERN_CREATION_FUNCTION(Cast); DML_OP_EXTERN_CREATION_FUNCTION(CastLike15); DML_OP_EXTERN_CREATION_FUNCTION(MemcpyFromHost); @@ -858,6 +859,7 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation {REG_INFO_MS( 1, Gelu, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO_MS( 1, BiasGelu, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO_MS( 1, FusedMatMul, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, + {REG_INFO_MS( 1, FusedMatMulActivation, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, {REG_INFO_MS( 1, QLinearSigmoid, typeNameListDefault, supportedTypeListQLinearSigmoid, DmlGraphSupport::Supported, requiredConstantCpuInputs(), std::nullopt, QueryQLinearSigmoid)}, {REG_INFO_MS( 1, Attention, typeNameListAttention, supportedTypeListAttention, DmlGraphSupport::Supported, requiredConstantCpuInputs(), std::nullopt, QueryAttention)}, diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorUtility.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorUtility.cpp index e805cb1e7a..f83ad5a3a4 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorUtility.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorUtility.cpp @@ -348,6 +348,44 @@ namespace Dml return activation; } + std::optional TryGetGraphFusedActivationDesc(const MLOperatorKernelCreationContext& kernelInfo) + { + if (!kernelInfo.HasAttribute(AttrName::GraphFusedActivation, MLOperatorAttributeType::String)) + { + return std::nullopt; // No activation + } + + auto activationName = kernelInfo.GetAttribute(AttrName::GraphFusedActivation); + ActivationOperatorDescWrapper activation = {}; + + if (activationName == "Softmax") + { + const uint32_t onnxDimCount = gsl::narrow_cast(kernelInfo.GetTensorShapeDescription().GetInputTensorShape(0).size()); + int onnxAxis = HandleNegativeAxis(kernelInfo.GetOptionalAttribute(AttrName::GraphFusedAxis, -1), onnxDimCount); + + auto dmlAdjustedAxis = GetDmlAdjustedAxis(onnxAxis, onnxDimCount, kernelInfo.GetTensorShapeDescription().GetInputTensorDimensionCount(0)); + + // If the axis is supported by Softmax, use this version instead since it's more likely to be supported by metacommands + if (dmlAdjustedAxis == onnxDimCount - 1) + { + activation.desc.activationType = DML_OPERATOR_ACTIVATION_SOFTMAX; + } + else + { + activation.desc.activationType = DML_OPERATOR_ACTIVATION_SOFTMAX1; + activation.dmlAxes.push_back(dmlAdjustedAxis); + activation.desc.params.softmax1.Axes = activation.dmlAxes.data(); + activation.desc.params.softmax1.AxisCount = gsl::narrow_cast(activation.dmlAxes.size()); + } + } + else + { + ML_INVALID_ARGUMENT("Unsupported activation function."); + } + + return activation; + } + /*static*/ std::string GetFusedAttributeName(std::string_view name) { return std::string("fused_").append(name); diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorUtility.h b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorUtility.h index 3893bc0019..f0fad6a05f 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorUtility.h +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorUtility.h @@ -7,6 +7,12 @@ namespace Dml { constexpr float DefaultEpsilon = 0.00001f; + struct ActivationOperatorDescWrapper + { + ActivationOperatorDesc desc; + std::vector dmlAxes; + }; + namespace ActivationHelper { float GetDefaultAlpha(DML_OPERATOR_TYPE function); @@ -41,6 +47,7 @@ namespace Dml bool IsFusableActivationOperator(std::string_view opType, std::string_view domain, int sinceVersion); std::optional TryGetFusedActivationDesc(const MLOperatorKernelCreationContext& kernelInfo); + std::optional TryGetGraphFusedActivationDesc(const MLOperatorKernelCreationContext& kernelInfo); // Produces names for attributes added to fused kernels. This effectively prepends a string to distinguish ONNX // attributes from those added dynamically via operator fusion. For example, this function would be used to diff --git a/onnxruntime/core/providers/dml/OperatorAuthorHelper/Attributes.h b/onnxruntime/core/providers/dml/OperatorAuthorHelper/Attributes.h index 5db6b2a4e4..ac15cb2b0e 100644 --- a/onnxruntime/core/providers/dml/OperatorAuthorHelper/Attributes.h +++ b/onnxruntime/core/providers/dml/OperatorAuthorHelper/Attributes.h @@ -114,6 +114,9 @@ namespace AttrName static constexpr const char* Activation = "activation"; static constexpr const char* Groups = "groups"; + static constexpr const char* GraphFusedActivation = "activation"; + static constexpr const char* GraphFusedAxis = "activation_axis"; + } // namespace AttrName namespace AttrValue diff --git a/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorHelper.h b/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorHelper.h index 1bb8e3db55..8372113393 100644 --- a/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorHelper.h +++ b/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorHelper.h @@ -1654,6 +1654,7 @@ using ShapeInferenceHelper_DmlFusedMeanVarianceNormalization = GetOutputShapeAsI using ShapeInferenceHelper_DmlFusedGemm = GemmHelper; using ShapeInferenceHelper_DmlFusedMatMul = MatMulHelper; using ShapeInferenceHelper_FusedMatMul = FusedMatMulHelper; +using ShapeInferenceHelper_FusedMatMulActivation = FusedMatMulHelper; using ShapeInferenceHelper_DmlFusedAdd = GetBroadcastedOutputShapeHelper; using ShapeInferenceHelper_DmlFusedSum = GetBroadcastedOutputShapeHelper; diff --git a/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorVersions.h b/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorVersions.h index cc64c559d0..77b297cd3e 100644 --- a/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorVersions.h +++ b/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorVersions.h @@ -406,6 +406,7 @@ namespace OperatorHelper static const int sc_sinceVer_Gelu = 1; static const int sc_sinceVer_BiasGelu = 1; static const int sc_sinceVer_FusedMatMul = 1; + static const int sc_sinceVer_FusedMatMulActivation = 1; static const int sc_sinceVer_QLinearSigmoid = 1; static const int sc_sinceVer_Attention = 1; static const int sc_sinceVer_SkipLayerNormalization = 1;