Merge pull request #11827 from microsoft/user/dwayner/DmlEp1.9

Integrate WindowsAI feature branch with DML EP features and DML 1.9
This commit is contained in:
Dwayne Robinson 2022-06-16 13:04:00 -07:00 committed by GitHub
commit 3d99f16e98
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 7183 additions and 2229 deletions

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="python" version="3.7.9" targetFramework="native" />
<package id="Microsoft.AI.DirectML" version="1.8.2" targetFramework="native" />
<package id="Microsoft.AI.DirectML.Preview" version="1.9.0-devd10042c94985065a565c042540e15eb75b554663" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.201201.7" targetFramework="native" />
</packages>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="pythonx86" version="3.7.9" targetFramework="native" />
<package id="Microsoft.AI.DirectML" version="1.8.2" targetFramework="native" />
<package id="Microsoft.AI.DirectML.Preview" version="1.9.0-devd10042c94985065a565c042540e15eb75b554663" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.201201.7" targetFramework="native" />
</packages>

View file

@ -1,6 +1,26 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
# There are effectively three ways to consume DirectML in this repo:
#
# 1) Public = the build points at a pre-built copy of DirectML distributed as a NuGet package.
# 2) Custom = the build points at a local copy of DirectML (bin/, include/, lib/). The dml_INCLUDE_DIR and
# dml_LIB_DIR variables are also expected to be set to the custom build location.
# 3) Internal = the build points at the DirectML source repo and builds it as part of the main project.
#
# Build Type | onnxruntime_USE_CUSTOM_DIRECTML | dml_EXTERNAL_PROJECT
# -----------|---------------------------------|---------------------
# Public | OFF | OFF
# Custom | ON | OFF
# Internal | ON | ON
#
# The "Public" build type is the default, and any mainline branches (e.g. master, rel-*) subject to CI
# should use the public build configuration. Topic branches can use the internal build type for testing,
# but they must be buildable with a public NuGet package before merging with a mainline branch.
set(onnxruntime_USE_CUSTOM_DIRECTML OFF CACHE BOOL "Depend on a custom/internal build of DirectML.")
set(dml_EXTERNAL_PROJECT OFF CACHE BOOL "Build DirectML as a source dependency.")
if (NOT onnxruntime_USE_CUSTOM_DIRECTML)
if (NOT(MSVC) OR NOT(WIN32))
message(FATAL_ERROR "NuGet packages are only supported for MSVC on Windows.")
@ -20,19 +40,60 @@ if (NOT onnxruntime_USE_CUSTOM_DIRECTML)
set(NUGET_CONFIG ${PROJECT_SOURCE_DIR}/../NuGet.config)
set(PACKAGES_CONFIG ${PROJECT_SOURCE_DIR}/../packages.config)
get_filename_component(PACKAGES_DIR ${CMAKE_CURRENT_BINARY_DIR}/../packages ABSOLUTE)
set(DML_PACKAGE_DIR ${PACKAGES_DIR}/Microsoft.AI.DirectML.1.8.2)
set(DML_PACKAGE_DIR ${PACKAGES_DIR}/Microsoft.AI.DirectML.Preview.1.9.0-devd10042c94985065a565c042540e15eb75b554663)
set(DML_SHARED_LIB DirectML.dll)
# Restore nuget packages, which will pull down the DirectML redist package
# Restore nuget packages, which will pull down the DirectML redist package.
add_custom_command(
OUTPUT ${DML_PACKAGE_DIR}/bin/x64-win/DirectML.lib ${DML_PACKAGE_DIR}/bin/x86-win/DirectML.lib ${DML_PACKAGE_DIR}/bin/arm-win/DirectML.lib ${DML_PACKAGE_DIR}/bin/arm64-win/DirectML.lib
DEPENDS ${PACKAGES_CONFIG} ${NUGET_CONFIG}
OUTPUT
${DML_PACKAGE_DIR}/bin/x64-win/DirectML.lib
${DML_PACKAGE_DIR}/bin/x86-win/DirectML.lib
${DML_PACKAGE_DIR}/bin/arm-win/DirectML.lib
${DML_PACKAGE_DIR}/bin/arm64-win/DirectML.lib
DEPENDS
${PACKAGES_CONFIG}
${NUGET_CONFIG}
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/nuget/src/nuget restore ${PACKAGES_CONFIG} -PackagesDirectory ${PACKAGES_DIR} -ConfigFile ${NUGET_CONFIG}
VERBATIM)
VERBATIM
)
include_directories(BEFORE "${DML_PACKAGE_DIR}/include")
add_custom_target(RESTORE_PACKAGES ALL DEPENDS ${DML_PACKAGE_DIR}/bin/x64-win/DirectML.lib ${DML_PACKAGE_DIR}/bin/x86-win/DirectML.lib ${DML_PACKAGE_DIR}/bin/arm-win/DirectML.lib ${DML_PACKAGE_DIR}/bin/arm64-win/DirectML.lib)
add_custom_target(
RESTORE_PACKAGES ALL
DEPENDS
${DML_PACKAGE_DIR}/bin/x64-win/DirectML.lib
${DML_PACKAGE_DIR}/bin/x86-win/DirectML.lib
${DML_PACKAGE_DIR}/bin/arm-win/DirectML.lib
${DML_PACKAGE_DIR}/bin/arm64-win/DirectML.lib
)
add_dependencies(RESTORE_PACKAGES nuget)
else()
include_directories(${dml_INCLUDE_DIR})
if (dml_EXTERNAL_PROJECT)
set(dml_preset_config $<IF:$<CONFIG:Debug>,debug,release>)
set(dml_preset_name ${onnxruntime_target_platform}-win-redist-${dml_preset_config})
include(ExternalProject)
ExternalProject_Add(
directml_repo
GIT_REPOSITORY https://dev.azure.com/microsoft/WindowsAI/_git/DirectML
GIT_TAG 2290bd6495fdf8c35822816213516d13f3742cc9
GIT_SHALLOW OFF # not allowed when GIT_TAG is a commit SHA, which is preferred (it's stable, unlike branches)
GIT_PROGRESS ON
BUILD_IN_SOURCE ON
CONFIGURE_COMMAND ${CMAKE_COMMAND} --preset ${dml_preset_name} -DDML_BUILD_TESTS=OFF
BUILD_COMMAND ${CMAKE_COMMAND} --build --preset ${dml_preset_name}
INSTALL_COMMAND ${CMAKE_COMMAND} --install build/${dml_preset_name}
STEP_TARGETS install
)
# Target that consumers can use to link with the internal build of DirectML.
set(directml_install_path ${CMAKE_BINARY_DIR}/directml_repo-prefix/src/directml_repo/build/${dml_preset_name}/install)
add_library(DirectML INTERFACE)
target_link_libraries(DirectML INTERFACE ${directml_install_path}/lib/DirectML.lib)
add_dependencies(DirectML directml_repo-install)
include_directories(BEFORE ${directml_install_path}/include)
else()
include_directories(${dml_INCLUDE_DIR})
endif()
endif()

View file

@ -1101,10 +1101,15 @@ if (onnxruntime_USE_DML)
function(target_add_dml target)
if (onnxruntime_USE_CUSTOM_DIRECTML)
if (dml_LIB_DIR)
target_link_libraries(${target} PRIVATE ${dml_LIB_DIR}/DirectML.lib)
else()
if (dml_EXTERNAL_PROJECT)
# Internal build of DirectML: link against the "DirectML" target.
target_link_libraries(${target} PRIVATE DirectML)
else()
if (dml_LIB_DIR)
target_link_libraries(${target} PRIVATE ${dml_LIB_DIR}/DirectML.lib)
else()
target_link_libraries(${target} PRIVATE DirectML)
endif()
endif()
else()
add_dependencies(${target} RESTORE_PACKAGES)

View file

@ -0,0 +1 @@
filter=-whitespace/braces,-whitespace/parens,-whitespace/line_length,-whitespace/indent,-whitespace/newline

View file

@ -92,7 +92,7 @@ namespace Windows::AI::MachineLearning::Adapter
const onnxruntime::Node& node,
MLOperatorTensorGetter& constantInputGetter,
const void* executionHandle,
DmlGraphNodeCreateInfo* graphNodeCreateInfo
/*out*/ DmlGraphNodeCreateInfo* graphNodeCreateInfo
)>;
struct GraphNodeFactoryRegistration

View file

