Fix clip.

This commit is contained in:
Dwayne Robinson 2020-03-24 01:04:08 -07:00
parent 1df264f4b3
commit 271126a86e
5 changed files with 72 additions and 19 deletions

View file

@ -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<int32_t>(ReadAsInt64(axisTensor.GetTensorDataType(), /*out*/ &rawAxisBytes));
ReadScalarTensorData(axisTensor, /*out*/ tensorBytes, sizeof(tensorBytes));
onnxAxis = gsl::narrow_cast<int32_t>(ReadAsInt64(axisTensor.GetTensorDataType(), /*out*/ tensorBytes));
}
uint32_t dmlAxis = GetDmlAdjustedAxis(onnxAxis, kernelCreationContext, m_inputTensorDescs.front().GetDimensionCount());

View file

@ -404,10 +404,10 @@ public:
std::vector<ComPtr<IDMLCompiledOperator>> 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<std::optional<uint32_t>> inputIndices = {0}; // min and max (1 and 2) are CPU-bound.
std::vector<std::optional<uint32_t>> outputIndices = {0};
DmlOperator::Initialize(kernelInfo, inputIndices, outputIndices, kernelInfo.GetTensorShapeDescription().GetOutputTensorShape(0));
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
std::vector<DML_TENSOR_DESC> 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_ELEMENT_WISE_QUANTIZE_LINEAR_OPERATOR_DESC>);
DML_OP_DEFINE_CREATION_FUNCTION(DequantizeLinear, DmlOperatorElementwiseQLinear<DML_ELEMENT_WISE_DEQUANTIZE_LINEAR_OPERATOR_DESC>);

View file

@ -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)},

View file

@ -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<uint32_t>(ceil((limit - start) / delta));
totalElementCount = gsl::narrow_cast<uint32_t>(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<uint32_t>((range / delta) + (range % delta != 0));
totalElementCount = gsl::narrow_cast<uint32_t>(std::max((range / delta) + (range % delta != 0), int64_t(0)));
}
m_outputDimensions.push_back(totalElementCount);
}

View file

@ -77,7 +77,9 @@ void RemoveValuesByIndex(gsl::span<const uint32_t> 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<DimensionType> m_outputDimensions;
MLOperatorTensorDataType m_tensorDataType = MLOperatorTensorDataType::Undefined;
using TensorScalarData = typename std::aligned_storage<sizeof(double), alignof(double)>::type;
using TensorScalarData = typename std::aligned_storage_t<sizeof(double), alignof(double)>;
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;