DML EP QuantizeLinear defer axis validation for test_quantizelinear_cpu (#11906)

DML EP QuantizeLinear defer axis validation
This commit is contained in:
Dwayne Robinson 2022-06-20 11:03:32 -07:00 committed by GitHub
parent 0736c604c7
commit c1577d08ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 10 additions and 7 deletions

View file

@ -508,18 +508,19 @@ public:
Initialize(kernelInfo, std::nullopt, std::nullopt);
uint32_t axis = 0;
uint32_t broadcastAxisLength = 0;
// If an axis was given explicitly passed (or the default value 1 is set from the schema),
// then other inputs are broadcasting to the shape of the input data tensor.
if (kernelInfo.HasAttribute(AttrName::Axis, MLOperatorAttributeType::Int))
{
// Avoid validating the axis until later because the axis parameter is ignorable unless
// broadcasting is actually needed. ONNX opset 13 returns a default value of 1 for the
// "axis" attribute even when the attribute doesn't actually exist in the model, which
// would cause a validation failure here.
const int32_t signedAxis = gsl::narrow_cast<int32_t>(kernelInfo.GetAttribute<int64_t>(AttrName::Axis));
axis = Dml::HandleNegativeAxis(signedAxis, outputShapeDimCount);
broadcastAxisLength = outputShape[axis];
axis = Dml::HandleNegativeAxis(signedAxis, outputShapeDimCount, /*validateAxis*/ false);
}
// Explicitly reshape each of the inputs after the first input (scale and zero point tensors).
for (uint32_t index = 1, inputCount = gsl::narrow_cast<uint32_t>(m_inputTensorDescs.size()); index < inputCount; ++index)
{
@ -535,6 +536,8 @@ public:
// The 1D vector should have a length equal to the output tensor's dimension on that axis.
if (inputTensorShape.size() == 1 && inputTensorShape != outputShape)
{
ML_CHECK_VALID_ARGUMENT(axis < outputShapeDimCount);
uint32_t broadcastAxisLength = outputShape[axis];
ML_CHECK_VALID_ARGUMENT(inputTensorShape[0] == broadcastAxisLength);
inputTensorShape.insert(inputTensorShape.begin(), axis, 1);
inputTensorShape.insert(inputTensorShape.end(), outputShapeDimCount - 1 - axis, 1);

View file

@ -13,14 +13,14 @@ namespace OperatorHelper
// Convert any negative axis into an absolute axis relative to the back end.
// So given 3 dimensions, a -1 refers to axis 2, and -3 to axis 0.
uint32_t HandleNegativeAxis(int32_t signedOnnxAxis, uint32_t dimCount)
uint32_t HandleNegativeAxis(int32_t signedOnnxAxis, uint32_t dimCount, bool validateAxis)
{
if (signedOnnxAxis < 0)
{
signedOnnxAxis += dimCount;
}
uint32_t absoluteAxis = gsl::narrow_cast<uint32_t>(signedOnnxAxis);
ML_CHECK_VALID_ARGUMENT(absoluteAxis < dimCount);
ML_CHECK_VALID_ARGUMENT(!validateAxis || absoluteAxis < dimCount);
return absoluteAxis;
}

View file

@ -46,7 +46,7 @@ void FindValueIndices(gsl::span<const T> values, T value, /*out*/ std::vector<ui
// Convert any negative axis into an absolute axis relative to the back end.
// So given 3 dimensions, a -1 refers to axis 2, and -3 to axis 0.
uint32_t HandleNegativeAxis(int32_t signedOnnxAxis, uint32_t dimCount);
uint32_t HandleNegativeAxis(int32_t signedOnnxAxis, uint32_t dimCount, bool validateAxis = true);
void HandleNegativeAxes(gsl::span<int32_t> onnxAxes, uint32_t dimCount);