@ -457,7 +457,7 @@ HRESULT STDMETHODCALLTYPE AbiCustomRegistry::RegisterOperatorKernel(
constantCpuInputCapture,
shapeInferrerCapture.Get(),
&defaultAttributesCapture);
return Status::OK();
return Status::OK();
};
onnxruntime::KernelCreateInfo create_info(builder.Build(), lotusKernelCreateFn);
@ -472,11 +472,18 @@ HRESULT STDMETHODCALLTYPE AbiCustomRegistry::RegisterOperatorKernel(
if (supportsGraph)
{
GraphNodeFactoryRegistration graphReg;
graphReg.factory =
[kernelFactoryCapture,
graphReg.factory = [
kernelFactoryCapture,
shapeInferrerCapture,
defaultAttributesCapture,
constantCpuInputCapture](const onnxruntime::Node& node, MLOperatorTensorGetter& constantInputGetter, const void* executionHandle, DmlGraphNodeCreateInfo* graphNodeCreateInfo)
constantCpuInputCapture
]
(
const onnxruntime::Node& node,
MLOperatorTensorGetter& constantInputGetter,
const void* executionHandle,
/*out*/ DmlGraphNodeCreateInfo* graphNodeCreateInfo
)
{
onnxruntime::ProtoHelperNodeContext nodeContext(node);
onnxruntime::OpNodeProtoHelper<onnxruntime::ProtoHelperNodeContext> protoHelper(&nodeContext);

View file

@ -30,16 +30,6 @@ DML_TENSOR_DATA_TYPE GetDmlDataTypeFromMlDataTypeNoThrow(MLOperatorTensorDataTyp
};
}
DML_TENSOR_DATA_TYPE Remap64bitDmlDataTypeTo32bit(DML_TENSOR_DATA_TYPE dmlElementType) noexcept
{
switch (dmlElementType)
{
case DML_TENSOR_DATA_TYPE_UINT64: return DML_TENSOR_DATA_TYPE_UINT32; break;
case DML_TENSOR_DATA_TYPE_INT64: return DML_TENSOR_DATA_TYPE_INT32; break;
default: return dmlElementType;
}
}
bool IsSigned(DML_TENSOR_DATA_TYPE dataType)
{
switch (dataType)

View file

@ -14,7 +14,6 @@ namespace Dml
DML_TENSOR_DATA_TYPE GetDmlDataTypeFromMlDataType(MLOperatorTensorDataType tensorDataType);
DML_TENSOR_DATA_TYPE GetDmlDataTypeFromMlDataTypeNoThrow(MLOperatorTensorDataType tensorDataType) noexcept;
DML_TENSOR_DATA_TYPE Remap64bitDmlDataTypeTo32bit(DML_TENSOR_DATA_TYPE dmlElementType) noexcept;
MLOperatorTensorDataType GetMlDataTypeFromDmlDataType(DML_TENSOR_DATA_TYPE tensorDataType);
size_t ComputeByteSizeFromDimensions(gsl::span<const DimensionType> dimensions, MLOperatorTensorDataType tensorDataType);
size_t ComputeByteSizeFromTensor(IMLOperatorTensor& tensor);
@ -23,80 +22,6 @@ namespace Dml
bool IsSigned(DML_TENSOR_DATA_TYPE dataType);
/** Calculates the minimum number of bytes required to store a buffer tensor with the specified type, sizes, and
strides. The formula can be expressed as the following:
IndexOfLastElement = dot(Sizes - 1, Strides);
MinimumImpliedSizeInBytes = roundup((IndexOfLastElement + 1) * ElementSizeInBytes, 4)
In other words, the minimum size of a tensor is the index of the one-past-the-end element, multiplied by the
element size (e.g. 2 bytes for a FLOAT16 tensor). Additionally DirectML requires that all buffers bound must have
a total size which is DWORD-aligned, and hence the minimum implied size in bytes must be rounded up to the nearest
4-byte boundary.
*/
inline UINT64 DMLCalcBufferTensorSize(
DML_TENSOR_DATA_TYPE dataType,
UINT dimensionCount,
_In_reads_(dimensionCount) const UINT* sizes,
_In_reads_opt_(dimensionCount) const UINT* strides)
{
UINT elementSizeInBytes = 0;
switch (dataType)
{
case DML_TENSOR_DATA_TYPE_FLOAT64:
case DML_TENSOR_DATA_TYPE_UINT64:
case DML_TENSOR_DATA_TYPE_INT64:
elementSizeInBytes = 8;
break;
case DML_TENSOR_DATA_TYPE_FLOAT32:
case DML_TENSOR_DATA_TYPE_UINT32:
case DML_TENSOR_DATA_TYPE_INT32:
elementSizeInBytes = 4;
break;
case DML_TENSOR_DATA_TYPE_FLOAT16:
case DML_TENSOR_DATA_TYPE_UINT16:
case DML_TENSOR_DATA_TYPE_INT16:
elementSizeInBytes = 2;
break;
case DML_TENSOR_DATA_TYPE_UINT8:
case DML_TENSOR_DATA_TYPE_INT8:
elementSizeInBytes = 1;
break;
default:
return 0; // Invalid data type
}
UINT64 minimumImpliedSizeInBytes = 0;
if (!strides)
{
minimumImpliedSizeInBytes = sizes[0];
for (UINT i = 1; i < dimensionCount; ++i)
{
minimumImpliedSizeInBytes *= sizes[i];
}
minimumImpliedSizeInBytes *= elementSizeInBytes;
}
else
{
UINT indexOfLastElement = 0;
for (UINT i = 0; i < dimensionCount; ++i)
{
indexOfLastElement += (sizes[i] - 1) * strides[i];
}
minimumImpliedSizeInBytes = (indexOfLastElement + 1) * elementSizeInBytes;
}
// Round up to the nearest 4 bytes.
minimumImpliedSizeInBytes = (minimumImpliedSizeInBytes + 3) & ~3ui64;
return minimumImpliedSizeInBytes;
}
template <typename T>
void CastToClampedScalarUnion(DML_TENSOR_DATA_TYPE dataType, T value, DML_SCALAR_UNION* outputValue)
{

View file

@ -3,7 +3,7 @@
#pragma once
#ifdef ORT_NO_EXCEPTIONS
#define ORT_CATCH_RETURN
#define ORT_CATCH_RETURN
#else
#define ORT_CATCH_RETURN CATCH_RETURN()
#endif

View file

@ -0,0 +1 @@
filter=-whitespace/comments,-readability/todo,-whitespace/end_of_line,-runtime/indentation_namespace

View file

@ -9,10 +9,12 @@ union ActivationOperatorDescUnion
DML_ACTIVATION_ELU_OPERATOR_DESC elu;
DML_ACTIVATION_CELU_OPERATOR_DESC celu;
DML_ACTIVATION_HARDMAX_OPERATOR_DESC hardmax;
DML_ACTIVATION_HARDMAX1_OPERATOR_DESC hardmax1;
DML_ACTIVATION_HARD_SIGMOID_OPERATOR_DESC hardSigmoid;
DML_ACTIVATION_LEAKY_RELU_OPERATOR_DESC leakyRelu;
DML_ACTIVATION_LINEAR_OPERATOR_DESC linear;
DML_ACTIVATION_LOG_SOFTMAX_OPERATOR_DESC logSoftmax;
DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_DESC logSoftmax1;
DML_ACTIVATION_PARAMETERIZED_RELU_OPERATOR_DESC parameterizedRelu;
DML_ACTIVATION_PARAMETRIC_SOFTPLUS_OPERATOR_DESC parametricSoftplus;
DML_ACTIVATION_RELU_OPERATOR_DESC relu;
@ -20,11 +22,13 @@ union ActivationOperatorDescUnion
DML_ACTIVATION_SCALED_ELU_OPERATOR_DESC scaledElu;
DML_ACTIVATION_SIGMOID_OPERATOR_DESC sigmoid;
DML_ACTIVATION_SOFTMAX_OPERATOR_DESC softmax;
DML_ACTIVATION_SOFTMAX1_OPERATOR_DESC softmax1;
DML_ACTIVATION_SOFTPLUS_OPERATOR_DESC softplus;
DML_ACTIVATION_SOFTSIGN_OPERATOR_DESC softsign;
DML_ACTIVATION_TANH_OPERATOR_DESC tanh;
DML_ACTIVATION_THRESHOLDED_RELU_OPERATOR_DESC thresholdedRelu;
DML_ACTIVATION_SHRINK_OPERATOR_DESC shrink;
DML_ACTIVATION_GELU_OPERATOR_DESC gelu;
};
struct ActivationOperatorDesc
@ -41,11 +45,13 @@ struct ActivationOperatorDesc
case DML_OPERATOR_ACTIVATION_ELU: return { activationType, &params.elu };
case DML_OPERATOR_ACTIVATION_CELU: return { activationType, &params.celu };
case DML_OPERATOR_ACTIVATION_HARDMAX: return { activationType, &params.hardmax };
case DML_OPERATOR_ACTIVATION_HARDMAX1: return { activationType, &params.hardmax1 };
case DML_OPERATOR_ACTIVATION_HARD_SIGMOID: return { activationType, &params.sigmoid };
case DML_OPERATOR_ACTIVATION_IDENTITY: return { activationType, &params.identity };
case DML_OPERATOR_ACTIVATION_LEAKY_RELU: return { activationType, &params.leakyRelu };
case DML_OPERATOR_ACTIVATION_LINEAR: return { activationType, &params.linear };
case DML_OPERATOR_ACTIVATION_LOG_SOFTMAX: return { activationType, &params.logSoftmax };
case DML_OPERATOR_ACTIVATION_LOG_SOFTMAX1: return { activationType, &params.logSoftmax1 };
case DML_OPERATOR_ACTIVATION_PARAMETERIZED_RELU: return { activationType, &params.parameterizedRelu };
case DML_OPERATOR_ACTIVATION_PARAMETRIC_SOFTPLUS: return { activationType, &params.parametricSoftplus };
case DML_OPERATOR_ACTIVATION_RELU: return { activationType, &params.relu };
@ -53,11 +59,13 @@ struct ActivationOperatorDesc
case DML_OPERATOR_ACTIVATION_SCALED_TANH: return { activationType, &params.scaledTanh };
case DML_OPERATOR_ACTIVATION_SIGMOID: return { activationType, &params.sigmoid };
case DML_OPERATOR_ACTIVATION_SOFTMAX: return { activationType, &params.softmax };
case DML_OPERATOR_ACTIVATION_SOFTMAX1: return { activationType, &params.softmax1 };
case DML_OPERATOR_ACTIVATION_SOFTPLUS: return { activationType, &params.softplus };
case DML_OPERATOR_ACTIVATION_SOFTSIGN: return { activationType, &params.softsign };
case DML_OPERATOR_ACTIVATION_TANH: return { activationType, &params.tanh };
case DML_OPERATOR_ACTIVATION_THRESHOLDED_RELU: return { activationType, &params.thresholdedRelu };
case DML_OPERATOR_ACTIVATION_SHRINK: return { activationType, &params.shrink };
case DML_OPERATOR_ACTIVATION_GELU: return { activationType, &params.gelu };
default:
ORT_THROW_HR(E_INVALIDARG);
return { activationType, &params.relu };

View file

@ -24,8 +24,8 @@ struct EnumTraits<DML_TENSOR_TYPE>
template <>
struct EnumTraits<DML_OPERATOR_TYPE>
{
static constexpr auto ValueCount = 153;
static constexpr size_t ActivationFunctionCount = 20;
static constexpr auto ValueCount = 160;
static constexpr size_t ActivationFunctionCount = 24;
};
template <>
@ -993,6 +993,24 @@ struct OperatorDescTraits<DML_BATCH_NORMALIZATION_TRAINING_OPERATOR_DESC>
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_BATCH_NORMALIZATION_TRAINING;
};
template <>
struct OperatorDescTraits<DML_RESAMPLE2_OPERATOR_DESC>
{
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_RESAMPLE2;
};
template <>
struct OperatorDescTraits<DML_RESAMPLE_GRAD1_OPERATOR_DESC>
{
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_RESAMPLE_GRAD1;
};
template <>
struct OperatorDescTraits<DML_DIAGONAL_MATRIX1_OPERATOR_DESC>
{
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_DIAGONAL_MATRIX1;
};
template <>
struct OperatorDescTraits<DML_ACTIVATION_ELU_OPERATOR_DESC>
{
@ -1011,6 +1029,12 @@ struct OperatorDescTraits<DML_ACTIVATION_HARDMAX_OPERATOR_DESC>
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_ACTIVATION_HARDMAX;
};
template <>
struct OperatorDescTraits<DML_ACTIVATION_HARDMAX1_OPERATOR_DESC>
{
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_ACTIVATION_HARDMAX1;
};
template <>
struct OperatorDescTraits<DML_ACTIVATION_HARD_SIGMOID_OPERATOR_DESC>
{
@ -1041,6 +1065,12 @@ struct OperatorDescTraits<DML_ACTIVATION_LOG_SOFTMAX_OPERATOR_DESC>
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_ACTIVATION_LOG_SOFTMAX;
};
template <>
struct OperatorDescTraits<DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_DESC>
{
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_ACTIVATION_LOG_SOFTMAX1;
};
template <>
struct OperatorDescTraits<DML_ACTIVATION_PARAMETERIZED_RELU_OPERATOR_DESC>
{
@ -1083,6 +1113,12 @@ struct OperatorDescTraits<DML_ACTIVATION_SOFTMAX_OPERATOR_DESC>
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_ACTIVATION_SOFTMAX;
};
template <>
struct OperatorDescTraits<DML_ACTIVATION_SOFTMAX1_OPERATOR_DESC>
{
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_ACTIVATION_SOFTMAX1;
};
template <>
struct OperatorDescTraits<DML_ACTIVATION_SOFTPLUS_OPERATOR_DESC>
{
@ -1113,6 +1149,12 @@ struct OperatorDescTraits<DML_ACTIVATION_SHRINK_OPERATOR_DESC>
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_ACTIVATION_SHRINK;
};
template <>
struct OperatorDescTraits<DML_ACTIVATION_GELU_OPERATOR_DESC>
{
static constexpr DML_OPERATOR_TYPE Type = DML_OPERATOR_ACTIVATION_GELU;
};
template <DML_OPERATOR_TYPE Type>
struct OperatorTypeTraits
@ -1935,6 +1977,24 @@ struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_BATCH_NORMALIZATION_TR
using DescType = DML_BATCH_NORMALIZATION_TRAINING_OPERATOR_DESC;
};
template <>
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_RESAMPLE2>
{
using DescType = DML_RESAMPLE2_OPERATOR_DESC;
};
template <>
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_RESAMPLE_GRAD1>
{
using DescType = DML_RESAMPLE_GRAD1_OPERATOR_DESC;
};
template <>
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_DIAGONAL_MATRIX1>
{
using DescType = DML_DIAGONAL_MATRIX1_OPERATOR_DESC;
};
template <>
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_ACTIVATION_ELU>
{
@ -1953,6 +2013,12 @@ struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_ACTIVATION_HARDMAX>
using DescType = DML_ACTIVATION_HARDMAX_OPERATOR_DESC;
};
template <>
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_ACTIVATION_HARDMAX1>
{
using DescType = DML_ACTIVATION_HARDMAX1_OPERATOR_DESC;
};
template <>
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_ACTIVATION_HARD_SIGMOID>
{
@ -1983,6 +2049,12 @@ struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_ACTIVATION_LOG_SOFTMAX
using DescType = DML_ACTIVATION_LOG_SOFTMAX_OPERATOR_DESC;
};
template <>
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_ACTIVATION_LOG_SOFTMAX1>
{
using DescType = DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_DESC;
};
template <>
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_ACTIVATION_PARAMETERIZED_RELU>
{
@ -2025,6 +2097,12 @@ struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_ACTIVATION_SOFTMAX>
using DescType = DML_ACTIVATION_SOFTMAX_OPERATOR_DESC;
};
template <>
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_ACTIVATION_SOFTMAX1>
{
using DescType = DML_ACTIVATION_SOFTMAX1_OPERATOR_DESC;
};
template <>
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_ACTIVATION_SOFTPLUS>
{
@ -2055,6 +2133,12 @@ struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_ACTIVATION_SHRINK>
using DescType = DML_ACTIVATION_SHRINK_OPERATOR_DESC;
};
template <>
struct OperatorTypeTraits<(DML_OPERATOR_TYPE)DML_OPERATOR_ACTIVATION_GELU>
{
using DescType = DML_ACTIVATION_GELU_OPERATOR_DESC;
};
// Calls a visitor functor, supplying an empty operator desc corresponding to the given DML_OPERATOR_TYPE as
// the first argument.
//
@ -2342,12 +2426,20 @@ auto OperatorTypeVisitor(DML_OPERATOR_TYPE type, Visitor&& visitor, Ts&&... args
return std::invoke(std::forward<Visitor>(visitor), DML_ROI_ALIGN_GRAD_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_BATCH_NORMALIZATION_TRAINING:
return std::invoke(std::forward<Visitor>(visitor), DML_BATCH_NORMALIZATION_TRAINING_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_RESAMPLE2:
return std::invoke(std::forward<Visitor>(visitor), DML_RESAMPLE2_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_RESAMPLE_GRAD1:
return std::invoke(std::forward<Visitor>(visitor), DML_RESAMPLE_GRAD1_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_DIAGONAL_MATRIX1:
return std::invoke(std::forward<Visitor>(visitor), DML_DIAGONAL_MATRIX1_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_CELU:
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_CELU_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_HARDMAX:
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_HARDMAX_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_HARDMAX1:
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_HARDMAX1_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_HARD_SIGMOID:
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_HARD_SIGMOID_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_IDENTITY:
@ -2358,6 +2450,8 @@ auto OperatorTypeVisitor(DML_OPERATOR_TYPE type, Visitor&& visitor, Ts&&... args
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_LINEAR_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_LOG_SOFTMAX:
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_LOG_SOFTMAX_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_LOG_SOFTMAX1:
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_PARAMETERIZED_RELU:
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_PARAMETERIZED_RELU_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_PARAMETRIC_SOFTPLUS:
@ -2372,6 +2466,8 @@ auto OperatorTypeVisitor(DML_OPERATOR_TYPE type, Visitor&& visitor, Ts&&... args
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_SIGMOID_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_SOFTMAX:
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_SOFTMAX_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_SOFTMAX1:
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_SOFTMAX1_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_SOFTPLUS:
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_SOFTPLUS_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_SOFTSIGN:
@ -2382,6 +2478,8 @@ auto OperatorTypeVisitor(DML_OPERATOR_TYPE type, Visitor&& visitor, Ts&&... args
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_THRESHOLDED_RELU_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_SHRINK:
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_SHRINK_OPERATOR_DESC{}, std::forward<Ts>(args)...);
case DML_OPERATOR_ACTIVATION_GELU:
return std::invoke(std::forward<Visitor>(visitor), DML_ACTIVATION_GELU_OPERATOR_DESC{}, std::forward<Ts>(args)...);
default:
ORT_THROW_HR(E_INVALIDARG);
@ -2532,6 +2630,9 @@ inline gsl::czstring ToString(DML_OPERATOR_TYPE value)
case DML_OPERATOR_ELEMENT_WISE_QUANTIZED_LINEAR_ADD: return "DML_OPERATOR_ELEMENT_WISE_QUANTIZED_LINEAR_ADD";
case DML_OPERATOR_ROI_ALIGN_GRAD: return "DML_OPERATOR_ROI_ALIGN_GRAD";
case DML_OPERATOR_BATCH_NORMALIZATION_TRAINING: return "DML_OPERATOR_BATCH_NORMALIZATION_TRAINING";
case DML_OPERATOR_RESAMPLE2: return "DML_OPERATOR_RESAMPLE2";
case DML_OPERATOR_RESAMPLE_GRAD1: return "DML_OPERATOR_RESAMPLE_GRAD1";
case DML_OPERATOR_DIAGONAL_MATRIX1: return "DML_OPERATOR_DIAGONAL_MATRIX1";
default:
assert(false);
return "<unknown>";

View file

@ -2247,6 +2247,61 @@ constexpr DML_OPERATOR_SCHEMA DML_BATCH_NORMALIZATION_TRAINING_OPERATOR_SCHEMA {
DML_BATCH_NORMALIZATION_TRAINING_OPERATOR_SCHEMA_FIELDS,
};
constexpr DML_SCHEMA_FIELD DML_RESAMPLE2_OPERATOR_SCHEMA_FIELDS[8]{
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, "RoundingDirection", 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_RESAMPLE2_OPERATOR_SCHEMA{
"DML_OPERATOR_RESAMPLE2",
DML_OPERATOR_RESAMPLE2,
DML_SCHEMA_OPERATOR_SUPPORT_FLAG_NONE,
8,
DML_RESAMPLE2_OPERATOR_SCHEMA_FIELDS,
};
constexpr DML_SCHEMA_FIELD DML_RESAMPLE_GRAD1_OPERATOR_SCHEMA_FIELDS[8]{
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "InputGradientTensor", false },
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_OUTPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "OutputGradientTensor", 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, "RoundingDirection", 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_RESAMPLE_GRAD1_OPERATOR_SCHEMA{
"DML_OPERATOR_RESAMPLE_GRAD1",
DML_OPERATOR_RESAMPLE_GRAD1,
DML_SCHEMA_OPERATOR_SUPPORT_FLAG_NONE,
8,
DML_RESAMPLE_GRAD1_OPERATOR_SCHEMA_FIELDS,
};
constexpr DML_SCHEMA_FIELD DML_DIAGONAL_MATRIX1_OPERATOR_SCHEMA_FIELDS[6]{
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "InputTensor", 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, "ValueDataType", false },
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_SCALAR_UNION, "Value", false },
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_INT, "DiagonalFillBegin", false },
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_INT, "DiagonalFillEnd", false },
};
constexpr DML_OPERATOR_SCHEMA DML_DIAGONAL_MATRIX1_OPERATOR_SCHEMA{
"DML_OPERATOR_DIAGONAL_MATRIX1",
DML_OPERATOR_DIAGONAL_MATRIX1,
DML_SCHEMA_OPERATOR_SUPPORT_FLAG_NONE,
6,
DML_DIAGONAL_MATRIX1_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 },
@ -2288,6 +2343,21 @@ constexpr DML_OPERATOR_SCHEMA DML_ACTIVATION_HARDMAX_OPERATOR_SCHEMA {
DML_ACTIVATION_HARDMAX_OPERATOR_SCHEMA_FIELDS,
};
constexpr DML_SCHEMA_FIELD DML_ACTIVATION_HARDMAX1_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_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT, "AxisCount", false },
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT_ARRAY, "Axes", false },
};
constexpr DML_OPERATOR_SCHEMA DML_ACTIVATION_HARDMAX1_OPERATOR_SCHEMA {
"DML_OPERATOR_ACTIVATION_HARDMAX1",
DML_OPERATOR_ACTIVATION_HARDMAX1,
DML_SCHEMA_OPERATOR_SUPPORT_FLAG_NONE,
4,
DML_ACTIVATION_HARDMAX1_OPERATOR_SCHEMA_FIELDS,
};
constexpr DML_SCHEMA_FIELD DML_ACTIVATION_HARD_SIGMOID_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 },
@ -2358,6 +2428,21 @@ constexpr DML_OPERATOR_SCHEMA DML_ACTIVATION_LOG_SOFTMAX_OPERATOR_SCHEMA {
DML_ACTIVATION_LOG_SOFTMAX_OPERATOR_SCHEMA_FIELDS,
};
constexpr DML_SCHEMA_FIELD DML_ACTIVATION_LOG_SOFTMAX1_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_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT, "AxisCount", false },
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT_ARRAY, "Axes", false },
};
constexpr DML_OPERATOR_SCHEMA DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_SCHEMA {
"DML_OPERATOR_ACTIVATION_LOG_SOFTMAX1",
DML_OPERATOR_ACTIVATION_LOG_SOFTMAX1,
DML_SCHEMA_OPERATOR_SUPPORT_FLAG_NONE,
4,
DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_SCHEMA_FIELDS,
};
constexpr DML_SCHEMA_FIELD DML_ACTIVATION_PARAMETERIZED_RELU_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_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "SlopeTensor", false },
@ -2456,6 +2541,21 @@ constexpr DML_OPERATOR_SCHEMA DML_ACTIVATION_SOFTMAX_OPERATOR_SCHEMA {
DML_ACTIVATION_SOFTMAX_OPERATOR_SCHEMA_FIELDS,
};
constexpr DML_SCHEMA_FIELD DML_ACTIVATION_SOFTMAX1_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_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT, "AxisCount", false },
DML_SCHEMA_FIELD { DML_SCHEMA_FIELD_KIND_ATTRIBUTE, DML_SCHEMA_FIELD_TYPE_UINT_ARRAY, "Axes", false },
};
constexpr DML_OPERATOR_SCHEMA DML_ACTIVATION_SOFTMAX1_OPERATOR_SCHEMA {
"DML_OPERATOR_ACTIVATION_SOFTMAX1",
DML_OPERATOR_ACTIVATION_SOFTMAX1,
DML_SCHEMA_OPERATOR_SUPPORT_FLAG_NONE,
4,
DML_ACTIVATION_SOFTMAX1_OPERATOR_SCHEMA_FIELDS,
};
constexpr DML_SCHEMA_FIELD DML_ACTIVATION_SOFTPLUS_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 },
@ -2525,6 +2625,19 @@ constexpr DML_OPERATOR_SCHEMA DML_ACTIVATION_SHRINK_OPERATOR_SCHEMA {
DML_ACTIVATION_SHRINK_OPERATOR_SCHEMA_FIELDS,
};
constexpr DML_SCHEMA_FIELD DML_ACTIVATION_GELU_OPERATOR_SCHEMA_FIELDS[2] {
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 },
};
constexpr DML_OPERATOR_SCHEMA DML_ACTIVATION_GELU_OPERATOR_SCHEMA {
"DML_OPERATOR_ACTIVATION_GELU",
DML_OPERATOR_ACTIVATION_GELU,
DML_SCHEMA_OPERATOR_SUPPORT_FLAG_IN_PLACE_EXECUTION,
2,
DML_ACTIVATION_GELU_OPERATOR_SCHEMA_FIELDS,
};
constexpr DML_SCHEMA_FIELD DML_RNN_ZERO_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_INPUT_TENSOR, DML_SCHEMA_FIELD_TYPE_TENSOR_DESC, "SequenceLengthsTensor", false },

File diff suppressed because it is too large Load diff

View file

