mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-30 20:18:08 +00:00
[DML EP] Add BiasAdd (#15211)
This commit is contained in:
parent
ce9ad8c8bc
commit
4a676b011a
6 changed files with 124 additions and 2 deletions
|
|
@ -1173,6 +1173,7 @@ Do not modify directly.*
|
|||
| |
|
||||
|**Operator Domain:** *com.microsoft*||||
|
||||
|Attention|*in* input:**T**<br> *in* weights:**T**<br> *in* bias:**T**<br> *in* mask_index:**M**<br> *in* past:**T**<br> *in* relative_position_bias:**T**<br> *in* past_sequence_length:**M**<br> *out* output:**T**<br> *out* present:**T**|1+|**M** = tensor(int32)<br/> **T** = tensor(float), tensor(float16)|
|
||||
|BiasAdd|*in* X:**T**<br> *in* bias:**T**<br> *in* skip:**T**<br> *out* Y:**T**|1+|**T** = tensor(float), tensor(float16)|
|
||||
|BiasGelu|*in* A:**T**<br> *in* B:**T**<br> *out* C:**T**|1+|**T** = tensor(float), tensor(float16)|
|
||||
|ConvTransposeWithDynamicPads|*in* X:**T**<br> *in* W:**T**<br> *in* Pads:**tensor(int64)**<br> *in* B:**T**<br> *out* Y:**T**|1+|**T** = tensor(float), tensor(float16)|
|
||||
|DequantizeLinear|*in* x:**T1**<br> *in* x_scale:**T2**<br> *in* x_zero_point:**T1**<br> *out* y:**T2**|1+|**T1** = tensor(float)<br/> **T2** = tensor(uint8)|
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
namespace Dml
|
||||
{
|
||||
|
||||
class DmlOperatorBiasAdd : public DmlOperator
|
||||
{
|
||||
public:
|
||||
DmlOperatorBiasAdd(const MLOperatorKernelCreationContext& kernelCreationContext)
|
||||
: DmlOperator(kernelCreationContext)
|
||||
{
|
||||
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetInputCount() == 3);
|
||||
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetOutputCount() == 1);
|
||||
|
||||
// Broadcast bias to have the same dimensions as the input
|
||||
std::vector<uint32_t> inputTensorShape = kernelCreationContext.GetTensorShapeDescription().GetInputTensorShape(0);
|
||||
DmlOperator::Initialize(kernelCreationContext, std::nullopt, std::nullopt, inputTensorShape);
|
||||
|
||||
ML_CHECK_VALID_ARGUMENT(m_inputTensorDescs.size() == 3);
|
||||
ML_CHECK_VALID_ARGUMENT(m_outputTensorDescs.size() == 1);
|
||||
ML_CHECK_VALID_ARGUMENT(m_inputTensorDescs[0].GetDimensionCount() == 4);
|
||||
ML_CHECK_VALID_ARGUMENT(m_inputTensorDescs[1].GetDimensionCount() == 4);
|
||||
ML_CHECK_VALID_ARGUMENT(m_inputTensorDescs[2].GetDimensionCount() == 4);
|
||||
ML_CHECK_VALID_ARGUMENT(m_inputTensorDescs[0].GetSizes() == m_inputTensorDescs[2].GetSizes());
|
||||
|
||||
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
|
||||
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
|
||||
|
||||
// 1. Add the bias
|
||||
DML_ELEMENT_WISE_ADD_OPERATOR_DESC addBiasDesc{};
|
||||
addBiasDesc.ATensor = &inputDescs[0];
|
||||
addBiasDesc.BTensor = &inputDescs[1];
|
||||
addBiasDesc.OutputTensor = &inputDescs[0];
|
||||
DML_OPERATOR_DESC dmlAddBiasDesc = { DML_OPERATOR_ELEMENT_WISE_ADD, &addBiasDesc };
|
||||
|
||||
// 2. Add the residual inputs
|
||||
DML_ELEMENT_WISE_ADD_OPERATOR_DESC addSkipDesc{};
|
||||
addSkipDesc.ATensor = &inputDescs[0];
|
||||
addSkipDesc.BTensor = &inputDescs[2];
|
||||
addSkipDesc.OutputTensor = &inputDescs[0];
|
||||
DML_OPERATOR_DESC dmlAddSkipDesc = { DML_OPERATOR_ELEMENT_WISE_ADD, &addSkipDesc };
|
||||
|
||||
enum NodeIndex
|
||||
{
|
||||
addBiasNodeIndex,
|
||||
addSkipNodeIndex,
|
||||
nodeCount,
|
||||
};
|
||||
|
||||
// Construct the graph
|
||||
std::vector<const DML_OPERATOR_DESC*> opDescs(nodeCount);
|
||||
opDescs[addBiasNodeIndex] = &dmlAddBiasDesc;
|
||||
opDescs[addSkipNodeIndex] = &dmlAddSkipDesc;
|
||||
|
||||
std::vector<DML_INPUT_GRAPH_EDGE_DESC> inputEdges;
|
||||
inputEdges.reserve(3);
|
||||
|
||||
std::vector<DML_INTERMEDIATE_GRAPH_EDGE_DESC> intermediateEdges;
|
||||
intermediateEdges.reserve(1);
|
||||
|
||||
std::vector<DML_OUTPUT_GRAPH_EDGE_DESC> outputEdges;
|
||||
outputEdges.reserve(1);
|
||||
|
||||
DML_INPUT_GRAPH_EDGE_DESC inputToAddBiasEdge{};
|
||||
inputToAddBiasEdge.GraphInputIndex = 0;
|
||||
inputToAddBiasEdge.ToNodeIndex = addBiasNodeIndex;
|
||||
inputToAddBiasEdge.ToNodeInputIndex = 0;
|
||||
inputEdges.push_back(inputToAddBiasEdge);
|
||||
|
||||
DML_INPUT_GRAPH_EDGE_DESC biasToAddBiasEdge{};
|
||||
biasToAddBiasEdge.GraphInputIndex = 1;
|
||||
biasToAddBiasEdge.ToNodeIndex = addBiasNodeIndex;
|
||||
biasToAddBiasEdge.ToNodeInputIndex = 1;
|
||||
inputEdges.push_back(biasToAddBiasEdge);
|
||||
|
||||
DML_INTERMEDIATE_GRAPH_EDGE_DESC addBiasToAddSkipEdge{};
|
||||
addBiasToAddSkipEdge.FromNodeIndex = addBiasNodeIndex;
|
||||
addBiasToAddSkipEdge.FromNodeOutputIndex = 0;
|
||||
addBiasToAddSkipEdge.ToNodeIndex = addSkipNodeIndex;
|
||||
addBiasToAddSkipEdge.ToNodeInputIndex = 0;
|
||||
intermediateEdges.push_back(addBiasToAddSkipEdge);
|
||||
|
||||
DML_INPUT_GRAPH_EDGE_DESC skipToAddSkipEdge{};
|
||||
skipToAddSkipEdge.GraphInputIndex = 2;
|
||||
skipToAddSkipEdge.ToNodeIndex = addSkipNodeIndex;
|
||||
skipToAddSkipEdge.ToNodeInputIndex = 1;
|
||||
inputEdges.push_back(skipToAddSkipEdge);
|
||||
|
||||
DML_OUTPUT_GRAPH_EDGE_DESC addSkipToOutputEdge{};
|
||||
addSkipToOutputEdge.FromNodeIndex = addSkipNodeIndex;
|
||||
addSkipToOutputEdge.FromNodeOutputIndex = 0;
|
||||
addSkipToOutputEdge.GraphOutputIndex = 0;
|
||||
outputEdges.push_back(addSkipToOutputEdge);
|
||||
|
||||
MLOperatorGraphDesc operatorGraphDesc = {};
|
||||
operatorGraphDesc.inputEdgeCount = gsl::narrow_cast<uint32_t>(inputEdges.size());
|
||||
operatorGraphDesc.inputEdges = inputEdges.data();
|
||||
operatorGraphDesc.intermediateEdgeCount = gsl::narrow_cast<uint32_t>(intermediateEdges.size());
|
||||
operatorGraphDesc.intermediateEdges = intermediateEdges.data();
|
||||
operatorGraphDesc.outputEdgeCount = gsl::narrow_cast<uint32_t>(outputEdges.size());
|
||||
operatorGraphDesc.outputEdges = outputEdges.data();
|
||||
operatorGraphDesc.nodeCount = gsl::narrow_cast<uint32_t>(opDescs.size());
|
||||
operatorGraphDesc.nodesAsOpDesc = opDescs.data();
|
||||
SetDmlOperatorGraphDesc(std::move(operatorGraphDesc), kernelCreationContext);
|
||||
}
|
||||
};
|
||||
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(BiasAdd, DmlOperatorBiasAdd);
|
||||
|
||||
} // namespace Dml
|
||||
|
|
@ -211,6 +211,7 @@ DML_OP_EXTERN_CREATION_FUNCTION(LayerNormalization);
|
|||
DML_OP_EXTERN_CREATION_FUNCTION(LayerNormalization17);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(SkipLayerNormalization);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(EmbedLayerNormalization);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(BiasAdd);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(LRN);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(MeanVarianceNormalization);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(GroupNorm);
|
||||
|
|
@ -879,6 +880,7 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation
|
|||
{REG_INFO( 7, LayerNormalization, typeNameListLayerNormContrib, supportedTypeListLayerNormalizationContrib, DmlGraphSupport::Supported, requiredConstantCpuInputs(), std::nullopt, QueryLayerNormalization)},
|
||||
{REG_INFO_MS( 1, SkipLayerNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(), std::nullopt, QuerySkipLayerNormalization)},
|
||||
{REG_INFO_MS( 1, EmbedLayerNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
|
||||
{REG_INFO_MS( 1, BiasAdd, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
|
||||
{REG_INFO_MS( 1, QuickGelu, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
|
||||
{REG_INFO_MS( 1, GroupNorm, typeNameListGroupNorm, supportedTypeListGroupNorm, DmlGraphSupport::Supported)},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1444,6 +1444,7 @@ using ShapeInferenceHelper_LpNormalization = GetOutputShapeAsInputShapeHelper;
|
|||
using ShapeInferenceHelper_RNN = RecurrentHelper;
|
||||
using ShapeInferenceHelper_GRU = RecurrentHelper;
|
||||
using ShapeInferenceHelper_LSTM = RecurrentHelper;
|
||||
using ShapeInferenceHelper_BiasAdd = GetOutputShapeAsInputShapeHelper;
|
||||
|
||||
using ShapeInferenceHelper_Gather = GatherHelper;
|
||||
using ShapeInferenceHelper_GatherElements = GetOutputShapeAsSpecificInputShapeHelper<1>;
|
||||
|
|
|
|||
|
|
@ -410,6 +410,7 @@ namespace OperatorHelper
|
|||
static const int sc_sinceVer_Attention = 1;
|
||||
static const int sc_sinceVer_SkipLayerNormalization = 1;
|
||||
static const int sc_sinceVer_EmbedLayerNormalization = 1;
|
||||
static const int sc_sinceVer_BiasAdd = 1;
|
||||
static const int sc_sinceVer_QuickGelu = 1;
|
||||
static const int sc_sinceVer_GroupNorm = 1;
|
||||
} // namespace MsftOperatorSet1
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ using namespace onnxruntime::test;
|
|||
namespace onnxruntime {
|
||||
namespace test {
|
||||
|
||||
#if defined(USE_CUDA) || defined(USE_ROCM)
|
||||
#if defined(USE_CUDA) || defined(USE_ROCM) || defined(USE_DML)
|
||||
static std::vector<float> GetExpectedResult(const std::vector<float>& input_data,
|
||||
const std::vector<float>& bias_data,
|
||||
const std::vector<float>& skip_data) {
|
||||
|
|
@ -39,8 +39,9 @@ static void RunSkipBiasGpuTest(const std::vector<float>& input_data,
|
|||
int min_cuda_architecture = use_float16 ? 530 : 0;
|
||||
bool enable_cuda = HasCudaEnvironment(min_cuda_architecture);
|
||||
bool enable_rocm = (nullptr != DefaultRocmExecutionProvider().get());
|
||||
bool enable_dml = (nullptr != DefaultDmlExecutionProvider().get());
|
||||
|
||||
if (!enable_cuda && !enable_rocm) {
|
||||
if (!enable_cuda && !enable_rocm && !enable_dml) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -65,6 +66,9 @@ static void RunSkipBiasGpuTest(const std::vector<float>& input_data,
|
|||
if (enable_rocm) {
|
||||
execution_providers.push_back(DefaultRocmExecutionProvider());
|
||||
}
|
||||
if (enable_dml) {
|
||||
execution_providers.push_back(DefaultDmlExecutionProvider());
|
||||
}
|
||||
tester.Run(OpTester::ExpectResult::kExpectSuccess, "", {}, nullptr, &execution_providers);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue