diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorCumSum.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorCumSum.cpp index 1f8cf4aa31..c323affc55 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorCumSum.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorCumSum.cpp @@ -29,10 +29,10 @@ public: int32_t onnxAxis = 0; if (kernelCreationContext.IsInputValid(1)) { - uint64_t rawAxisBytes; + std::byte tensorBytes[8]; MLOperatorTensor axisTensor = kernelCreationContext.GetConstantInputTensor(1); - ReadScalarTensorData(axisTensor, /*out*/ &rawAxisBytes, sizeof(rawAxisBytes)); - onnxAxis = gsl::narrow_cast(ReadAsInt64(axisTensor.GetTensorDataType(), /*out*/ &rawAxisBytes)); + ReadScalarTensorData(axisTensor, /*out*/ tensorBytes, sizeof(tensorBytes)); + onnxAxis = gsl::narrow_cast(ReadAsInt64(axisTensor.GetTensorDataType(), /*out*/ tensorBytes)); } uint32_t dmlAxis = GetDmlAdjustedAxis(onnxAxis, kernelCreationContext, m_inputTensorDescs.front().GetDimensionCount()); diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorElementWise.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorElementWise.cpp index d68c270ad3..bbbb8f2e59 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorElementWise.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/DmlOperatorElementWise.cpp @@ -404,10 +404,10 @@ public: std::vector> m_compiledOperators; }; -class DmlOperatorElementwiseClip : public DmlOperator +class DmlOperatorElementwiseClip7 : public DmlOperator { public: - DmlOperatorElementwiseClip(const MLOperatorKernelCreationContext& kernelInfo) : DmlOperator(kernelInfo) + DmlOperatorElementwiseClip7(const MLOperatorKernelCreationContext& kernelInfo) : DmlOperator(kernelInfo) { ML_CHECK_VALID_ARGUMENT(kernelInfo.GetInputCount() == 1); ML_CHECK_VALID_ARGUMENT(kernelInfo.GetOutputCount() == 1); @@ -427,6 +427,42 @@ public: } }; +class DmlOperatorElementwiseClip11 : public DmlOperator +{ +public: + DmlOperatorElementwiseClip11(const MLOperatorKernelCreationContext& kernelInfo) : DmlOperator(kernelInfo) + { + ML_CHECK_VALID_ARGUMENT(kernelInfo.GetInputCount() >= 1 && kernelInfo.GetInputCount() <= 3); + ML_CHECK_VALID_ARGUMENT(kernelInfo.GetOutputCount() == 1); + + std::vector> inputIndices = {0}; // min and max (1 and 2) are CPU-bound. + std::vector> outputIndices = {0}; + DmlOperator::Initialize(kernelInfo, inputIndices, outputIndices, kernelInfo.GetTensorShapeDescription().GetOutputTensorShape(0)); + + std::vector inputDescs = GetDmlInputDescs(); + std::vector outputDescs = GetDmlOutputDescs(); + + float minValue = -FLT_MAX; + float maxValue = FLT_MAX; + if (kernelInfo.IsInputValid(1)) + { + minValue = ReadScalarTensorAsFloat64(kernelInfo.GetConstantInputTensor(1)); + } + if (kernelInfo.IsInputValid(2)) + { + maxValue = ReadScalarTensorAsFloat64(kernelInfo.GetConstantInputTensor(2)); + } + + DML_ELEMENT_WISE_CLIP_OPERATOR_DESC opDesc = {}; + opDesc.InputTensor = inputDescs.data(); + opDesc.OutputTensor = outputDescs.data(); + opDesc.Min = minValue; + opDesc.Max = maxValue; + + SetDmlOperatorDesc({ DML_OPERATOR_ELEMENT_WISE_CLIP, &opDesc}, kernelInfo); + } +}; + class DmlOperatorElementwisePow : public DmlOperator { public: @@ -681,7 +717,8 @@ DML_OP_DEFINE_CREATION_FUNCTION(Max, DmlOperatorElementwiseBinaryLo DML_OP_DEFINE_CREATION_FUNCTION(Mean, DmlOperatorElementwiseMean); // Operators with extra attributes: -DML_OP_DEFINE_CREATION_FUNCTION(Clip, DmlOperatorElementwiseClip); +DML_OP_DEFINE_CREATION_FUNCTION(Clip7, DmlOperatorElementwiseClip7); +DML_OP_DEFINE_CREATION_FUNCTION(Clip11, DmlOperatorElementwiseClip11); DML_OP_DEFINE_CREATION_FUNCTION(Pow, DmlOperatorElementwisePow); DML_OP_DEFINE_CREATION_FUNCTION(QuantizeLinear, DmlOperatorElementwiseQLinear); DML_OP_DEFINE_CREATION_FUNCTION(DequantizeLinear, DmlOperatorElementwiseQLinear); diff --git a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorRegistration.cpp b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorRegistration.cpp index 1dc7727749..a3770ca2fa 100644 --- a/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorRegistration.cpp +++ b/onnxruntime/core/providers/dml/DmlExecutionProvider/src/Operators/OperatorRegistration.cpp @@ -113,7 +113,8 @@ DML_OP_EXTERN_CREATION_FUNCTION(Log); DML_OP_EXTERN_CREATION_FUNCTION(Abs); DML_OP_EXTERN_CREATION_FUNCTION(Ceil); DML_OP_EXTERN_CREATION_FUNCTION(Floor); -DML_OP_EXTERN_CREATION_FUNCTION(Clip); +DML_OP_EXTERN_CREATION_FUNCTION(Clip7); +DML_OP_EXTERN_CREATION_FUNCTION(Clip11); DML_OP_EXTERN_CREATION_FUNCTION(Greater); DML_OP_EXTERN_CREATION_FUNCTION(Less); DML_OP_EXTERN_CREATION_FUNCTION(Equal); @@ -329,8 +330,8 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl {REG_INFO( 7, Concat, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)}, {REG_INFO( 11, Concat, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)}, // Adds negative axis. {REG_INFO_VER( 7, Slice, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)}, - {REG_INFO_VER( 10, Slice, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported, {1, 2, 3}, std::nullopt, QuerySlice)}, - {REG_INFO_VER( 11, Slice, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported, {1, 2, 3}, std::nullopt, QuerySlice)}, // Adds negative axes. + {REG_INFO_VER( 10, Slice, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported, {1, 2, 3}, std::nullopt, QuerySlice)}, + {REG_INFO_VER( 11, Slice, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported, {1, 2, 3}, std::nullopt, QuerySlice)}, // Adds negative axes. {REG_INFO( 7, Pad, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)}, #if 0 // TODO:DwayneR Pads and Value are inputs. https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Pad-11 {REG_INFO( 11, Pad, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)}, @@ -341,7 +342,7 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl // TODO:Dwayner https://microsoft.visualstudio.com/OS/_workitems/edit/24672169 {REG_INFO( 11, DepthToSpace, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)}, #endif - {REG_INFO( 7, Tile, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported, {1})}, + {REG_INFO( 7, Tile, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported, {1})}, {REG_INFO( 8, Expand, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {1})}, {REG_INFO( 9, ConstantOfShape, typeNameListConstantOfShape, supportedTypeListConstantOfShape, DmGraphSupport::NotSupported, {0})}, {REG_INFO( 7, Gather, typeNameListScatterGather, supportedTypeListScatterGather, DmGraphSupport::Supported)}, @@ -370,10 +371,8 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl {REG_INFO( 7, Abs, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)}, {REG_INFO( 7, Ceil, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)}, {REG_INFO( 7, Floor, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)}, - {REG_INFO( 7, Clip, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)}, -#if 0 // TODO:DwayneR https://microsoft.visualstudio.com/OS/_workitems/edit/24674103 - {REG_INFO( 11, Clip, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)}, -#endif + {REG_INFO_VER( 7, Clip, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)}, + {REG_INFO_VER( 11, Clip, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {1,2})}, {REG_INFO( 7, Add, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)}, {REG_INFO( 7, Sub, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)}, {REG_INFO( 7, Mul, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)}, diff --git a/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorHelper.cpp b/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorHelper.cpp index 24340b911e..2a17a8e288 100644 --- a/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorHelper.cpp +++ b/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorHelper.cpp @@ -107,6 +107,20 @@ namespace OperatorHelper memcpy(data, tensor.GetByteData(), elementByteSize); } + int64_t ReadScalarTensorAsInt64(const MLOperatorTensor& tensor) + { + std::byte tensorBytes[8]; + ReadScalarTensorData(tensor, /*out*/ &tensorBytes, sizeof(tensorBytes)); + return ReadAsInt64(tensor.GetTensorDataType(), &tensorBytes); + } + + double ReadScalarTensorAsFloat64(const MLOperatorTensor& tensor) + { + std::byte tensorBytes[8]; + ReadScalarTensorData(tensor, /*out*/ &tensorBytes, sizeof(tensorBytes)); + return ReadAsFloat64(tensor.GetTensorDataType(), &tensorBytes); + } + // Calculates the spatial dimensions from input dimensions and a kernel. The non-spatial (leading) // dimensions will be initialized to match the input dimensions. This assumes the spatial dimensions // are ordered such that they are at the end (e.g. NCHW or NCDHW). @@ -1312,7 +1326,7 @@ namespace OperatorHelper double start = ReadAsFloat64(m_tensorDataType, &m_valueStart); double limit = ReadAsFloat64(m_tensorDataType, &m_valueLimit); double delta = ReadAsFloat64(m_tensorDataType, &m_valueDelta); - totalElementCount = gsl::narrow_cast(ceil((limit - start) / delta)); + totalElementCount = gsl::narrow_cast(std::max(ceil((limit - start) / delta), 0.0)); } else { @@ -1320,7 +1334,7 @@ namespace OperatorHelper int64_t limit = ReadAsInt64(m_tensorDataType, &m_valueLimit); int64_t delta = ReadAsInt64(m_tensorDataType, &m_valueDelta); int64_t range = limit - start; - totalElementCount = gsl::narrow_cast((range / delta) + (range % delta != 0)); + totalElementCount = gsl::narrow_cast(std::max((range / delta) + (range % delta != 0), int64_t(0))); } m_outputDimensions.push_back(totalElementCount); } diff --git a/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorHelper.h b/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorHelper.h index 44a15abc79..585011ff91 100644 --- a/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorHelper.h +++ b/onnxruntime/core/providers/dml/OperatorAuthorHelper/OperatorHelper.h @@ -77,7 +77,9 @@ void RemoveValuesByIndex(gsl::span indices, bool keepOneValue, / int64_t ReadAsInt64(MLOperatorTensorDataType tensorDataType, const void* p); double ReadAsFloat64(MLOperatorTensorDataType tensorDataType, const void* p); -void ReadScalarTensorData(const MLOperatorTensor& tensor, void* data, size_t dataByteSize); +void ReadScalarTensorData(const MLOperatorTensor& tensor, /*out*/ void* data, size_t dataByteSize); +int64_t ReadScalarTensorAsInt64(const MLOperatorTensor& tensor); +double ReadScalarTensorAsFloat64(const MLOperatorTensor& tensor); class EdgeShapes { public: @@ -1220,7 +1222,7 @@ protected: std::vector m_outputDimensions; MLOperatorTensorDataType m_tensorDataType = MLOperatorTensorDataType::Undefined; - using TensorScalarData = typename std::aligned_storage::type; + using TensorScalarData = typename std::aligned_storage_t; TensorScalarData m_valueStart; TensorScalarData m_valueLimit; TensorScalarData m_valueDelta; @@ -1322,7 +1324,8 @@ using ShapeInferenceHelper_Log = GetOutputShapeAsInputShapeHelper; using ShapeInferenceHelper_Abs = GetOutputShapeAsInputShapeHelper; using ShapeInferenceHelper_Ceil = GetOutputShapeAsInputShapeHelper; using ShapeInferenceHelper_Floor = GetOutputShapeAsInputShapeHelper; -using ShapeInferenceHelper_Clip = GetOutputShapeAsInputShapeHelper; +using ShapeInferenceHelper_Clip7 = GetOutputShapeAsInputShapeHelper; +using ShapeInferenceHelper_Clip11 = GetOutputShapeAsInputShapeHelper; using ShapeInferenceHelper_Greater = GetBroadcastedOutputShapeHelper; using ShapeInferenceHelper_Less = GetBroadcastedOutputShapeHelper; using ShapeInferenceHelper_Equal = GetBroadcastedOutputShapeHelper;