@ -1381,6 +1381,43 @@ inline std::vector<OperatorField> GetFields(const DML_BATCH_NORMALIZATION_TRAINI
OperatorField(&DML_BATCH_NORMALIZATION_TRAINING_OPERATOR_SCHEMA.Fields[8], ToOperatorFieldType(static_cast<const DML_OPERATOR_DESC*>(desc.FusedActivation))),
};
}
inline std::vector<OperatorField> GetFields(const DML_RESAMPLE2_OPERATOR_DESC& desc)
{
return {
OperatorField(&DML_RESAMPLE2_OPERATOR_SCHEMA.Fields[0], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.InputTensor))),
OperatorField(&DML_RESAMPLE2_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
OperatorField(&DML_RESAMPLE2_OPERATOR_SCHEMA.Fields[2], ToOperatorFieldType(static_cast<UINT>(desc.InterpolationMode))),
OperatorField(&DML_RESAMPLE2_OPERATOR_SCHEMA.Fields[3], ToOperatorFieldType(static_cast<UINT>(desc.RoundingDirection))),
OperatorField(&DML_RESAMPLE2_OPERATOR_SCHEMA.Fields[4], ToOperatorFieldType(static_cast<UINT>(desc.DimensionCount))),
OperatorField(&DML_RESAMPLE2_OPERATOR_SCHEMA.Fields[5], ToOperatorFieldType(static_cast<const FLOAT*>(desc.Scales), desc.DimensionCount)),
OperatorField(&DML_RESAMPLE2_OPERATOR_SCHEMA.Fields[6], ToOperatorFieldType(static_cast<const FLOAT*>(desc.InputPixelOffsets), desc.DimensionCount)),
OperatorField(&DML_RESAMPLE2_OPERATOR_SCHEMA.Fields[7], ToOperatorFieldType(static_cast<const FLOAT*>(desc.OutputPixelOffsets), desc.DimensionCount)),
};
}
inline std::vector<OperatorField> GetFields(const DML_RESAMPLE_GRAD1_OPERATOR_DESC& desc)
{
return {
OperatorField(&DML_RESAMPLE_GRAD1_OPERATOR_SCHEMA.Fields[0], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.InputGradientTensor))),
OperatorField(&DML_RESAMPLE_GRAD1_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputGradientTensor))),
OperatorField(&DML_RESAMPLE_GRAD1_OPERATOR_SCHEMA.Fields[2], ToOperatorFieldType(static_cast<UINT>(desc.InterpolationMode))),
OperatorField(&DML_RESAMPLE_GRAD1_OPERATOR_SCHEMA.Fields[3], ToOperatorFieldType(static_cast<UINT>(desc.RoundingDirection))),
OperatorField(&DML_RESAMPLE_GRAD1_OPERATOR_SCHEMA.Fields[4], ToOperatorFieldType(static_cast<UINT>(desc.DimensionCount))),
OperatorField(&DML_RESAMPLE_GRAD1_OPERATOR_SCHEMA.Fields[5], ToOperatorFieldType(static_cast<const FLOAT*>(desc.Scales), desc.DimensionCount)),
OperatorField(&DML_RESAMPLE_GRAD1_OPERATOR_SCHEMA.Fields[6], ToOperatorFieldType(static_cast<const FLOAT*>(desc.InputPixelOffsets), desc.DimensionCount)),
OperatorField(&DML_RESAMPLE_GRAD1_OPERATOR_SCHEMA.Fields[7], ToOperatorFieldType(static_cast<const FLOAT*>(desc.OutputPixelOffsets), desc.DimensionCount)),
};
}
inline std::vector<OperatorField> GetFields(const DML_DIAGONAL_MATRIX1_OPERATOR_DESC& desc)
{
return {
OperatorField(&DML_DIAGONAL_MATRIX1_OPERATOR_SCHEMA.Fields[0], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.InputTensor))),
OperatorField(&DML_DIAGONAL_MATRIX1_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
OperatorField(&DML_DIAGONAL_MATRIX1_OPERATOR_SCHEMA.Fields[2], ToOperatorFieldType(static_cast<UINT>(desc.ValueDataType))),
OperatorField(&DML_DIAGONAL_MATRIX1_OPERATOR_SCHEMA.Fields[3], ToOperatorFieldType(static_cast<DML_SCALAR_UNION>(desc.Value))),
OperatorField(&DML_DIAGONAL_MATRIX1_OPERATOR_SCHEMA.Fields[4], ToOperatorFieldType(static_cast<INT>(desc.DiagonalFillBegin))),
OperatorField(&DML_DIAGONAL_MATRIX1_OPERATOR_SCHEMA.Fields[5], ToOperatorFieldType(static_cast<INT>(desc.DiagonalFillEnd))),
};
}
inline std::vector<OperatorField> GetFields(const DML_ACTIVATION_ELU_OPERATOR_DESC& desc)
{
return {
@ -1404,6 +1441,15 @@ inline std::vector<OperatorField> GetFields(const DML_ACTIVATION_HARDMAX_OPERATO
OperatorField(&DML_ACTIVATION_HARDMAX_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
};
}
inline std::vector<OperatorField> GetFields(const DML_ACTIVATION_HARDMAX1_OPERATOR_DESC& desc)
{
return {
OperatorField(&DML_ACTIVATION_HARDMAX1_OPERATOR_SCHEMA.Fields[0], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.InputTensor))),
OperatorField(&DML_ACTIVATION_HARDMAX1_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
OperatorField(&DML_ACTIVATION_HARDMAX1_OPERATOR_SCHEMA.Fields[2], ToOperatorFieldType(static_cast<UINT>(desc.AxisCount))),
OperatorField(&DML_ACTIVATION_HARDMAX1_OPERATOR_SCHEMA.Fields[3], ToOperatorFieldType(static_cast<const UINT*>(desc.Axes), desc.AxisCount)),
};
}
inline std::vector<OperatorField> GetFields(const DML_ACTIVATION_HARD_SIGMOID_OPERATOR_DESC& desc)
{
return {
@ -1444,6 +1490,15 @@ inline std::vector<OperatorField> GetFields(const DML_ACTIVATION_LOG_SOFTMAX_OPE
OperatorField(&DML_ACTIVATION_LOG_SOFTMAX_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
};
}
inline std::vector<OperatorField> GetFields(const DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_DESC& desc)
{
return {
OperatorField(&DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_SCHEMA.Fields[0], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.InputTensor))),
OperatorField(&DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
OperatorField(&DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_SCHEMA.Fields[2], ToOperatorFieldType(static_cast<UINT>(desc.AxisCount))),
OperatorField(&DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_SCHEMA.Fields[3], ToOperatorFieldType(static_cast<const UINT*>(desc.Axes), desc.AxisCount)),
};
}
inline std::vector<OperatorField> GetFields(const DML_ACTIVATION_PARAMETERIZED_RELU_OPERATOR_DESC& desc)
{
return {
@ -1500,6 +1555,15 @@ inline std::vector<OperatorField> GetFields(const DML_ACTIVATION_SOFTMAX_OPERATO
OperatorField(&DML_ACTIVATION_SOFTMAX_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
};
}
inline std::vector<OperatorField> GetFields(const DML_ACTIVATION_SOFTMAX1_OPERATOR_DESC& desc)
{
return {
OperatorField(&DML_ACTIVATION_SOFTMAX1_OPERATOR_SCHEMA.Fields[0], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.InputTensor))),
OperatorField(&DML_ACTIVATION_SOFTMAX1_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
OperatorField(&DML_ACTIVATION_SOFTMAX1_OPERATOR_SCHEMA.Fields[2], ToOperatorFieldType(static_cast<UINT>(desc.AxisCount))),
OperatorField(&DML_ACTIVATION_SOFTMAX1_OPERATOR_SCHEMA.Fields[3], ToOperatorFieldType(static_cast<const UINT*>(desc.Axes), desc.AxisCount)),
};
}
inline std::vector<OperatorField> GetFields(const DML_ACTIVATION_SOFTPLUS_OPERATOR_DESC& desc)
{
return {
@ -1539,7 +1603,13 @@ inline std::vector<OperatorField> GetFields(const DML_ACTIVATION_SHRINK_OPERATOR
OperatorField(&DML_ACTIVATION_SHRINK_OPERATOR_SCHEMA.Fields[3], ToOperatorFieldType(static_cast<FLOAT>(desc.Threshold))),
};
}
inline std::vector<OperatorField> GetFields(const DML_ACTIVATION_GELU_OPERATOR_DESC& desc)
{
return {
OperatorField(&DML_ACTIVATION_GELU_OPERATOR_SCHEMA.Fields[0], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.InputTensor))),
OperatorField(&DML_ACTIVATION_GELU_OPERATOR_SCHEMA.Fields[1], ToOperatorFieldType(static_cast<const DML_TENSOR_DESC*>(desc.OutputTensor))),
};
}
inline const DML_OPERATOR_SCHEMA& GetSchema(DML_OPERATOR_TYPE operatorType)
{
switch (operatorType)
@ -1680,14 +1750,19 @@ inline const DML_OPERATOR_SCHEMA& GetSchema(DML_OPERATOR_TYPE operatorType)
case DML_OPERATOR_ELEMENT_WISE_QUANTIZED_LINEAR_ADD: return DML_ELEMENT_WISE_QUANTIZED_LINEAR_ADD_OPERATOR_SCHEMA;
case DML_OPERATOR_ROI_ALIGN_GRAD: return DML_ROI_ALIGN_GRAD_OPERATOR_SCHEMA;
case DML_OPERATOR_BATCH_NORMALIZATION_TRAINING: return DML_BATCH_NORMALIZATION_TRAINING_OPERATOR_SCHEMA;
case DML_OPERATOR_RESAMPLE2: return DML_RESAMPLE2_OPERATOR_SCHEMA;
case DML_OPERATOR_RESAMPLE_GRAD1: return DML_RESAMPLE_GRAD1_OPERATOR_SCHEMA;
case DML_OPERATOR_DIAGONAL_MATRIX1: return DML_DIAGONAL_MATRIX1_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_ELU: return DML_ACTIVATION_ELU_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_CELU: return DML_ACTIVATION_CELU_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_HARDMAX: return DML_ACTIVATION_HARDMAX_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_HARDMAX1: return DML_ACTIVATION_HARDMAX1_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_HARD_SIGMOID: return DML_ACTIVATION_HARD_SIGMOID_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_IDENTITY: return DML_ACTIVATION_IDENTITY_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_LEAKY_RELU: return DML_ACTIVATION_LEAKY_RELU_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_LINEAR: return DML_ACTIVATION_LINEAR_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_LOG_SOFTMAX: return DML_ACTIVATION_LOG_SOFTMAX_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_LOG_SOFTMAX1: return DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_PARAMETERIZED_RELU: return DML_ACTIVATION_PARAMETERIZED_RELU_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_PARAMETRIC_SOFTPLUS: return DML_ACTIVATION_PARAMETRIC_SOFTPLUS_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_RELU: return DML_ACTIVATION_RELU_OPERATOR_SCHEMA;
@ -1695,11 +1770,13 @@ inline const DML_OPERATOR_SCHEMA& GetSchema(DML_OPERATOR_TYPE operatorType)
case DML_OPERATOR_ACTIVATION_SCALED_TANH: return DML_ACTIVATION_SCALED_TANH_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_SIGMOID: return DML_ACTIVATION_SIGMOID_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_SOFTMAX: return DML_ACTIVATION_SOFTMAX_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_SOFTMAX1: return DML_ACTIVATION_SOFTMAX1_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_SOFTPLUS: return DML_ACTIVATION_SOFTPLUS_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_SOFTSIGN: return DML_ACTIVATION_SOFTSIGN_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_TANH: return DML_ACTIVATION_TANH_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_THRESHOLDED_RELU: return DML_ACTIVATION_THRESHOLDED_RELU_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_SHRINK: return DML_ACTIVATION_SHRINK_OPERATOR_SCHEMA;
case DML_OPERATOR_ACTIVATION_GELU: return DML_ACTIVATION_GELU_OPERATOR_SCHEMA;
default:
ORT_THROW_HR(E_INVALIDARG);
@ -2249,7 +2326,7 @@ inline AbstractOperatorDesc ConvertOperatorDesc(const DML_OPERATOR_DESC& opDesc)
return AbstractOperatorDesc(
&DML_ELEMENT_WISE_QUANTIZED_LINEAR_ADD_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_ELEMENT_WISE_QUANTIZED_LINEAR_ADD_OPERATOR_DESC*>(opDesc.Desc)));
case DML_OPERATOR_ROI_ALIGN_GRAD:
case DML_OPERATOR_ROI_ALIGN_GRAD:
return AbstractOperatorDesc(
&DML_ROI_ALIGN_GRAD_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_ROI_ALIGN_GRAD_OPERATOR_DESC*>(opDesc.Desc)));
@ -2257,6 +2334,18 @@ inline AbstractOperatorDesc ConvertOperatorDesc(const DML_OPERATOR_DESC& opDesc)
return AbstractOperatorDesc(
&DML_BATCH_NORMALIZATION_TRAINING_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_BATCH_NORMALIZATION_TRAINING_OPERATOR_DESC*>(opDesc.Desc)));
case DML_OPERATOR_RESAMPLE2:
return AbstractOperatorDesc(
&DML_RESAMPLE2_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_RESAMPLE2_OPERATOR_DESC*>(opDesc.Desc)));
case DML_OPERATOR_RESAMPLE_GRAD1:
return AbstractOperatorDesc(
&DML_RESAMPLE_GRAD1_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_RESAMPLE_GRAD1_OPERATOR_DESC*>(opDesc.Desc)));
case DML_OPERATOR_DIAGONAL_MATRIX1:
return AbstractOperatorDesc(
&DML_DIAGONAL_MATRIX1_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_DIAGONAL_MATRIX1_OPERATOR_DESC*>(opDesc.Desc)));
case DML_OPERATOR_ACTIVATION_ELU:
return AbstractOperatorDesc(
&DML_ACTIVATION_ELU_OPERATOR_SCHEMA,
@ -2269,6 +2358,10 @@ inline AbstractOperatorDesc ConvertOperatorDesc(const DML_OPERATOR_DESC& opDesc)
return AbstractOperatorDesc(
&DML_ACTIVATION_HARDMAX_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_ACTIVATION_HARDMAX_OPERATOR_DESC*>(opDesc.Desc)));
case DML_OPERATOR_ACTIVATION_HARDMAX1:
return AbstractOperatorDesc(
&DML_ACTIVATION_HARDMAX1_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_ACTIVATION_HARDMAX1_OPERATOR_DESC*>(opDesc.Desc)));
case DML_OPERATOR_ACTIVATION_HARD_SIGMOID:
return AbstractOperatorDesc(
&DML_ACTIVATION_HARD_SIGMOID_OPERATOR_SCHEMA,
@ -2289,6 +2382,10 @@ inline AbstractOperatorDesc ConvertOperatorDesc(const DML_OPERATOR_DESC& opDesc)
return AbstractOperatorDesc(
&DML_ACTIVATION_LOG_SOFTMAX_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_ACTIVATION_LOG_SOFTMAX_OPERATOR_DESC*>(opDesc.Desc)));
case DML_OPERATOR_ACTIVATION_LOG_SOFTMAX1:
return AbstractOperatorDesc(
&DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_ACTIVATION_LOG_SOFTMAX1_OPERATOR_DESC*>(opDesc.Desc)));
case DML_OPERATOR_ACTIVATION_PARAMETERIZED_RELU:
return AbstractOperatorDesc(
&DML_ACTIVATION_PARAMETERIZED_RELU_OPERATOR_SCHEMA,
@ -2317,6 +2414,10 @@ inline AbstractOperatorDesc ConvertOperatorDesc(const DML_OPERATOR_DESC& opDesc)
return AbstractOperatorDesc(
&DML_ACTIVATION_SOFTMAX_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_ACTIVATION_SOFTMAX_OPERATOR_DESC*>(opDesc.Desc)));
case DML_OPERATOR_ACTIVATION_SOFTMAX1:
return AbstractOperatorDesc(
&DML_ACTIVATION_SOFTMAX1_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_ACTIVATION_SOFTMAX1_OPERATOR_DESC*>(opDesc.Desc)));
case DML_OPERATOR_ACTIVATION_SOFTPLUS:
return AbstractOperatorDesc(
&DML_ACTIVATION_SOFTPLUS_OPERATOR_SCHEMA,
@ -2337,6 +2438,10 @@ inline AbstractOperatorDesc ConvertOperatorDesc(const DML_OPERATOR_DESC& opDesc)
return AbstractOperatorDesc(
&DML_ACTIVATION_SHRINK_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_ACTIVATION_SHRINK_OPERATOR_DESC*>(opDesc.Desc)));
case DML_OPERATOR_ACTIVATION_GELU:
return AbstractOperatorDesc(
&DML_ACTIVATION_GELU_OPERATOR_SCHEMA,
GetFields(*static_cast<const DML_ACTIVATION_GELU_OPERATOR_DESC*>(opDesc.Desc)));
default:
ORT_THROW_HR(E_INVALIDARG);
return AbstractOperatorDesc(

View file

@ -140,8 +140,9 @@ namespace Dml::GraphDescBuilder
node,
constantCpuNodeInputGetter,
executionHandle,
&graphNodeInfo
/*out*/ &graphNodeInfo
);
ORT_THROW_HR_IF(E_UNEXPECTED, !graphNodeInfo.desc);
uint32_t nodeIndex = gsl::narrow_cast<uint32_t>(graphNodes.size());
AbstractOperatorDesc opDesc = *graphNodeInfo.desc; // Make a copy

View file

