mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-30 20:18:08 +00:00
Merge remote-tracking branch 'origin/DmlDev' into user/jeffbloo/MergeGithubMasterToDmlDevPlusPending
This commit is contained in:
commit
acbfa42647
24 changed files with 1093 additions and 434 deletions
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ApiTraits
|
||||
|
|
@ -25,7 +24,7 @@ struct EnumTraits<DML_TENSOR_TYPE>
|
|||
template <>
|
||||
struct EnumTraits<DML_OPERATOR_TYPE>
|
||||
{
|
||||
static constexpr auto ValueCount = 119;
|
||||
static constexpr auto ValueCount = 120;
|
||||
static constexpr size_t ActivationFunctionCount = 19;
|
||||
};
|
||||
|
||||
|
|
@ -748,6 +747,12 @@ struct OperatorDescTraits<DML_MEAN_VARIANCE_NORMALIZATION1_OPERATOR_DESC>
|
|||
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_MEAN_VARIANCE_NORMALIZATION1;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperatorDescTraits<DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_DESC>
|
||||
{
|
||||
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_MATRIX_MULTIPLY_INTEGER;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperatorDescTraits<DML_QUANTIZED_LINEAR_MATRIX_MULTIPLY_OPERATOR_DESC>
|
||||
{
|
||||
|
|
@ -755,15 +760,15 @@ struct OperatorDescTraits<DML_QUANTIZED_LINEAR_MATRIX_MULTIPLY_OPERATOR_DESC>
|
|||
};
|
||||
|
||||
template <>
|
||||
struct OperatorDescTraits<DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_DESC>
|
||||
struct OperatorDescTraits<DML_CONVOLUTION_INTEGER_OPERATOR_DESC>
|
||||
{
|
||||
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_QUANTIZED_LINEAR_CONVOLUTION;
|
||||
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_CONVOLUTION_INTEGER;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperatorDescTraits<DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_DESC>
|
||||
struct OperatorDescTraits<DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_DESC>
|
||||
{
|
||||
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_DYNAMIC_QUANTIZE_LINEAR;
|
||||
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_QUANTIZED_LINEAR_CONVOLUTION;
|
||||
};
|
||||
|
||||
template <>
|
||||
|
|
@ -1462,6 +1467,12 @@ struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_MEAN_VARIANCE_NORMALIZ
|
|||
using DescType = DML_MEAN_VARIANCE_NORMALIZATION1_OPERATOR_DESC;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_MATRIX_MULTIPLY_INTEGER>
|
||||
{
|
||||
using DescType = DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_DESC;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_QUANTIZED_LINEAR_MATRIX_MULTIPLY>
|
||||
{
|
||||
|
|
@ -1469,15 +1480,15 @@ struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_QUANTIZED_LINEAR_MATRI
|
|||
};
|
||||
|
||||
template <>
|
||||
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_QUANTIZED_LINEAR_CONVOLUTION>
|
||||
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_CONVOLUTION_INTEGER>
|
||||
{
|
||||
using DescType = DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_DESC;
|
||||
using DescType = DML_CONVOLUTION_INTEGER_OPERATOR_DESC;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_DYNAMIC_QUANTIZE_LINEAR>
|
||||
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_QUANTIZED_LINEAR_CONVOLUTION>
|
||||
{
|
||||
using DescType = DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_DESC;
|
||||
using DescType = DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_DESC;
|
||||
};
|
||||
|
||||
template <>
|
||||
|
|
@ -1799,12 +1810,16 @@ auto OperatorTypeVisitor(DML_OPERATOR_TYPE type, Visitor&& visitor, Ts&&... args
|
|||
return std::invoke(std::forward<Visitor>(visitor), DML_SPACE_TO_DEPTH1_OPERATOR_DESC{}, std::forward<Ts>(args)...);
|
||||
case DML_OPERATOR_MEAN_VARIANCE_NORMALIZATION1:
|
||||
return std::invoke(std::forward<Visitor>(visitor), DML_MEAN_VARIANCE_NORMALIZATION1_OPERATOR_DESC{}, std::forward<Ts>(args)...);
|
||||
case DML_OPERATOR_RESAMPLE1:
|
||||
return std::invoke(std::forward<Visitor>(visitor), DML_RESAMPLE1_OPERATOR_DESC{}, std::forward<Ts>(args)...);
|
||||
case DML_OPERATOR_MATRIX_MULTIPLY_INTEGER:
|
||||
return std::invoke(std::forward<Visitor>(visitor), DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_DESC{}, std::forward<Ts>(args)...);
|
||||
case DML_OPERATOR_QUANTIZED_LINEAR_MATRIX_MULTIPLY:
|
||||
return std::invoke(std::forward<Visitor>(visitor), DML_QUANTIZED_LINEAR_MATRIX_MULTIPLY_OPERATOR_DESC{}, std::forward<Ts>(args)...);
|
||||
case DML_OPERATOR_CONVOLUTION_INTEGER:
|
||||
return std::invoke(std::forward<Visitor>(visitor), DML_CONVOLUTION_INTEGER_OPERATOR_DESC{}, std::forward<Ts>(args)...);
|
||||
case DML_OPERATOR_QUANTIZED_LINEAR_CONVOLUTION:
|
||||
return std::invoke(std::forward<Visitor>(visitor), DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_DESC{}, std::forward<Ts>(args)...);
|
||||
case DML_OPERATOR_DYNAMIC_QUANTIZE_LINEAR:
|
||||
return std::invoke(std::forward<Visitor>(visitor), DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_DESC{}, std::forward<Ts>(args)...);
|
||||
case DML_OPERATOR_ACTIVATION_ELU:
|
||||
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_ELU_OPERATOR_DESC{}, std::forward<Ts>(args)...);
|
||||
case DML_OPERATOR_ACTIVATION_HARDMAX:
|
||||
|
|
@ -1951,9 +1966,11 @@ inline gsl::czstring ToString(DML_OPERATOR_TYPE value)
|
|||
case DML_OPERATOR_DEPTH_TO_SPACE1: return "DML_OPERATOR_DEPTH_TO_SPACE1";
|
||||
case DML_OPERATOR_SPACE_TO_DEPTH1: return "DML_OPERATOR_SPACE_TO_DEPTH1";
|
||||
case DML_OPERATOR_MEAN_VARIANCE_NORMALIZATION1: return "DML_OPERATOR_MEAN_VARIANCE_NORMALIZATION1";
|
||||
case DML_OPERATOR_RESAMPLE1: return "DML_OPERATOR_RESAMPLE1";
|
||||
case DML_OPERATOR_MATRIX_MULTIPLY_INTEGER: return "DML_OPERATOR_MATRIX_MULTIPLY_INTEGER";
|
||||
case DML_OPERATOR_QUANTIZED_LINEAR_MATRIX_MULTIPLY: return "DML_OPERATOR_QUANTIZED_LINEAR_MATRIX_MULTIPLY";
|
||||
case DML_OPERATOR_CONVOLUTION_INTEGER: return "DML_OPERATOR_CONVOLUTION_INTEGER";
|
||||
case DML_OPERATOR_QUANTIZED_LINEAR_CONVOLUTION: return "DML_OPERATOR_QUANTIZED_LINEAR_CONVOLUTION";
|
||||
case DML_OPERATOR_DYNAMIC_QUANTIZE_LINEAR: return "DML_OPERATOR_DYNAMIC_QUANTIZE_LINEAR";
|
||||
default:
|
||||
assert(false);
|
||||
return "<unknown>";
|
||||
|
|
|
|||
|
|
@ -1545,15 +1545,49 @@ constexpr DML_OPERATOR_SCHEMA DML_MEAN_VARIANCE_NORMALIZATION1_OPERATOR_SCHEMA {
|
|||
DML_MEAN_VARIANCE_NORMALIZATION1_OPERATOR_SCHEMA_FIELDS,
|
||||
};
|
||||
|
||||
constexpr DML_SCHEMA_FIELD DML_RESAMPLE1_OPERATOR_SCHEMA_FIELDS[7] {
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "InputTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_OUTPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT, "InterpolationMode", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT, "DimensionCount", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_FLOAT_ARRAY, "Scales", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_FLOAT_ARRAY, "InputPixelOffsets", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_FLOAT_ARRAY, "OutputPixelOffsets", false },
|
||||
};
|
||||
|
||||
constexpr DML_OPERATOR_SCHEMA DML_RESAMPLE1_OPERATOR_SCHEMA {
|
||||
"DML_OPERATOR_RESAMPLE1",
|
||||
DML_OPERATOR_RESAMPLE1,
|
||||
DML_SCHEMA_OPERATOR_SUPPORT_FLAG_NONE,
|
||||
7,
|
||||
DML_RESAMPLE1_OPERATOR_SCHEMA_FIELDS,
|
||||
};
|
||||
|
||||
constexpr DML_SCHEMA_FIELD DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_SCHEMA_FIELDS[5] {
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "ATensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "AZeroPointTensor", true },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "BTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "BZeroPointTensor", true },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_OUTPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputTensor", false },
|
||||
};
|
||||
|
||||
constexpr DML_OPERATOR_SCHEMA DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_SCHEMA {
|
||||
"DML_OPERATOR_MATRIX_MULTIPLY_INTEGER",
|
||||
DML_OPERATOR_MATRIX_MULTIPLY_INTEGER,
|
||||
DML_SCHEMA_OPERATOR_SUPPORT_FLAG_NONE,
|
||||
5,
|
||||
DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_SCHEMA_FIELDS,
|
||||
};
|
||||
|
||||
constexpr DML_SCHEMA_FIELD DML_QUANTIZED_LINEAR_MATRIX_MULTIPLY_OPERATOR_SCHEMA_FIELDS[9] {
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "ATensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "AScaleTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "AZeroPointTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "AZeroPointTensor", true },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "BTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "BScaleTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "BZeroPointTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "BZeroPointTensor", true },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputScaleTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputZeroPointTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputZeroPointTensor", true },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_OUTPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputTensor", false },
|
||||
};
|
||||
|
||||
|
|
@ -1565,16 +1599,38 @@ constexpr DML_OPERATOR_SCHEMA DML_QUANTIZED_LINEAR_MATRIX_MULTIPLY_OPERATOR_SCHE
|
|||
DML_QUANTIZED_LINEAR_MATRIX_MULTIPLY_OPERATOR_SCHEMA_FIELDS,
|
||||
};
|
||||
|
||||
constexpr DML_SCHEMA_FIELD DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA_FIELDS[11] {
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "InputTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "InputZeroPointTensor", true },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "FilterTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "FilterZeroPointTensor", true },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_OUTPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT, "DimensionCount", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT_ARRAY, "Strides", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT_ARRAY, "Dilations", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT_ARRAY, "StartPadding", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT_ARRAY, "EndPadding", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT, "GroupCount", false },
|
||||
};
|
||||
|
||||
constexpr DML_OPERATOR_SCHEMA DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA {
|
||||
"DML_OPERATOR_CONVOLUTION_INTEGER",
|
||||
DML_OPERATOR_CONVOLUTION_INTEGER,
|
||||
DML_SCHEMA_OPERATOR_SUPPORT_FLAG_NONE,
|
||||
11,
|
||||
DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA_FIELDS,
|
||||
};
|
||||
|
||||
constexpr DML_SCHEMA_FIELD DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_SCHEMA_FIELDS[16] {
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "InputTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "InputScaleTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "InputZeroPointTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "InputZeroPointTensor", true },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "FilterTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "FilterScaleTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "FilterZeroPointTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "FilterZeroPointTensor", true },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "BiasTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputScaleTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputZeroPointTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputZeroPointTensor", true },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_OUTPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT, "DimensionCount", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT_ARRAY, "Strides", false },
|
||||
|
|
@ -1592,21 +1648,6 @@ constexpr DML_OPERATOR_SCHEMA DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_SCHEMA {
|
|||
DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_SCHEMA_FIELDS,
|
||||
};
|
||||
|
||||
constexpr DML_SCHEMA_FIELD DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_SCHEMA_FIELDS[4] {
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "InputTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_OUTPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_OUTPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputScaleTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_OUTPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputZeroPointTensor", false },
|
||||
};
|
||||
|
||||
constexpr DML_OPERATOR_SCHEMA DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_SCHEMA {
|
||||
"DML_OPERATOR_DYNAMIC_QUANTIZE_LINEAR",
|
||||
DML_OPERATOR_DYNAMIC_QUANTIZE_LINEAR,
|
||||
DML_SCHEMA_OPERATOR_SUPPORT_FLAG_NONE,
|
||||
4,
|
||||
DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_SCHEMA_FIELDS,
|
||||
};
|
||||
|
||||
constexpr DML_SCHEMA_FIELD DML_ACTIVATION_ELU_OPERATOR_SCHEMA_FIELDS[3] {
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "InputTensor", false },
|
||||
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_OUTPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputTensor", false },
|
||||
|
|
|
|||
|
|
@ -920,6 +920,28 @@ inline std::vector<OperatorField> GetFields(const DML_MEAN_VARIANCE_NORMALIZATIO
|
|||
OperatorField(&DML_MEAN_VARIANCE_NORMALIZATION1_OPERATOR_SCHEMA.Fields[8], ToOperatorFieldType(static_cast<const DML_OPERATOR_DESC*>(desc.FusedActivation))),
|
||||
};
|
||||
}
|
||||
inline std::vector<OperatorField> GetFields(const DML_RESAMPLE1_OPERATOR_DESC& desc)
|
||||
{
|
||||
return {
|
||||
OperatorField(&DML_RESAMPLE1_OPERATOR_SCHEMA.Fields[0], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.InputTensor))),
|
||||
OperatorField(&DML_RESAMPLE1_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
|
||||
OperatorField(&DML_RESAMPLE1_OPERATOR_SCHEMA.Fields[2], ToOperatorFieldType(static_cast<UINT>(desc.InterpolationMode))),
|
||||
OperatorField(&DML_RESAMPLE1_OPERATOR_SCHEMA.Fields[3], ToOperatorFieldType(static_cast<UINT>(desc.DimensionCount))),
|
||||
OperatorField(&DML_RESAMPLE1_OPERATOR_SCHEMA.Fields[4], ToOperatorFieldType(static_cast<const FLOAT*>(desc.Scales), desc.DimensionCount)),
|
||||
OperatorField(&DML_RESAMPLE1_OPERATOR_SCHEMA.Fields[5], ToOperatorFieldType(static_cast<const FLOAT*>(desc.InputPixelOffsets), desc.DimensionCount)),
|
||||
OperatorField(&DML_RESAMPLE1_OPERATOR_SCHEMA.Fields[6], ToOperatorFieldType(static_cast<const FLOAT*>(desc.OutputPixelOffsets), desc.DimensionCount)),
|
||||
};
|
||||
}
|
||||
inline std::vector<OperatorField> GetFields(const DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_DESC& desc)
|
||||
{
|
||||
return {
|
||||
OperatorField(&DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_SCHEMA.Fields[0], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.ATensor))),
|
||||
OperatorField(&DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.AZeroPointTensor))),
|
||||
OperatorField(&DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_SCHEMA.Fields[2], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.BTensor))),
|
||||
OperatorField(&DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_SCHEMA.Fields[3], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.BZeroPointTensor))),
|
||||
OperatorField(&DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_SCHEMA.Fields[4], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
|
||||
};
|
||||
}
|
||||
inline std::vector<OperatorField> GetFields(const DML_QUANTIZED_LINEAR_MATRIX_MULTIPLY_OPERATOR_DESC& desc)
|
||||
{
|
||||
return {
|
||||
|
|
@ -934,6 +956,22 @@ inline std::vector<OperatorField> GetFields(const DML_QUANTIZED_LINEAR_MATRIX_MU
|
|||
OperatorField(&DML_QUANTIZED_LINEAR_MATRIX_MULTIPLY_OPERATOR_SCHEMA.Fields[8], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
|
||||
};
|
||||
}
|
||||
inline std::vector<OperatorField> GetFields(const DML_CONVOLUTION_INTEGER_OPERATOR_DESC& desc)
|
||||
{
|
||||
return {
|
||||
OperatorField(&DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA.Fields[0], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.InputTensor))),
|
||||
OperatorField(&DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.InputZeroPointTensor))),
|
||||
OperatorField(&DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA.Fields[2], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.FilterTensor))),
|
||||
OperatorField(&DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA.Fields[3], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.FilterZeroPointTensor))),
|
||||
OperatorField(&DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA.Fields[4], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
|
||||
OperatorField(&DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA.Fields[5], ToOperatorFieldType(static_cast<UINT>(desc.DimensionCount))),
|
||||
OperatorField(&DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA.Fields[6], ToOperatorFieldType(static_cast<const UINT*>(desc.Strides), desc.DimensionCount)),
|
||||
OperatorField(&DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA.Fields[7], ToOperatorFieldType(static_cast<const UINT*>(desc.Dilations), desc.DimensionCount)),
|
||||
OperatorField(&DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA.Fields[8], ToOperatorFieldType(static_cast<const UINT*>(desc.StartPadding), desc.DimensionCount)),
|
||||
OperatorField(&DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA.Fields[9], ToOperatorFieldType(static_cast<const UINT*>(desc.EndPadding), desc.DimensionCount)),
|
||||
OperatorField(&DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA.Fields[10], ToOperatorFieldType(static_cast<UINT>(desc.GroupCount))),
|
||||
};
|
||||
}
|
||||
inline std::vector<OperatorField> GetFields(const DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_DESC& desc)
|
||||
{
|
||||
return {
|
||||
|
|
@ -955,15 +993,6 @@ inline std::vector<OperatorField> GetFields(const DML_QUANTIZED_LINEAR_CONVOLUTI
|
|||
OperatorField(&DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_SCHEMA.Fields[15], ToOperatorFieldType(static_cast<UINT>(desc.GroupCount))),
|
||||
};
|
||||
}
|
||||
inline std::vector<OperatorField> GetFields(const DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_DESC& desc)
|
||||
{
|
||||
return {
|
||||
OperatorField(&DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_SCHEMA.Fields[0], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.InputTensor))),
|
||||
OperatorField(&DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
|
||||
OperatorField(&DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_SCHEMA.Fields[2], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputScaleTensor))),
|
||||
OperatorField(&DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_SCHEMA.Fields[3], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputZeroPointTensor))),
|
||||
};
|
||||
}
|
||||
inline std::vector<OperatorField> GetFields(const DML_ACTIVATION_ELU_OPERATOR_DESC& desc)
|
||||
{
|
||||
return {
|
||||
|
|
@ -1215,9 +1244,11 @@ inline const DML_OPERATOR_SCHEMA& GetSchema(DML_OPERATOR_TYPE operatorType)
|
|||
case DML_OPERATOR_DEPTH_TO_SPACE1: return DML_DEPTH_TO_SPACE1_OPERATOR_SCHEMA;
|
||||
case DML_OPERATOR_SPACE_TO_DEPTH1: return DML_SPACE_TO_DEPTH1_OPERATOR_SCHEMA;
|
||||
case DML_OPERATOR_MEAN_VARIANCE_NORMALIZATION1: return DML_MEAN_VARIANCE_NORMALIZATION1_OPERATOR_SCHEMA;
|
||||
case DML_OPERATOR_RESAMPLE1: return DML_RESAMPLE1_OPERATOR_SCHEMA;
|
||||
case DML_OPERATOR_MATRIX_MULTIPLY_INTEGER: return DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_SCHEMA;
|
||||
case DML_OPERATOR_QUANTIZED_LINEAR_MATRIX_MULTIPLY: return DML_QUANTIZED_LINEAR_MATRIX_MULTIPLY_OPERATOR_SCHEMA;
|
||||
case DML_OPERATOR_CONVOLUTION_INTEGER: return DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA;
|
||||
case DML_OPERATOR_QUANTIZED_LINEAR_CONVOLUTION: return DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_SCHEMA;
|
||||
case DML_OPERATOR_DYNAMIC_QUANTIZE_LINEAR: return DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_SCHEMA;
|
||||
case DML_OPERATOR_ACTIVATION_ELU: return DML_ACTIVATION_ELU_OPERATOR_SCHEMA;
|
||||
case DML_OPERATOR_ACTIVATION_HARDMAX: return DML_ACTIVATION_HARDMAX_OPERATOR_SCHEMA;
|
||||
case DML_OPERATOR_ACTIVATION_HARD_SIGMOID: return DML_ACTIVATION_HARD_SIGMOID_OPERATOR_SCHEMA;
|
||||
|
|
@ -1630,18 +1661,26 @@ inline AbstractOperatorDesc ConvertOperatorDesc(const DML_OPERATOR_DESC& opDesc)
|
|||
return AbstractOperatorDesc(
|
||||
&DML_MEAN_VARIANCE_NORMALIZATION1_OPERATOR_SCHEMA,
|
||||
GetFields(*static_cast<const DML_MEAN_VARIANCE_NORMALIZATION1_OPERATOR_DESC*>(opDesc.Desc)));
|
||||
case DML_OPERATOR_RESAMPLE1:
|
||||
return AbstractOperatorDesc(
|
||||
&DML_RESAMPLE1_OPERATOR_SCHEMA,
|
||||
GetFields(*static_cast<const DML_RESAMPLE1_OPERATOR_DESC*>(opDesc.Desc)));
|
||||
case DML_OPERATOR_MATRIX_MULTIPLY_INTEGER:
|
||||
return AbstractOperatorDesc(
|
||||
&DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_SCHEMA,
|
||||
GetFields(*static_cast<const DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_DESC*>(opDesc.Desc)));
|
||||
case DML_OPERATOR_QUANTIZED_LINEAR_MATRIX_MULTIPLY:
|
||||
return AbstractOperatorDesc(
|
||||
&DML_QUANTIZED_LINEAR_MATRIX_MULTIPLY_OPERATOR_SCHEMA,
|
||||
GetFields(*static_cast<const DML_QUANTIZED_LINEAR_MATRIX_MULTIPLY_OPERATOR_DESC*>(opDesc.Desc)));
|
||||
case DML_OPERATOR_CONVOLUTION_INTEGER:
|
||||
return AbstractOperatorDesc(
|
||||
&DML_CONVOLUTION_INTEGER_OPERATOR_SCHEMA,
|
||||
GetFields(*static_cast<const DML_CONVOLUTION_INTEGER_OPERATOR_DESC*>(opDesc.Desc)));
|
||||
case DML_OPERATOR_QUANTIZED_LINEAR_CONVOLUTION:
|
||||
return AbstractOperatorDesc(
|
||||
&DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_SCHEMA,
|
||||
GetFields(*static_cast<const DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_DESC*>(opDesc.Desc)));
|
||||
case DML_OPERATOR_DYNAMIC_QUANTIZE_LINEAR:
|
||||
return AbstractOperatorDesc(
|
||||
&DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_SCHEMA,
|
||||
GetFields(*static_cast<const DML_DYNAMIC_QUANTIZE_LINEAR_OPERATOR_DESC*>(opDesc.Desc)));
|
||||
case DML_OPERATOR_ACTIVATION_ELU:
|
||||
return AbstractOperatorDesc(
|
||||
&DML_ACTIVATION_ELU_OPERATOR_SCHEMA,
|
||||
|
|
|
|||
|
|
@ -6,31 +6,62 @@
|
|||
namespace Dml
|
||||
{
|
||||
|
||||
class DmlOperatorConvInteger : public DmlOperator
|
||||
class DmlOperatorConvInteger : public DmlOperator, public ConvolutionHelperBase
|
||||
{
|
||||
private:
|
||||
enum InputTensors
|
||||
{
|
||||
IN_X,
|
||||
IN_X_ZERO_POINT,
|
||||
IN_F,
|
||||
IN_F_ZERO_POINT,
|
||||
};
|
||||
|
||||
public:
|
||||
using Self = DmlOperatorConvInteger;
|
||||
|
||||
DmlOperatorConvInteger(const MLOperatorKernelCreationContext& kernelCreationContext)
|
||||
: DmlOperator(kernelCreationContext)
|
||||
DmlOperatorConvInteger(
|
||||
const MLOperatorKernelCreationContext& kernelInfo
|
||||
)
|
||||
: DmlOperator(kernelInfo),
|
||||
ConvolutionHelperBase(kernelInfo, kernelInfo.GetTensorShapeDescription(), false, false, 0, 1)
|
||||
{
|
||||
#if 0 // TODO:NickFe - https://github.com/onnx/onnx/blob/master/docs/Operators.md#convinteger
|
||||
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetInputCount() >= 2 && kernelCreationContext.GetInputCount() <= 4);
|
||||
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetOutputCount() == 1);
|
||||
DmlOperator::Initialize(kernelCreationContext, inputIndices, outputIndices);
|
||||
std::vector<std::optional<uint32_t>> kernelInputIndices = {0, 2, 1, 3};
|
||||
std::vector<std::optional<uint32_t>> kernelOutputIndices = {0};
|
||||
|
||||
DmlOperator::Initialize(kernelInfo, kernelInputIndices);
|
||||
|
||||
// DirectML is limited to handle only 2D. So for 1D tensors, massage the tensor descriptions. By default, the
|
||||
// TensorDesc simply right aligns all the values up to 4D (padding the leading dimensions with 1's),
|
||||
// but 1D tensors actually need to insert the 1 between C and W. e.g. [2,3,4] becomes [2,3,1,4]
|
||||
m_inputTensorDescs[IN_X] = CreateTensorDescFromInput(kernelInfo, 0/*Onnx Index*/, TensorAxis::DoNotCoerce, TensorAxis::NoPlacementAdjustment, NonspatialDimensionCount, std::nullopt);
|
||||
m_inputTensorDescs[IN_F] = CreateTensorDescFromInput(kernelInfo, 1/*Onnx Index*/, TensorAxis::DoNotCoerce, TensorAxis::NoPlacementAdjustment, NonspatialDimensionCount, std::nullopt);
|
||||
|
||||
m_outputTensorDescs[0] = CreateTensorDescFromOutput(kernelInfo, 0, TensorAxis::DoNotCoerce, TensorAxis::NoPlacementAdjustment, NonspatialDimensionCount, std::nullopt);
|
||||
|
||||
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
|
||||
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
|
||||
|
||||
DML_PLACEHOLDER_OPERATOR_DESC operatorDesc = {};
|
||||
operatorDesc.IndicesTensor = &inputDescs[0];
|
||||
operatorDesc.ValuesTensor = &inputDescs[1];
|
||||
operatorDesc.OutputTensor = outputDescs.data();
|
||||
operatorDesc.Axis = dmlAxis;
|
||||
// Form transient kernel arguments with spatial dimensions padded up to at least 2,
|
||||
// since the DirectML API rejects 1D convolution. Leave the base m_kernel alone
|
||||
// so that all output tensor size computations are correct.
|
||||
KernelArgs kernelArgs(m_kernel, NchwSpatialDimensionCount);
|
||||
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_PLACEHOLDER, &operatorDesc };
|
||||
SetDmlOperatorDesc(opDesc, kernelCreationContext);
|
||||
#endif
|
||||
DML_CONVOLUTION_INTEGER_OPERATOR_DESC convDesc = {};
|
||||
convDesc.InputTensor = &inputDescs[IN_X];
|
||||
convDesc.InputZeroPointTensor = inputDescs[IN_X_ZERO_POINT].Desc != nullptr ? &inputDescs[IN_X_ZERO_POINT] : nullptr;
|
||||
convDesc.FilterTensor = &inputDescs[IN_F];
|
||||
convDesc.FilterZeroPointTensor = inputDescs[IN_F_ZERO_POINT].Desc != nullptr ? &inputDescs[IN_F_ZERO_POINT] : nullptr;
|
||||
convDesc.OutputTensor = &outputDescs[0];
|
||||
convDesc.DimensionCount = kernelArgs.spatialDimensionCount;
|
||||
convDesc.Strides = kernelArgs.strides;
|
||||
convDesc.Dilations = kernelArgs.dilations;
|
||||
convDesc.StartPadding = kernelArgs.startPadding;
|
||||
convDesc.EndPadding = kernelArgs.endPadding;
|
||||
convDesc.GroupCount = m_groupCount;
|
||||
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_CONVOLUTION_INTEGER, &convDesc };
|
||||
SetDmlOperatorDesc(opDesc, kernelInfo);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public:
|
|||
bool hasDynamicPads
|
||||
)
|
||||
: DmlOperator(kernelInfo),
|
||||
ConvolutionHelperBase(kernelInfo, kernelInfo.GetTensorShapeDescription(), direction == DML_CONVOLUTION_DIRECTION_BACKWARD, hasDynamicPads)
|
||||
ConvolutionHelperBase(kernelInfo, kernelInfo.GetTensorShapeDescription(), direction == DML_CONVOLUTION_DIRECTION_BACKWARD, hasDynamicPads, 0, 1)
|
||||
{
|
||||
uint32_t biasIndex = hasDynamicPads ? 3 : 2;
|
||||
bool hasBiasInput = kernelInfo.GetInputCount() > biasIndex;
|
||||
|
|
|
|||
|
|
@ -20,12 +20,16 @@ public:
|
|||
ML_CHECK_VALID_ARGUMENT(inputDescs.size() == 1);
|
||||
ML_CHECK_VALID_ARGUMENT(outputDescs.size() == 1);
|
||||
|
||||
DML_DEPTH_TO_SPACE_OPERATOR_DESC operatorDesc = {};
|
||||
std::string mode = kernelCreationContext.GetOptionalAttribute<std::string>(AttrName::Mode, "DCR");
|
||||
DML_DEPTH_SPACE_ORDER depthSpaceOrder = Dml::MapStringToDepthSpaceMode(mode);
|
||||
|
||||
DML_DEPTH_TO_SPACE1_OPERATOR_DESC operatorDesc = {};
|
||||
operatorDesc.InputTensor = inputDescs.data();
|
||||
operatorDesc.OutputTensor = outputDescs.data();
|
||||
operatorDesc.BlockSize = m_blockSize;
|
||||
operatorDesc.Order = depthSpaceOrder;
|
||||
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_DEPTH_TO_SPACE, &operatorDesc };
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_DEPTH_TO_SPACE1, &operatorDesc };
|
||||
SetDmlOperatorDesc(opDesc, kernelCreationContext);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,26 +23,7 @@ public:
|
|||
std::vector<DimensionType> inputShape1 = kernelInfo.GetTensorShapeDescription().GetInputTensorShape(1);
|
||||
std::vector<DimensionType> outputShape = kernelInfo.GetTensorShapeDescription().GetOutputTensorShape(0);
|
||||
|
||||
// Get the padded input shapes and undo the effect of padding removal from the output shape
|
||||
if (inputShape1.size() == 1)
|
||||
{
|
||||
inputShape1.push_back(1);
|
||||
outputShape.push_back(1);
|
||||
}
|
||||
|
||||
if (inputShape0.size() == 1)
|
||||
{
|
||||
inputShape0.insert(inputShape0.begin(), 1);
|
||||
outputShape.insert(outputShape.end() - 1, 1);
|
||||
}
|
||||
|
||||
// Remove the batch dimensions from each input, then re-add the broadcasted batch dimensions
|
||||
// based on the output shape
|
||||
inputShape0.erase(inputShape0.begin(), inputShape0.end() - 2);
|
||||
inputShape1.erase(inputShape1.begin(), inputShape1.end() - 2);
|
||||
|
||||
inputShape0.insert(inputShape0.begin(), outputShape.begin(), outputShape.end() - 2);
|
||||
inputShape1.insert(inputShape1.begin(), outputShape.begin(), outputShape.end() - 2);
|
||||
OperatorHelper::MatMulShapeMapping(inputShape0, inputShape1, outputShape);
|
||||
|
||||
// Initialize the input descriptions with broadcasting
|
||||
m_inputTensorDescs[0] = CreateTensorDescFromInput(kernelInfo, 0, TensorAxis::DoNotCoerce, TensorAxis::W, TensorAxis::RightAligned, inputShape0);
|
||||
|
|
|
|||
|
|
@ -8,32 +8,49 @@ namespace Dml
|
|||
|
||||
class DmlOperatorMatMulInteger : public DmlOperator
|
||||
{
|
||||
public:
|
||||
using Self = DmlOperatorMatMulInteger;
|
||||
enum InputTensors {
|
||||
IN_A,
|
||||
IN_A_ZERO_POINT,
|
||||
IN_B,
|
||||
IN_B_ZERO_POINT
|
||||
};
|
||||
|
||||
DmlOperatorMatMulInteger(const MLOperatorKernelCreationContext& kernelCreationContext)
|
||||
: DmlOperator(kernelCreationContext)
|
||||
public:
|
||||
DmlOperatorMatMulInteger(const MLOperatorKernelCreationContext& kernelInfo)
|
||||
: DmlOperator(kernelInfo)
|
||||
{
|
||||
#if 0 // TODO:NickFe - https://github.com/onnx/onnx/blob/master/docs/Operators.md#MatMulInteger
|
||||
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetInputCount() >= 2 || kernelCreationContext.GetInputCount() <= 4);
|
||||
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetOutputCount() == 1);
|
||||
DmlOperator::Initialize(kernelCreationContext, inputIndices, outputIndices);
|
||||
std::vector<std::optional<uint32_t>> inputIndices = { 0, 2, 1, 3 };
|
||||
DmlOperator::Initialize(kernelInfo, inputIndices);
|
||||
|
||||
std::vector<DimensionType> inputShape0 = kernelInfo.GetTensorShapeDescription().GetInputTensorShape(0);
|
||||
std::vector<DimensionType> inputShape1 = kernelInfo.GetTensorShapeDescription().GetInputTensorShape(1);
|
||||
std::vector<DimensionType> outputShape = kernelInfo.GetTensorShapeDescription().GetOutputTensorShape(0);
|
||||
|
||||
OperatorHelper::MatMulShapeMapping(inputShape0, inputShape1, outputShape);
|
||||
|
||||
// Initialize the input descriptions with broadcasting
|
||||
m_inputTensorDescs[IN_A] = CreateTensorDescFromInput(kernelInfo, 0/*OnnxIndex*/, TensorAxis::DoNotCoerce, TensorAxis::W, TensorAxis::RightAligned, inputShape0);
|
||||
m_inputTensorDescs[IN_B] = CreateTensorDescFromInput(kernelInfo, 1/*OnnxIndex*/, TensorAxis::DoNotCoerce, TensorAxis::W, TensorAxis::RightAligned, inputShape1);
|
||||
|
||||
// Initialize the output description while overriding the shape
|
||||
m_outputTensorDescs[0] = CreateTensorDescFromOutput(kernelInfo, 0, TensorAxis::DoNotCoerce, TensorAxis::W, TensorAxis::RightAligned, outputShape);
|
||||
|
||||
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
|
||||
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
|
||||
|
||||
DML_PLACEHOLDER_OPERATOR_DESC operatorDesc = {};
|
||||
operatorDesc.IndicesTensor = &inputDescs[0];
|
||||
operatorDesc.ValuesTensor = &inputDescs[1];
|
||||
operatorDesc.OutputTensor = outputDescs.data();
|
||||
operatorDesc.Axis = dmlAxis;
|
||||
DML_MATRIX_MULTIPLY_INTEGER_OPERATOR_DESC matmulDesc = {};
|
||||
matmulDesc.ATensor = &inputDescs[IN_A];
|
||||
matmulDesc.AZeroPointTensor = inputDescs[IN_A_ZERO_POINT].Desc != nullptr ? &inputDescs[IN_A_ZERO_POINT] : nullptr;
|
||||
matmulDesc.BTensor = &inputDescs[IN_B];
|
||||
matmulDesc.BZeroPointTensor = inputDescs[IN_B_ZERO_POINT].Desc != nullptr ? &inputDescs[IN_B_ZERO_POINT] : nullptr;
|
||||
matmulDesc.OutputTensor = &outputDescs[0];
|
||||
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_PLACEHOLDER, &operatorDesc };
|
||||
SetDmlOperatorDesc(opDesc, kernelCreationContext);
|
||||
#endif
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_MATRIX_MULTIPLY_INTEGER, &matmulDesc };
|
||||
SetDmlOperatorDesc(opDesc, kernelInfo);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(MatMulInteger, DmlOperatorMatMulInteger);
|
||||
|
||||
} // namespace Dml
|
||||
|
|
|
|||
|
|
@ -16,24 +16,40 @@ public:
|
|||
DmlOperator::Initialize(kernelCreationContext, kernelInputIndices);
|
||||
|
||||
const bool acrossChannels = (static_cast<bool>(kernelCreationContext.GetOptionalAttribute<int>(AttrName::AcrossChannels, 0)));
|
||||
const bool normalizeVariance = (static_cast<bool>(kernelCreationContext.GetOptionalAttribute<int>(AttrName::NormalizeVariance, 0)));
|
||||
const bool normalizeVariance = (static_cast<bool>(kernelCreationContext.GetOptionalAttribute<int>(AttrName::NormalizeVariance, 1)));
|
||||
|
||||
// If not specified, the default axes are [0,2,3].
|
||||
std::vector<int32_t> onnxAxes = kernelCreationContext.GetOptionalAttributeVectorInt32(AttrName::Axes);
|
||||
if (onnxAxes.empty())
|
||||
{
|
||||
int32_t crossChannelAxes[] = { 0, 1, 2, 3 };
|
||||
int32_t nonChannelAxes[] = {0, 2, 3};
|
||||
gsl::span<int32_t> defaultAxes(acrossChannels ? gsl::make_span(crossChannelAxes) : gsl::make_span(nonChannelAxes));
|
||||
onnxAxes.assign(defaultAxes.begin(), defaultAxes.end());
|
||||
}
|
||||
|
||||
std::vector<uint32_t> dmlAxes;
|
||||
const std::vector<DimensionType> inputDimensions = kernelCreationContext.GetTensorShapeDescription().GetInputTensorShape(0);
|
||||
const int32_t inputDimCount = gsl::narrow_cast<int32_t>(inputDimensions.size());
|
||||
GetDmlAdjustedAxes(onnxAxes, inputDimCount, m_inputTensorDescs.front().GetDimensionCount(), /*out*/ dmlAxes);
|
||||
|
||||
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
|
||||
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
|
||||
std::optional<ActivationOperatorDesc> fusedActivation = FusionHelpers::TryGetFusedActivationDesc(kernelCreationContext);
|
||||
DML_OPERATOR_DESC fusedActivationDmlDesc = fusedActivation ? fusedActivation->GetDmlDesc() : DML_OPERATOR_DESC();
|
||||
|
||||
DML_MEAN_VARIANCE_NORMALIZATION_OPERATOR_DESC operatorDesc = {};
|
||||
DML_MEAN_VARIANCE_NORMALIZATION1_OPERATOR_DESC operatorDesc = {};
|
||||
operatorDesc.InputTensor = &inputDescs[0];
|
||||
operatorDesc.ScaleTensor = nullptr;
|
||||
operatorDesc.BiasTensor = nullptr;
|
||||
operatorDesc.OutputTensor = outputDescs.data();
|
||||
operatorDesc.CrossChannel = acrossChannels;
|
||||
operatorDesc.Axes = dmlAxes.data();
|
||||
operatorDesc.AxisCount = gsl::narrow_cast<uint32_t>(dmlAxes.size());
|
||||
operatorDesc.NormalizeVariance = normalizeVariance;
|
||||
operatorDesc.Epsilon = DefaultEpsilon;
|
||||
operatorDesc.FusedActivation = fusedActivation ? &fusedActivationDmlDesc : nullptr;
|
||||
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_MEAN_VARIANCE_NORMALIZATION, &operatorDesc };
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_MEAN_VARIANCE_NORMALIZATION1, &operatorDesc };
|
||||
SetDmlOperatorDesc(opDesc, kernelCreationContext);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,13 +9,17 @@ namespace Dml
|
|||
class DmlOperatorPadding : public DmlOperator, public PaddingHelper
|
||||
{
|
||||
public:
|
||||
DmlOperatorPadding(const MLOperatorKernelCreationContext& kernelInfo)
|
||||
DmlOperatorPadding(const MLOperatorKernelCreationContext& kernelInfo, uint32_t opsetVersion)
|
||||
: DmlOperator(kernelInfo),
|
||||
PaddingHelper(kernelInfo, kernelInfo.GetTensorShapeDescription())
|
||||
PaddingHelper(kernelInfo, kernelInfo.GetTensorShapeDescription(), opsetVersion)
|
||||
{
|
||||
ML_CHECK_VALID_ARGUMENT(kernelInfo.GetInputCount() == 1);
|
||||
const uint32_t inputCount = kernelInfo.GetInputCount();
|
||||
ML_CHECK_VALID_ARGUMENT((opsetVersion >= 2 && opsetVersion < 11 && inputCount == 1)
|
||||
|| (opsetVersion >= 11 && inputCount >= 2 && inputCount <= 3));
|
||||
ML_CHECK_VALID_ARGUMENT(kernelInfo.GetOutputCount() == 1);
|
||||
DmlOperator::Initialize(kernelInfo);
|
||||
|
||||
std::vector<std::optional<uint32_t>> kernelInputIndices = { 0 }; // Only bind GPU to first 'data' tensor.
|
||||
DmlOperator::Initialize(kernelInfo, kernelInputIndices);
|
||||
|
||||
assert(m_inputTensorDescs[0].GetDimensionCount() >= gsl::narrow_cast<uint32_t>(m_startPadding.size()));
|
||||
assert(m_inputTensorDescs[0].GetDimensionCount() >= gsl::narrow_cast<uint32_t>(m_endPadding.size()));
|
||||
|
|
@ -52,7 +56,20 @@ public:
|
|||
ML_INVALID_ARGUMENT("Unknown Pad mode attribute.");
|
||||
}
|
||||
|
||||
float value = kernelInfo.GetOptionalAttribute<float>(AttrName::Value, 0.0f);
|
||||
// Read the constant value which can come from an attribute or tensor.
|
||||
float value = 0.0f;
|
||||
if (opsetVersion >= 11)
|
||||
{
|
||||
if (kernelInfo.IsInputValid(2))
|
||||
{
|
||||
auto valueTensor = kernelInfo.GetConstantInputTensor(2);
|
||||
value = static_cast<float>(ReadScalarTensorCastToFloat64(valueTensor));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value = kernelInfo.GetOptionalAttribute<float>(AttrName::Value, 0.0f);
|
||||
}
|
||||
|
||||
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
|
||||
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
|
||||
|
|
@ -72,6 +89,18 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(Pad, DmlOperatorPadding);
|
||||
// A specific type of operation for registration.
|
||||
template <uint32_t opsetVersion>
|
||||
class DmlOperatorPaddingTemplate : public DmlOperatorPadding
|
||||
{
|
||||
public:
|
||||
DmlOperatorPaddingTemplate(const MLOperatorKernelCreationContext& kernelInfo)
|
||||
: DmlOperatorPadding(kernelInfo, opsetVersion)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(Pad7, DmlOperatorPaddingTemplate<7>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(Pad11, DmlOperatorPaddingTemplate<11>);
|
||||
|
||||
} // namespace Dml
|
||||
|
|
|
|||
|
|
@ -30,17 +30,15 @@ public:
|
|||
assert(m_kernel.spatialDimensionCount <= ARRAYSIZE(m_kernel.windowSize));
|
||||
|
||||
// The below attributes are temporarily not supported:
|
||||
int ceilMode = kernelInfo.GetOptionalAttribute<int>(AttrName::CeilMode, 0);
|
||||
THROW_HR_IF(E_NOTIMPL, ceilMode != 0);
|
||||
|
||||
int storageOrder = kernelInfo.GetOptionalAttribute<int>(AttrName::StorageOrder, 0);
|
||||
THROW_HR_IF(E_NOTIMPL, storageOrder != 0);
|
||||
|
||||
auto dilations = kernelInfo.GetOptionalAttributeVectorInt32(AttrName::Dilations);
|
||||
for (int dilation : dilations)
|
||||
{
|
||||
THROW_HR_IF(E_NOTIMPL, dilation != 1);
|
||||
}
|
||||
const bool hasDilations =
|
||||
std::any_of(
|
||||
m_kernel.dilations,
|
||||
m_kernel.dilations + m_kernel.spatialDimensionCount,
|
||||
[](auto d) {return d != 1; }
|
||||
);
|
||||
|
||||
// DML requires that DimensionCount be equal to Input.DimCount - 2 for Pooling
|
||||
uint32_t expectedSpatialDimCount = m_inputTensorDescs[0].GetDimensionCount() - 2;
|
||||
|
|
@ -61,6 +59,9 @@ public:
|
|||
|
||||
m_kernel.endPadding[i + shift] = m_kernel.endPadding[i];
|
||||
m_kernel.endPadding[i] = 0;
|
||||
|
||||
m_kernel.dilations[i + shift] = m_kernel.dilations[i];
|
||||
m_kernel.dilations[i] = 1;
|
||||
}
|
||||
|
||||
m_kernel.spatialDimensionCount = expectedSpatialDimCount;
|
||||
|
|
@ -101,11 +102,14 @@ public:
|
|||
}
|
||||
case DML_OPERATOR_MAX_POOLING:
|
||||
case DML_OPERATOR_MAX_POOLING1:
|
||||
case DML_OPERATOR_MAX_POOLING2:
|
||||
{
|
||||
if (outputDescs.size() > 1 && outputDescs[1].Desc != nullptr)
|
||||
bool hasOutputIndices = (outputDescs.size() > 1 && outputDescs[1].Desc != nullptr);
|
||||
if (hasOutputIndices || hasDilations)
|
||||
{
|
||||
DML_MAX_POOLING1_OPERATOR_DESC desc = {};
|
||||
desc.OutputIndicesTensor = &outputDescs[1];
|
||||
DML_MAX_POOLING2_OPERATOR_DESC desc = {};
|
||||
desc.OutputIndicesTensor = hasOutputIndices ? &outputDescs[1] : nullptr;
|
||||
desc.Dilations = m_kernel.dilations;
|
||||
SetOpDesc(desc);
|
||||
}
|
||||
else
|
||||
|
|
@ -134,40 +138,24 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
void CALLBACK QueryMaxPool(IMLOperatorSupportQueryContextPrivate* context, bool *isSupported)
|
||||
void CALLBACK QueryMaxPool(IMLOperatorSupportQueryContextPrivate* context, bool* isSupported)
|
||||
{
|
||||
*isSupported = false;
|
||||
|
||||
MLOperatorAttributes attributes(context);
|
||||
|
||||
// The below attributes are temporarily not supported:
|
||||
int ceilMode = attributes.GetOptionalAttribute<int>(AttrName::CeilMode, 0);
|
||||
if (ceilMode != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int storageOrder = attributes.GetOptionalAttribute<int>(AttrName::StorageOrder, 0);
|
||||
if (storageOrder != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto dilations = attributes.GetOptionalAttributeVectorInt32(AttrName::Dilations);
|
||||
for (int dilation : dilations)
|
||||
{
|
||||
if (dilation != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*isSupported = true;
|
||||
}
|
||||
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(AveragePool, DmlOperatorPoolingTemplate<DML_OPERATOR_AVERAGE_POOLING, false>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(GlobalAveragePool, DmlOperatorPoolingTemplate<DML_OPERATOR_AVERAGE_POOLING, true>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(MaxPool, DmlOperatorPoolingTemplate<DML_OPERATOR_MAX_POOLING1, false>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(MaxPool, DmlOperatorPoolingTemplate<DML_OPERATOR_MAX_POOLING2, false>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(GlobalMaxPool, DmlOperatorPoolingTemplate<DML_OPERATOR_MAX_POOLING, true>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(LpPool, DmlOperatorPoolingTemplate<DML_OPERATOR_LP_POOLING, false>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(GlobalLpPool, DmlOperatorPoolingTemplate<DML_OPERATOR_LP_POOLING, true>);
|
||||
|
|
|
|||
|
|
@ -6,34 +6,98 @@
|
|||
namespace Dml
|
||||
{
|
||||
|
||||
class DmlOperatorQLinearConv : public DmlOperator
|
||||
class DmlOperatorQLinearConv : public DmlOperator, public ConvolutionHelperBase
|
||||
{
|
||||
private:
|
||||
enum InputTensors
|
||||
{
|
||||
IN_X,
|
||||
IN_X_SCALE,
|
||||
IN_X_ZERO_POINT,
|
||||
IN_F,
|
||||
IN_F_SCALE,
|
||||
IN_F_ZERO_POINT,
|
||||
IN_BIAS,
|
||||
IN_Y_SCALE,
|
||||
IN_Y_ZERO_POINT
|
||||
};
|
||||
|
||||
public:
|
||||
using Self = DmlOperatorQLinearConv;
|
||||
|
||||
DmlOperatorQLinearConv(const MLOperatorKernelCreationContext& kernelCreationContext)
|
||||
: DmlOperator(kernelCreationContext)
|
||||
DmlOperatorQLinearConv(
|
||||
const MLOperatorKernelCreationContext& kernelInfo
|
||||
)
|
||||
: DmlOperator(kernelInfo),
|
||||
ConvolutionHelperBase(kernelInfo, kernelInfo.GetTensorShapeDescription(), false, false, 0, 3)
|
||||
{
|
||||
#if 0 // TODO:NickFe - https://github.com/onnx/onnx/blob/master/docs/Operators.md#qlinearconv
|
||||
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetInputCount() >= 8 && kernelCreationContext.GetInputCount() <= 9);
|
||||
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetOutputCount() == 1);
|
||||
DmlOperator::Initialize(kernelCreationContext, inputIndices, outputIndices);
|
||||
std::vector<std::optional<uint32_t>> kernelInputIndices = {0, 1, 2, 3, 4, 5, 8, 6, 7};
|
||||
std::vector<std::optional<uint32_t>> kernelOutputIndices = {0};
|
||||
|
||||
DmlOperator::Initialize(kernelInfo, kernelInputIndices);
|
||||
|
||||
// DirectML is limited to handle only 2D. So for 1D tensors, massage the tensor descriptions. By default, the
|
||||
// TensorDesc simply right aligns all the values up to 4D (padding the leading dimensions with 1's),
|
||||
// but 1D tensors actually need to insert the 1 between C and W. e.g. [2,3,4] becomes [2,3,1,4]
|
||||
m_inputTensorDescs[IN_X] = CreateTensorDescFromInput(kernelInfo, 0/*Onnx Index*/, TensorAxis::DoNotCoerce, TensorAxis::NoPlacementAdjustment, NonspatialDimensionCount, std::nullopt);
|
||||
m_inputTensorDescs[IN_F] = CreateTensorDescFromInput(kernelInfo, 3/*Onnx Index*/, TensorAxis::DoNotCoerce, TensorAxis::NoPlacementAdjustment, NonspatialDimensionCount, std::nullopt);
|
||||
|
||||
// Bias is optional so only adjust it if it exists.
|
||||
if (m_inputTensorDescs[IN_BIAS].GetDmlDesc().Desc != nullptr)
|
||||
{
|
||||
uint32_t inputDimSize = kernelInfo.GetTensorShapeDescription().GetInputTensorDimensionCount(0);
|
||||
ML_CHECK_VALID_ARGUMENT(
|
||||
inputDimSize >= 3 && inputDimSize <= 5,
|
||||
"Bias can only be used with 3D/4D/5D tensors."
|
||||
);
|
||||
uint32_t dmlDimSize = m_inputTensorDescs[0].GetDimensionCount();
|
||||
|
||||
// Resize the bias to be the same dimension as the input tensor.
|
||||
// The 1D tensor needs to be moved to the C channel.
|
||||
m_inputTensorDescs[IN_BIAS] = CreateTensorDescFromInput(
|
||||
kernelInfo,
|
||||
8/*Onnx Index*/,
|
||||
TensorAxis::DoNotCoerce,
|
||||
TensorAxis::C,
|
||||
TensorAxis::LeftAligned,
|
||||
std::nullopt,
|
||||
dmlDimSize
|
||||
);
|
||||
}
|
||||
|
||||
m_outputTensorDescs[0] = CreateTensorDescFromOutput(kernelInfo, 0, TensorAxis::DoNotCoerce, TensorAxis::NoPlacementAdjustment, NonspatialDimensionCount, std::nullopt);
|
||||
|
||||
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
|
||||
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
|
||||
|
||||
DML_PLACEHOLDER_OPERATOR_DESC operatorDesc = {};
|
||||
operatorDesc.IndicesTensor = &inputDescs[0];
|
||||
operatorDesc.ValuesTensor = &inputDescs[1];
|
||||
operatorDesc.OutputTensor = outputDescs.data();
|
||||
operatorDesc.Axis = dmlAxis;
|
||||
// Form transient kernel arguments with spatial dimensions padded up to at least 2,
|
||||
// since the DirectML API rejects 1D convolution. Leave the base m_kernel alone
|
||||
// so that all output tensor size computations are correct.
|
||||
KernelArgs kernelArgs(m_kernel, NchwSpatialDimensionCount);
|
||||
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_PLACEHOLDER, &operatorDesc };
|
||||
SetDmlOperatorDesc(opDesc, kernelCreationContext);
|
||||
#endif
|
||||
DML_QUANTIZED_LINEAR_CONVOLUTION_OPERATOR_DESC convDesc = {};
|
||||
convDesc.InputTensor = &inputDescs[IN_X];
|
||||
convDesc.InputScaleTensor = &inputDescs[IN_X_SCALE];
|
||||
convDesc.InputZeroPointTensor = inputDescs[IN_X_ZERO_POINT].Desc != nullptr ? &inputDescs[IN_X_ZERO_POINT] : nullptr;
|
||||
convDesc.FilterTensor = &inputDescs[IN_F];
|
||||
convDesc.FilterScaleTensor = &inputDescs[IN_F_SCALE];
|
||||
convDesc.FilterZeroPointTensor = inputDescs[IN_F_ZERO_POINT].Desc != nullptr ? &inputDescs[IN_F_ZERO_POINT] : nullptr;
|
||||
convDesc.BiasTensor = inputDescs[IN_BIAS].Desc != nullptr ? &inputDescs[IN_BIAS] : nullptr;
|
||||
convDesc.OutputScaleTensor = &inputDescs[IN_Y_SCALE];
|
||||
convDesc.OutputZeroPointTensor = inputDescs[IN_Y_ZERO_POINT].Desc != nullptr ? &inputDescs[IN_Y_ZERO_POINT] : nullptr;
|
||||
convDesc.OutputTensor = &outputDescs[0];
|
||||
convDesc.DimensionCount = kernelArgs.spatialDimensionCount;
|
||||
convDesc.Strides = kernelArgs.strides;
|
||||
convDesc.Dilations = kernelArgs.dilations;
|
||||
convDesc.StartPadding = kernelArgs.startPadding;
|
||||
convDesc.EndPadding = kernelArgs.endPadding;
|
||||
convDesc.GroupCount = m_groupCount;
|
||||
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_QUANTIZED_LINEAR_CONVOLUTION, &convDesc };
|
||||
SetDmlOperatorDesc(opDesc, kernelInfo);
|
||||
}
|
||||
};
|
||||
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(QLinearConv, DmlOperatorQLinearConv);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(QLinearConv, DmlOperatorQLinearConv);
|
||||
|
||||
} // namespace Dml
|
||||
|
|
|
|||
|
|
@ -8,32 +8,57 @@ namespace Dml
|
|||
|
||||
class DmlOperatorQLinearMatMul : public DmlOperator
|
||||
{
|
||||
public:
|
||||
using Self = DmlOperatorQLinearMatMul;
|
||||
enum InputTensors {
|
||||
IN_A,
|
||||
IN_A_SCALE,
|
||||
IN_A_ZERO_POINT,
|
||||
IN_B,
|
||||
IN_B_SCALE,
|
||||
IN_B_ZERO_POINT,
|
||||
IN_Y_SCALE,
|
||||
IN_Y_ZERO_POINT
|
||||
};
|
||||
|
||||
DmlOperatorQLinearMatMul(const MLOperatorKernelCreationContext& kernelCreationContext)
|
||||
: DmlOperator(kernelCreationContext)
|
||||
public:
|
||||
DmlOperatorQLinearMatMul(const MLOperatorKernelCreationContext& kernelInfo)
|
||||
: DmlOperator(kernelInfo)
|
||||
{
|
||||
#if 0 // TODO:NickFe - https://github.com/onnx/onnx/blob/master/docs/Operators.md#qlinearmatmul
|
||||
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetInputCount() == 8);
|
||||
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetOutputCount() == 1);
|
||||
DmlOperator::Initialize(kernelCreationContext, inputIndices, outputIndices);
|
||||
std::vector<std::optional<uint32_t>> inputIndices = { 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||
DmlOperator::Initialize(kernelInfo, inputIndices);
|
||||
|
||||
std::vector<DimensionType> inputShape0 = kernelInfo.GetTensorShapeDescription().GetInputTensorShape(0/*A OnnxIndex*/);
|
||||
std::vector<DimensionType> inputShape1 = kernelInfo.GetTensorShapeDescription().GetInputTensorShape(3/*B OnnxIndex*/);
|
||||
std::vector<DimensionType> outputShape = kernelInfo.GetTensorShapeDescription().GetOutputTensorShape(0);
|
||||
|
||||
OperatorHelper::MatMulShapeMapping(inputShape0, inputShape1, outputShape);
|
||||
|
||||
// Initialize the input descriptions with broadcasting
|
||||
m_inputTensorDescs[IN_A] = CreateTensorDescFromInput(kernelInfo, 0/*A OnnxIndex*/, TensorAxis::DoNotCoerce, TensorAxis::W, TensorAxis::RightAligned, inputShape0);
|
||||
m_inputTensorDescs[IN_B] = CreateTensorDescFromInput(kernelInfo, 3/*B OnnxIndex*/, TensorAxis::DoNotCoerce, TensorAxis::W, TensorAxis::RightAligned, inputShape1);
|
||||
|
||||
// Initialize the output description while overriding the shape
|
||||
m_outputTensorDescs[0] = CreateTensorDescFromOutput(kernelInfo, 0, TensorAxis::DoNotCoerce, TensorAxis::W, TensorAxis::RightAligned, outputShape);
|
||||
|
||||
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
|
||||
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
|
||||
|
||||
DML_PLACEHOLDER_OPERATOR_DESC operatorDesc = {};
|
||||
operatorDesc.IndicesTensor = &inputDescs[0];
|
||||
operatorDesc.ValuesTensor = &inputDescs[1];
|
||||
operatorDesc.OutputTensor = outputDescs.data();
|
||||
operatorDesc.Axis = dmlAxis;
|
||||
DML_QUANTIZED_LINEAR_MATRIX_MULTIPLY_OPERATOR_DESC matMulDesc = {};
|
||||
matMulDesc.ATensor = &inputDescs[IN_A];
|
||||
matMulDesc.AScaleTensor = &inputDescs[IN_A_SCALE];
|
||||
matMulDesc.AZeroPointTensor = inputDescs[IN_A_ZERO_POINT].Desc != nullptr ? &inputDescs[IN_A_ZERO_POINT] : nullptr;
|
||||
matMulDesc.BTensor = &inputDescs[IN_B];
|
||||
matMulDesc.BScaleTensor = &inputDescs[IN_B_SCALE];
|
||||
matMulDesc.BZeroPointTensor = inputDescs[IN_B_ZERO_POINT].Desc != nullptr ? &inputDescs[IN_B_ZERO_POINT] : nullptr;
|
||||
matMulDesc.OutputScaleTensor = &inputDescs[IN_Y_SCALE];
|
||||
matMulDesc.OutputZeroPointTensor = inputDescs[IN_Y_ZERO_POINT].Desc != nullptr ? &inputDescs[IN_Y_ZERO_POINT] : nullptr;
|
||||
matMulDesc.OutputTensor = &outputDescs[0];
|
||||
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_PLACEHOLDER, &operatorDesc };
|
||||
SetDmlOperatorDesc(opDesc, kernelCreationContext);
|
||||
#endif
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_QUANTIZED_LINEAR_MATRIX_MULTIPLY, &matMulDesc };
|
||||
SetDmlOperatorDesc(opDesc, kernelInfo);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(QLinearMatMul, DmlOperatorQLinearMatMul);
|
||||
|
||||
} // namespace Dml
|
||||
|
|
|
|||
|
|
@ -6,13 +6,165 @@
|
|||
namespace Dml
|
||||
{
|
||||
|
||||
void ComputePixelOffsetsAndScales(
|
||||
const MLOperatorKernelCreationContext& kernelCreationContext,
|
||||
gsl::span<const float> regionOfInterest, // May be empty depending on mode.
|
||||
gsl::span<const uint32_t> inputDimensions,
|
||||
gsl::span<const uint32_t> outputDimensions,
|
||||
/*inout*/ gsl::span<float> scales,
|
||||
/*out*/ gsl::span<float> inputPixelOffsets,
|
||||
/*out*/ gsl::span<float> outputPixelOffsets
|
||||
)
|
||||
{
|
||||
assert(inputDimensions.size() == outputDimensions.size());
|
||||
assert(inputPixelOffsets.size() == outputPixelOffsets.size());
|
||||
assert(inputPixelOffsets.size() == scales.size());
|
||||
assert(inputPixelOffsets.size() == inputDimensions.size());
|
||||
assert(regionOfInterest.empty() || regionOfInterest.size() == inputDimensions.size() * 2);
|
||||
|
||||
std::string coordinateTransformationMode = kernelCreationContext.GetOptionalAttribute<std::string>(AttrName::CoordinateTransformationMode, "half_pixel");
|
||||
uint32_t coordinateTransformationModeValue = UINT32_MAX;
|
||||
|
||||
const char* modes[] = { "half_pixel", "pytorch_half_pixel", "align_corners", "asymmetric", "tf_half_pixel_for_nn", "tf_crop_and_resize" };
|
||||
for (uint32_t i = 0; i < std::size(modes); ++i)
|
||||
{
|
||||
if (strcmp(modes[i], coordinateTransformationMode.c_str()) == 0)
|
||||
{
|
||||
coordinateTransformationModeValue = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ML_CHECK_VALID_ARGUMENT(
|
||||
!regionOfInterest.empty() || coordinateTransformationModeValue != 5 /*tf_crop_and_resize*/,
|
||||
"Resize expects 'roi' tensor for 'tf_crop_and_resize' mode."
|
||||
);
|
||||
|
||||
const uint32_t rank = gsl::narrow_cast<uint32_t>(inputDimensions.size());
|
||||
|
||||
// Fill in all the input/output pixel offset for each axis,
|
||||
// and recompute the scale for certain modes.
|
||||
|
||||
for (uint32_t i = 0; i < rank; ++i)
|
||||
{
|
||||
float inputPixelOffset = 0;
|
||||
float outputPixelOffset = 0;
|
||||
|
||||
// All these mapping modes can be generalized to the equations:
|
||||
//
|
||||
// output_coordinate = (input_coordinate + input_offset ) * scale + output_offset
|
||||
// input_coordinate = (output_coordinate - output_offset) / scale - input_offset
|
||||
//
|
||||
// With DML, a scale > 1 maps input to an upsampled output, and a positive pixel
|
||||
// offset shifts the input contents to the right/down in the output.
|
||||
//
|
||||
// Since the equations from ONNX are in terms of mapping the output coordinate back
|
||||
// to the input coordinate, any offsets need their signs flipped. e.g. For "half_pixel",
|
||||
// the "x_resized" is the output coordinate, and the "+ 0.5" is the output coordinate
|
||||
// adjustment which needs to be -0.5 when passed to DML.
|
||||
|
||||
switch (coordinateTransformationModeValue)
|
||||
{
|
||||
case 0:
|
||||
// coordinate_transformation_mode is "half_pixel",
|
||||
// x_original = (x_resized + 0.5) / scale - 0.5
|
||||
inputPixelOffset = 0.5;
|
||||
outputPixelOffset = -0.5;
|
||||
// Keep existing scales.
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// if coordinate_transformation_mode is "pytorch_half_pixel",
|
||||
// x_original = length_resized > 1 ? (x_resized + 0.5) / scale - 0.5 : 0
|
||||
if (inputDimensions[i] <= 1)
|
||||
{
|
||||
inputPixelOffset = 0.0;
|
||||
outputPixelOffset = 0.0;
|
||||
scales[i] = FLT_MAX; // Set large scale so all output pixels map to 0th input pixel.
|
||||
}
|
||||
else
|
||||
{
|
||||
inputPixelOffset = 0.5;
|
||||
outputPixelOffset = -0.5;
|
||||
// Keep existing scales.
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// if coordinate_transformation_mode is "align_corners",
|
||||
// x_original = x_resized * (length_original - 1) / (length_resized - 1)
|
||||
inputPixelOffset = 0.0;
|
||||
outputPixelOffset = 0.0;
|
||||
if (outputDimensions[i] <= 1 || inputDimensions[i] <= 1)
|
||||
{
|
||||
// Protect against division by zero when either input/output is a single pixel.
|
||||
scales[i] = FLT_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Recalcalculate scale, ignoring existing one (only used to determine output size).
|
||||
scales[i] = float(outputDimensions[i] - 1) / (inputDimensions[i] - 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// if coordinate_transformation_mode is "asymmetric",
|
||||
// x_original = x_resized / scale
|
||||
inputPixelOffset = 0.0;
|
||||
outputPixelOffset = 0.0;
|
||||
// Keep existing scales.
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// if coordinate_transformation_mode is "tf_half_pixel_for_nn",
|
||||
// x_original = (x_resized + 0.5) / scale
|
||||
inputPixelOffset = 0.0;
|
||||
outputPixelOffset = -0.5;
|
||||
// Keep existing scales.
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// if coordinate_transformation_mode is "tf_crop_and_resize",
|
||||
// x_original = length_resized > 1 ? start_x * (length_original - 1) + x_resized * (end_x - start_x) * (length_original - 1) / (length_resized - 1)
|
||||
// : 0.5 * (start_x + end_x) * (length_original - 1)
|
||||
if (inputDimensions[i] > 1)
|
||||
{
|
||||
assert(regionOfInterest.size() == rank * 2);
|
||||
|
||||
// Fold this part of the equation into the input offset: start_x * (length_original - 1)
|
||||
inputPixelOffset = -(regionOfInterest[i] * (inputDimensions[i] - 1));
|
||||
outputPixelOffset = 0.0;
|
||||
|
||||
// Fold this part to scale: (end_x - start_x) * (length_original - 1) / (length_resized - 1)
|
||||
float computedScale = float(outputDimensions[i] - 1)
|
||||
/ std::max((regionOfInterest[i + rank] - regionOfInterest[i]) * (inputDimensions[i] - 1), 1.0f);
|
||||
scales[i] = computedScale;
|
||||
}
|
||||
else // inputDimensions[i] <= 1
|
||||
{
|
||||
// 0.5 * (start_x + end_x) * (length_original - 1)
|
||||
inputPixelOffset = -0.5 * (regionOfInterest[i] + regionOfInterest[i + rank]) * (inputDimensions[i] - 1);
|
||||
outputPixelOffset = 0.0;
|
||||
scales[i] = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ML_INVALID_ARGUMENT("Unknown 'coordinate_transformation_mode'");
|
||||
}
|
||||
|
||||
inputPixelOffsets[i] = inputPixelOffset;
|
||||
outputPixelOffsets[i] = outputPixelOffset;
|
||||
}
|
||||
}
|
||||
|
||||
class DmlOperatorResize : public DmlOperator, public ResizeHelper
|
||||
{
|
||||
public:
|
||||
// Resample a multidimensional image to a new size.
|
||||
DmlOperatorResize(const MLOperatorKernelCreationContext& kernelCreationContext)
|
||||
DmlOperatorResize(const MLOperatorKernelCreationContext& kernelCreationContext, uint32_t opsetVersion)
|
||||
: DmlOperator(kernelCreationContext),
|
||||
ResizeHelper(kernelCreationContext, kernelCreationContext.GetTensorShapeDescription())
|
||||
ResizeHelper(kernelCreationContext, kernelCreationContext.GetTensorShapeDescription(), opsetVersion)
|
||||
{
|
||||
ML_CHECK_VALID_ARGUMENT(!m_scales.empty(), "Resize/Upsample expect scales, either a 2nd input tensors or 'scales' attribute.");
|
||||
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetOutputCount() == 1, "Resize/Upsample expect 1 output tensor.");
|
||||
|
|
@ -32,9 +184,31 @@ public:
|
|||
std::vector<uint32_t> squeezedOutputShape = m_outputDimensions;
|
||||
std::vector<uint32_t> squeezableDimensionIndices;
|
||||
std::vector<float> paddedScales = m_scales;
|
||||
FindValueIndices<uint32_t>(gsl::make_span(m_outputDimensions), 1u, /*out*/ squeezableDimensionIndices);
|
||||
std::vector<float> inputPixelOffsets(paddedScales.size());
|
||||
std::vector<float> outputPixelOffsets(paddedScales.size());
|
||||
|
||||
ComputePixelOffsetsAndScales(
|
||||
kernelCreationContext,
|
||||
m_regionOfInterest, // May be empty depending on mode.
|
||||
m_inputDimensions,
|
||||
m_outputDimensions,
|
||||
/*inout*/ paddedScales,
|
||||
/*out*/ inputPixelOffsets,
|
||||
/*out*/ outputPixelOffsets
|
||||
);
|
||||
|
||||
// Find any useless dimensions of size 1 that occur in both input and output.
|
||||
for (size_t i = 0, rank = m_outputDimensions.size(); i < rank; ++i)
|
||||
{
|
||||
if (m_inputDimensions[i] = 1 && m_outputDimensions[i] == 1)
|
||||
{
|
||||
squeezableDimensionIndices.push_back(gsl::narrow_cast<uint32_t>(i));
|
||||
}
|
||||
}
|
||||
RemoveValuesByIndex(squeezableDimensionIndices, /*keepOneValue*/ true, /*inout*/ squeezedInputShape);
|
||||
RemoveValuesByIndex(squeezableDimensionIndices, /*keepOneValue*/ true, /*inout*/ paddedScales);
|
||||
RemoveValuesByIndex(squeezableDimensionIndices, /*keepOneValue*/ true, /*inout*/ inputPixelOffsets);
|
||||
RemoveValuesByIndex(squeezableDimensionIndices, /*keepOneValue*/ true, /*inout*/ outputPixelOffsets);
|
||||
RemoveValuesByIndex(squeezableDimensionIndices, /*keepOneValue*/ true, /*inout*/ squeezedOutputShape);
|
||||
|
||||
// Update the tensor descriptions.
|
||||
|
|
@ -52,6 +226,8 @@ public:
|
|||
if (dmlCompatibleDimCount > squeezedDimCount)
|
||||
{
|
||||
paddedScales.insert(paddedScales.begin(), dmlCompatibleDimCount - squeezedDimCount, 1.0f);
|
||||
inputPixelOffsets.insert(inputPixelOffsets.begin(), dmlCompatibleDimCount - squeezedDimCount, 0.5f);
|
||||
outputPixelOffsets.insert(outputPixelOffsets.begin(), dmlCompatibleDimCount - squeezedDimCount, -0.5f);
|
||||
}
|
||||
|
||||
std::string mode = kernelCreationContext.GetOptionalAttribute<std::string>(AttrName::Mode, "NEAREST");
|
||||
|
|
@ -61,19 +237,77 @@ public:
|
|||
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
|
||||
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
|
||||
|
||||
DML_RESAMPLE_OPERATOR_DESC operatorDesc = {};
|
||||
DML_RESAMPLE1_OPERATOR_DESC operatorDesc = {};
|
||||
operatorDesc.InputTensor = inputDescs.data();
|
||||
operatorDesc.OutputTensor = outputDescs.data();
|
||||
operatorDesc.InterpolationMode = interpolationMode;
|
||||
operatorDesc.Scales = paddedScales.data();
|
||||
operatorDesc.ScaleCount = gsl::narrow_cast<uint32_t>(paddedScales.size());
|
||||
operatorDesc.DimensionCount = gsl::narrow_cast<uint32_t>(paddedScales.size());
|
||||
operatorDesc.InputPixelOffsets = inputPixelOffsets.data();
|
||||
operatorDesc.OutputPixelOffsets = outputPixelOffsets.data();
|
||||
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_RESAMPLE, &operatorDesc };
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_RESAMPLE1, &operatorDesc };
|
||||
SetDmlOperatorDesc(opDesc, kernelCreationContext);
|
||||
}
|
||||
};
|
||||
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(Resize, DmlOperatorResize);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(Upsample, DmlOperatorResize);
|
||||
// A specific type of operation for registration.
|
||||
template <uint32_t OpsetVersion>
|
||||
struct DmlOperatorResizeTemplate : public DmlOperatorResize
|
||||
{
|
||||
public:
|
||||
DmlOperatorResizeTemplate(const MLOperatorKernelCreationContext& kernelInfo)
|
||||
: DmlOperatorResize(kernelInfo, OpsetVersion)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
void CALLBACK QueryResize(IMLOperatorSupportQueryContextPrivate* context, bool* isSupported)
|
||||
{
|
||||
*isSupported = false;
|
||||
|
||||
MLOperatorAttributes attributes(context);
|
||||
|
||||
// DML does not support cubic.
|
||||
std::string mode = attributes.GetOptionalAttribute<std::string>(AttrName::Mode, "nearest");
|
||||
if (mode == "cubic")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// DML clamps the input coordinates to the edges and essentially repeats the last pixel.
|
||||
// So rescaling the input kernel total denominator is not supported.
|
||||
int32_t excludeOutside = attributes.GetOptionalAttribute<int32_t>(AttrName::ExcludeOutside, 0);
|
||||
if (excludeOutside != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// DML does not support specifying a specific element value for reading outside the edges.
|
||||
// Note the extrapolation value is only pertinent for "tf_crop_and_resize" mode.
|
||||
float extrapolationValue = attributes.GetOptionalAttribute<float>(AttrName::ExtrapolationValue, 0.0);
|
||||
if (extrapolationValue != 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// DML's nearest neighbor mode uses half pixels rounded down.
|
||||
std::string nearestMode = attributes.GetOptionalAttribute<std::string>(AttrName::NearestMode, "round_prefer_floor");
|
||||
if (nearestMode != "round_prefer_floor")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore parameter "cubic_coeff_a" since Cubic interpolation unsupported in DML.
|
||||
// Ignore parameter "extrapolation_value" as DML clamps to the input rather than reading black pixels.
|
||||
|
||||
*isSupported = true;
|
||||
}
|
||||
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(Resize10, DmlOperatorResizeTemplate<10>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(Resize11, DmlOperatorResizeTemplate<11>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(Upsample7, DmlOperatorResizeTemplate<7>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(Upsample9, DmlOperatorResizeTemplate<9>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(Upsample10, DmlOperatorResizeTemplate<10>);
|
||||
|
||||
} // namespace Dml
|
||||
|
|
|
|||
|
|
@ -6,16 +6,16 @@
|
|||
namespace Dml
|
||||
{
|
||||
|
||||
class DmlOperatorSlice : public DmlOperator, public SliceHelperBase
|
||||
class DmlOperatorSlice : public DmlOperator, public SliceHelper
|
||||
{
|
||||
public:
|
||||
DmlOperatorSlice(const MLOperatorKernelCreationContext& kernelInfo, uint32_t opsetVersion)
|
||||
: DmlOperator(kernelInfo),
|
||||
SliceHelperBase(kernelInfo, kernelInfo.GetTensorShapeDescription(), opsetVersion)
|
||||
SliceHelper(kernelInfo, kernelInfo.GetTensorShapeDescription(), opsetVersion)
|
||||
{
|
||||
const uint32_t inputCount = kernelInfo.GetInputCount();
|
||||
ML_CHECK_VALID_ARGUMENT((opsetVersion < 10 && inputCount == 1)
|
||||
|| (opsetVersion >= 10 && opsetVersion <= 11 && inputCount >= 3 && inputCount <= 5));
|
||||
|| (opsetVersion >= 10 && inputCount >= 3 && inputCount <= 5));
|
||||
ML_CHECK_VALID_ARGUMENT(kernelInfo.GetOutputCount() == 1);
|
||||
|
||||
std::vector<std::optional<uint32_t>> kernelInputIndices = { 0 }; // Only bind GPU to first 'data' tensor.
|
||||
|
|
|
|||
|
|
@ -11,11 +11,17 @@ class DmlOperatorTopK : public DmlOperator, public TopKHelper
|
|||
public:
|
||||
using Self = DmlOperatorTopK;
|
||||
|
||||
DmlOperatorTopK(const MLOperatorKernelCreationContext& kernelCreationContext)
|
||||
DmlOperatorTopK(const MLOperatorKernelCreationContext& kernelCreationContext, uint32_t opsetVersion)
|
||||
: DmlOperator(kernelCreationContext),
|
||||
TopKHelper(kernelCreationContext, kernelCreationContext.GetTensorShapeDescription())
|
||||
TopKHelper(kernelCreationContext, kernelCreationContext.GetTensorShapeDescription(), opsetVersion)
|
||||
{
|
||||
DmlOperator::Initialize(kernelCreationContext);
|
||||
ML_CHECK_VALID_ARGUMENT(((opsetVersion >= 1 && opsetVersion < 10) && kernelCreationContext.GetInputCount() == 1)
|
||||
|| ((opsetVersion >= 10) && kernelCreationContext.GetInputCount() == 2));
|
||||
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetOutputCount() == 2, "TopK expects 2 output tensors.");
|
||||
|
||||
std::vector<std::optional<uint32_t>> inputIndices = { 0 }; // Use only the first tensor. The second tensor is CPU-based.
|
||||
std::vector<std::optional<uint32_t>> outputIndices = { 0, 1 };
|
||||
DmlOperator::Initialize(kernelCreationContext, inputIndices, outputIndices);
|
||||
|
||||
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
|
||||
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
|
||||
|
|
@ -23,19 +29,25 @@ public:
|
|||
ML_CHECK_VALID_ARGUMENT(outputDescs.size() == 2);
|
||||
|
||||
uint32_t dmlAxis = GetDmlAdjustedAxis(m_axis, kernelCreationContext, m_inputTensorDescs.front().GetDimensionCount());
|
||||
int32_t largest = kernelCreationContext.GetOptionalAttribute<int32_t>(AttrName::Largest, 1);
|
||||
// Note the "sorted" attribute is not needed because the specification only dictates that
|
||||
// when sorted is true that elements are returned in order, but when false, the order of
|
||||
// returned 'Values' and 'Indices' are undefined. So returning them in order is a superset
|
||||
// of returning them in arbitrary order.
|
||||
|
||||
DML_TOP_K_OPERATOR_DESC operatorDesc = {};
|
||||
DML_TOP_K1_OPERATOR_DESC operatorDesc = {};
|
||||
operatorDesc.InputTensor = inputDescs.data();
|
||||
operatorDesc.OutputValueTensor = &outputDescs[0];
|
||||
operatorDesc.OutputIndexTensor = &outputDescs[1];
|
||||
operatorDesc.Axis = dmlAxis;
|
||||
operatorDesc.K = m_k;
|
||||
operatorDesc.AxisDirection = largest ? DML_AXIS_DIRECTION_DECREASING : DML_AXIS_DIRECTION_INCREASING;
|
||||
|
||||
// Index tensor is always of type int64. We need to create an extra DML operator to
|
||||
// initialize the tensor data.
|
||||
m_zeroOperator = InitializeZeroInt64Tensor(m_outputTensorDescs[1].GetBufferSizeInBytes());
|
||||
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_TOP_K, &operatorDesc };
|
||||
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_TOP_K1, &operatorDesc };
|
||||
SetDmlOperatorDesc(opDesc, kernelCreationContext);
|
||||
}
|
||||
|
||||
|
|
@ -58,6 +70,19 @@ private:
|
|||
ComPtr<IDMLCompiledOperator> m_zeroOperator;
|
||||
};
|
||||
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(TopK, DmlOperatorTopK);
|
||||
// A specific type of operation for registration.
|
||||
template <uint32_t OpsetVersion>
|
||||
class DmlOperatorTopKTemplate : public DmlOperatorTopK
|
||||
{
|
||||
public:
|
||||
DmlOperatorTopKTemplate(const MLOperatorKernelCreationContext& kernelInfo)
|
||||
: DmlOperatorTopK(kernelInfo, OpsetVersion)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(TopK7, DmlOperatorTopKTemplate<7>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(TopK10, DmlOperatorTopKTemplate<10>);
|
||||
DML_OP_DEFINE_CREATION_FUNCTION(TopK11, DmlOperatorTopKTemplate<11>);
|
||||
|
||||
} // namespace Dml
|
||||
|
|
|
|||
|
|
@ -38,8 +38,9 @@ enum class SupportedTensorDataTypes : uint32_t
|
|||
Int32to64 = UInt32|Int32|UInt64|Int64,
|
||||
Float16to32 = Float16|Float32, // Float64 is not supported by DirectML.
|
||||
NumericDefault = Int8to32|Float16to32,
|
||||
Scalars8to32 = UInt8|Int8|UInt16|Int16|UInt32|Int32|Float16to32|Bool,
|
||||
Scalars8to32 = UInt8|Int8|UInt16|Int16|UInt32|Int32|Float16to32|Bool,
|
||||
AllScalars = UInt8|Int8|UInt16|Int16|UInt32|Int32|UInt64|Int64|Float16to32|Bool,
|
||||
Ints8Bit = UInt8|Int8,
|
||||
All = static_cast<uint32_t>(-1),
|
||||
};
|
||||
DEFINE_ENUM_FLAG_OPERATORS(Dml::SupportedTensorDataTypes);
|
||||
|
|
@ -64,7 +65,7 @@ struct OperatorRegistrationInformation
|
|||
gsl::span<const SupportedTensorDataTypes> supportedTensorDataTypes;
|
||||
DmGraphSupport DmGraphSupport;
|
||||
|
||||
std::vector<uint32_t> requiresFloatFormatsExceptConstInputs;
|
||||
std::vector<uint32_t> requiredConstantCpuInputs;
|
||||
|
||||
// For use by operators such as Sum, which may require multiple calls to DML, in which case they
|
||||
// can't be represented as nodes in an optimized graph yet.
|
||||
|
|
@ -102,7 +103,8 @@ DML_OP_EXTERN_CREATION_FUNCTION(Concat);
|
|||
DML_OP_EXTERN_CREATION_FUNCTION(Slice7);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Slice10);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Slice11);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Pad);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Pad7);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Pad11);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(SpaceToDepth);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(DepthToSpace);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Sqrt);
|
||||
|
|
@ -146,7 +148,9 @@ DML_OP_EXTERN_CREATION_FUNCTION(Gemm);
|
|||
DML_OP_EXTERN_CREATION_FUNCTION(Neg);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Crop);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(ImageScaler);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Upsample);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Upsample7);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Upsample9);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Upsample10);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Sigmoid);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(HardSigmoid);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Tanh);
|
||||
|
|
@ -169,7 +173,9 @@ DML_OP_EXTERN_CREATION_FUNCTION(MatMul);
|
|||
DML_OP_EXTERN_CREATION_FUNCTION(Cast);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(MemcpyFromHost);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(MemcpyToHost);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(TopK);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(TopK7);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(TopK10);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(TopK11);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Expand);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Cos);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Sin);
|
||||
|
|
@ -204,7 +210,8 @@ DML_OP_EXTERN_CREATION_FUNCTION(EyeLike);
|
|||
DML_OP_EXTERN_CREATION_FUNCTION(MaxUnpool);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Scatter9);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Scatter11);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Resize);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Resize10);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Resize11);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(ConstantOfShape);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(IsInf);
|
||||
DML_OP_EXTERN_CREATION_FUNCTION(Mod);
|
||||
|
|
@ -225,31 +232,35 @@ DML_OP_EXTERN_CREATION_FUNCTION(ConvInteger);
|
|||
|
||||
DML_OP_EXTERN_QUERY_FUNCTION(MaxPool);
|
||||
DML_OP_EXTERN_QUERY_FUNCTION(Slice);
|
||||
DML_OP_EXTERN_QUERY_FUNCTION(Resize);
|
||||
|
||||
const static char* const typeNameListDefault[1] = {"T"};
|
||||
const static char* const typeNameListTwo[2] = { "T1", "T2" };
|
||||
const static char* const typeNameListThree[3] = { "T1", "T2", "T3" };
|
||||
const static char* const typeNameListFour[4] = { "T1", "T2", "T3", "T4" };
|
||||
const static char* const typeNameListTopK[2] = { "T", "I" };
|
||||
const static char* const typeNameListLogicalComparison[2] = { "T", "T1" };
|
||||
const static char* const typeNameListT1T2[2] = { "T1", "T2" };
|
||||
const static char* const typeNameListConstantOfShape[2] = { "T1", "T2" };
|
||||
const static char* const typeNameListScatterGather[2] = { "T", "Tind" };
|
||||
const static char* const typeNameListScatterGatherND[1] = { "T" }; // Tind is curiously missing, only allowing 64-bit.
|
||||
const static char* const typeNameListSlice10[2] = { "T", "Tind" };
|
||||
const static char* const typeNameListQuantize[2] = { "T1", "T2" };
|
||||
const static char* const typeNameListWhere[2] = { "B", "T" };
|
||||
const static char* const typeNameListOneHot[3] = { "T1", "T2", "T3" };
|
||||
const static char* const typeNameListEyeLike[1] = { "T2" };
|
||||
const static SupportedTensorDataTypes supportedTypeListAll[1] = {SupportedTensorDataTypes::All};
|
||||
const static SupportedTensorDataTypes supportedTypeListFloat32[1] = {SupportedTensorDataTypes::Float32};
|
||||
const static SupportedTensorDataTypes supportedTypeListFloat16to32[1] = {SupportedTensorDataTypes::Float16to32};
|
||||
const static SupportedTensorDataTypes supportedTypeListFloat16to32Int32[1] = {SupportedTensorDataTypes::Float16to32 | SupportedTensorDataTypes::Int32 | SupportedTensorDataTypes::UInt32};
|
||||
const static SupportedTensorDataTypes supportedTypeListInt8to32[1] = {SupportedTensorDataTypes::Int8to32};
|
||||
const static SupportedTensorDataTypes supportedTypeListInt32to64AndFloat16to32[1] = {SupportedTensorDataTypes::Int32to64|SupportedTensorDataTypes::Float16to32};
|
||||
const static SupportedTensorDataTypes supportedTypeListNumericDefault[1] = { SupportedTensorDataTypes::NumericDefault };
|
||||
const static SupportedTensorDataTypes supportedTypeListAllScalars[1] = { SupportedTensorDataTypes::AllScalars };
|
||||
const static SupportedTensorDataTypes supportedTypeListBool[1] = {SupportedTensorDataTypes::Bool};
|
||||
const static SupportedTensorDataTypes supportedTypeListTopK[2] = {SupportedTensorDataTypes::Float16to32, SupportedTensorDataTypes::Int64};
|
||||
const static SupportedTensorDataTypes supportedTypeListTopK[2] = {SupportedTensorDataTypes::NumericDefault, SupportedTensorDataTypes::Int64};
|
||||
const static SupportedTensorDataTypes supportedTypeListIndices[1] = { SupportedTensorDataTypes::Int32|SupportedTensorDataTypes::Int64 };
|
||||
const static SupportedTensorDataTypes supportedTypeListCast[2] = { SupportedTensorDataTypes::AllScalars, SupportedTensorDataTypes::Scalars8to32 };
|
||||
const static SupportedTensorDataTypes supportedTypeListScatterGather[2] = { SupportedTensorDataTypes::NumericDefault, SupportedTensorDataTypes::Int32 | SupportedTensorDataTypes::Int64 };
|
||||
const static SupportedTensorDataTypes supportedTypeListScatterGatherND[1] = { SupportedTensorDataTypes::NumericDefault };
|
||||
const static SupportedTensorDataTypes supportedTypeListScalars8to32[1] = { SupportedTensorDataTypes::Scalars8to32 };
|
||||
const static SupportedTensorDataTypes supportedTypeListScatterGather[2] = { SupportedTensorDataTypes::Scalars8to32, SupportedTensorDataTypes::Int32 | SupportedTensorDataTypes::Int64 };
|
||||
const static SupportedTensorDataTypes supportedTypeListScatterGatherND[1] = { SupportedTensorDataTypes::Scalars8to32 };
|
||||
const static SupportedTensorDataTypes supportedTypeListSlice10[2] = { SupportedTensorDataTypes::NumericDefault, SupportedTensorDataTypes::Int32 | SupportedTensorDataTypes::Int64 };
|
||||
const static SupportedTensorDataTypes supportedTypeListQuantizeLinear[2] = { SupportedTensorDataTypes::Float32 | SupportedTensorDataTypes::Int32, SupportedTensorDataTypes::UInt8 | SupportedTensorDataTypes::Int8 };
|
||||
const static SupportedTensorDataTypes supportedTypeListDequantizeLinear[2] = { SupportedTensorDataTypes::Float32, SupportedTensorDataTypes::UInt8 | SupportedTensorDataTypes::Int8 | SupportedTensorDataTypes::Int32 };
|
||||
|
|
@ -257,12 +268,25 @@ const static SupportedTensorDataTypes supportedTypeListQuantize[2] = { Supported
|
|||
const static SupportedTensorDataTypes supportedTypeListIsNan[2] = { SupportedTensorDataTypes::Float16to32, SupportedTensorDataTypes::Bool };
|
||||
const static SupportedTensorDataTypes supportedTypeListIsInf[2] = { SupportedTensorDataTypes::Float32, SupportedTensorDataTypes::Bool };
|
||||
const static SupportedTensorDataTypes supportedTypeListConstantOfShape[2] = { SupportedTensorDataTypes::Int32|SupportedTensorDataTypes::Int64, SupportedTensorDataTypes::Float16to32 };
|
||||
const static SupportedTensorDataTypes supportedTypeListWhere[2] = { SupportedTensorDataTypes::Bool, SupportedTensorDataTypes::Float16to32 };
|
||||
const static SupportedTensorDataTypes supportedTypeListOneHot[3] = /* indices, depth, values */ { SupportedTensorDataTypes::Int32to64, SupportedTensorDataTypes::AllScalars, SupportedTensorDataTypes::Float16to32 };
|
||||
const static SupportedTensorDataTypes supportedTypeListWhere[2] = { SupportedTensorDataTypes::Bool, SupportedTensorDataTypes::AllScalars };
|
||||
const static SupportedTensorDataTypes supportedTypeListOneHot[3] = /* indices, depth, values */ { SupportedTensorDataTypes::Int32to64, SupportedTensorDataTypes::AllScalars, SupportedTensorDataTypes::Scalars8to32 };
|
||||
const static SupportedTensorDataTypes supportedTypeListLogicalComparison7[2] = /* A&B,C */ { SupportedTensorDataTypes::Float16to32, SupportedTensorDataTypes::Bool };
|
||||
const static SupportedTensorDataTypes supportedTypeListLogicalComparison9[2] = /* A&B,C */ { SupportedTensorDataTypes::NumericDefault, SupportedTensorDataTypes::Bool };
|
||||
const static SupportedTensorDataTypes supportedTypeListSigned[1] = { SupportedTensorDataTypes::Float16to32 | SupportedTensorDataTypes::Int32 | SupportedTensorDataTypes::Int16 | SupportedTensorDataTypes::Int8 };
|
||||
const static SupportedTensorDataTypes supportedTypeListRange[1] = {SupportedTensorDataTypes::Int16|SupportedTensorDataTypes::Int32|SupportedTensorDataTypes::Float32};
|
||||
const static SupportedTensorDataTypes supportedTypeListInteger[3] = {SupportedTensorDataTypes::Int8|SupportedTensorDataTypes::UInt8, SupportedTensorDataTypes::Int8|SupportedTensorDataTypes::UInt8, SupportedTensorDataTypes::Int32 };
|
||||
const static SupportedTensorDataTypes supportedTypeListPadWithoutFloat16[1] = { SupportedTensorDataTypes::Int8to32 | SupportedTensorDataTypes::Float32 };
|
||||
const static SupportedTensorDataTypes supportedTypeListQLinearMatMul[3] = {
|
||||
SupportedTensorDataTypes::Int8|SupportedTensorDataTypes::UInt8,
|
||||
SupportedTensorDataTypes::Int8|SupportedTensorDataTypes::UInt8,
|
||||
SupportedTensorDataTypes::Int8|SupportedTensorDataTypes::UInt8
|
||||
};
|
||||
const static SupportedTensorDataTypes supportedTypeListQLinearConv[4] = {
|
||||
SupportedTensorDataTypes::Int8|SupportedTensorDataTypes::UInt8,
|
||||
SupportedTensorDataTypes::Int8|SupportedTensorDataTypes::UInt8,
|
||||
SupportedTensorDataTypes::Int8|SupportedTensorDataTypes::UInt8,
|
||||
SupportedTensorDataTypes::Int32
|
||||
};
|
||||
|
||||
// Define a single row of registration information.
|
||||
#define REG_INFO(version, operatorName, ...) \
|
||||
|
|
@ -295,24 +319,21 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl
|
|||
|
||||
// Deep Learning Standard Layers
|
||||
{REG_INFO( 7, Conv, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, Conv, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, ConvTranspose, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, ConvTranspose, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, AveragePool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
#if 0
|
||||
// TODO:DwayneR add ceil mode https://microsoft.visualstudio.com/OS/_workitems/edit/24674310
|
||||
{REG_INFO( 10, AveragePool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, AveragePool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
#endif
|
||||
{REG_INFO( 7, GlobalAveragePool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, MaxPool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 8, MaxPool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {}, std::nullopt, QueryMaxPool)},
|
||||
{REG_INFO( 10, MaxPool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {}, std::nullopt, QueryMaxPool)},
|
||||
#if 0
|
||||
// TODO:DwayneR add ceil mode https://microsoft.visualstudio.com/OS/_workitems/edit/24674310
|
||||
{REG_INFO( 11, MaxPool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {}, std::nullopt, QueryMaxPool)},
|
||||
#endif
|
||||
|
||||
{REG_INFO( 7, GlobalMaxPool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, LpPool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, LpPool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, GlobalLpPool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, MaxRoiPool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, InstanceNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
|
|
@ -320,6 +341,7 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl
|
|||
{REG_INFO( 9, BatchNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)}, // v9 just removes 'spatial' attribute.
|
||||
{REG_INFO( 7, LRN, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, MeanVarianceNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, MeanVarianceNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, LpNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, RNN, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::NotSupported)},
|
||||
{REG_INFO( 7, GRU, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::NotSupported)},
|
||||
|
|
@ -335,17 +357,12 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl
|
|||
{REG_INFO_VER( 7, Slice, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)},
|
||||
{REG_INFO_VER( 10, Slice, typeNameListSlice10, supportedTypeListSlice10, DmGraphSupport::Supported, {1, 2, 3, 4}, std::nullopt, QuerySlice)}, // Adds negative axes.
|
||||
{REG_INFO_VER( 11, Slice, typeNameListSlice10, supportedTypeListSlice10, DmGraphSupport::Supported, {1, 2, 3, 4}, std::nullopt, QuerySlice)},
|
||||
{REG_INFO( 7, Pad, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
#if 0 // TODO:NickFe Pads and Value are inputs. https://microsoft.visualstudio.com/OS/_workitems/edit/24674281, https://github.com/onnx/onnx/blob/master/docs/Changelog.md#Pad-11
|
||||
{REG_INFO( 11, Pad, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
#endif
|
||||
{REG_INFO( 7, SpaceToDepth, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, DepthToSpace, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
#if 0
|
||||
// TODO:DwayneR Update operator DepthToSpace-11 - added column-row-depth shuffle order mode 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_VER( 7, Pad, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)},
|
||||
{REG_INFO_VER( 11, Pad, typeNameListDefault, supportedTypeListPadWithoutFloat16, DmGraphSupport::Supported, {1, 2} /*pads, value*/)}, // https://microsoft.visualstudio.com/OS/_workitems/edit/26007728
|
||||
{REG_INFO( 7, SpaceToDepth, typeNameListDefault, supportedTypeListScalars8to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, DepthToSpace, typeNameListDefault, supportedTypeListScalars8to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, DepthToSpace, typeNameListDefault, supportedTypeListScalars8to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Tile, typeNameListDefault, supportedTypeListScalars8to32, 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)},
|
||||
|
|
@ -356,7 +373,7 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl
|
|||
{REG_INFO_VER( 11, Scatter, typeNameListScatterGather, supportedTypeListScatterGather, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, ScatterElements, typeNameListScatterGather, supportedTypeListScatterGather, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, ScatterND, typeNameListScatterGatherND, supportedTypeListScatterGatherND, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, EyeLike, typeNameListEyeLike, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, EyeLike, typeNameListEyeLike, supportedTypeListScalars8to32, DmGraphSupport::Supported)},
|
||||
|
||||
// Data reorganization that merely changes the dimensions while keeping the data identical.
|
||||
{REG_INFO_ID( 7, Identity, typeNameListDefault, supportedTypeListAllScalars, DmGraphSupport::Supported)},
|
||||
|
|
@ -380,10 +397,10 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl
|
|||
{REG_INFO( 7, Floor, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{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)},
|
||||
{REG_INFO( 7, Div, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Add, typeNameListDefault, supportedTypeListFloat16to32Int32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Sub, typeNameListDefault, supportedTypeListFloat16to32Int32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Mul, typeNameListDefault, supportedTypeListFloat16to32Int32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Div, typeNameListDefault, supportedTypeListFloat16to32Int32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Sum, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {}, 2)},
|
||||
{REG_INFO( 8, Sum, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {}, 2)},
|
||||
{REG_INFO( 7, Mean, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {}, 2)},
|
||||
|
|
@ -399,12 +416,12 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl
|
|||
{REG_INFO( 7, Asin, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Atan, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Affine, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 10, QuantizeLinear, typeNameListQuantize, supportedTypeListQuantizeLinear, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 10, DequantizeLinear, typeNameListQuantize, supportedTypeListDequantizeLinear, DmGraphSupport::Supported)},
|
||||
{REG_INFO_MS( 1, QuantizeLinear, typeNameListQuantize, supportedTypeListQuantize, DmGraphSupport::Supported)},
|
||||
{REG_INFO_MS( 1, DequantizeLinear, typeNameListQuantize, supportedTypeListQuantize, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 10, QuantizeLinear, typeNameListTwo, supportedTypeListQuantizeLinear, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 10, DequantizeLinear, typeNameListTwo, supportedTypeListDequantizeLinear, DmGraphSupport::Supported)},
|
||||
{REG_INFO_MS( 1, QuantizeLinear, typeNameListTwo, supportedTypeListQuantize, DmGraphSupport::Supported)},
|
||||
{REG_INFO_MS( 1, DequantizeLinear, typeNameListTwo, supportedTypeListQuantize, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, Sign, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, IsNan, typeNameListT1T2, supportedTypeListIsNan, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, IsNan, typeNameListTwo, supportedTypeListIsNan, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, Sinh, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, Cosh, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, Asinh, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
|
|
@ -432,10 +449,10 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl
|
|||
{REG_INFO( 11, ReduceMax, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, ReduceMin, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, ReduceMin, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, ArgMax, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, ArgMax, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, ArgMin, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, ArgMin, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, ArgMax, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, ArgMax, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, ArgMin, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, ArgMin, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Gemm, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, Gemm, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, Gemm, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
|
|
@ -451,14 +468,16 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl
|
|||
{REG_INFO( 7, Or, typeNameListDefault, supportedTypeListBool, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Xor, typeNameListDefault, supportedTypeListBool, DmGraphSupport::Supported)},
|
||||
|
||||
// Imaging Operators
|
||||
// Imaging Operators
|
||||
{REG_INFO( 7, Crop, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, ImageScaler, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Upsample, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, Upsample, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {1})},
|
||||
{REG_INFO( 10, Resize, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {1})},
|
||||
|
||||
// Activation Functions
|
||||
{REG_INFO_VER( 7, Upsample, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO_VER( 9, Upsample, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {1} /*scales*/)},
|
||||
{REG_INFO_VER( 10, Upsample, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {1} /*scales*/)},
|
||||
{REG_INFO_VER( 10, Resize, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {1} /*scales*/)},
|
||||
{REG_INFO_VER( 11, Resize, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {1, 2, 3} /*roi, scales, sizes*/, std::nullopt, QueryResize)},
|
||||
|
||||
// Activation Functions
|
||||
{REG_INFO( 7, Sigmoid, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, HardSigmoid, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Tanh, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
|
|
@ -482,25 +501,21 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl
|
|||
{REG_INFO( 7, ParametricSoftplus, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Dropout, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, Shrink, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)},
|
||||
|
||||
// Uncategorized
|
||||
|
||||
// Uncategorized
|
||||
{REG_INFO( 7, MatMul, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, MatMul, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Cast, typeNameListT1T2, supportedTypeListCast, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, Cast, typeNameListT1T2, supportedTypeListCast, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, Cast, typeNameListTwo, supportedTypeListCast, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 9, Cast, typeNameListTwo, supportedTypeListCast, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 7, MemcpyFromHost, typeNameListDefault, supportedTypeListAll)},
|
||||
{REG_INFO( 7, MemcpyToHost, typeNameListDefault, supportedTypeListAll)},
|
||||
{REG_INFO( 7, TopK, typeNameListTopK, supportedTypeListTopK, DmGraphSupport::Supported)},
|
||||
#if 0
|
||||
// TODO:Dwayner https://microsoft.visualstudio.com/OS/_workitems/edit/24674287
|
||||
{REG_INFO( 10, TopK, typeNameListTopK, supportedTypeListTopK, DmGraphSupport::Supported)},
|
||||
// TODO:Dwayner https://microsoft.visualstudio.com/OS/_workitems/edit/24671996
|
||||
{REG_INFO( 11, TopK, typeNameListTopK, supportedTypeListTopK, DmGraphSupport::Supported)},
|
||||
#endif
|
||||
{REG_INFO( 9, OneHot, typeNameListOneHot, supportedTypeListOneHot, DmGraphSupport::Supported, {1})},
|
||||
{REG_INFO( 11, OneHot, typeNameListOneHot, supportedTypeListOneHot, DmGraphSupport::Supported, {1})},
|
||||
|
||||
// Fused operators
|
||||
{REG_INFO_VER( 7, TopK, typeNameListTopK, supportedTypeListTopK, DmGraphSupport::Supported)},
|
||||
{REG_INFO_VER( 10, TopK, typeNameListTopK, supportedTypeListTopK, DmGraphSupport::Supported, {1})},
|
||||
{REG_INFO_VER( 11, TopK, typeNameListTopK, supportedTypeListTopK, DmGraphSupport::Supported, {1})},
|
||||
{REG_INFO( 9, OneHot, typeNameListThree, supportedTypeListOneHot, DmGraphSupport::Supported, {1})},
|
||||
{REG_INFO( 11, OneHot, typeNameListThree, supportedTypeListOneHot, DmGraphSupport::Supported, {1})},
|
||||
|
||||
// Fused operators
|
||||
{REG_INFO_MSDML(1, FusedConv, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO_MSDML(1, FusedConvTranspose, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO_MSDML(1, FusedInstanceNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
|
|
@ -511,7 +526,7 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl
|
|||
{REG_INFO_MSDML(1, FusedAdd, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO_MSDML(1, FusedSum, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {}, 2)},
|
||||
|
||||
{REG_INFO( 10, IsInf, typeNameListT1T2, supportedTypeListIsInf, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 10, IsInf, typeNameListTwo, supportedTypeListIsInf, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 10, Mod, typeNameListDefault, supportedTypeListNumericDefault, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, BitShift, typeNameListDefault, supportedTypeListInt8to32, DmGraphSupport::Supported)},
|
||||
{REG_INFO( 11, Round, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
|
|
@ -521,32 +536,12 @@ const static OperatorRegistrationInformation operatorRegistrationInformationTabl
|
|||
|
||||
{REG_INFO( 9, MaxUnpool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {2})},
|
||||
{REG_INFO( 11, MaxUnpool, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {2})}, // 11 is identical to 9.
|
||||
#if 0 // TODO:DwayneR
|
||||
{REG_INFO( 11, Resize, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported, {1})},
|
||||
#endif
|
||||
|
||||
#if 0 // TODO:NickFe
|
||||
{REG_INFO( 11, QLinearConv, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
// T1 : tensor(int8), tensor(uint8) - Constrain input type to 8-bit integer tensor.
|
||||
// T2 : tensor(int8), tensor(uint8) - Constrain filter type to 8-bit integer tensor.
|
||||
// T3 : tensor(int8), tensor(uint8) - Constrain output type to 8-bit integer tensor.
|
||||
// T4 : tensor(int32) - Constrain bias type to 32-bit integer tensor.
|
||||
{REG_INFO( 11, QLinearMatMul, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
// T1 : tensor(int8), tensor(uint8) - Constrain input a and its zero point data type to 8-bit integer tensor.
|
||||
// T2 : tensor(int8), tensor(uint8) - Constrain input b and its zero point data type to 8-bit integer tensor.
|
||||
// T3 : tensor(int8), tensor(uint8) - Constrain output y and its zero point data type to 8-bit integer tensor.
|
||||
{REG_INFO( 11, DynamicQuantizeLinear, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
//T1 : tensor(float) - Constrain 'x' to float tensor.
|
||||
//T2 : tensor(uint8)
|
||||
{REG_INFO( 11, MatMulInteger, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
//T1 : tensor(int8), tensor(uint8) - Constrain input A data type to 8-bit integer tensor.
|
||||
//T2 : tensor(int8), tensor(uint8) - Constrain input B data type to 8-bit integer tensor.
|
||||
//T3 : tensor(int32) - Constrain output Y data type as 32-bit integer tensor.
|
||||
{REG_INFO( 11, ConvInteger, typeNameListDefault, supportedTypeListFloat16to32, DmGraphSupport::Supported)},
|
||||
// T1 : tensor(int8), tensor(uint8) - Constrain input x and its zero point data type to 8-bit integer tensor.
|
||||
// T2 : tensor(int8), tensor(uint8) - Constrain input w and its zero point data type to 8-bit integer tensor.
|
||||
// T3 : tensor(int32) - Constrain output y data type to 32-bit integer tensor.
|
||||
#endif
|
||||
{REG_INFO( 10, QLinearConv, typeNameListFour, supportedTypeListQLinearConv, DmGraphSupport::NotSupported)},
|
||||
{REG_INFO( 10, QLinearMatMul, typeNameListThree, supportedTypeListQLinearMatMul, DmGraphSupport::NotSupported)},
|
||||
{REG_INFO( 10, MatMulInteger, typeNameListThree, supportedTypeListInteger, DmGraphSupport::NotSupported)},
|
||||
{REG_INFO( 10, ConvInteger, typeNameListThree, supportedTypeListInteger, DmGraphSupport::NotSupported)},
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
|
@ -649,8 +644,8 @@ void RegisterDmlOperators(IMLOperatorRegistry* registry)
|
|||
kernelSupportsGraph, // supportsGraph
|
||||
information.requiredInputCountForDmlGraphSupport ? &(*information.requiredInputCountForDmlGraphSupport) : nullptr,
|
||||
information.requiresFloatFormatsForGraph,
|
||||
information.requiresFloatFormatsExceptConstInputs.empty() ? nullptr : information.requiresFloatFormatsExceptConstInputs.data(),
|
||||
static_cast<uint32_t>(information.requiresFloatFormatsExceptConstInputs.size())
|
||||
information.requiredConstantCpuInputs.empty() ? nullptr : information.requiredConstantCpuInputs.data(),
|
||||
static_cast<uint32_t>(information.requiredConstantCpuInputs.size())
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -348,6 +348,16 @@ namespace Dml
|
|||
return dmlAxis;
|
||||
}
|
||||
|
||||
void GetDmlAdjustedAxes(gsl::span<const int32_t> onnxAxes, uint32_t onnxDimCount, uint32_t dmlDimCount, std::vector<uint32_t>& dmlAxes)
|
||||
{
|
||||
dmlAxes.clear();
|
||||
dmlAxes.reserve(onnxAxes.size());
|
||||
for (auto& axis : onnxAxes)
|
||||
{
|
||||
dmlAxes.push_back(GetDmlAdjustedAxis(axis, onnxDimCount, dmlDimCount));
|
||||
}
|
||||
}
|
||||
|
||||
DML_INTERPOLATION_MODE MapStringToInteropolationMode(std::string_view mode)
|
||||
{
|
||||
// The ONNX modes are "nearest" and "linear." Other modes exist for compatibility,
|
||||
|
|
@ -365,4 +375,20 @@ namespace Dml
|
|||
}
|
||||
}
|
||||
|
||||
DML_DEPTH_SPACE_ORDER MapStringToDepthSpaceMode(std::string_view mode)
|
||||
{
|
||||
if (mode == "DCR")
|
||||
{
|
||||
return DML_DEPTH_SPACE_ORDER_DEPTH_COLUMN_ROW;
|
||||
}
|
||||
else if (mode == "CRD")
|
||||
{
|
||||
return DML_DEPTH_SPACE_ORDER_COLUMN_ROW_DEPTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
ML_INVALID_ARGUMENT("Unknown depth space mode.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Dml
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@ namespace Dml
|
|||
|
||||
uint32_t GetDmlAdjustedAxis(int32_t onnxAxis, uint32_t onnxDimCount, uint32_t dmlDimCount);
|
||||
|
||||
void GetDmlAdjustedAxes(/*inout*/ gsl::span<const int32_t> axes, uint32_t onnxDimCount, uint32_t dmlDimCount, std::vector<uint32_t>& dmlAxes);
|
||||
|
||||
DML_INTERPOLATION_MODE MapStringToInteropolationMode(std::string_view mode);
|
||||
|
||||
DML_DEPTH_SPACE_ORDER MapStringToDepthSpaceMode(std::string_view mode);
|
||||
|
||||
} // namespace Dml
|
||||
|
|
@ -22,7 +22,9 @@ namespace AttrName
|
|||
static constexpr const char* Broadcast = "broadcast";
|
||||
static constexpr const char* CeilMode = "ceil_mode";
|
||||
static constexpr const char* Clip = "clip";
|
||||
static constexpr const char* CoordinateTransformationMode = "coordinate_transformation_mode";
|
||||
static constexpr const char* CountIncludePad = "count_include_pad";
|
||||
static constexpr const char* CubicCoefficientA = "cubic_coeff_a";
|
||||
static constexpr const char* DetectPositive = "detect_positive";
|
||||
static constexpr const char* DetectNegative = "detect_negative";
|
||||
static constexpr const char* Dilations = "dilations";
|
||||
|
|
@ -30,11 +32,13 @@ namespace AttrName
|
|||
static constexpr const char* Dtype = "dtype";
|
||||
static constexpr const char* Ends = "ends";
|
||||
static constexpr const char* Epsilon = "epsilon";
|
||||
static constexpr const char* ExcludeOutside = "exclude_outside";
|
||||
static constexpr const char* Exclusive = "exclusive";
|
||||
static constexpr const char* Exponent = "exponent";
|
||||
static constexpr const char* ExtrapolationValue = "extrapolation_value";
|
||||
static constexpr const char* Fmod = "fmod";
|
||||
static constexpr const char* Gamma = "gamma";
|
||||
static constexpr const char* Group = "group";
|
||||
static constexpr const char* Exclusive = "exclusive";
|
||||
static constexpr const char* HeightScale = "height_scale";
|
||||
static constexpr const char* HiddenSize = "hidden_size";
|
||||
static constexpr const char* High = "high";
|
||||
|
|
@ -44,11 +48,13 @@ namespace AttrName
|
|||
static constexpr const char* KernelShape = "kernel_shape";
|
||||
static constexpr const char* LinearBeforeReset = "linear_before_reset";
|
||||
static constexpr const char* Lambda = "lambd"; // Deliberate typo to match ONNX spec.
|
||||
static constexpr const char* Largest = "largest";
|
||||
static constexpr const char* Low = "low";
|
||||
static constexpr const char* Max = "max";
|
||||
static constexpr const char* Mean = "mean";
|
||||
static constexpr const char* Min = "min";
|
||||
static constexpr const char* Mode = "mode";
|
||||
static constexpr const char* NearestMode = "nearest_mode";
|
||||
static constexpr const char* NormalizeVariance = "normalize_variance";
|
||||
static constexpr const char* P = "p";
|
||||
static constexpr const char* OutputShape = "output_shape";
|
||||
|
|
@ -62,6 +68,7 @@ namespace AttrName
|
|||
static constexpr const char* Seed = "seed";
|
||||
static constexpr const char* Shape = "shape";
|
||||
static constexpr const char* Size = "size";
|
||||
static constexpr const char* Sorted = "sorted";
|
||||
static constexpr const char* Spatial = "spatial";
|
||||
static constexpr const char* SpatialScale = "spatial_scale";
|
||||
static constexpr const char* Split = "split";
|
||||
|
|
|
|||
|
|
@ -76,6 +76,32 @@ namespace OperatorHelper
|
|||
}
|
||||
}
|
||||
|
||||
void ReadCpuLocalTensorIntoFloat32(
|
||||
const MLOperatorTensor& tensor,
|
||||
std::vector<float>& result
|
||||
)
|
||||
{
|
||||
result.clear();
|
||||
ML_CHECK_VALID_ARGUMENT(tensor.IsCpuData(), "Tensor must be CPU Tensor.");
|
||||
|
||||
const std::vector<uint32_t>& tensorDimensions = tensor.GetShape();
|
||||
const uint32_t elementCount = ComputeElementCountFromDimensions(tensorDimensions);
|
||||
|
||||
switch (tensor.GetTensorDataType())
|
||||
{
|
||||
case MLOperatorTensorDataType::Float:
|
||||
{
|
||||
const float* data = tensor.GetData<float>();
|
||||
result.assign(data, data + elementCount);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ML_INVALID_ARGUMENT("Expecting CPU local tensor of type float32.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DowncastDimensions(gsl::span<const int64_t> inputDimensions, std::vector<DimensionType>& outputDimensions)
|
||||
{
|
||||
outputDimensions.reserve(inputDimensions.size());
|
||||
|
|
@ -197,8 +223,12 @@ namespace OperatorHelper
|
|||
|
||||
ML_CHECK_VALID_ARGUMENT(kernelLength <= paddedLength, "kernelLength must be < paddedLength.");
|
||||
ML_CHECK_VALID_ARGUMENT(args.strides[dim] != 0, "strides must be non-zero.");
|
||||
uint32_t stride = args.strides[dim];
|
||||
uint32_t strideableOutputLength = paddedLength - kernelLength;
|
||||
uint32_t outputLength = 1 + (strideableOutputLength / stride)
|
||||
+ (args.useCeilingOutputShape && (strideableOutputLength % stride != 0));
|
||||
|
||||
outputDimensions[dimOffset + dim] = (1 + (paddedLength - kernelLength) / args.strides[dim]);
|
||||
outputDimensions[dimOffset + dim] = outputLength;
|
||||
}
|
||||
|
||||
return outputDimensions;
|
||||
|
|
@ -355,6 +385,8 @@ namespace OperatorHelper
|
|||
std::fill(args.outputPadding, args.outputPadding + spatialDimensionCount, 0);
|
||||
}
|
||||
|
||||
args.useCeilingOutputShape = kernelInfo.GetOptionalAttribute<bool>(AttrName::CeilMode, 0);
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
|
|
@ -407,6 +439,33 @@ namespace OperatorHelper
|
|||
args.endPadding[dim] = padding - args.startPadding[dim];
|
||||
}
|
||||
}
|
||||
|
||||
void MatMulShapeMapping(
|
||||
std::vector<DimensionType>& inputShape0,
|
||||
std::vector<DimensionType>& inputShape1,
|
||||
std::vector<DimensionType>& outputShape)
|
||||
{
|
||||
// Get the padded input shapes and undo the effect of padding removal from the output shape
|
||||
if (inputShape1.size() == 1)
|
||||
{
|
||||
inputShape1.push_back(1);
|
||||
outputShape.push_back(1);
|
||||
}
|
||||
|
||||
if (inputShape0.size() == 1)
|
||||
{
|
||||
inputShape0.insert(inputShape0.begin(), 1);
|
||||
outputShape.insert(outputShape.end() - 1, 1);
|
||||
}
|
||||
|
||||
// Remove the batch dimensions from each input, then re-add the broadcasted batch dimensions
|
||||
// based on the output shape
|
||||
inputShape0.erase(inputShape0.begin(), inputShape0.end() - 2);
|
||||
inputShape1.erase(inputShape1.begin(), inputShape1.end() - 2);
|
||||
|
||||
inputShape0.insert(inputShape0.begin(), outputShape.begin(), outputShape.end() - 2);
|
||||
inputShape1.insert(inputShape1.begin(), outputShape.begin(), outputShape.end() - 2);
|
||||
}
|
||||
|
||||
std::vector<EdgeShapes> GetOutputShapeAsInputShapeHelper::GetOutputShapes(const MLShapeInferenceContext& shapeInfo) const
|
||||
{
|
||||
|
|
@ -550,15 +609,13 @@ namespace OperatorHelper
|
|||
return edgeShapes;
|
||||
}
|
||||
|
||||
std::vector<EdgeShapes> SliceHelperBase::GetOutputShapes(const MLShapeInferenceContext& shapeInfo) const
|
||||
std::vector<EdgeShapes> SliceHelper::GetOutputShapes(const MLShapeInferenceContext& shapeInfo) const
|
||||
{
|
||||
return { m_outputDimensions };
|
||||
}
|
||||
|
||||
void PaddingHelper::Initialize(const MLOperatorAttributes& operatorAttributes)
|
||||
void PaddingHelper::Initialize(const MLOperatorAttributes& operatorAttributes, gsl::span<int32_t> padding, uint32_t opsetVersion)
|
||||
{
|
||||
// Convert padding.
|
||||
std::vector<int> padding = operatorAttributes.GetOptionalAttributeVectorInt32(AttrName::Pads);
|
||||
ML_CHECK_VALID_ARGUMENT(padding.size() % 2 == 0, "Padding must be even count, including begin/end pairs.");
|
||||
|
||||
uint32_t dimCount = gsl::narrow_cast<uint32_t>(padding.size() / 2);
|
||||
|
|
@ -770,7 +827,7 @@ namespace OperatorHelper
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<EdgeShapes> MatMulHelper::GetOutputShapes(const MLShapeInferenceContext& shapeInfo) const
|
||||
std::vector<EdgeShapes> MatMulHelperBase::GetOutputShapes(const MLShapeInferenceContext& shapeInfo) const
|
||||
{
|
||||
ML_CHECK_VALID_ARGUMENT(shapeInfo.GetInputCount() >= 2);
|
||||
|
||||
|
|
@ -782,8 +839,8 @@ namespace OperatorHelper
|
|||
// * If the first argument is 1 - D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
|
||||
// * If the second argument is 1 - D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.
|
||||
|
||||
auto inputShape0 = shapeInfo.GetInputTensorShape(0);
|
||||
auto inputShape1 = shapeInfo.GetInputTensorShape(1);
|
||||
auto inputShape0 = shapeInfo.GetInputTensorShape(m_aTensorIndex);
|
||||
auto inputShape1 = shapeInfo.GetInputTensorShape(m_bTensorIndex);
|
||||
ML_CHECK_VALID_ARGUMENT(inputShape0.size() >= 1);
|
||||
ML_CHECK_VALID_ARGUMENT(inputShape1.size() >= 1);
|
||||
|
||||
|
|
@ -1286,48 +1343,40 @@ namespace OperatorHelper
|
|||
}
|
||||
|
||||
void ResizeHelper::Initialize(
|
||||
const MLOperatorAttributes& operatorAttributes,
|
||||
gsl::span<const DimensionType> inputDimensions
|
||||
)
|
||||
{
|
||||
m_inputDimensions.assign(inputDimensions.begin(), inputDimensions.end());
|
||||
m_scales = operatorAttributes.GetOptionalAttribute<std::vector<float>>(AttrName::Scales, std::vector<float>());
|
||||
ML_CHECK_VALID_ARGUMENT(inputDimensions.size() == m_scales.size(), "Input dimensions and scales must have same rank.");
|
||||
InitializeOutputDimensions(m_scales, inputDimensions);
|
||||
}
|
||||
|
||||
void ResizeHelper::Initialize(
|
||||
const MLOperatorTensor& scalesTensor,
|
||||
gsl::span<const DimensionType> inputDimensions
|
||||
)
|
||||
{
|
||||
m_inputDimensions.assign(inputDimensions.begin(), inputDimensions.end());
|
||||
|
||||
// Read the input shape and scale factors.
|
||||
const std::vector<uint32_t> scalesTensorDimensions = scalesTensor.GetShape();
|
||||
ML_CHECK_VALID_ARGUMENT(scalesTensorDimensions.size() == 1, "Resize's scales tensor must be 1D.");
|
||||
size_t dimCount = scalesTensorDimensions[0];
|
||||
ML_CHECK_VALID_ARGUMENT(inputDimensions.size() == dimCount, "Input dimensions and scales must have same rank.");
|
||||
|
||||
ML_CHECK_VALID_ARGUMENT(scalesTensor.IsCpuData(), "Resize's scales tensor must be CPU Tensor.");
|
||||
const float* scalesData = scalesTensor.GetData<float>();
|
||||
m_scales.assign(scalesData, scalesData + dimCount);
|
||||
|
||||
InitializeOutputDimensions(m_scales, inputDimensions);
|
||||
}
|
||||
|
||||
void ResizeHelper::InitializeOutputDimensions(
|
||||
gsl::span<const float> scales,
|
||||
gsl::span<const DimensionType> inputDimensions
|
||||
gsl::span<const int32_t> outputSizes
|
||||
)
|
||||
{
|
||||
assert(m_outputDimensions.empty());
|
||||
ML_CHECK_VALID_ARGUMENT(m_scales.empty() || outputSizes.empty(), "scales and roi cannot both be present.");
|
||||
|
||||
for (size_t i = 0, rank = scales.size(); i < rank; ++i)
|
||||
const size_t rank = m_inputDimensions.size();
|
||||
|
||||
if (outputSizes.empty())
|
||||
{
|
||||
float scale = m_scales[i];
|
||||
ML_CHECK_VALID_ARGUMENT(scale > FLT_EPSILON, "Scale values should be positive.");
|
||||
m_outputDimensions.push_back(gsl::narrow_cast<uint32_t>(floor(inputDimensions[i] * scale)));
|
||||
// Compute output size from scales and normalized region of interest (each axis 0 to 1).
|
||||
ML_CHECK_VALID_ARGUMENT(m_scales.size() == rank, "The 'scales' parameter must have same rank as input dimensions.");
|
||||
ML_CHECK_VALID_ARGUMENT(m_regionOfInterest.empty() || m_regionOfInterest.size() == rank * 2, "The 'roi' parameter must have two values for each input dimension.");
|
||||
|
||||
for (size_t i = 0; i < rank; ++i)
|
||||
{
|
||||
float scale = m_scales[i];
|
||||
ML_CHECK_VALID_ARGUMENT(scale > FLT_EPSILON, "Scale values should be positive.");
|
||||
float roiRange = m_regionOfInterest.empty() ? 1.0f : m_regionOfInterest[i + rank] - m_regionOfInterest[i];
|
||||
m_outputDimensions.push_back(gsl::narrow_cast<uint32_t>(floor(m_inputDimensions[i] * roiRange * scale)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Determine scales from output / input ratio.
|
||||
ML_CHECK_VALID_ARGUMENT(outputSizes.size() == rank, "Input dimensions and 'sizes' must have same rank.");
|
||||
|
||||
m_scales.resize(rank);
|
||||
for (size_t i = 0; i < rank; ++i)
|
||||
{
|
||||
float scale = float(outputSizes[i]) / std::max(m_inputDimensions[i], 1u);
|
||||
m_scales[i] = scale;
|
||||
m_outputDimensions.push_back(gsl::narrow_cast<uint32_t>(outputSizes[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ int64_t ReadScalarTensorCastToInt64(const MLOperatorTensor& tensor);
|
|||
double ReadScalarTensorCastToFloat64(const MLOperatorTensor& tensor);
|
||||
|
||||
void ReadCpuLocalTensorIntoInt32(const MLOperatorTensor& tensor, std::vector<int32_t>& result);
|
||||
void ReadCpuLocalTensorIntoFloat32(const MLOperatorTensor& tensor, std::vector<float>& result);
|
||||
|
||||
class EdgeShapes {
|
||||
public:
|
||||
|
|
@ -128,9 +129,17 @@ struct KernelArgs {
|
|||
uint32_t endPadding[NcdhwSpatialDimensionCount];
|
||||
uint32_t outputPadding[NcdhwSpatialDimensionCount];
|
||||
|
||||
KernelArgs(uint32_t spatialDimensionCount) : autoPad(false),
|
||||
autoPadSameUpper(false),
|
||||
spatialDimensionCount(spatialDimensionCount) {
|
||||
// This is true if padding must be automatically computed based on input sizes.
|
||||
// ResolveAutoPadding must happen during Compute rather than initialization.
|
||||
// This is temporary until kernel initialization routine once Lotus can provide
|
||||
// sizes at operator initialization.
|
||||
bool autoPad = false;
|
||||
bool autoPadSameUpper = false;
|
||||
bool useCeilingOutputShape = false;
|
||||
uint32_t spatialDimensionCount = 0;
|
||||
|
||||
KernelArgs(uint32_t spatialDimensionCount) : spatialDimensionCount(spatialDimensionCount)
|
||||
{
|
||||
ML_CHECK_VALID_ARGUMENT(spatialDimensionCount <= NcdhwSpatialDimensionCount);
|
||||
}
|
||||
|
||||
|
|
@ -165,14 +174,6 @@ struct KernelArgs {
|
|||
FillWithLeadingValues(kernelArgs.endPadding, this->endPadding, fillCount, 0u);
|
||||
FillWithLeadingValues(kernelArgs.outputPadding, this->outputPadding, fillCount, 0u);
|
||||
}
|
||||
|
||||
// This is true if padding must be automatically computed based on input sizes.
|
||||
// ResolveAutoPadding must happen during Compute rather than initialization.
|
||||
// This is temporary until kernel initialization routine once Lotus can provide
|
||||
// sizes at operator initialization.
|
||||
bool autoPad;
|
||||
bool autoPadSameUpper;
|
||||
uint32_t spatialDimensionCount;
|
||||
};
|
||||
|
||||
std::vector<DimensionType> InitializeKernelOutputDimensions(
|
||||
|
|
@ -194,6 +195,11 @@ void ResolveAutoPadding(
|
|||
KernelArgs& args,
|
||||
gsl::span<const DimensionType> inputDimensions);
|
||||
|
||||
void MatMulShapeMapping(
|
||||
std::vector<DimensionType>& inputShape0,
|
||||
std::vector<DimensionType>& inputShape1,
|
||||
std::vector<DimensionType>& outputShape);
|
||||
|
||||
class GetOutputShapeAsInputShapeHelper {
|
||||
public:
|
||||
// Info_t is used to obtain attributes which will be used for calculating the output shape later.
|
||||
|
|
@ -320,14 +326,15 @@ class ConvolutionHelperBase
|
|||
{
|
||||
public:
|
||||
enum FilterDims { K };
|
||||
enum InputTensor { X, Filter};
|
||||
enum InputDims { N, C, H, W };
|
||||
|
||||
public:
|
||||
// Info_t is used to obtain attributes which will be used for calculating the output shape later.
|
||||
template<typename Info_t, typename Shape_t>
|
||||
ConvolutionHelperBase(const Info_t& info, const Shape_t& shape, bool transpose, bool hasDynamicPads) :
|
||||
m_kernel(InitializeKernel(info, shape.GetInputTensorDimensionCount(0), shape.GetInputTensorShape(1)))
|
||||
ConvolutionHelperBase(const Info_t& info, const Shape_t& shape, bool transpose, bool hasDynamicPads, uint32_t inputTensorIndex, uint32_t filterTensorIndex) :
|
||||
m_kernel(InitializeKernel(info, shape.GetInputTensorDimensionCount(inputTensorIndex), shape.GetInputTensorShape(filterTensorIndex))),
|
||||
m_inputTensorIndex(inputTensorIndex),
|
||||
m_filterTensorIndex(filterTensorIndex)
|
||||
{
|
||||
m_groupCount = info.GetOptionalAttribute<uint32_t>(AttrName::Group, 1);
|
||||
|
||||
|
|
@ -350,8 +357,8 @@ public:
|
|||
|
||||
template <typename Shape_t>
|
||||
void InitializeKernelAndShapes(const Shape_t& shapeInfo) {
|
||||
const std::vector<DimensionType> inputDimensions = shapeInfo.GetInputTensorShape(0);
|
||||
const std::vector<DimensionType> filterDims = shapeInfo.GetInputTensorShape(1);
|
||||
const std::vector<DimensionType> inputDimensions = shapeInfo.GetInputTensorShape(m_inputTensorIndex);
|
||||
const std::vector<DimensionType> filterDims = shapeInfo.GetInputTensorShape(m_filterTensorIndex);
|
||||
|
||||
ML_CHECK_VALID_ARGUMENT(
|
||||
inputDimensions.size() >= 3 && inputDimensions.size() <= 5,
|
||||
|
|
@ -378,8 +385,8 @@ public:
|
|||
);
|
||||
}
|
||||
|
||||
const std::vector<DimensionType> inputDimensions = shapeInfo.GetInputTensorShape(0);
|
||||
const std::vector<DimensionType> filterDims = shapeInfo.GetInputTensorShape(1);
|
||||
const std::vector<DimensionType> inputDimensions = shapeInfo.GetInputTensorShape(m_inputTensorIndex);
|
||||
const std::vector<DimensionType> filterDims = shapeInfo.GetInputTensorShape(m_filterTensorIndex);
|
||||
|
||||
ML_CHECK_VALID_ARGUMENT(inputDimensions.size() > NonspatialDimensionCount, "Input dimensions must be >= 3");
|
||||
|
||||
|
|
@ -453,6 +460,8 @@ public:
|
|||
|
||||
protected:
|
||||
uint32_t m_groupCount;
|
||||
uint32_t m_inputTensorIndex;
|
||||
uint32_t m_filterTensorIndex;
|
||||
KernelArgs m_kernel;
|
||||
std::vector<EdgeShapes> m_outputShapes;
|
||||
};
|
||||
|
|
@ -461,21 +470,28 @@ class ConvHelper : public ConvolutionHelperBase
|
|||
{
|
||||
public:
|
||||
template<typename Info_t, typename Shape_t>
|
||||
ConvHelper(const Info_t& info, const Shape_t& shape) : ConvolutionHelperBase(info, shape, false, false) {}
|
||||
ConvHelper(const Info_t& info, const Shape_t& shape) : ConvolutionHelperBase(info, shape, false, false, 0, 1) {}
|
||||
};
|
||||
|
||||
class ConvTransposeHelper : public ConvolutionHelperBase
|
||||
{
|
||||
public:
|
||||
template<typename Info_t, typename Shape_t>
|
||||
ConvTransposeHelper(const Info_t& info, const Shape_t& shape) : ConvolutionHelperBase(info, shape, true, false) {}
|
||||
ConvTransposeHelper(const Info_t& info, const Shape_t& shape) : ConvolutionHelperBase(info, shape, true, false, 0, 1) {}
|
||||
};
|
||||
|
||||
class ConvTransposeWithDynamicPadsHelper : public ConvolutionHelperBase
|
||||
{
|
||||
public:
|
||||
template<typename Info_t, typename Shape_t>
|
||||
ConvTransposeWithDynamicPadsHelper(const Info_t& info, const Shape_t& shape) : ConvolutionHelperBase(info, shape, true, true) {}
|
||||
ConvTransposeWithDynamicPadsHelper(const Info_t& info, const Shape_t& shape) : ConvolutionHelperBase(info, shape, true, true, 0, 1) {}
|
||||
};
|
||||
|
||||
class QLinearConvHelper : public ConvolutionHelperBase
|
||||
{
|
||||
public:
|
||||
template<typename Info_t, typename Shape_t>
|
||||
QLinearConvHelper(const Info_t& info, const Shape_t& shape) : ConvolutionHelperBase(info, shape, false, false, 0, 3) {}
|
||||
};
|
||||
|
||||
class GemmHelper
|
||||
|
|
@ -547,7 +563,7 @@ class SplitHelper {
|
|||
std::vector<int> m_split;
|
||||
};
|
||||
|
||||
class SliceHelperBase
|
||||
class SliceHelper
|
||||
{
|
||||
public:
|
||||
template<typename Info_t>
|
||||
|
|
@ -657,7 +673,7 @@ public:
|
|||
// Info_t is used to obtain attributes which will be used for calculating the output shape later.
|
||||
// Shape_t is used to obtain input shape which will be used for adjusting attribute value.
|
||||
template<typename Info_t, typename Shape_t>
|
||||
SliceHelperBase(const Info_t& info, const Shape_t& shape, uint32_t opsetVersion)
|
||||
SliceHelper(const Info_t& info, const Shape_t& shape, uint32_t opsetVersion)
|
||||
{
|
||||
Initialize(info, shape.GetInputTensorShape(0), opsetVersion);
|
||||
}
|
||||
|
|
@ -671,31 +687,27 @@ public:
|
|||
std::vector<int32_t> m_strides;
|
||||
};
|
||||
|
||||
class SliceHelper : public SliceHelperBase
|
||||
{
|
||||
public:
|
||||
template<typename Info_t, typename Shape_t>
|
||||
SliceHelper(const Info_t& info, const Shape_t& shape) : SliceHelperBase(info, shape, 7) {}
|
||||
};
|
||||
|
||||
class Slice10Helper : public SliceHelperBase
|
||||
{
|
||||
public:
|
||||
template<typename Info_t, typename Shape_t>
|
||||
Slice10Helper(const Info_t& info, const Shape_t& shape) : SliceHelperBase(info, shape, 10) {}
|
||||
};
|
||||
|
||||
|
||||
class PaddingHelper
|
||||
{
|
||||
public:
|
||||
void Initialize(const MLOperatorAttributes& operatorAttributes);
|
||||
void Initialize(const MLOperatorAttributes& operatorAttributes, gsl::span<int32_t> padding, uint32_t opsetVersion);
|
||||
|
||||
// Info_t is used to obtain attributes which will be used for calculating the output shape later.
|
||||
// Shape_t is used to obtain input shape which will be used for adjusting attribute value.
|
||||
template <typename Info_t, typename Shape_t>
|
||||
PaddingHelper(const Info_t& info, const Shape_t& shape) {
|
||||
Initialize(info);
|
||||
PaddingHelper(const Info_t& info, const Shape_t& shape, uint32_t opsetVersion) {
|
||||
std::vector<int32_t> padding;
|
||||
if (opsetVersion >= 11)
|
||||
{
|
||||
MLOperatorTensor padsTensor = info.GetConstantInputTensor(1);
|
||||
ReadCpuLocalTensorIntoInt32(padsTensor, /*out*/ padding);
|
||||
}
|
||||
else
|
||||
{
|
||||
padding = info.GetOptionalAttributeVectorInt32(AttrName::Pads);
|
||||
}
|
||||
|
||||
Initialize(info, padding, opsetVersion);
|
||||
}
|
||||
|
||||
std::vector<EdgeShapes> GetOutputShapes(const MLShapeInferenceContext& shapeInfo) const;
|
||||
|
|
@ -705,6 +717,14 @@ public:
|
|||
std::vector<uint32_t> m_endPadding;
|
||||
};
|
||||
|
||||
template <typename OpsetHelper, uint32_t OpsetVersion>
|
||||
class VersionedOpsetHelper : public OpsetHelper
|
||||
{
|
||||
public:
|
||||
template<typename Info_t, typename Shape_t>
|
||||
VersionedOpsetHelper(const Info_t& info, const Shape_t& shape) : OpsetHelper(info, shape, OpsetVersion) {}
|
||||
};
|
||||
|
||||
class ReduceHelperBase {
|
||||
public:
|
||||
// Info_t is used to obtain attributes which will be used for calculating the output shape later.
|
||||
|
|
@ -748,39 +768,63 @@ class ReduceHelper : public ReduceHelperBase {
|
|||
ReduceHelper(const Info_t& info, const Shape_t& shape) : ReduceHelperBase(info, shape, true) {}
|
||||
};
|
||||
|
||||
class MatMulHelper {
|
||||
class MatMulHelperBase {
|
||||
public:
|
||||
// Info_t is used to obtain attributes which will be used for calculating the output shape later.
|
||||
// Shape_t is used to obtain input shape which will be used for adjusting attribute value.
|
||||
template <typename Info_t, typename Shape_t>
|
||||
MatMulHelper(const Info_t& info, const Shape_t& shape) {}
|
||||
MatMulHelperBase(const Info_t& info, const Shape_t& shape, uint32_t aTensorIndex, uint32_t bTensorIndex) :
|
||||
m_aTensorIndex(aTensorIndex),
|
||||
m_bTensorIndex(bTensorIndex)
|
||||
{}
|
||||
|
||||
std::vector<EdgeShapes> GetOutputShapes(const MLShapeInferenceContext& shapeInfo) const;
|
||||
protected:
|
||||
uint32_t m_aTensorIndex = 0;
|
||||
uint32_t m_bTensorIndex = 1;
|
||||
};
|
||||
|
||||
class MatMulHelper : public MatMulHelperBase
|
||||
{
|
||||
public:
|
||||
template<typename Info_t, typename Shape_t>
|
||||
MatMulHelper(const Info_t& info, const Shape_t& shape) : MatMulHelperBase(info, shape, 0, 1) {}
|
||||
};
|
||||
|
||||
class QLinearMatMulHelper : public MatMulHelperBase
|
||||
{
|
||||
public:
|
||||
template<typename Info_t, typename Shape_t>
|
||||
QLinearMatMulHelper(const Info_t& info, const Shape_t& shape) : MatMulHelperBase(info, shape, 0, 3) {}
|
||||
};
|
||||
|
||||
|
||||
class TopKHelper {
|
||||
public:
|
||||
// Info_t is used to obtain attributes which will be used for calculating the output shape later.
|
||||
// Shape_t is used to obtain input shape which will be used for adjusting attribute value.
|
||||
template <typename Info_t, typename Shape_t>
|
||||
TopKHelper(const Info_t& info, const Shape_t& shape) {
|
||||
m_k = info.GetOptionalAttribute<int32_t>(AttrName::K, -1);
|
||||
ML_CHECK_VALID_ARGUMENT(m_k >= 0, "Attribute k is missing.");
|
||||
|
||||
m_axis = info.GetOptionalAttribute<int32_t>(AttrName::Axis, -1);
|
||||
auto inputShape = shape.GetInputTensorShape(0);
|
||||
|
||||
if (m_axis < 0) {
|
||||
m_axis = m_axis + gsl::narrow_cast<uint32_t>(inputShape.size());
|
||||
TopKHelper(const Info_t& info, const Shape_t& shape, uint32_t opsetVersion) {
|
||||
int32_t k;
|
||||
if (opsetVersion >= 10) {
|
||||
MLOperatorTensor kTensor = info.GetConstantInputTensor(1);
|
||||
k = gsl::narrow_cast<int32_t>(ReadScalarTensorCastToInt64(kTensor));
|
||||
} else {
|
||||
k = info.GetOptionalAttribute<int32_t>(AttrName::K, -1);
|
||||
}
|
||||
ML_CHECK_VALID_ARGUMENT(m_axis >= 0 && m_axis < gsl::narrow_cast<int32_t>(inputShape.size()));
|
||||
ML_CHECK_VALID_ARGUMENT(k >= 0, "Attribute k is missing or negative.");
|
||||
m_k = k;
|
||||
|
||||
auto inputShape = shape.GetInputTensorShape(0);
|
||||
int32_t axis = info.GetOptionalAttribute<int32_t>(AttrName::Axis, -1);
|
||||
m_axis = HandleNegativeAxis(axis, gsl::narrow_cast<uint32_t>(inputShape.size()));
|
||||
}
|
||||
|
||||
std::vector<EdgeShapes> GetOutputShapes(const MLShapeInferenceContext& shapeInfo) const;
|
||||
|
||||
protected:
|
||||
int32_t m_k;
|
||||
int32_t m_axis;
|
||||
uint32_t m_k;
|
||||
uint32_t m_axis;
|
||||
};
|
||||
|
||||
class RecurrentHelper {
|
||||
|
|
@ -1081,22 +1125,11 @@ class ReshapeHelper {
|
|||
ML_CHECK_VALID_ARGUMENT(info.GetInputCount() >= 2);
|
||||
ML_CHECK_VALID_ARGUMENT(info.GetOutputCount() >= 1);
|
||||
|
||||
MLOperatorTensor shapeTensor = info.GetConstantInputTensor(1);
|
||||
|
||||
// The 'shape' tensor is a 1D tensor holding the new shape to reshape to,
|
||||
// and the first element of its own shape holds how many dimensions there
|
||||
// will be for the output.
|
||||
std::vector<uint32_t> shapeTensorDimensions = shapeTensor.GetShape();
|
||||
ML_CHECK_VALID_ARGUMENT(shapeTensorDimensions.size() == 1, "Reshape's shape tensor must be 1D.");
|
||||
size_t dimCount = shapeTensorDimensions[0];
|
||||
|
||||
ML_CHECK_VALID_ARGUMENT(shapeTensor.IsCpuData(), "Reshape's shape tensor must be CPU Tensor.");
|
||||
const int64_t* shapeData = shapeTensor.GetData<int64_t>();
|
||||
|
||||
// Shape of shape tensor is how many dims to reshape to.
|
||||
for (size_t i = 0; i < dimCount; ++i) {
|
||||
m_shapeDims.push_back(gsl::narrow_cast<int>(shapeData[i]));
|
||||
}
|
||||
MLOperatorTensor shapeTensor = info.GetConstantInputTensor(1);
|
||||
ReadCpuLocalTensorIntoInt32(shapeTensor, /*out*/ m_shapeDims);
|
||||
}
|
||||
|
||||
std::vector<EdgeShapes> GetOutputShapes(const MLShapeInferenceContext& shapeInfo) const;
|
||||
|
|
@ -1169,35 +1202,51 @@ class ResizeHelper {
|
|||
// Info_t is used to obtain attributes which will be used for calculating the output shape later.
|
||||
// Shape_t is used to obtain input shape which will be used for adjusting attribute value.
|
||||
template <typename Info_t, typename Shape_t>
|
||||
ResizeHelper(const Info_t& info, const Shape_t& shape) {
|
||||
// Read the scales from the 2nd tensor.
|
||||
if (info.GetInputCount() > 1) {
|
||||
MLOperatorTensor scalesTensor = info.GetConstantInputTensor(1);
|
||||
Initialize(scalesTensor, shape.GetInputTensorShape(0));
|
||||
} else // From attribute.
|
||||
{
|
||||
Initialize(info, shape.GetInputTensorShape(0));
|
||||
ResizeHelper(const Info_t& info, const Shape_t& shape, uint32_t opsetVersion) {
|
||||
|
||||
m_inputDimensions = shape.GetInputTensorShape(0);
|
||||
std::vector<int32_t> outputSizes;
|
||||
|
||||
if (opsetVersion >= 11) {
|
||||
if (info.IsInputValid(1))
|
||||
{
|
||||
MLOperatorTensor regionOfInterestTensor = info.GetConstantInputTensor(1);
|
||||
ReadCpuLocalTensorIntoFloat32(regionOfInterestTensor, /*out*/ m_regionOfInterest);
|
||||
}
|
||||
if (info.IsInputValid(2))
|
||||
{
|
||||
MLOperatorTensor scalesTensor = info.GetConstantInputTensor(2);
|
||||
ReadCpuLocalTensorIntoFloat32(scalesTensor, /*out*/ m_scales);
|
||||
}
|
||||
if (info.IsInputValid(3))
|
||||
{
|
||||
MLOperatorTensor outputSizesTensor = info.GetConstantInputTensor(3);
|
||||
ReadCpuLocalTensorIntoInt32(outputSizesTensor, /*out*/ outputSizes);
|
||||
}
|
||||
}
|
||||
else if (opsetVersion >= 9) {
|
||||
// Read the scales from the 2nd tensor.
|
||||
// Compatible with Upsample-9/Upsample-10 and Resize-10.
|
||||
MLOperatorTensor scalesTensor = info.GetConstantInputTensor(1);
|
||||
ReadCpuLocalTensorIntoFloat32(scalesTensor, /*out*/ m_scales);
|
||||
} else
|
||||
{
|
||||
// From attribute, compatible with Upsample-7.
|
||||
m_scales = info.GetOptionalAttribute<std::vector<float>>(AttrName::Scales, std::vector<float>());
|
||||
}
|
||||
|
||||
Initialize(outputSizes);
|
||||
}
|
||||
|
||||
void Initialize(
|
||||
const MLOperatorAttributes& operatorAttributes,
|
||||
gsl::span<const DimensionType> inputDimensions);
|
||||
|
||||
void Initialize(
|
||||
const MLOperatorTensor& scalesTensor,
|
||||
gsl::span<const DimensionType> inputDimensions);
|
||||
|
||||
void InitializeOutputDimensions(
|
||||
gsl::span<const float> scales,
|
||||
gsl::span<const DimensionType> inputDimensions);
|
||||
void Initialize(gsl::span<const int32_t> outputSizes);
|
||||
|
||||
std::vector<EdgeShapes> GetOutputShapes(const MLShapeInferenceContext& shapeInfo) const;
|
||||
|
||||
protected:
|
||||
std::vector<DimensionType> m_inputDimensions;
|
||||
std::vector<DimensionType> m_outputDimensions;
|
||||
std::vector<float> m_scales; // Cached scales to check for updates/invalidate operator.
|
||||
std::vector<float> m_scales;
|
||||
std::vector<float> m_regionOfInterest; // Stored as [start1, ..., startN, end1, ..., endN], where N is the input rank.
|
||||
};
|
||||
|
||||
class RangeHelper {
|
||||
|
|
@ -1251,11 +1300,7 @@ class OneHotHelper {
|
|||
|
||||
// The shape tensor ('depth') is a 0D tensor holding the size for the output tensor along the specified axis.
|
||||
// It must be registered as OrtMemType::OrtMemTypeCPUInput for CPU read access.
|
||||
const uint32_t depthElementCount = ComputeElementCountFromDimensions(shapeTensor.GetShape());
|
||||
ML_CHECK_VALID_ARGUMENT(shapeTensor.IsCpuData(), "OneHots's 'depth' tensor must be a CPU Tensor.");
|
||||
ML_CHECK_VALID_ARGUMENT(depthElementCount == 1, "OneHots's 'depth' tensor must have one element.");
|
||||
const void* tensorData = shapeTensor.GetByteData();
|
||||
const int64_t depth64 = CastToInt64(shapeTensor.GetTensorDataType(), tensorData);
|
||||
const int64_t depth64 = ReadScalarTensorCastToInt64(shapeTensor);
|
||||
ML_CHECK_VALID_ARGUMENT(depth64 > 0, "Negative or zero 'depth' values for OneHot are illegal.");
|
||||
const uint32_t depth = gsl::narrow_cast<uint32_t>(depth64);
|
||||
m_outputDimensions.assign(indicesShape.begin(), indicesShape.end());
|
||||
|
|
@ -1274,6 +1319,8 @@ class OneHotHelper {
|
|||
using ShapeInferenceHelper_Conv = ConvHelper;
|
||||
using ShapeInferenceHelper_ConvTranspose = ConvTransposeHelper;
|
||||
using ShapeInferenceHelper_ConvTransposeWithDynamicPads = ConvTransposeWithDynamicPadsHelper;
|
||||
using ShapeInferenceHelper_ConvInteger = ConvHelper;
|
||||
using ShapeInferenceHelper_QLinearConv = QLinearConvHelper;
|
||||
using ShapeInferenceHelper_AveragePool = PoolingHelper;
|
||||
using ShapeInferenceHelper_GlobalAveragePool = GlobalPoolingHelper;
|
||||
using ShapeInferenceHelper_MaxPool = PoolingHelper;
|
||||
|
|
@ -1304,10 +1351,12 @@ using ShapeInferenceHelper_Flatten = FlattenHelper;
|
|||
using ShapeInferenceHelper_Split = SplitHelper;
|
||||
using ShapeInferenceHelper_Transpose = TransposeHelper;
|
||||
using ShapeInferenceHelper_Concat = ConcatHelper;
|
||||
using ShapeInferenceHelper_Slice7 = SliceHelper;
|
||||
using ShapeInferenceHelper_Slice10 = Slice10Helper;
|
||||
using ShapeInferenceHelper_Slice11 = Slice10Helper; // 11 and 10 are identical - no functional change.
|
||||
using ShapeInferenceHelper_Pad = PaddingHelper;
|
||||
using ShapeInferenceHelper_Slice7 = VersionedOpsetHelper<SliceHelper, 7>;
|
||||
using ShapeInferenceHelper_Slice10 = VersionedOpsetHelper<SliceHelper, 10>;
|
||||
using ShapeInferenceHelper_Slice11 = VersionedOpsetHelper<SliceHelper, 11>; // Note 11 and 10 are identical - no functional change.
|
||||
using ShapeInferenceHelper_Pad7 = VersionedOpsetHelper<PaddingHelper, 7>;
|
||||
using ShapeInferenceHelper_Pad11 = VersionedOpsetHelper<PaddingHelper, 11>;
|
||||
|
||||
using ShapeInferenceHelper_SpaceToDepth = SpaceToDepthHelper;
|
||||
using ShapeInferenceHelper_DepthToSpace = DepthToSpaceHelper;
|
||||
using ShapeInferenceHelper_Squeeze = SqueezeHelper;
|
||||
|
|
@ -1318,7 +1367,8 @@ using ShapeInferenceHelper_Expand = ExpandHelper;
|
|||
using ShapeInferenceHelper_Reshape = ReshapeHelper;
|
||||
using ShapeInferenceHelper_ConstantOfShape = ConstantOfShapeHelper;
|
||||
using ShapeInferenceHelper_Tile = TileHelper;
|
||||
using ShapeInferenceHelper_Resize = ResizeHelper;
|
||||
using ShapeInferenceHelper_Resize10 = VersionedOpsetHelper<ResizeHelper, 10>;
|
||||
using ShapeInferenceHelper_Resize11 = VersionedOpsetHelper<ResizeHelper, 11>;
|
||||
using ShapeInferenceHelper_OneHot = OneHotHelper;
|
||||
|
||||
using ShapeInferenceHelper_Sqrt = GetOutputShapeAsInputShapeHelper;
|
||||
|
|
@ -1386,7 +1436,9 @@ using ShapeInferenceHelper_Neg = GetOutputShapeAsInputShapeHelper;
|
|||
|
||||
using ShapeInferenceHelper_Crop = CropHelper;
|
||||
using ShapeInferenceHelper_ImageScaler = GetOutputShapeAsInputShapeHelper;
|
||||
using ShapeInferenceHelper_Upsample = ResizeHelper;
|
||||
using ShapeInferenceHelper_Upsample7 = VersionedOpsetHelper<ResizeHelper, 7>;
|
||||
using ShapeInferenceHelper_Upsample9 = VersionedOpsetHelper<ResizeHelper, 9>;
|
||||
using ShapeInferenceHelper_Upsample10 = VersionedOpsetHelper<ResizeHelper, 10>;
|
||||
|
||||
using ShapeInferenceHelper_Sigmoid = GetOutputShapeAsInputShapeHelper;
|
||||
using ShapeInferenceHelper_HardSigmoid = GetOutputShapeAsInputShapeHelper;
|
||||
|
|
@ -1409,10 +1461,15 @@ using ShapeInferenceHelper_Shrink = GetOutputShapeAsInputShapeHelper;
|
|||
|
||||
using ShapeInferenceHelper_Identity = GetOutputShapeAsInputShapeHelper;
|
||||
using ShapeInferenceHelper_MatMul = MatMulHelper;
|
||||
using ShapeInferenceHelper_MatMulInteger = MatMulHelper;
|
||||
using ShapeInferenceHelper_QLinearMatMul = QLinearMatMulHelper;
|
||||
|
||||
using ShapeInferenceHelper_Cast = GetOutputShapeAsInputShapeHelper;
|
||||
using ShapeInferenceHelper_MemcpyFromHost = GetOutputShapeAsInputShapeHelper;
|
||||
using ShapeInferenceHelper_MemcpyToHost = GetOutputShapeAsInputShapeHelper;
|
||||
using ShapeInferenceHelper_TopK = TopKHelper;
|
||||
using ShapeInferenceHelper_TopK7 = VersionedOpsetHelper<TopKHelper, 7>;
|
||||
using ShapeInferenceHelper_TopK10 = VersionedOpsetHelper<TopKHelper, 10>;
|
||||
using ShapeInferenceHelper_TopK11 = VersionedOpsetHelper<TopKHelper, 11>;
|
||||
|
||||
using ShapeInferenceHelper_RandomUniform = RandomUniformHelper;
|
||||
using ShapeInferenceHelper_RandomUniformLike = GetOutputShapeAsInputShapeHelper;
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ namespace OperatorHelper
|
|||
|
||||
namespace OnnxOperatorSet10
|
||||
{
|
||||
static const int sc_sinceVer_Crop = 10; // Removed in this version.
|
||||
static const int sc_sinceVer_Resize = 10;
|
||||
static const int sc_sinceVer_MaxPool = 10;
|
||||
static const int sc_sinceVer_QuantizeLinear = 10;
|
||||
|
|
@ -186,6 +187,11 @@ namespace OperatorHelper
|
|||
static const int sc_sinceVer_RoiAlign = 10;
|
||||
static const int sc_sinceVer_TopK = 10;
|
||||
static const int sc_sinceVer_ReverseSequence = 10;
|
||||
static const int sc_sinceVer_AveragePool = 10;
|
||||
static const int sc_sinceVer_ConvInteger = 10;
|
||||
static const int sc_sinceVer_MatMulInteger = 10;
|
||||
static const int sc_sinceVer_QLinearConv = 10;
|
||||
static const int sc_sinceVer_QLinearMatMul = 10;
|
||||
} // namespace OnnxOperatorSet10
|
||||
|
||||
namespace OnnxOperatorSet11
|
||||
|
|
@ -197,6 +203,8 @@ namespace OperatorHelper
|
|||
static const int sc_sinceVer_Clip = 11;
|
||||
static const int sc_sinceVer_Compress = 11;
|
||||
static const int sc_sinceVer_Concat = 11;
|
||||
static const int sc_sinceVer_Conv = 11;
|
||||
static const int sc_sinceVer_ConvTranspose = 11;
|
||||
static const int sc_sinceVer_CumSum = 11;
|
||||
static const int sc_sinceVer_DepthToSpace = 11;
|
||||
static const int sc_sinceVer_Equal = 11;
|
||||
|
|
@ -207,6 +215,7 @@ namespace OperatorHelper
|
|||
static const int sc_sinceVer_Gemm = 11;
|
||||
static const int sc_sinceVer_Hardmax = 11;
|
||||
static const int sc_sinceVer_LogSoftmax = 11;
|
||||
static const int sc_sinceVer_LpPool = 11;
|
||||
static const int sc_sinceVer_MaxPool = 11;
|
||||
static const int sc_sinceVer_MaxUnpool = 11;
|
||||
static const int sc_sinceVer_OneHot = 11;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ OverrideSchemaInferenceFunction<OperatorHelper::ShapeInferenceHelper_##opName>(
|
|||
#opName, OperatorHelper::OnnxOperatorSet##version##::sc_sinceVer_##opName, isLatest, gsl::span<uint32_t>());
|
||||
|
||||
#pragma push_macro("OVERRIDE_SCHEMA_EX")
|
||||
#define OVERRIDE_SCHEMA_EX(version, isLatest, opName, shapeInferenceName, ...) \
|
||||
#define OVERRIDE_SCHEMA_EX(version, isLatest, opName, shapeInferenceName, /*CPU constant tensor indices*/ ...) \
|
||||
OverrideSchemaInferenceFunction<OperatorHelper::ShapeInferenceHelper_##shapeInferenceName>( \
|
||||
#opName, OperatorHelper::OnnxOperatorSet##version##::sc_sinceVer_##opName, isLatest, std::vector<uint32_t>({##__VA_ARGS__}));
|
||||
|
||||
|
|
@ -78,15 +78,16 @@ OverrideSchemaInferenceFunction<OperatorHelper::ShapeInferenceHelper_##shapeInfe
|
|||
OVERRIDE_SCHEMA( 7, false, MaxPool);
|
||||
OVERRIDE_SCHEMA( 7, true, LpPool);
|
||||
OVERRIDE_SCHEMA( 7, true, Crop);
|
||||
OVERRIDE_SCHEMA( 7, false, Upsample);
|
||||
OVERRIDE_SCHEMA_EX( 9, true, Upsample, Resize, 1); // Upsample v9 uses Resize's shape inference function.
|
||||
OVERRIDE_SCHEMA_EX( 7, false, Upsample, Upsample7);
|
||||
OVERRIDE_SCHEMA_EX( 9, true, Upsample, Upsample9, 1);
|
||||
OVERRIDE_SCHEMA_EX( 7, true, Slice, Slice7);
|
||||
OVERRIDE_SCHEMA( 7, true, Split);
|
||||
OVERRIDE_SCHEMA_EX( 7, true, Tile, Tile, 1);
|
||||
OVERRIDE_SCHEMA_EX( 8, true, Expand, Expand, 1);
|
||||
OVERRIDE_SCHEMA( 8, true, MaxPool);
|
||||
OVERRIDE_SCHEMA_EX( 9, true, OneHot, OneHot, 1);
|
||||
OVERRIDE_SCHEMA_EX( 10, true, Resize, Resize, 1);
|
||||
OVERRIDE_SCHEMA_EX( 10, false, Resize, Resize10, 1);
|
||||
|
||||
}
|
||||
#pragma pop_macro("OVERRIDE_SCHEMA_EX")
|
||||
#pragma pop_macro("REGISTER_FUSED_OP_SCHEMA")
|
||||
|
|
|
|||
Loading…
Reference in a new issue