@ -164,14 +164,10 @@ namespace Dml
bool DoesNodeContainSupportedDataTypes(
const onnxruntime::Node& node,
bool allow64BitInputThroughStrides,
_In_opt_ const std::unordered_map<std::string, GraphPartition*>* nodeNameToPartitionMap, // Only used when allow64BitInputThroughStrides is true
_In_opt_ const InternalRegistrationInfo* regInfo,
uint32_t supportedDeviceDataTypeMask // Each bit corresponds to each DML_TENSOR_DATA_TYPE.
)
{
ORT_THROW_HR_IF(E_INVALIDARG, allow64BitInputThroughStrides && !nodeNameToPartitionMap);
std::vector<onnxruntime::NodeArg const*> constantCpuInputs;
if (regInfo != nullptr)
@ -253,13 +249,9 @@ namespace Dml
const onnxruntime::Node& node,
const onnxruntime::KernelRegistry& registry,
uint32_t supportedDeviceDataTypeMask, // Each bit corresponds to each DML_TENSOR_DATA_TYPE.
const InternalRegistrationInfoMap& internalRegInfoMap,
bool allow64BitInputThroughStrides,
_In_opt_ const std::unordered_map<std::string, GraphPartition*>* nodeNameToPartitionMap
const InternalRegistrationInfoMap& internalRegInfoMap
)
{
ORT_THROW_HR_IF(E_INVALIDARG, allow64BitInputThroughStrides && !nodeNameToPartitionMap);
const onnxruntime::KernelCreateInfo* createInfo;
Status st = registry.TryFindKernel(node, onnxruntime::kDmlExecutionProvider, &createInfo);
if (!st.IsOK())
@ -279,7 +271,7 @@ namespace Dml
}
// Check whether the node uses any data types which are unsupported by the device.
if (!DoesNodeContainSupportedDataTypes(node, allow64BitInputThroughStrides, nodeNameToPartitionMap, internalRegInfo.get(), supportedDeviceDataTypeMask))
if (!DoesNodeContainSupportedDataTypes(node, internalRegInfo.get(), supportedDeviceDataTypeMask))
{
return false;
}
@ -309,8 +301,7 @@ namespace Dml
// registration. Determine if that registration supports usage as a graph node.
for (auto registry : dmlRegistries)
{
bool allow64BitInputThroughStrides = true;
if (IsNodeSupportedByDml(node, *registry, supportedDeviceDataTypeMask, internalRegInfoMap, allow64BitInputThroughStrides, nodeNameToPartitionMap))
if (IsNodeSupportedByDml(node, *registry, supportedDeviceDataTypeMask, internalRegInfoMap))
{
*isDmlNode = true;
@ -541,7 +532,7 @@ namespace Dml
partitionNodePropsMap.insert(std::make_pair(
GraphDescBuilder::GetUniqueNodeName(*node), std::move(graphNodePropertyMap[node])));
}
#ifdef PRINT_PARTITON_INFO
printf("\n");
#endif
@ -549,7 +540,7 @@ namespace Dml
auto fused_kernel_func = [partitionNodePropsMap, transferredInitializerMap](onnxruntime::FuncManager& func_mgr, const onnxruntime::OpKernelInfo& info, std::unique_ptr<onnxruntime::OpKernel>& out) mutable ->onnxruntime::Status
{
out.reset(CreateFusedGraphKernel(info, partitionNodePropsMap, *transferredInitializerMap));
return Status::OK();
return Status::OK();
};
// build the kernel definition on the fly, and register it to the fused_kernel_regisitry.

View file

@ -64,9 +64,7 @@ namespace Dml
const onnxruntime::Node& node,
const onnxruntime::KernelRegistry& registry,
uint32_t supportedDeviceDataTypeMask, // Each bit corresponds to each DML_TENSOR_DATA_TYPE.
const Windows::AI::MachineLearning::Adapter::InternalRegistrationInfoMap& internalRegInfoMap,
bool allow64BitInputThroughStrides,
_In_opt_ const std::unordered_map<std::string, GraphPartition*>* nodeNameToPartitionMap // Only used when allow64BitInputThroughStrides is true
const Windows::AI::MachineLearning::Adapter::InternalRegistrationInfoMap& internalRegInfoMap
);
} // namespace Dml

View file

@ -89,14 +89,12 @@ namespace Dml
// We need to predict whether the nodes will be assigned to the DML transformer by Lotus,
// which occurs in IExecutionProvider::GetCapability.
bool allow64BitInputThroughStrides = false;
if (!IsNodeSupportedByDml(
node,
*registry,
m_providerImpl->GetSupportedDeviceDataTypeMask(),
*m_providerImpl->GetInternalRegistrationInfoMap().get(),
allow64BitInputThroughStrides,
nullptr))
*m_providerImpl->GetInternalRegistrationInfoMap().get()
))
{
// Can't fuse nodes that don't belong to this execution provider
continue;

View file

@ -22,10 +22,10 @@ namespace WRL
}
namespace Windows::AI::MachineLearning::Adapter
{
{
using namespace Microsoft::WRL;
// Inline method querying whether tensor shapes are defined, during wrappers
// of shape inference callbacks.
template <class T>
@ -122,7 +122,7 @@ public:
};
// Base class for ABI objects which may be "Closed", at which point calls will predictably
// fail or return a dummy value. This is used for transient ABI context objects which
// fail or return a dummy value. This is used for transient ABI context objects which
// are passed to methods on kernel or inferencers, and which wrap Lotus objects whose lifetimes
// are not controlled by reference counts of the encapsulating object.
class Closable
@ -158,15 +158,16 @@ class OpNodeInfoWrapper : public Base1_t, public Base2_t, public Closable
OpNodeInfoWrapper() = delete;
OpNodeInfoWrapper(
const onnxruntime::OpNodeProtoHelper<NodeInfoImpl_t>* impl,
const onnxruntime::OpNodeProtoHelper<NodeInfoImpl_t>* impl,
const EdgeShapes* inputShapesOverride,
const AttributeMap* defaultAttributes,
gsl::span<const uint32_t> requiredConstantCpuInputs,
MLOperatorTensorGetter& constantInputGetter) :
m_impl(impl),
m_inputShapesOverride(inputShapesOverride),
m_constantInputGetter(constantInputGetter),
m_defaultAttributes(defaultAttributes)
MLOperatorTensorGetter& constantInputGetter
)
: m_impl(impl),
m_inputShapesOverride(inputShapesOverride),
m_constantInputGetter(constantInputGetter),
m_defaultAttributes(defaultAttributes)
{
m_requiredConstantCpuInputs.assign(requiredConstantCpuInputs.begin(), requiredConstantCpuInputs.end());
}
@ -213,12 +214,12 @@ class OpNodeInfoWrapper : public Base1_t, public Base2_t, public Closable
HRESULT STDMETHODCALLTYPE GetInputTensorDimensionCount(uint32_t inputIndex, uint32_t* dimensionCount) const noexcept;
HRESULT STDMETHODCALLTYPE GetInputTensorShape(uint32_t inputIndex, uint32_t dimensionCount, uint32_t* dimensions) const noexcept;
bool STDMETHODCALLTYPE IsInputValid(uint32_t inputIndex) const noexcept override;
bool STDMETHODCALLTYPE IsOutputValid(uint32_t outputIndex) const noexcept override;
HRESULT STDMETHODCALLTYPE GetConstantInputTensor(
uint32_t inputIndex,
uint32_t inputIndex,
_Outptr_ IMLOperatorTensor** tensor
) const noexcept;
@ -239,7 +240,7 @@ class OpNodeInfoWrapper : public Base1_t, public Base2_t, public Closable
// May be null
const EdgeShapes* m_inputShapesOverride;
std::vector<uint32_t> m_requiredConstantCpuInputs;
MLOperatorTensorGetter m_constantInputGetter;
@ -275,7 +276,7 @@ class TensorWrapper : public WRL::Base<IMLOperatorTensor>, public Closable
private:
// Lifetime is managed by the caller and guaranteed to outlive this class
onnxruntime::Tensor* m_impl = nullptr;
ComPtr<IWinmlExecutionProvider> m_winmlExecutionProvider;
bool m_internalOperator = false;
@ -284,7 +285,7 @@ class TensorWrapper : public WRL::Base<IMLOperatorTensor>, public Closable
bool m_isDataInterface = false;
// The returned data may be a converted shadow copy, and the piece of it which
// is returned may vary according to kernel registration options.
// is returned may vary according to kernel registration options.
ComPtr<IUnknown> m_dataInterfaceOrShadowCopy;
ComPtr<IUnknown> m_abiDataInterface;
@ -326,7 +327,7 @@ class OnnxTensorWrapper : public WRL::Base<IMLOperatorTensor>, public Closable
};
class OpKernelInfoWrapper : public OpNodeInfoWrapper<
onnxruntime::ProtoHelperNodeContext,
onnxruntime::ProtoHelperNodeContext,
WRL::Base<
Microsoft::WRL::ChainInterfaces<IMLOperatorKernelCreationContextPrivate, IMLOperatorKernelCreationContext>,
IMLOperatorTensorShapeDescription, IMLOperatorAttributes1>,
@ -334,17 +335,17 @@ class OpKernelInfoWrapper : public OpNodeInfoWrapper<
{
public:
OpKernelInfoWrapper(
const onnxruntime::OpKernelInfo* kerneInfo,
IUnknown* abiExecutionObject,
const EdgeShapes* inputShapeOverrides,
const EdgeShapes* inferredOutputShapes,
bool allowInputShapeQuery,
bool allowOutputShapeQuery,
bool isInternalOperator,
const AttributeMap* defaultAttributes,
gsl::span<const uint32_t> requiredConstantCpuInputs,
MLOperatorTensorGetter& constantInputGetter
);
const onnxruntime::OpKernelInfo* kerneInfo,
IUnknown* abiExecutionObject,
const EdgeShapes* inputShapeOverrides,
const EdgeShapes* inferredOutputShapes,
bool allowInputShapeQuery,
bool allowOutputShapeQuery,
bool isInternalOperator,
const AttributeMap* defaultAttributes,
gsl::span<const uint32_t> requiredConstantCpuInputs,
MLOperatorTensorGetter& constantInputGetter
);
// HasTensorShapeDescription returns false if and only if the kernel is registered using
// MLOperatorKernelOptions::AllowDynamicInputTensorSizes. If this flag is specified and upstream
@ -372,7 +373,7 @@ class OpKernelInfoWrapper : public OpNodeInfoWrapper<
{
return E_NOTIMPL;
}
private:
// For shape info, in addition to the info
const EdgeShapes* m_inferredOutputShapes = nullptr;
@ -383,15 +384,15 @@ private:
ComPtr<IWinmlExecutionProvider> m_winmlProvider;
const onnxruntime::OpKernelInfo* m_impl = nullptr;
// The execution object returned through the ABI, which may vary according to kernel
// registration options.
ComPtr<IUnknown> m_abiExecutionObject;
ComPtr<IUnknown> m_abiExecutionObject;
};
// OpKernelInfo used for DML graph fusion. This uses the ONNX graph structures instead of ORT OpKernelInfo.
class DmlGraphOpKernelInfoWrapper : public OpNodeInfoWrapper<
onnxruntime::ProtoHelperNodeContext,
onnxruntime::ProtoHelperNodeContext,
WRL::Base<
Microsoft::WRL::ChainInterfaces<IMLOperatorKernelCreationContextPrivate, IMLOperatorKernelCreationContext>,
IMLOperatorTensorShapeDescription, IMLOperatorAttributes1>,
@ -399,15 +400,15 @@ class DmlGraphOpKernelInfoWrapper : public OpNodeInfoWrapper<
{
public:
DmlGraphOpKernelInfoWrapper(
const onnxruntime::OpNodeProtoHelper<onnxruntime::ProtoHelperNodeContext> * protoHelper,
const void* executionHandle,
bool isInternalOperator,
const EdgeShapes* inferredOutputShapes,
const AttributeMap* defaultAttributes,
DmlGraphNodeCreateInfo* graphNodeCreateInfo,
gsl::span<const uint32_t> requiredConstantCpuInputs,
MLOperatorTensorGetter& constantInputGetter
);
const onnxruntime::OpNodeProtoHelper<onnxruntime::ProtoHelperNodeContext> * protoHelper,
const void* executionHandle,
bool isInternalOperator,
const EdgeShapes* inferredOutputShapes,
const AttributeMap* defaultAttributes,
DmlGraphNodeCreateInfo* graphNodeCreateInfo,
gsl::span<const uint32_t> requiredConstantCpuInputs,
MLOperatorTensorGetter& constantInputGetter
);
// HasTensorShapeDescription returns false if and only if the kernel is registered using
// MLOperatorKernelOptions::AllowDynamicInputTensorSizes. If this flag is specified and upstream
@ -421,9 +422,9 @@ class DmlGraphOpKernelInfoWrapper : public OpNodeInfoWrapper<
HRESULT STDMETHODCALLTYPE GetOutputTensorDimensionCount(uint32_t inputIndex, uint32_t* dimensionCount) const noexcept override;
bool STDMETHODCALLTYPE HasOutputShapeDescription() const noexcept override;
HRESULT STDMETHODCALLTYPE GetOutputTensorShape(uint32_t inputIndex, uint32_t dimensionCount, uint32_t* dimensions) const noexcept override;
bool STDMETHODCALLTYPE IsDmlGraphNode() const noexcept override;
HRESULT STDMETHODCALLTYPE SetDmlOperator(
IDMLOperator* op,
_In_ const DML_OPERATOR_DESC* desc,
@ -459,7 +460,7 @@ class OpKernelContextWrapper : public WRL::Base<IMLOperatorKernelContext>, publi
HRESULT STDMETHODCALLTYPE AllocateTemporaryData(size_t size, IUnknown** data, uint64_t* allocId) const;
void STDMETHODCALLTYPE GetExecutionInterface(IUnknown** executionInterface) const noexcept override;
void Close() override;
std::vector<IMLOperatorTensor*> GetInputTensors();
@ -488,20 +489,21 @@ class OpKernelContextWrapper : public WRL::Base<IMLOperatorKernelContext>, publi
// Compute being called on the kernel. This list is used to maintain their lifetime.
mutable std::vector<ComPtr<IUnknown>> m_temporaryAllocations;
mutable std::vector<ComPtr<IUnknown>> m_temporaryAbiAllocations;
};
};
class AbiOpKernel : public onnxruntime::OpKernel
{
public:
AbiOpKernel(
IMLOperatorKernelFactory* operatorFactory,
const onnxruntime::OpKernelInfo& kerneInfo,
bool requiresInputShapesAtCreation,
bool requiresOutputShapesAtCreation,
bool isInternalOperator,
gsl::span<const uint32_t> requiredConstantCpuInputs,
IMLOperatorShapeInferrer* shapeInferrer,
const AttributeMap* defaultAttributes);
IMLOperatorKernelFactory* operatorFactory,
const onnxruntime::OpKernelInfo& kerneInfo,
bool requiresInputShapesAtCreation,
bool requiresOutputShapesAtCreation,
bool isInternalOperator,
gsl::span<const uint32_t> requiredConstantCpuInputs,
IMLOperatorShapeInferrer* shapeInferrer,
const AttributeMap* defaultAttributes
);
onnxruntime::Status Compute(onnxruntime::OpKernelContext* context) const override;
@ -545,19 +547,19 @@ class AbiOpKernel : public onnxruntime::OpKernel
ComPtr<IWinmlExecutionProvider> m_winmlProvider;
bool m_internalOperator = false;
std::vector<uint32_t> m_requiredConstantCpuInputs;
// The execution object returned through the ABI may vary according to kernel
// registration options.
// registration options.
ComPtr<IUnknown> m_providerExecutionObject;
ComPtr<IUnknown> m_abiExecutionObject;
const AttributeMap* m_defaultAttributes = nullptr;
};
class MLSchemaInferenceContext final : public OpNodeInfoWrapper<
onnx::InferenceContext,
onnx::InferenceContext,
WRL::Base<
Microsoft::WRL::ChainInterfaces<IMLOperatorShapeInferenceContextPrivate, IMLOperatorShapeInferenceContext>,
Microsoft::WRL::ChainInterfaces<IMLOperatorShapeInferenceContextPrivate, IMLOperatorShapeInferenceContext>,
IMLOperatorTypeInferenceContext, IMLOperatorAttributes, IMLOperatorAttributes1>,
onnxruntime::null_type>
{
@ -565,13 +567,13 @@ class MLSchemaInferenceContext final : public OpNodeInfoWrapper<
MLSchemaInferenceContext() = delete;
MLSchemaInferenceContext(
onnxruntime::OpNodeProtoHelper<onnx::InferenceContext>* info,
onnxruntime::OpNodeProtoHelper<onnx::InferenceContext>* info,
onnx::InferenceContext* ctx,
gsl::span<const uint32_t> requiredConstantCpuInputs,
MLOperatorTensorGetter& mLOperatorTensorGetter
);
static ComPtr<MLSchemaInferenceContext> Create(onnxruntime::OpNodeProtoHelper<onnx::InferenceContext>* info,
static ComPtr<MLSchemaInferenceContext> Create(onnxruntime::OpNodeProtoHelper<onnx::InferenceContext>* info,
onnx::InferenceContext* ctx,
gsl::span<const uint32_t> requiredConstantCpuInputs);
@ -595,13 +597,14 @@ class MLKernelInferenceContext final : public OpNodeInfoWrapper<
public:
MLKernelInferenceContext() = delete;
MLKernelInferenceContext(
onnxruntime::OpNodeProtoHelper<onnxruntime::ProtoHelperNodeContext>* info,
const EdgeShapes* inputShapesOverride,
EdgeShapes& inferredOutputShapes,
const AttributeMap* defaultAttributes,
gsl::span<const uint32_t> requiredConstantCpuInputs,
MLOperatorTensorGetter& constantInputGetter) :
OpNodeInfoWrapper(info, inputShapesOverride, defaultAttributes, requiredConstantCpuInputs, constantInputGetter),
onnxruntime::OpNodeProtoHelper<onnxruntime::ProtoHelperNodeContext>* info,
const EdgeShapes* inputShapesOverride,
EdgeShapes& inferredOutputShapes,
const AttributeMap* defaultAttributes,
gsl::span<const uint32_t> requiredConstantCpuInputs,
MLOperatorTensorGetter& constantInputGetter
)
: OpNodeInfoWrapper(info, inputShapesOverride, defaultAttributes, requiredConstantCpuInputs, constantInputGetter),
m_inferredOutputShapes(inferredOutputShapes)
{
}
@ -630,13 +633,15 @@ class MLSupportQueryContext final : public OpNodeInfoWrapper<
MLSupportQueryContext() = delete;
MLSupportQueryContext(
onnxruntime::OpNodeProtoHelper<onnxruntime::ProtoHelperNodeContext>* info,
const AttributeMap* defaultAttributes,
MLOperatorTensorGetter& mLOperatorTensorGetter);
onnxruntime::OpNodeProtoHelper<onnxruntime::ProtoHelperNodeContext>* info,
const AttributeMap* defaultAttributes,
MLOperatorTensorGetter& mLOperatorTensorGetter
);
static ComPtr<MLSupportQueryContext> Create(
onnxruntime::OpNodeProtoHelper<onnxruntime::ProtoHelperNodeContext>* info,
const AttributeMap* defaultAttributes);
onnxruntime::OpNodeProtoHelper<onnxruntime::ProtoHelperNodeContext>* info,
const AttributeMap* defaultAttributes
);
// TODO - ...
};

View file

@ -13,7 +13,7 @@ namespace Dml
}
void DmlOperator::SetDmlOperatorDesc(
const DML_OPERATOR_DESC& operatorDesc,
const DML_OPERATOR_DESC& operatorDesc,
const MLOperatorKernelCreationContext& kernelInfo
)
{
@ -99,7 +99,7 @@ namespace Dml
}
void DmlOperator::SetDmlOperatorDesc(
const DML_OPERATOR_DESC& operatorDesc,
const DML_OPERATOR_DESC& operatorDesc,
const MLOperatorKernelContext& kernelInfo
)
{

View file

@ -25,7 +25,7 @@ public:
ActivationOperatorDescUnion operatorDesc = {};
int coerceAxis = TensorAxis::DoNotCoerce;
std::vector<uint32_t> dmlAxes;
switch (operatorType)
{
@ -39,7 +39,29 @@ public:
case DML_OPERATOR_ACTIVATION_HARDMAX:
{
const uint32_t onnxDimCount = gsl::narrow_cast<uint32_t>(kernelCreationContext.GetTensorShapeDescription().GetInputTensorShape(0).size());
coerceAxis = HandleNegativeAxis(kernelCreationContext.GetOptionalAttribute<int>(AttrName::Axis, 1), onnxDimCount);
int axis = HandleNegativeAxis(kernelCreationContext.GetOptionalAttribute<int>(AttrName::Axis, 1), onnxDimCount);
std::vector<int32_t> onnxAxes(onnxDimCount - axis);
std::iota(onnxAxes.begin(), onnxAxes.end(), static_cast<int32_t>(axis));
dmlAxes.resize(onnxDimCount - axis);
GetDmlAdjustedAxes(onnxAxes, onnxDimCount, m_inputTensorDescs.front().GetDimensionCount(), /*out*/ dmlAxes);
operatorDesc.hardmax1.Axes = dmlAxes.data();
operatorDesc.hardmax1.AxisCount = gsl::narrow_cast<uint32_t>(dmlAxes.size());
}
break;
case DML_OPERATOR_ACTIVATION_SOFTMAX1:
case DML_OPERATOR_ACTIVATION_LOG_SOFTMAX1:
case DML_OPERATOR_ACTIVATION_HARDMAX1:
{
const uint32_t onnxDimCount = gsl::narrow_cast<uint32_t>(kernelCreationContext.GetTensorShapeDescription().GetInputTensorShape(0).size());
int onnxAxis = HandleNegativeAxis(kernelCreationContext.GetOptionalAttribute<int>(AttrName::Axis, -1), onnxDimCount);
dmlAxes.push_back(GetDmlAdjustedAxis(onnxAxis, onnxDimCount, m_inputTensorDescs.front().GetDimensionCount()));
operatorDesc.hardmax1.Axes = dmlAxes.data();
operatorDesc.hardmax1.AxisCount = gsl::narrow_cast<uint32_t>(dmlAxes.size());
}
break;
@ -91,6 +113,7 @@ public:
case DML_OPERATOR_ACTIVATION_SIGMOID:
case DML_OPERATOR_ACTIVATION_TANH:
case DML_OPERATOR_ACTIVATION_SOFTSIGN:
case DML_OPERATOR_ACTIVATION_GELU:
// No additional parameters to set.
break;
@ -99,12 +122,6 @@ public:
break;
}
if (coerceAxis != TensorAxis::DoNotCoerce)
{
m_inputTensorDescs[0] = CreateTensorDescFromInput(kernelCreationContext, 0, coerceAxis);
m_outputTensorDescs[0] = CreateTensorDescFromOutput(kernelCreationContext, 0, coerceAxis);
}
gsl::span<const uint32_t> outputSizes = m_outputTensorDescs[0].GetSizes();
std::vector<DML_TENSOR_DESC> inputDescs;
std::vector<DML_TENSOR_DESC> outputDescs;
@ -134,9 +151,24 @@ public:
operatorDesc.elu.OutputTensor = outputDescs.data();
}
DML_OPERATOR_DESC opDesc = { operatorType, &operatorDesc };
DML_OPERATOR_DESC opDesc = { remappedOperatorType(operatorType), &operatorDesc };
SetDmlOperatorDesc(opDesc, kernelCreationContext);
}
private:
DML_OPERATOR_TYPE remappedOperatorType(const DML_OPERATOR_TYPE operatorType) const {
switch (operatorType)
{
case DML_OPERATOR_ACTIVATION_HARDMAX:
return DML_OPERATOR_ACTIVATION_HARDMAX1;
case DML_OPERATOR_ACTIVATION_SOFTMAX:
return DML_OPERATOR_ACTIVATION_SOFTMAX1;
case DML_OPERATOR_ACTIVATION_LOG_SOFTMAX:
return DML_OPERATOR_ACTIVATION_LOG_SOFTMAX1;
default:
return operatorType;
}
}
};
// A specific type of operation for registration.
@ -166,8 +198,12 @@ DML_OP_DEFINE_CREATION_FUNCTION(Softplus, DmlOperatorActivationTempla
DML_OP_DEFINE_CREATION_FUNCTION(ParametricSoftplus, DmlOperatorActivationTemplate<DML_OPERATOR_ACTIVATION_PARAMETRIC_SOFTPLUS>);
DML_OP_DEFINE_CREATION_FUNCTION(Dropout, DmlOperatorActivationTemplate<DML_OPERATOR_ACTIVATION_IDENTITY>);
DML_OP_DEFINE_CREATION_FUNCTION(Softmax, DmlOperatorActivationTemplate<DML_OPERATOR_ACTIVATION_SOFTMAX>);
DML_OP_DEFINE_CREATION_FUNCTION(Softmax13, DmlOperatorActivationTemplate<DML_OPERATOR_ACTIVATION_SOFTMAX1>);
DML_OP_DEFINE_CREATION_FUNCTION(LogSoftmax, DmlOperatorActivationTemplate<DML_OPERATOR_ACTIVATION_LOG_SOFTMAX>);
DML_OP_DEFINE_CREATION_FUNCTION(LogSoftmax13, DmlOperatorActivationTemplate<DML_OPERATOR_ACTIVATION_LOG_SOFTMAX1>);
DML_OP_DEFINE_CREATION_FUNCTION(Hardmax, DmlOperatorActivationTemplate<DML_OPERATOR_ACTIVATION_HARDMAX>);
DML_OP_DEFINE_CREATION_FUNCTION(Hardmax13, DmlOperatorActivationTemplate<DML_OPERATOR_ACTIVATION_HARDMAX1>);
DML_OP_DEFINE_CREATION_FUNCTION(Shrink, DmlOperatorActivationTemplate<DML_OPERATOR_ACTIVATION_SHRINK>);
DML_OP_DEFINE_CREATION_FUNCTION(Gelu, DmlOperatorActivationTemplate<DML_OPERATOR_ACTIVATION_GELU>);
} // namespace Dml

View file

@ -6,7 +6,7 @@
namespace Dml
{
class DmlOperatorBatchNormalization : public DmlOperator
class DmlOperatorBatchNormalization : public DmlOperator, BatchNormalizationHelper
{
// This order matches the ONNX schema.
enum OnnxInputIndex
@ -21,7 +21,8 @@ class DmlOperatorBatchNormalization : public DmlOperator
public:
DmlOperatorBatchNormalization(const MLOperatorKernelCreationContext& kernelCreationContext)
: DmlOperator(kernelCreationContext)
: DmlOperator(kernelCreationContext),
BatchNormalizationHelper(kernelCreationContext, kernelCreationContext.GetTensorShapeDescription())
{
std::vector<std::optional<uint32_t>> kernelInputIndices = {X, Mean, Variance, Scale, Bias};
DmlOperator::Initialize(kernelCreationContext, kernelInputIndices);
@ -44,6 +45,9 @@ public:
m_outputTensorDescs[0] = CreateTensorDescFromOutput(kernelCreationContext, 0, TensorAxis::DoNotCoerce, TensorAxis::N, TensorAxis::LeftAligned, std::nullopt, m_inputTensorDescs[0].GetDimensionCount());
ML_CHECK_VALID_ARGUMENT(m_inputTensorDescs.size() == 5);
ML_CHECK_VALID_ARGUMENT(m_outputTensorDescs.size() >= 1);
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
@ -63,6 +67,140 @@ public:
}
};
class DmlOperatorBatchNormalization15 : public DmlOperator, BatchNormalizationHelper
{
// This order matches the ONNX schema.
enum OnnxInputIndex
{
X, // Input
Scale,
Bias,
Mean,
Variance,
Count,
};
public:
DmlOperatorBatchNormalization15(const MLOperatorKernelCreationContext& kernelCreationContext)
: DmlOperator(kernelCreationContext),
BatchNormalizationHelper(kernelCreationContext, kernelCreationContext.GetTensorShapeDescription())
{
// DML's BatchNormalization and ONNX order the input tensors differently (with DML as X, Mean, Variance, Scale, Bias),
// and normally we'd need to specify kernelInputIndices to Initialize, but we'll utilize DMLX's mapping instead.
// Passing both reordered kernelInputIndices to Initialize would otherwise confuse DMLX.
DmlOperator::Initialize(kernelCreationContext);
ML_CHECK_VALID_ARGUMENT(m_inputTensorDescs.size() == 5);
ML_CHECK_VALID_ARGUMENT(m_outputTensorDescs.size() >= 1);
const float epsilon = kernelCreationContext.GetOptionalAttribute<float>(AttrName::Epsilon, 0.0f);
const int spatial = kernelCreationContext.GetOptionalAttribute<int>(AttrName::Spatial, 1);
const std::optional<ActivationOperatorDesc> fusedActivation = FusionHelpers::TryGetFusedActivationDesc(kernelCreationContext);
DML_OPERATOR_DESC fusedActivationDmlDesc = fusedActivation ? fusedActivation->GetDmlDesc() : DML_OPERATOR_DESC();
m_inputTensorDescs[0] = CreateTensorDescFromInput(kernelCreationContext, 0, TensorAxis::DoNotCoerce, TensorAxis::N, TensorAxis::LeftAligned);
// Massage each of these 1D tensors (of length C) into ND tensors of the form [1,C,1,1,...].
for (uint32_t i = Scale; i < OnnxInputIndex::Count; ++i)
{
m_inputTensorDescs[i] = CreateTensorDescFromInput(kernelCreationContext, i, TensorAxis::DoNotCoerce, TensorAxis::C, TensorAxis::LeftAligned, std::nullopt, m_inputTensorDescs[0].GetDimensionCount());
}
m_outputTensorDescs[0] = CreateTensorDescFromOutput(kernelCreationContext, 0, TensorAxis::DoNotCoerce, TensorAxis::N, TensorAxis::LeftAligned, std::nullopt, m_inputTensorDescs[0].GetDimensionCount());
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
dml::Graph graph(m_dmlDevice.Get());
dml::TensorDesc inputTensorDesc = inputDescs[OnnxInputIndex::X];
dml::TensorDesc scaleTensorDesc = inputDescs[OnnxInputIndex::Scale];
dml::TensorDesc biasTensorDesc = inputDescs[OnnxInputIndex::Bias];
dml::Expression input = dml::InputTensor(graph, OnnxInputIndex::X, inputTensorDesc);
dml::Expression scale = dml::InputTensor(graph, OnnxInputIndex::Scale, scaleTensorDesc);
dml::Expression bias = dml::InputTensor(graph, OnnxInputIndex::Bias, biasTensorDesc);
dml::Expression mean = dml::InputTensor(graph, OnnxInputIndex::Mean, inputDescs[OnnxInputIndex::Mean]);
dml::Expression variance = dml::InputTensor(graph, OnnxInputIndex::Variance, inputDescs[OnnxInputIndex::Variance]);
// If scale and bias have different data types than input, then coerce them.
if (scaleTensorDesc.dataType != inputTensorDesc.dataType)
{
scale = dml::Cast(scale, inputTensorDesc.dataType);
}
if (biasTensorDesc.dataType != inputTensorDesc.dataType)
{
bias = dml::Cast(bias, inputTensorDesc.dataType);
}
dml::Expression batchNormalization = dml::BatchNormalization(
input,
mean,
variance,
scale,
bias,
static_cast<BOOL>(spatial),
epsilon,
fusedActivation ? &fusedActivationDmlDesc : nullptr
);
DML_EXECUTION_FLAGS executionFlags = GetExecutionFlags();
m_compiledOperator.Attach(graph.Compile(executionFlags, { batchNormalization }).Detach());
}
void Compute(const MLOperatorKernelContext& kernelContext) override
{
std::vector<IMLOperatorTensor*> inputTensors = GetInputTensorsForExecute(kernelContext);
std::vector<IMLOperatorTensor*> outputTensors = GetOutputTensorsForExecute(kernelContext);
ORT_THROW_IF_FAILED(m_executionProvider->ExecuteOperator(
m_compiledOperator.Get(),
m_persistentResourceBinding ? &*m_persistentResourceBinding : nullptr,
gsl::make_span(inputTensors),
gsl::make_span(outputTensors)
));
}
};
void CALLBACK QueryBatchNormalization(IMLOperatorSupportQueryContextPrivate* context, /*out*/ bool* isSupported)
{
*isSupported = false;
// training_mode=1 is unsupported as it isn't needed for inference (https://github.com/onnx/onnx/pull/3333).
MLOperatorAttributes attributes(context);
int32_t trainingMode = attributes.GetOptionalAttribute<int32_t>(AttrName::TrainingMode, 0);
if (trainingMode != 0)
{
return;
}
if (context->GetInputCount() < 5)
{
return;
}
// Get the data type of each tensor.
MLOperatorEdgeDescription operatorEdgeDescription[5];
for (uint32_t i = 0; i < 5; ++i)
{
if (FAILED(context->GetInputEdgeDescription(i, &operatorEdgeDescription[i]))
|| operatorEdgeDescription[i].edgeType != MLOperatorEdgeType::Tensor)
{
return;
}
}
// Fall back if the data types of the mean/variance or scale/bias differ from the input.
MLOperatorTensorDataType inputTensorDataType = operatorEdgeDescription[0].tensorDataType;
for (uint32_t i = 1; i < 5; ++i)
{
if (operatorEdgeDescription[i].tensorDataType != inputTensorDataType)
{
return;
}
}
*isSupported = true;
}
DML_OP_DEFINE_CREATION_FUNCTION(BatchNormalization, DmlOperatorBatchNormalization);
DML_OP_DEFINE_CREATION_FUNCTION(FusedBatchNormalization, DmlOperatorBatchNormalization);

View file

@ -15,7 +15,11 @@ public:
const MLOperatorKernelCreationContext& kernelInfo
) : DmlOperator(kernelInfo)
{
Initialize(kernelInfo);
ML_CHECK_VALID_ARGUMENT(kernelInfo.GetInputCount() >= 1);
ML_CHECK_VALID_ARGUMENT(kernelInfo.GetOutputCount() == 1);
std::vector<std::optional<uint32_t>> inputIndices = { 0 }; // For CastLike, the second tensor ('target_type') is not bound.
std::vector<std::optional<uint32_t>> outputIndices = { 0 };
DmlOperator::Initialize(kernelInfo, inputIndices, outputIndices);
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
@ -38,10 +42,12 @@ public:
m_compiledOperator.Get(),
m_persistentResourceBinding ? &*m_persistentResourceBinding : nullptr,
gsl::make_span(inputTensors),
gsl::make_span(outputTensors)));
gsl::make_span(outputTensors)
));
}
};
DML_OP_DEFINE_CREATION_FUNCTION(Cast, DmlOperatorCast);
DML_OP_DEFINE_CREATION_FUNCTION(CastLike15, DmlOperatorCast);
} // namespace Dml

View file

@ -51,6 +51,7 @@ public:
}
};
DML_OP_DEFINE_CREATION_FUNCTION(CumSum, DmlOperatorCumSum);
DML_OP_DEFINE_CREATION_FUNCTION(CumSum11, DmlOperatorCumSum);
DML_OP_DEFINE_CREATION_FUNCTION(CumSum14, DmlOperatorCumSum);
} // namespace Dml

View file

@ -24,7 +24,7 @@ public:
assert(inputDescs.size() <= 1);
assert(outputDescs.size() == 1);
auto outputTensorShapeDescription = kernelCreationContext.GetTensorShapeDescription();;
auto outputTensorShapeDescription = kernelCreationContext.GetTensorShapeDescription();
std::vector<DimensionType> outputDimensions = outputTensorShapeDescription.GetOutputTensorShape(0);
ML_CHECK_VALID_ARGUMENT(outputDimensions.size() <= OperatorHelper::NchwDimensionCount);

View file

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "precomp.h"
#include "./precomp.h"
namespace Dml
{
@ -13,7 +13,7 @@ class DmlOperatorRecurrentBase: public DmlOperator, public RecurrentHelper
public:
using Self = DmlOperatorRecurrentBase;
DmlOperatorRecurrentBase(const MLOperatorKernelCreationContext& kernelInfo):
explicit DmlOperatorRecurrentBase(const MLOperatorKernelCreationContext& kernelInfo):
DmlOperator(kernelInfo),
RecurrentHelper(kernelInfo, kernelInfo.GetTensorShapeDescription())
{
@ -404,6 +404,28 @@ private:
};
};
void CALLBACK QueryRecurrentNeuralNetwork(IMLOperatorSupportQueryContextPrivate* context, /*out*/ bool* isSupported)
{
// layout=1 for batchwise operation is unsupported, added in opset 14 for RNN, GRU, and LSTM
// (https://github.com/onnx/onnx/pull/3217, https://github.com/onnx/onnx/pull/2284).
// Currently (2022-05-27) the ORT CPU execution provider (lstm_base.h) does not support it either,
// with no models warranting it. When needed, it can be achieved with no new DML API's by just
// swapping the size and strides in the TensorDesc before filling in the *_OPERATOR_DESC, where:
//
// layout=0: (default, consistent with opset 7)
// X.shape = [seq_length, batch_size, input_size]
// Y.shape = [seq_length, num_directions, batch_size, hidden_size]
// initial_h.shape = Y_h.shape = initial_c.shape = Y_c.shape = [num_directions, batch_size, hidden_size]
// layout=1:
// X.shape = [batch_size, seq_length, input_size]
// Y.shape = [batch_size, seq_length, num_directions, hidden_size]
// initial_h.shape = Y_h.shape = initial_c.shape = Y_c.shape = [batch_size, num_directions, hidden_size]
MLOperatorAttributes attributes(context);
int32_t layout = attributes.GetOptionalAttribute<int32_t>(AttrName::Layout, 0);
*isSupported = (layout == 0);
}
DML_OP_DEFINE_CREATION_FUNCTION(RNN, DmlOperatorRecurrentNeuralNetwork);
DML_OP_DEFINE_CREATION_FUNCTION(GRU, DmlOperatorGatedRecurrentUnit);
DML_OP_DEFINE_CREATION_FUNCTION(LSTM, DmlOperatorLongShortTermUnit);

View file

@ -22,7 +22,7 @@ constexpr NameAndIndex nearestNeighborRoundingModes[] =
{"round_prefer_floor", 0}, // round halves down
{"round_prefer_ceil", 1}, // round halves up
{"floor", 2}, // round always down
// {"ceil", 3}, // round always up (requires a DirectML API addition)
{"ceil", 3}, // round always up
};
void ComputePixelOffsetsAndScales(
@ -212,14 +212,16 @@ public:
);
// Find any useless dimensions of size 1 that occur in both input and output.
// This enables higher dimension cases (where models prepend unnecessary
// dimensions) beyond DML's supported dimension count of 4.
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);
@ -248,48 +250,56 @@ public:
std::string mode = kernelCreationContext.GetOptionalAttribute<std::string>(AttrName::Mode, "NEAREST");
DML_INTERPOLATION_MODE interpolationMode = Dml::MapStringToInteropolationMode(mode);
// DML's nearest neighbor mode uses round-halves-up (or round_prefer_ceil) via floor(input.x + 0.5).
// So to support floor, adjust the input by half a pixel.
// round_prefer_floor is not supported without an API extension,
// but existing code already default to treating it as round_prefer_ceil.
// So continue that.
// Map ONNX to DML's mode using offsets and rounding direction.
// These offsets are in addition to the coordinate transform offsets.
DML_AXIS_DIRECTION roundingDirection = DML_AXIS_DIRECTION_DECREASING;
if (interpolationMode == DML_INTERPOLATION_MODE_NEAREST_NEIGHBOR)
{
std::string nearestMode = kernelCreationContext.GetOptionalAttribute<std::string>(AttrName::NearestMode, "round_prefer_floor");
float offsetAdjustment = 0.5f;
auto optionalNearestModeValue = TryMapStringToIndex(nearestMode, nearestNeighborRoundingModes);
if (optionalNearestModeValue)
{
// The round_prefer_floor mode rounds values to the nearest integer, with half ties rounded toward
// negative infinity. The increasing rounding direction is correct, albeit unintuitive, because
// floor(x + 0.5) would return the wrong result, whereas the correct implementation is ceil(x - 0.5).
// The input offset is positive because positive input offsets translate the output rightward and
// downward, which (from the perspective of the output) is equivalent to panning the input
// toward further negative coordinates.
switch (*optionalNearestModeValue)
{
case 0: // round_prefer_floor
case 1: // round_prefer_ceil
break;
case 2: // floor
for (auto& offset : inputPixelOffsets)
{
offset += 0.5;
}
break;
case 0: /*round_prefer_floor*/ roundingDirection = DML_AXIS_DIRECTION_INCREASING; offsetAdjustment = 0.5; break;
case 1: /*round_prefer_ceil */ roundingDirection = DML_AXIS_DIRECTION_DECREASING; offsetAdjustment = -0.5; break;
case 2: /*floor */ roundingDirection = DML_AXIS_DIRECTION_DECREASING; offsetAdjustment = 0.0; break;
case 3: /*ceil */ roundingDirection = DML_AXIS_DIRECTION_INCREASING; offsetAdjustment = 0.0; break;
default:
assert(false);
}
}
if (offsetAdjustment != 0.0f)
{
for (auto& offset : inputPixelOffsets)
{
offset += offsetAdjustment;
}
}
}
// Create the operator description.
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
DML_RESAMPLE1_OPERATOR_DESC operatorDesc = {};
DML_RESAMPLE2_OPERATOR_DESC operatorDesc = {};
operatorDesc.InputTensor = inputDescs.data();
operatorDesc.OutputTensor = outputDescs.data();
operatorDesc.InterpolationMode = interpolationMode;
operatorDesc.RoundingDirection = roundingDirection;
operatorDesc.Scales = paddedScales.data();
operatorDesc.DimensionCount = gsl::narrow_cast<uint32_t>(paddedScales.size());
operatorDesc.InputPixelOffsets = inputPixelOffsets.data();
operatorDesc.OutputPixelOffsets = outputPixelOffsets.data();
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_RESAMPLE1, &operatorDesc };
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_RESAMPLE2, &operatorDesc };
SetDmlOperatorDesc(opDesc, kernelCreationContext);
}
};
@ -323,14 +333,6 @@ void CALLBACK QueryResize(IMLOperatorSupportQueryContextPrivate* context, bool*
return;
}
// DML's nearest neighbor mode uses half pixels rounded down.
std::string nearestMode = attributes.GetOptionalAttribute<std::string>(AttrName::NearestMode, "round_prefer_floor");
auto optionalNearestModeValue = TryMapStringToIndex(nearestMode, nearestNeighborRoundingModes);
if (!optionalNearestModeValue)
{
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.

View file

@ -19,18 +19,13 @@ public:
ML_CHECK_VALID_ARGUMENT(kernelInfo.GetOutputCount() == 1);
std::vector<std::optional<uint32_t>> kernelInputIndices = { 0 }; // Only bind GPU to first 'data' tensor.
DmlOperator::Initialize(kernelInfo, kernelInputIndices);
DmlOperator::Initialize(kernelInfo, kernelInputIndices, std::nullopt, std::nullopt, std::nullopt, /*minimumDimensionCount*/ 1);
const uint32_t inputTensorRank = m_inputTensorDescs[0].GetDimensionCount();
assert(inputTensorRank >= gsl::narrow_cast<uint32_t>(m_offsets.size()));
assert(inputTensorRank >= gsl::narrow_cast<uint32_t>(m_sizes.size()));
assert(inputTensorRank >= gsl::narrow_cast<uint32_t>(m_strides.size()));
// Pad the parameters to respect DML's requirements
FillWithLeadingValues(/*inout*/ m_offsets, inputTensorRank, 0u);
FillWithLeadingValues(/*inout*/ m_sizes, inputTensorRank, 1u);
FillWithLeadingValues(/*inout*/ m_strides, inputTensorRank, 1);
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();

View file

@ -0,0 +1,56 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "./precomp.h"
namespace Dml
{
class DmlOperatorTrilu : public DmlOperator
{
public:
explicit DmlOperatorTrilu(const MLOperatorKernelCreationContext& kernelCreationContext)
: DmlOperator(kernelCreationContext)
{
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetInputCount() >= 1, "Trilu expects 1-2 inputs.");
ML_CHECK_VALID_ARGUMENT(kernelCreationContext.GetOutputCount() == 1, "Trilu expects 1 output.");
std::vector<std::optional<uint32_t>> inputIndices = {0}; // Use only the first tensor. The second tensor is CPU-based (k).
std::vector<std::optional<uint32_t>> outputIndices = {0};
DmlOperator::Initialize(kernelCreationContext, inputIndices, outputIndices);
std::vector<DML_TENSOR_DESC> inputDescs = GetDmlInputDescs();
std::vector<DML_TENSOR_DESC> outputDescs = GetDmlOutputDescs();
assert(inputDescs.size() == 1);
assert(outputDescs.size() == 1);
// Read the diagonal offset from the 2nd tensor (defaults to 0 if absent).
int32_t k = 0;
if (kernelCreationContext.IsInputValid(1))
{
MLOperatorTensor kTensor = kernelCreationContext.GetConstantInputTensor(1);
k = gsl::narrow_cast<int32_t>(ReadScalarTensorCastToInt64(kTensor));
}
auto outputTensorShapeDescription = kernelCreationContext.GetTensorShapeDescription();
std::vector<DimensionType> outputDimensions = outputTensorShapeDescription.GetOutputTensorShape(0);
ML_CHECK_VALID_ARGUMENT(outputDimensions.size() <= OperatorHelper::NchwDimensionCount);
const bool keepUpperDiagonal = kernelCreationContext.GetOptionalAttribute<bool>(AttrName::Upper, 0);
DML_DIAGONAL_MATRIX1_OPERATOR_DESC operatorDesc = {};
operatorDesc.InputTensor = inputDescs.data();
operatorDesc.OutputTensor = outputDescs.data();
operatorDesc.DiagonalFillBegin = keepUpperDiagonal ? INT32_MIN : k + 1;
operatorDesc.DiagonalFillEnd = keepUpperDiagonal ? k : INT32_MAX;
operatorDesc.ValueDataType = m_inputTensorDescs[0].GetDmlDataType();
CastToClampedScalarUnion<float>(operatorDesc.ValueDataType, 0.0f, /*out*/&operatorDesc.Value);
DML_OPERATOR_DESC opDesc = { DML_OPERATOR_DIAGONAL_MATRIX1, &operatorDesc };
SetDmlOperatorDesc(opDesc, kernelCreationContext);
}
};
DML_OP_DEFINE_CREATION_FUNCTION(Trilu, DmlOperatorTrilu);
} // namespace Dml

View file

@ -53,8 +53,8 @@ DEFINE_ENUM_FLAG_OPERATORS(Dml::SupportedTensorDataTypes);
enum class DmlGraphSupport : uint32_t
{
Supported = 0,
NotSupported = 1,
Supported = 0,
NotSupported = 1,
};
DEFINE_ENUM_FLAG_OPERATORS(DmlGraphSupport);
@ -95,6 +95,7 @@ DML_OP_EXTERN_CREATION_FUNCTION(MaxRoiPool);
DML_OP_EXTERN_CREATION_FUNCTION(RoiAlign10);
DML_OP_EXTERN_CREATION_FUNCTION(InstanceNormalization);
DML_OP_EXTERN_CREATION_FUNCTION(BatchNormalization);
DML_OP_EXTERN_CREATION_FUNCTION(BatchNormalization15);
DML_OP_EXTERN_CREATION_FUNCTION(LRN);
DML_OP_EXTERN_CREATION_FUNCTION(MeanVarianceNormalization);
DML_OP_EXTERN_CREATION_FUNCTION(LpNormalization);
@ -179,8 +180,11 @@ DML_OP_EXTERN_CREATION_FUNCTION(Elu);
DML_OP_EXTERN_CREATION_FUNCTION(Celu);
DML_OP_EXTERN_CREATION_FUNCTION(Selu);
DML_OP_EXTERN_CREATION_FUNCTION(Softmax);
DML_OP_EXTERN_CREATION_FUNCTION(Softmax13);
DML_OP_EXTERN_CREATION_FUNCTION(LogSoftmax);
DML_OP_EXTERN_CREATION_FUNCTION(LogSoftmax13);
DML_OP_EXTERN_CREATION_FUNCTION(Hardmax);
DML_OP_EXTERN_CREATION_FUNCTION(Hardmax13);
DML_OP_EXTERN_CREATION_FUNCTION(Softsign);
DML_OP_EXTERN_CREATION_FUNCTION(Softplus);
DML_OP_EXTERN_CREATION_FUNCTION(ParametricSoftplus);
@ -188,6 +192,7 @@ DML_OP_EXTERN_CREATION_FUNCTION(Affine);
DML_OP_EXTERN_CREATION_FUNCTION(Dropout);
DML_OP_EXTERN_CREATION_FUNCTION(MatMul);
DML_OP_EXTERN_CREATION_FUNCTION(Cast);
DML_OP_EXTERN_CREATION_FUNCTION(CastLike15);
DML_OP_EXTERN_CREATION_FUNCTION(MemcpyFromHost);
DML_OP_EXTERN_CREATION_FUNCTION(MemcpyToHost);
DML_OP_EXTERN_CREATION_FUNCTION(TopK7);
@ -222,6 +227,7 @@ DML_OP_EXTERN_CREATION_FUNCTION(Atanh);
DML_OP_EXTERN_CREATION_FUNCTION(Erf);
DML_OP_EXTERN_CREATION_FUNCTION(Where);
DML_OP_EXTERN_CREATION_FUNCTION(Shrink);
DML_OP_EXTERN_CREATION_FUNCTION(Gelu);
DML_OP_EXTERN_CREATION_FUNCTION(OneHot);
DML_OP_EXTERN_CREATION_FUNCTION(EyeLike);
DML_OP_EXTERN_CREATION_FUNCTION(MaxUnpool);
@ -235,7 +241,8 @@ DML_OP_EXTERN_CREATION_FUNCTION(ConstantOfShape);
DML_OP_EXTERN_CREATION_FUNCTION(IsInf);
DML_OP_EXTERN_CREATION_FUNCTION(Mod);
DML_OP_EXTERN_CREATION_FUNCTION(BitShift);
DML_OP_EXTERN_CREATION_FUNCTION(CumSum);
DML_OP_EXTERN_CREATION_FUNCTION(CumSum11);
DML_OP_EXTERN_CREATION_FUNCTION(CumSum14);
DML_OP_EXTERN_CREATION_FUNCTION(GatherElements);
DML_OP_EXTERN_CREATION_FUNCTION(GatherND);
DML_OP_EXTERN_CREATION_FUNCTION(Range);
@ -249,11 +256,14 @@ DML_OP_EXTERN_CREATION_FUNCTION(QLinearMatMul);
DML_OP_EXTERN_CREATION_FUNCTION(DynamicQuantizeLinear);
DML_OP_EXTERN_CREATION_FUNCTION(MatMulInteger);
DML_OP_EXTERN_CREATION_FUNCTION(ConvInteger);
DML_OP_EXTERN_CREATION_FUNCTION(Trilu);
DML_OP_EXTERN_QUERY_FUNCTION(MaxPool);
DML_OP_EXTERN_QUERY_FUNCTION(Slice);
DML_OP_EXTERN_QUERY_FUNCTION(Resize);
DML_OP_EXTERN_QUERY_FUNCTION(EinSum);
DML_OP_EXTERN_QUERY_FUNCTION(RecurrentNeuralNetwork);
DML_OP_EXTERN_QUERY_FUNCTION(BatchNormalization);
constexpr static std::array<const char*, 1> typeNameListDefault = {"T"};
constexpr static std::array<const char*, 2> typeNameListTwo = { "T1", "T2" };
@ -268,7 +278,7 @@ constexpr static std::array<const char*, 2> typeNameListScatterGather = { "T", "
constexpr static std::array<const char*, 1> typeNameListScatterGatherND = { "T" }; // Tind is curiously missing, only allowing 64-bit.
constexpr static std::array<const char*, 2> typeNameListSlice10 = { "T", "Tind" };
constexpr static std::array<const char*, 2> typeNameListWhere = { "B", "T" };
constexpr static std::array<const char*, 1> typeNameListEyeLike = { "T2" };
constexpr static std::array<const char*, 2> typeNameListEyeLike = { "T1", "T2" };
constexpr static std::array<SupportedTensorDataTypes, 1> supportedTypeListAll = {SupportedTensorDataTypes::All};
constexpr static std::array<SupportedTensorDataTypes, 1> supportedTypeListFloat32 = {SupportedTensorDataTypes::Float32};
@ -277,10 +287,12 @@ constexpr static std::array<SupportedTensorDataTypes, 1> supportedTypeListFloat1
constexpr static std::array<SupportedTensorDataTypes, 1> supportedTypeListFloat16to32Ints32 = {SupportedTensorDataTypes::Float16to32 | SupportedTensorDataTypes::Int32 | SupportedTensorDataTypes::UInt32};
constexpr static std::array<SupportedTensorDataTypes, 1> supportedTypeListFloat16to32Ints8to32 = {SupportedTensorDataTypes::Float16to32 | SupportedTensorDataTypes::Ints8Bit | SupportedTensorDataTypes::Ints16Bit | SupportedTensorDataTypes::Ints32Bit};
constexpr static std::array<SupportedTensorDataTypes, 1> supportedTypeListFloat16to32Ints8to64 = {SupportedTensorDataTypes::Float16to32 | SupportedTensorDataTypes::Ints8Bit | SupportedTensorDataTypes::Ints16Bit | SupportedTensorDataTypes::Ints32Bit | SupportedTensorDataTypes::Ints64Bit};
constexpr static std::array<SupportedTensorDataTypes, 1> supportedTypeListFloat16to32SignedInts8to32 = {SupportedTensorDataTypes::Float16to32 | SupportedTensorDataTypes::Int8 | SupportedTensorDataTypes::Int16 | SupportedTensorDataTypes::Int32};
constexpr static std::array<SupportedTensorDataTypes, 1> supportedTypeListFloat16to32Ints32to64 = {SupportedTensorDataTypes::Float16to32 | SupportedTensorDataTypes::Ints32Bit | SupportedTensorDataTypes::Ints64Bit};
constexpr static std::array<SupportedTensorDataTypes, 1> supportedTypeListUInt8to64 = {SupportedTensorDataTypes::UInt8to64};
constexpr static std::array<SupportedTensorDataTypes, 1> supportedTypeListNumericDefault = { SupportedTensorDataTypes::NumericDefault };
constexpr static std::array<SupportedTensorDataTypes, 1> supportedTypeListAllScalars = { SupportedTensorDataTypes::AllScalars };
constexpr static std::array<SupportedTensorDataTypes, 1> supportedTypeListAllScalars = {SupportedTensorDataTypes::AllScalars};
constexpr static std::array<SupportedTensorDataTypes, 2> supportedTypeListEyeLike = { SupportedTensorDataTypes::AllScalars, SupportedTensorDataTypes::AllScalars};
constexpr static std::array<SupportedTensorDataTypes, 1> supportedTypeListBool = {SupportedTensorDataTypes::Bool};
constexpr static std::array<SupportedTensorDataTypes, 2> supportedTypeListPow12 = {SupportedTensorDataTypes::Int32 | SupportedTensorDataTypes::Float16to32, SupportedTensorDataTypes::NumericDefault};
constexpr static std::array<SupportedTensorDataTypes, 2> supportedTypeListTopK = {SupportedTensorDataTypes::NumericDefault | SupportedTensorDataTypes::Ints64Bit, SupportedTensorDataTypes::Int64};
@ -346,7 +358,7 @@ constexpr auto requiredConstantCpuInputs(Args... args)
// Identity operators use Copy, alias their first input, and use elementwise identity operators
// when needed for striding support, but issue actual copies outside the graph.
#define REG_INFO_ID(version, operatorName, ...) \
#define REG_INFO_COPY(version, operatorName, ...) \
#operatorName, OnnxOperatorSet##version::sc_sinceVer_##operatorName, onnxruntime::kOnnxDomain, CreateCopy, ShapeInferenceFunction<ShapeInferenceHelper_##operatorName##version>, true, ##__VA_ARGS__,
// MS-domain operators
@ -386,7 +398,9 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation
{REG_INFO_VER( 10, RoiAlign, typeNameListTwo, supportedTypeListRoiAlign, DmlGraphSupport::Supported)},
{REG_INFO( 7, InstanceNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, BatchNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 9, BatchNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, // v9 just removes 'spatial' attribute.
{REG_INFO( 9, BatchNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)}, // v9 just removes 'spatial' attribute.
{REG_INFO( 14, BatchNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(), std::nullopt, QueryBatchNormalization)}, // v14 adds training_mode attribute
{REG_INFO( 15, BatchNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(), std::nullopt, QueryBatchNormalization)}, // v15 adds differing types for scale and bias vs input.
{REG_INFO( 7, LRN, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 13, LRN, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, MeanVarianceNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
@ -394,21 +408,24 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation
{REG_INFO( 13, MeanVarianceNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, LpNormalization, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, RNN, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::NotSupported)},
{REG_INFO( 14, RNN, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::NotSupported, requiredConstantCpuInputs(), std::nullopt, QueryRecurrentNeuralNetwork)},
{REG_INFO( 7, GRU, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::NotSupported)},
{REG_INFO( 14, GRU, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::NotSupported, requiredConstantCpuInputs(), std::nullopt, QueryRecurrentNeuralNetwork)},
{REG_INFO( 7, LSTM, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::NotSupported)},
{REG_INFO( 14, LSTM, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::NotSupported, requiredConstantCpuInputs(), std::nullopt, QueryRecurrentNeuralNetwork)},
{REG_INFO_MS( 1, ConvTransposeWithDynamicPads, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(2))},
// Data Reorganization Layers
{REG_INFO_VER( 7, Split, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_VER( 11, Split, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, // Adds negative axis.
{REG_INFO_VER( 13, Split, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))}, // Moves splits from constant parameter to dynamic input.
{REG_INFO_VER( 11, Split, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, // Adds negative axis.
{REG_INFO_VER( 13, Split, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))}, // Moves splits from constant parameter to dynamic input.
{REG_INFO( 7, Transpose, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO( 13, Transpose, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO( 7, Concat, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO( 11, Concat, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, // Adds negative axis.
{REG_INFO( 13, Concat, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, // Adds negative axis.
{REG_INFO( 11, Concat, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, // Adds negative axis.
{REG_INFO( 13, Concat, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)}, // Adds negative axis.
{REG_INFO_VER( 7, Slice, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_VER( 10, Slice, typeNameListSlice10, supportedTypeListSlice10, DmlGraphSupport::Supported, requiredConstantCpuInputs(1, 2, 3, 4), std::nullopt, QuerySlice)}, // Adds negative axes.
{REG_INFO_VER( 10, Slice, typeNameListSlice10, supportedTypeListSlice10, DmlGraphSupport::Supported, requiredConstantCpuInputs(1, 2, 3, 4), std::nullopt, QuerySlice)}, // Adds negative axes.
{REG_INFO_VER( 11, Slice, typeNameListSlice10, supportedTypeListSlice10, DmlGraphSupport::Supported, requiredConstantCpuInputs(1, 2, 3, 4), std::nullopt, QuerySlice)},
{REG_INFO_VER( 13, Slice, typeNameListSlice10, supportedTypeListSlice10, DmlGraphSupport::Supported, requiredConstantCpuInputs(1, 2, 3, 4), std::nullopt, QuerySlice)},
{REG_INFO_VER( 7, Pad, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
@ -439,23 +456,26 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation
{REG_INFO( 13, ScatterElements, typeNameListScatterGather, supportedTypeListScatterGather, DmlGraphSupport::Supported)},
{REG_INFO( 11, ScatterND, typeNameListScatterGatherND, supportedTypeListScatterGatherND, DmlGraphSupport::Supported)},
{REG_INFO( 13, ScatterND, typeNameListScatterGatherND, supportedTypeListScatterGatherND, DmlGraphSupport::Supported)},
{REG_INFO( 9, EyeLike, typeNameListEyeLike, supportedTypeListScalars8to32, DmlGraphSupport::Supported)},
{REG_INFO( 9, EyeLike, typeNameListEyeLike, supportedTypeListEyeLike, DmlGraphSupport::Supported)},
{REG_INFO( 14, Trilu, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
// Data reorganization that merely changes the dimensions while keeping the data identical.
{REG_INFO_ID( 7, Identity, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_ID( 13, Identity, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_ID( 7, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_ID( 9, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_ID( 11, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_ID( 13, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_ID( 7, Squeeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_ID( 11, Squeeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_ID( 13, Squeeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
{REG_INFO_ID( 7, Unsqueeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_ID( 11, Unsqueeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_ID( 13, Unsqueeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
{REG_INFO_ID( 7, Reshape, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
{REG_INFO_ID( 13, Reshape, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
{REG_INFO_COPY( 7, Identity, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_COPY(13, Identity, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_COPY(14, Identity, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_COPY( 7, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_COPY( 9, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_COPY(11, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_COPY(13, Flatten, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_COPY( 7, Squeeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_COPY(11, Squeeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_COPY(13, Squeeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
{REG_INFO_COPY( 7, Unsqueeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_COPY(11, Unsqueeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO_COPY(13, Unsqueeze, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
{REG_INFO_COPY( 7, Reshape, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
{REG_INFO_COPY(13, Reshape, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
{REG_INFO_COPY(14, Reshape, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
// Elementwise
{REG_INFO( 7, Sqrt, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
@ -464,7 +484,8 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation
{REG_INFO( 13, Reciprocal, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, Pow, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 12, Pow, typeNameListPow12, supportedTypeListPow12, DmlGraphSupport::Supported)},
{REG_INFO( 13, Pow, typeNameListPow12, supportedTypeListPow12, DmlGraphSupport::Supported)},
{REG_INFO( 13, Pow, typeNameListPow12, supportedTypeListPow12, DmlGraphSupport::Supported)}, // 13 added bfloat16 to T.
{REG_INFO( 15, Pow, typeNameListPow12, supportedTypeListPow12, DmlGraphSupport::Supported)}, // 15 added bfloat16 to T1.
{REG_INFO( 7, Exp, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 13, Exp, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, Log, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
@ -479,14 +500,18 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation
{REG_INFO_VER( 11, Clip, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(1,2))},
{REG_INFO_VER( 12, Clip, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported, requiredConstantCpuInputs(1,2))},
{REG_INFO_VER( 13, Clip, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported, requiredConstantCpuInputs(1,2))},
{REG_INFO( 7, Add, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported)},
{REG_INFO( 13, Add, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported)},
{REG_INFO( 7, Sub, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported)},
{REG_INFO( 13, Sub, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported)},
{REG_INFO( 7, Mul, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported)},
{REG_INFO( 13, Mul, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported)},
{REG_INFO( 7, Div, typeNameListDefault, supportedTypeListFloat16to32Ints32, DmlGraphSupport::Supported)},
{REG_INFO( 13, Div, typeNameListDefault, supportedTypeListFloat16to32Ints32, DmlGraphSupport::Supported)},
{REG_INFO( 7, Add, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported)},
{REG_INFO( 13, Add, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported)},
{REG_INFO( 14, Add, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported)},
{REG_INFO( 7, Sub, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported)},
{REG_INFO( 13, Sub, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported)},
{REG_INFO( 14, Sub, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported)},
{REG_INFO( 7, Mul, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported)},
{REG_INFO( 13, Mul, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported)},
{REG_INFO( 14, Mul, typeNameListDefault, supportedTypeListFloat16to32Ints8to64, DmlGraphSupport::Supported)},
{REG_INFO( 7, Div, typeNameListDefault, supportedTypeListFloat16to32Ints8to32, DmlGraphSupport::Supported)},
{REG_INFO( 13, Div, typeNameListDefault, supportedTypeListFloat16to32Ints8to32, DmlGraphSupport::Supported)},
{REG_INFO( 14, Div, typeNameListDefault, supportedTypeListFloat16to32Ints8to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, Sum, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(), 2)},
{REG_INFO( 8, Sum, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(), 2)},
{REG_INFO( 13, Sum, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported, requiredConstantCpuInputs(), 2)},
@ -608,9 +633,10 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation
{REG_INFO( 7, ScaledTanh, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, Relu, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 13, Relu, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 14, Relu, typeNameListDefault, supportedTypeListFloat16to32SignedInts8to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, LeakyRelu, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, PRelu, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 9, PRelu, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 9, PRelu, typeNameListDefault, supportedTypeListFloat16to32SignedInts8to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, ThresholdedRelu, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 10, ThresholdedRelu, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, Elu, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
@ -618,15 +644,19 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation
{REG_INFO( 7, Selu, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, Softmax, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 11, Softmax, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO_VER( 13, Softmax, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, LogSoftmax, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 11, LogSoftmax, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO_VER( 13, LogSoftmax, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, Hardmax, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 11, Hardmax, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO_VER( 13, Hardmax, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, Softsign, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, Softplus, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, ParametricSoftplus, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 7, Dropout, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 9, Shrink, typeNameListDefault, supportedTypeListNumericDefault, DmlGraphSupport::Supported)},
{REG_INFO_MS( 1, Gelu, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
// Uncategorized
{REG_INFO( 7, MatMul, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
@ -635,6 +665,7 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation
{REG_INFO( 7, Cast, typeNameListTwo, supportedTypeListCast, DmlGraphSupport::Supported)},
{REG_INFO( 9, Cast, typeNameListTwo, supportedTypeListCast, DmlGraphSupport::Supported)},
{REG_INFO( 13, Cast, typeNameListTwo, supportedTypeListCast, DmlGraphSupport::Supported)},
{REG_INFO_VER( 15, CastLike, typeNameListTwo, supportedTypeListCast, DmlGraphSupport::Supported)},
{REG_INFO( 7, MemcpyFromHost, typeNameListDefault, supportedTypeListAll)},
{REG_INFO( 7, MemcpyToHost, typeNameListDefault, supportedTypeListAll)},
{REG_INFO_VER( 7, TopK, typeNameListTopK, supportedTypeListTopK, DmlGraphSupport::Supported)},
@ -642,6 +673,8 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation
{REG_INFO_VER( 11, TopK, typeNameListTopK, supportedTypeListTopK, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
{REG_INFO( 9, OneHot, typeNameListThree, supportedTypeListOneHot, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
{REG_INFO( 11, OneHot, typeNameListThree, supportedTypeListOneHot, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
// Shape-1, Shape-13, Shape-15 rely on CPU.
// Size-1 relies on CPU.
// Fused operators
{REG_INFO_MSDML(1, FusedConv, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
@ -660,11 +693,12 @@ constexpr static OperatorRegistrationInformation operatorRegistrationInformation
{REG_INFO( 11, BitShift, typeNameListDefault, supportedTypeListUInt8to64, DmlGraphSupport::Supported)},
{REG_INFO( 11, Round, typeNameListDefault, supportedTypeListFloat16to32, DmlGraphSupport::Supported)},
{REG_INFO( 10, ReverseSequence, typeNameListDefault, supportedTypeListAllScalars, DmlGraphSupport::Supported)},
{REG_INFO( 11, CumSum, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
{REG_INFO_VER( 11, CumSum, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
{REG_INFO_VER( 14, CumSum, typeNameListDefault, supportedTypeListFloat16to32Ints32to64, DmlGraphSupport::Supported, requiredConstantCpuInputs(1))},
{REG_INFO( 11, Range, typeNameListDefault, supportedTypeListRange, DmlGraphSupport::Supported, requiredConstantCpuInputs(0,1,2))},
{REG_INFO( 9, MaxUnpool, typeNameListTwo, supportedTypeListMaxUnpool, DmlGraphSupport::Supported, requiredConstantCpuInputs(2))},
{REG_INFO( 11, MaxUnpool, typeNameListTwo, supportedTypeListMaxUnpool, DmlGraphSupport::Supported, requiredConstantCpuInputs(2))}, // 11 is identical to 9.
{REG_INFO( 11, MaxUnpool, typeNameListTwo, supportedTypeListMaxUnpool, DmlGraphSupport::Supported, requiredConstantCpuInputs(2))}, // 11 is identical to 9.
{REG_INFO_MS( 1, QLinearAdd, typeNameListDefault, supportedTypeListInteger8, DmlGraphSupport::Supported)},
{REG_INFO( 10, QLinearConv, typeNameListFour, supportedTypeListQLinearConv, DmlGraphSupport::Supported)},

View file

@ -148,6 +148,8 @@ namespace Dml
OperatorInfo{ "ConvTranspose", onnxruntime::kOnnxDomain, OnnxOperatorSet11::sc_sinceVer_ConvTranspose },
OperatorInfo{ "BatchNormalization", onnxruntime::kOnnxDomain, OnnxOperatorSet7::sc_sinceVer_BatchNormalization },
OperatorInfo{ "BatchNormalization", onnxruntime::kOnnxDomain, OnnxOperatorSet9::sc_sinceVer_BatchNormalization },
OperatorInfo{ "BatchNormalization", onnxruntime::kOnnxDomain, OnnxOperatorSet14::sc_sinceVer_BatchNormalization },
OperatorInfo{ "BatchNormalization", onnxruntime::kOnnxDomain, OnnxOperatorSet15::sc_sinceVer_BatchNormalization },
OperatorInfo{ "InstanceNormalization", onnxruntime::kOnnxDomain, OnnxOperatorSet7::sc_sinceVer_InstanceNormalization },
OperatorInfo{ "MeanVarianceNormalization", onnxruntime::kOnnxDomain, OnnxOperatorSet7::sc_sinceVer_MeanVarianceNormalization },
OperatorInfo{ "MeanVarianceNormalization", onnxruntime::kOnnxDomain, OnnxOperatorSet9::sc_sinceVer_MeanVarianceNormalization },
@ -163,6 +165,7 @@ namespace Dml
// The filter for activation functions maps to what DML's fused op internally fuses at the shader level.
OperatorInfo{ "Add", onnxruntime::kOnnxDomain, OnnxOperatorSet7::sc_sinceVer_Add, {"Relu", "LeakyRelu"} },
OperatorInfo{ "Add", onnxruntime::kOnnxDomain, OnnxOperatorSet13::sc_sinceVer_Add, {"Relu", "LeakyRelu"} },
OperatorInfo{ "Add", onnxruntime::kOnnxDomain, OnnxOperatorSet14::sc_sinceVer_Add, {"Relu", "LeakyRelu"} },
OperatorInfo{ "Sum", onnxruntime::kOnnxDomain, OnnxOperatorSet8::sc_sinceVer_Sum, {"Relu", "LeakyRelu"}, 2 },
OperatorInfo{ "Sum", onnxruntime::kOnnxDomain, OnnxOperatorSet13::sc_sinceVer_Sum, {"Relu", "LeakyRelu"}, 2 },
};
@ -179,6 +182,7 @@ namespace Dml
OperatorInfo{ "ScaledTanh", onnxruntime::kOnnxDomain, OnnxOperatorSet7::sc_sinceVer_ScaledTanh },
OperatorInfo{ "Relu", onnxruntime::kOnnxDomain, OnnxOperatorSet7::sc_sinceVer_Relu },
OperatorInfo{ "Relu", onnxruntime::kOnnxDomain, OnnxOperatorSet13::sc_sinceVer_Relu },
OperatorInfo{ "Relu", onnxruntime::kOnnxDomain, OnnxOperatorSet14::sc_sinceVer_Relu },
OperatorInfo{ "LeakyRelu", onnxruntime::kOnnxDomain, OnnxOperatorSet7::sc_sinceVer_LeakyRelu },
OperatorInfo{ "PRelu", onnxruntime::kOnnxDomain, OnnxOperatorSet7::sc_sinceVer_PRelu },
OperatorInfo{ "PRelu", onnxruntime::kOnnxDomain, OnnxOperatorSet9::sc_sinceVer_PRelu },
@ -446,7 +450,7 @@ namespace Dml
return *index;
}
ML_INVALID_ARGUMENT("Unknown interpolation mode");
return (DML_INTERPOLATION_MODE)0;
return static_cast<DML_INTERPOLATION_MODE>(0);
}
#pragma warning(pop)
@ -464,7 +468,7 @@ namespace Dml
return *index;
}
ML_INVALID_ARGUMENT("Unknown depth/space order");
return (DML_DEPTH_SPACE_ORDER)0;
return static_cast<DML_DEPTH_SPACE_ORDER>(0);
}
#pragma warning(pop)

View file

@ -201,62 +201,6 @@ TensorDesc::TensorDesc(
assert(m_bufferTensorDesc.TotalTensorSizeInBytes >= ComputeByteSizeFromDimensions(nonBroadcastDimensions, dataType));
}
void TensorDesc::Remap64bitDmlDataTypeTo32bit()
{
if (m_bufferTensorDesc.DataType != DML_TENSOR_DATA_TYPE_UINT64 &&
m_bufferTensorDesc.DataType != DML_TENSOR_DATA_TYPE_INT64)
{
return; // Nothing to do.
}
uint64_t endPaddingInBytes = 0;
// A workaround for older devices is to use strides to fake 64-bit memory access
// while only the lower 32 bits contains the data. This trick obviously doesn't
// work if the data element is genuine 64-bit. It also doesn't work if the data
// element is negative as the signed bit will be incorrectly interpreted.
m_bufferTensorDesc.DataType = Dml::Remap64bitDmlDataTypeTo32bit(m_bufferTensorDesc.DataType);
// If the strides haven't been calculated yet, initialize them as packed.
if (m_bufferTensorDesc.Strides == nullptr)
{
uint32_t stride = 1;
for (int i = m_bufferTensorDesc.DimensionCount - 1; i >= 0; i--)
{
m_strides[i] = stride;
stride *= m_sizes[i];
}
}
// Double the stride values to emulate 64-bit integer support.
for (uint32_t i = 0; i < m_bufferTensorDesc.DimensionCount; ++i)
{
m_strides[i] *= 2;
}
// The physical size of the tensor will have an extra 4 bytes at the end.
// DMLCalcBufferTensorSize calculates the minimum implied size, which is based on the last
// addressable element of the tensor plus the space for the last element. However, the size
// of the last element is now halved from 8 bytes to 4 bytes.
//
// Example:
// Original Tensor: size={2,3}, strides={3,1}, type=int64, size = (1+{1,2}*{3,1})*sizeof(int64) = 6 * 8 = 48
// Emulated Tensor: size={2,3}, strides={6,2}, type=int32, size = (1+{1,2}*{6,2})*sizeof(int32) = 11 * 4 = 44
//
// DirectML itself won't read/write the last 4 bytes, but we want the total size to be accurate
// so that the entire region can be zeroed.
endPaddingInBytes = sizeof(uint32_t);
m_bufferTensorDesc.Strides = m_strides;
m_bufferTensorDesc.TotalTensorSizeInBytes = DMLCalcBufferTensorSize(
m_bufferTensorDesc.DataType,
m_bufferTensorDesc.DimensionCount,
m_sizes,
m_strides
) + endPaddingInBytes;
}
gsl::span<const uint32_t> TensorDesc::GetStrides() const
{
if (m_bufferTensorDesc.Strides == nullptr)

View file

@ -37,7 +37,6 @@ namespace Dml
inline DML_TENSOR_DATA_TYPE GetDmlDataType() const { return m_bufferTensorDesc.DataType; }
inline MLOperatorTensorDataType GetMlOperatorDataType() const { return m_mlOperatorTensorDataType; }
void ForceUnsignedDataType();
void Remap64bitDmlDataTypeTo32bit();
inline bool IsValid() const { return m_tensorType != DML_TENSOR_TYPE_INVALID; }
inline uint32_t GetDimensionCount() const { return m_bufferTensorDesc.DimensionCount; }

View file

@ -52,6 +52,7 @@
#include "External/DirectMLHelpers/GeneratedSchemaTypes.h"
#include "External/DirectMLHelpers/SchemaHelpers.h"
#include "External/DirectMLHelpers/GeneratedSchemaHelpers.h"
#include "External/DirectMLHelpers/DirectMLX.h"
using Microsoft::WRL::ComPtr;

View file

@ -9,6 +9,7 @@ namespace AttrName
static constexpr const char* ActivationAlpha = "activation_alpha";
static constexpr const char* ActivationBeta = "activation_beta";
static constexpr const char* Activations = "activations";
static constexpr const char* AllowZero = "allowzero";
static constexpr const char* Alpha = "alpha";
static constexpr const char* AutoPad = "auto_pad";
static constexpr const char* Axes = "axes";
@ -51,6 +52,7 @@ namespace AttrName
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* Layout = "layout";
static constexpr const char* Low = "low";
static constexpr const char* Max = "max";
static constexpr const char* Mean = "mean";
@ -86,8 +88,10 @@ namespace AttrName
static constexpr const char* Tiles = "tiles";
static constexpr const char* TimeAxis = "time_axis";
static constexpr const char* To = "to";
static constexpr const char* TrainingMode = "training_mode";
static constexpr const char* TransA = "transA";
static constexpr const char* TransB = "transB";
static constexpr const char* Upper = "upper";
static constexpr const char* Value = "value";
static constexpr const char* WidthScale = "width_scale";

View file

@ -1971,32 +1971,44 @@ namespace OperatorHelper
int inferDim = -1;
DimensionType inElementCount = ComputeElementCountFromDimensions(inputDimensions);
bool allowZero = shapeInfo.template GetOptionalAttribute<int32_t>(AttrName::AllowZero, 0);
for (int i = 0, ci = gsl::narrow_cast<int>(m_shapeDims.size()); i < ci; ++i)
if (allowZero)
{
switch (m_shapeDims[i])
// Just take the shape directly (no special handling for 0).
for (int i = 0, ci = gsl::narrow_cast<int>(m_shapeDims.size()); i < ci; ++i)
{
case -1:
ML_CHECK_VALID_ARGUMENT(inferDim == -1, "Only one dimension can be inferred.");
inferDim = i;
break;
case 0:
outputDimensions[i] = inputDimensions[i];
outElementCount *= outputDimensions[i];
break;
default:
outputDimensions[i] = m_shapeDims[i];
outElementCount *= outputDimensions[i];
break;
}
}
if (inferDim != -1)
else
{
outputDimensions[inferDim] = inElementCount / outElementCount;
outElementCount *= outputDimensions[inferDim];
// Special handling where 0 size means to copy the corresponding input tensor dimension.
for (int i = 0, ci = gsl::narrow_cast<int>(m_shapeDims.size()); i < ci; ++i)
{
switch (m_shapeDims[i])
{
case -1:
ML_CHECK_VALID_ARGUMENT(inferDim == -1, "Only one dimension can be inferred.");
inferDim = i;
break;
case 0:
outputDimensions[i] = inputDimensions[i];
outElementCount *= outputDimensions[i];
break;
default:
outputDimensions[i] = m_shapeDims[i];
outElementCount *= outputDimensions[i];
break;
}
}
if (inferDim != -1)
{
outputDimensions[inferDim] = inElementCount / outElementCount;
}
}
return { EdgeShapes(outputDimensions) };
@ -2241,4 +2253,27 @@ namespace OperatorHelper
return { EdgeShapes(m_outputDimensions) };
}
void BatchNormalizationHelper::Initialize(
const IKernelInformationAdapter& kernelInformation,
const IShapeInformationAdapter& shapeInformation
)
{
ML_CHECK_VALID_ARGUMENT(kernelInformation.GetInputCount() == 5);
ML_CHECK_VALID_ARGUMENT(kernelInformation.GetOutputCount() >= 1 && kernelInformation.GetOutputCount() <= 3);
}
std::vector<EdgeShapes> BatchNormalizationHelper::GetOutputShapes(const MLShapeInferenceContext& shapeInformation) const
{
std::vector<EdgeShapes> outputDimensionsList;
outputDimensionsList.push_back(EdgeShapes(shapeInformation.GetInputTensorShape(0))); // output.shape = input.shape
int32_t trainingMode = shapeInformation.GetOptionalAttribute<int32_t>(AttrName::TrainingMode, 0);
if (trainingMode && shapeInformation.GetOutputCount() >= 3)
{
outputDimensionsList.push_back(EdgeShapes(shapeInformation.GetInputTensorShape(3))); // running_mean.shape = input_mean.shape
outputDimensionsList.push_back(EdgeShapes(shapeInformation.GetInputTensorShape(4))); // running_variance.shape = input_variance.shape
}
return outputDimensionsList;
}
} // namespace OperatorHelper

View file

@ -1302,6 +1302,23 @@ protected:
std::vector<uint32_t> m_outputDimensions;
};
class BatchNormalizationHelper
{
void Initialize(
const IKernelInformationAdapter& kernelInformation,
const IShapeInformationAdapter& shapeInformation
);
public:
template <typename Info_t, typename Shape_t>
BatchNormalizationHelper(const Info_t& info, const Shape_t& shapeInfo)
{
Initialize(KernelInformationAdapter(info), ShapeInformationAdapter(shapeInfo));
}
std::vector<EdgeShapes> GetOutputShapes(const MLShapeInferenceContext& shapeInfo) const;
};
using ShapeInferenceHelper_Conv = ConvHelper;
using ShapeInferenceHelper_ConvTranspose = ConvTransposeHelper;
using ShapeInferenceHelper_ConvTransposeWithDynamicPads = ConvTransposeWithDynamicPadsHelper;
@ -1318,6 +1335,7 @@ using ShapeInferenceHelper_MaxRoiPool = RoiPoolingHelper;
using ShapeInferenceHelper_RoiAlign10 = VersionedOpsetHelper<RoiAlignHelper, 10>;
using ShapeInferenceHelper_InstanceNormalization = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_BatchNormalization = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_BatchNormalization15 = BatchNormalizationHelper;
using ShapeInferenceHelper_LRN = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_MeanVarianceNormalization = GetOutputShapeAsInputShapeHelper;
@ -1361,10 +1379,12 @@ using ShapeInferenceHelper_Unsqueeze7 = VersionedOpsetHelper<UnsqueezeHelper, 7>
using ShapeInferenceHelper_Unsqueeze11 = VersionedOpsetHelper<UnsqueezeHelper, 11>;
using ShapeInferenceHelper_Unsqueeze13 = VersionedOpsetHelper<UnsqueezeHelper, 13>;
using ShapeInferenceHelper_EyeLike = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Trilu = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Expand = ExpandHelper;
using ShapeInferenceHelper_Reshape7 = ReshapeHelper;
using ShapeInferenceHelper_Reshape13 = ReshapeHelper;
using ShapeInferenceHelper_Reshape14 = ReshapeHelper;
using ShapeInferenceHelper_ConstantOfShape = ConstantOfShapeHelper;
using ShapeInferenceHelper_Tile = TileHelper;
using ShapeInferenceHelper_Resize10 = VersionedOpsetHelper<ResizeHelper, 10>;
@ -1458,16 +1478,21 @@ using ShapeInferenceHelper_Elu = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Celu = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Selu = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Softmax = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Softmax13 = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_LogSoftmax = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_LogSoftmax13 = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Hardmax = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Hardmax13 = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Softsign = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Softplus = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_ParametricSoftplus = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Dropout = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Shrink = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Gelu = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Identity7 = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Identity13 = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Identity14 = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_MatMul = MatMulHelper;
using ShapeInferenceHelper_MatMulInteger = MatMulHelper;
using ShapeInferenceHelper_QLinearMatMul = QLinearMatMulHelper;
@ -1488,13 +1513,16 @@ using ShapeInferenceHelper_RandomNormalLike = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Multinomial = MultinomialHelper;
using ShapeInferenceHelper_ReverseSequence = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_CumSum = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_CumSum11 = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_CumSum14 = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_Range = RangeHelper;
using ShapeInferenceHelper_CastLike15 = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_FusedConv = ConvHelper;
using ShapeInferenceHelper_FusedConvTranspose = ConvTransposeHelper;
using ShapeInferenceHelper_FusedInstanceNormalization = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_FusedBatchNormalization = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_FusedBatchNormalization = BatchNormalizationHelper;
using ShapeInferenceHelper_FusedMeanVarianceNormalization = GetOutputShapeAsInputShapeHelper;
using ShapeInferenceHelper_FusedGemm = GemmHelper;
using ShapeInferenceHelper_FusedMatMul = MatMulHelper;

View file

@ -336,8 +336,35 @@ namespace OperatorHelper
static const int sc_sinceVer_Transpose = 13;
static const int sc_sinceVer_Unsqueeze = 13;
static const int sc_sinceVer_ReduseSum = 13;
static const int sc_sinceVer_Softmax = 13;
static const int sc_sinceVer_LogSoftmax = 13;
static const int sc_sinceVer_Hardmax = 13;
} // namespace OnnxOperatorSet13
namespace OnnxOperatorSet14
{
static const int sc_sinceVer_Add = 14;
static const int sc_sinceVer_BatchNormalization = 14;
static const int sc_sinceVer_CumSum = 14;
static const int sc_sinceVer_Div = 14;
static const int sc_sinceVer_Identity = 14;
static const int sc_sinceVer_GRU = 14;
static const int sc_sinceVer_LSTM = 14;
static const int sc_sinceVer_Mul = 14;
static const int sc_sinceVer_Relu = 14;
static const int sc_sinceVer_Reshape = 14;
static const int sc_sinceVer_RNN = 14;
static const int sc_sinceVer_Sub = 14;
static const int sc_sinceVer_Trilu = 14;
} // namespace OnnxOperatorSet14
namespace OnnxOperatorSet15
{
static const int sc_sinceVer_CastLike = 15;
static const int sc_sinceVer_BatchNormalization = 15;
static const int sc_sinceVer_Pow = 15;
} // namespace OnnxOperatorSet14
namespace MsftOperatorSet1
{
static const int sc_sinceVer_FusedConv = 1;
@ -353,6 +380,7 @@ namespace OperatorHelper
static const int sc_sinceVer_DequantizeLinear = 1;
static const int sc_sinceVer_ConvTransposeWithDynamicPads = 1;
static const int sc_sinceVer_QLinearAdd = 1;
static const int sc_sinceVer_Gelu = 1;
} // namespace MsftOperatorSet1
} // namespace OperatorHelper

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="GoogleTestAdapter" version="0.17.1" targetFramework="net46" />
<package id="Microsoft.AI.DirectML" version="1.8.2" targetFramework="native" />
<package id="Microsoft.AI.DirectML.Preview" version="1.9.0-devd10042c94985065a565c042540e15eb75b554663" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.201201.7" targetFramework="native" />
</packages>

View file

@ -523,6 +523,9 @@ def parse_arguments():
parser.add_argument(
"--winml_root_namespace_override", type=str, help="Specify the namespace that WinML builds into."
)
parser.add_argument(
"--dml_external_project", action="store_true", help="Build with DirectML as an external project."
)
parser.add_argument(
"--use_telemetry", action="store_true", help="Only official builds can set this flag to enable telemetry."
)
@ -1035,6 +1038,12 @@ def generate_build_tree(
"-Ddml_LIB_DIR=" + os.path.join(args.dml_path, "lib"),
]
if args.dml_external_project:
cmake_args += [
"-Donnxruntime_USE_CUSTOM_DIRECTML=ON",
"-Ddml_EXTERNAL_PROJECT=ON",
]
if args.use_gdk:
cmake_args += [
"-DCMAKE_TOOLCHAIN_FILE=" + os.path.join(source_dir, "cmake", "gdk_toolchain.cmake"),
@ -1042,8 +1051,8 @@ def generate_build_tree(
"-DGDK_PLATFORM=" + args.gdk_platform,
"-Donnxruntime_BUILD_UNIT_TESTS=OFF", # gtest doesn't build for GDK
]
if args.use_dml and not args.dml_path:
raise BuildError("You must set dml_path when building with the GDK.")
if args.use_dml and not (args.dml_path or args.dml_external_project):
raise BuildError("You must set dml_path or dml_external_project when building with the GDK.")
if is_macOS() and not args.android:
cmake_args += ["-DCMAKE_OSX_ARCHITECTURES=" + args.osx_arch]
@ -1377,7 +1386,7 @@ def setup_dml_build(args, cmake_path, build_dir, configs):
raise BuildError(
"dml_path is invalid.", "dml_path='{}' expected_file='{}'.".format(args.dml_path, file_path)
)
else:
elif not args.dml_external_project:
for config in configs:
# Run the RESTORE_PACKAGES target to perform the initial
# NuGet setup.

View file

@ -188,7 +188,9 @@ def generate_dependencies(xml_text, package_name, version, dependency_id, depend
xml_text.append("</dependencies>")
return
dml_dependency = '<dependency id="Microsoft.AI.DirectML" version="1.8.2"/>'
dml_dependency = (
'<dependency id="Microsoft.AI.DirectML.Preview" version="1.9.0-devd10042c94985065a565c042540e15eb75b554663"/>'
)
if package_name == "Microsoft.AI.MachineLearning":
xml_text.append("<dependencies>")
@ -208,7 +210,7 @@ def generate_dependencies(xml_text, package_name, version, dependency_id, depend
xml_text.append("</dependencies>")
else:
include_dml = package_name == "Microsoft.ML.OnnxRuntime.DirectML"
include_dml = package_name == "Microsoft.ML.OnnxRuntime.DirectML.Preview"
xml_text.append("<dependencies>")
# Support .Net Core