reduce max/min 20 (#17805)

### Description
reducemax/min have been updated in onnx(20). implement it in ort



### Motivation and Context
this is for ort1.17.0 release

---------

Signed-off-by: Liqun Fu <liqfu@microsoft.com>
This commit is contained in:
liqun Fu 2024-01-04 17:41:01 -08:00 committed by GitHub
parent 55a669409a
commit e10a8ae31f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 737 additions and 142 deletions

View file

@ -278,7 +278,8 @@ Do not modify directly.*
|||[13, 17]|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64)|
|||[11, 12]|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64)|
|||[1, 10]|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64)|
|ReduceMax|*in* data:**T**<br> *in* axes:**tensor(int64)**<br> *out* reduced:**T**<br><br>or<br><br>*in* data:**T**<br> *out* reduced:**T**|18+|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(int8), tensor(uint8)|
|ReduceMax|*in* data:**T**<br> *in* axes:**tensor(int64)**<br> *out* reduced:**T**<br><br>or<br><br>*in* data:**T**<br> *out* reduced:**T**|20+|**T** = tensor(bool), tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(int8), tensor(uint8)|
|||[18, 19]|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(int8), tensor(uint8)|
|||[13, 17]|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(int8), tensor(uint8)|
|||12|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(int8), tensor(uint8)|
|||11|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64)|
@ -287,7 +288,8 @@ Do not modify directly.*
|||[13, 17]|**T** = tensor(double), tensor(float), tensor(int32)|
|||[11, 12]|**T** = tensor(double), tensor(float), tensor(int32)|
|||[1, 10]|**T** = tensor(double), tensor(float), tensor(int32)|
|ReduceMin|*in* data:**T**<br> *in* axes:**tensor(int64)**<br> *out* reduced:**T**<br><br>or<br><br>*in* data:**T**<br> *out* reduced:**T**|18+|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(int8), tensor(uint8)|
|ReduceMin|*in* data:**T**<br> *in* axes:**tensor(int64)**<br> *out* reduced:**T**<br><br>or<br><br>*in* data:**T**<br> *out* reduced:**T**|20+|**T** = tensor(bool), tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(int8), tensor(uint8)|
|||[18, 19]|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(int8), tensor(uint8)|
|||[13, 17]|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(int8), tensor(uint8)|
|||12|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64), tensor(int8), tensor(uint8)|
|||11|**T** = tensor(double), tensor(float), tensor(int32), tensor(int64)|

View file

@ -850,21 +850,21 @@ class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain,
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, double, ReduceLogSumExp);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int32_t, ReduceLogSumExp);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int64_t, ReduceLogSumExp);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, float, ReduceMax);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, double, ReduceMax);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int32_t, ReduceMax);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int64_t, ReduceMax);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int8_t, ReduceMax);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, uint8_t, ReduceMax);
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, float, ReduceMax);
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, double, ReduceMax);
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, int32_t, ReduceMax);
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, int64_t, ReduceMax);
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, int8_t, ReduceMax);
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, uint8_t, ReduceMax);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, float, ReduceMean);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, double, ReduceMean);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int32_t, ReduceMean);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, float, ReduceMin);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, double, ReduceMin);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int32_t, ReduceMin);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int64_t, ReduceMin);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int8_t, ReduceMin);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, uint8_t, ReduceMin);
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, float, ReduceMin);
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, double, ReduceMin);
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, int32_t, ReduceMin);
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, int64_t, ReduceMin);
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, int8_t, ReduceMin);
class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, uint8_t, ReduceMin);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, float, ReduceProd);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int32_t, ReduceProd);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int64_t, ReduceProd);
@ -960,6 +960,20 @@ class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 19, Sh
// Opset 20
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, ConstantOfShape);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, bool, ReduceMax);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, float, ReduceMax);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, double, ReduceMax);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, int32_t, ReduceMax);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, int64_t, ReduceMax);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, int8_t, ReduceMax);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, uint8_t, ReduceMax);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, bool, ReduceMin);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, float, ReduceMin);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, double, ReduceMin);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, int32_t, ReduceMin);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, int64_t, ReduceMin);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, int8_t, ReduceMin);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, uint8_t, ReduceMin);
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, DFT);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, float, GridSample);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, double, GridSample);
@ -2263,36 +2277,36 @@ Status RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) {
ReduceLogSumExp)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int64_t,
ReduceLogSumExp)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, float,
ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, double,
ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int32_t,
ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int64_t,
ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int8_t,
ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, uint8_t,
ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, float,
ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, double,
ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, int32_t,
ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, int64_t,
ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, int8_t,
ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, uint8_t,
ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, float,
ReduceMean)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, double,
ReduceMean)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int32_t,
ReduceMean)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, float,
ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, double,
ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int32_t,
ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int64_t,
ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int8_t,
ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, uint8_t,
ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, float,
ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, double,
ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, int32_t,
ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, int64_t,
ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, int8_t,
ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 19, uint8_t,
ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, float,
ReduceProd)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int32_t,
@ -2404,6 +2418,20 @@ Status RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) {
// Opset 20
BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, ConstantOfShape)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, bool, ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, float, ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, double, ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, int32_t, ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, int64_t, ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, int8_t, ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, uint8_t, ReduceMax)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, bool, ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, float, ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, double, ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, int32_t, ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, int64_t, ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, int8_t, ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, uint8_t, ReduceMin)>,
BuildKernelCreateInfo<ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, DFT)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, float, GridSample)>,
BuildKernelCreateInfo<ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 20, double, GridSample)>,

View file

@ -0,0 +1,40 @@
#ifndef CORE_PROVIDERS_CPU_REDUCTION_KERNEL_BASE_H
#define CORE_PROVIDERS_CPU_REDUCTION_KERNEL_BASE_H
#ifndef SHARED_PROVIDER
#include "core/common/optional.h"
#include "core/framework/op_kernel.h"
#endif
namespace onnxruntime {
template <bool allow_multi_axes>
class ReduceKernelBase {
protected:
ReduceKernelBase(const OpKernelInfo& info, optional<int64_t> keepdims_override = {}) {
if (allow_multi_axes) {
axes_ = ToShapeVector(info.GetAttrsOrDefault<int64_t>("axes"));
} else {
auto v = info.GetAttrOrDefault<int64_t>("axis", 0);
axes_.push_back(v);
}
int64_t keepdims = 1;
if (keepdims_override.has_value()) {
keepdims = *keepdims_override;
} else {
ORT_ENFORCE(info.GetAttr("keepdims", &keepdims).IsOK());
}
keepdims_ = (keepdims == 1);
int64_t noop_with_empty_axes = info.GetAttrOrDefault<int64_t>("noop_with_empty_axes", 0);
noop_with_empty_axes_ = (noop_with_empty_axes == 1);
int64_t select_last_index = info.GetAttrOrDefault<int64_t>("select_last_index", 0);
select_last_index_ = (select_last_index != 0);
}
TensorShapeVector axes_;
bool keepdims_;
bool noop_with_empty_axes_;
bool select_last_index_;
};
} // namespace onnxruntime
#endif // !CORE_PROVIDERS_CPU_REDUCTION_KERNEL_BASE_H

View file

@ -114,6 +114,14 @@ namespace onnxruntime {
KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType<uint8_t>()), \
x<uint8_t>);
#define REGISTER_UNARY_ELEMENTWISE_KERNEL_BOOL_ONLY(x, sinceVersion) \
ONNX_CPU_OPERATOR_TYPED_KERNEL( \
x, \
sinceVersion, \
bool, \
KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType<bool>()), \
x<bool>);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL(ReduceL1, 1, 10);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_INT64_ONLY(ReduceL1, 1, 10);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL(ReduceL1, 11, 12);
@ -173,11 +181,18 @@ REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_DOUBLE_ONLY(ReduceMax, 13, 17);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_INT8_ONLY(ReduceMax, 13, 17);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_UINT8_ONLY(ReduceMax, 13, 17);
REGISTER_UNARY_ELEMENTWISE_KERNEL(ReduceMax, 18);
REGISTER_UNARY_ELEMENTWISE_KERNEL_INT64_ONLY(ReduceMax, 18);
REGISTER_UNARY_ELEMENTWISE_KERNEL_DOUBLE_ONLY(ReduceMax, 18);
REGISTER_UNARY_ELEMENTWISE_KERNEL_INT8_ONLY(ReduceMax, 18);
REGISTER_UNARY_ELEMENTWISE_KERNEL_UINT8_ONLY(ReduceMax, 18);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL(ReduceMax, 18, 19);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_INT64_ONLY(ReduceMax, 18, 19);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_DOUBLE_ONLY(ReduceMax, 18, 19);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_INT8_ONLY(ReduceMax, 18, 19);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_UINT8_ONLY(ReduceMax, 18, 19);
REGISTER_UNARY_ELEMENTWISE_KERNEL(ReduceMax, 20);
REGISTER_UNARY_ELEMENTWISE_KERNEL_INT64_ONLY(ReduceMax, 20);
REGISTER_UNARY_ELEMENTWISE_KERNEL_DOUBLE_ONLY(ReduceMax, 20);
REGISTER_UNARY_ELEMENTWISE_KERNEL_INT8_ONLY(ReduceMax, 20);
REGISTER_UNARY_ELEMENTWISE_KERNEL_UINT8_ONLY(ReduceMax, 20);
REGISTER_UNARY_ELEMENTWISE_KERNEL_BOOL_ONLY(ReduceMax, 20);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL(ReduceMean, 1, 10);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL(ReduceMean, 11, 12);
@ -207,11 +222,18 @@ REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_DOUBLE_ONLY(ReduceMin, 13, 17);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_INT8_ONLY(ReduceMin, 13, 17);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_UINT8_ONLY(ReduceMin, 13, 17);
REGISTER_UNARY_ELEMENTWISE_KERNEL(ReduceMin, 18);
REGISTER_UNARY_ELEMENTWISE_KERNEL_INT64_ONLY(ReduceMin, 18);
REGISTER_UNARY_ELEMENTWISE_KERNEL_DOUBLE_ONLY(ReduceMin, 18);
REGISTER_UNARY_ELEMENTWISE_KERNEL_INT8_ONLY(ReduceMin, 18);
REGISTER_UNARY_ELEMENTWISE_KERNEL_UINT8_ONLY(ReduceMin, 18);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL(ReduceMin, 18, 19);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_INT64_ONLY(ReduceMin, 18, 19);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_DOUBLE_ONLY(ReduceMin, 18, 19);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_INT8_ONLY(ReduceMin, 18, 19);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_UINT8_ONLY(ReduceMin, 18, 19);
REGISTER_UNARY_ELEMENTWISE_KERNEL(ReduceMin, 20);
REGISTER_UNARY_ELEMENTWISE_KERNEL_INT64_ONLY(ReduceMin, 20);
REGISTER_UNARY_ELEMENTWISE_KERNEL_DOUBLE_ONLY(ReduceMin, 20);
REGISTER_UNARY_ELEMENTWISE_KERNEL_INT8_ONLY(ReduceMin, 20);
REGISTER_UNARY_ELEMENTWISE_KERNEL_UINT8_ONLY(ReduceMin, 20);
REGISTER_UNARY_ELEMENTWISE_KERNEL_BOOL_ONLY(ReduceMin, 20);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL(ReduceProd, 1, 10);
REGISTER_UNARY_ELEMENTWISE_VERSIONED_KERNEL_INT64_ONLY(ReduceProd, 1, 10);
@ -822,10 +844,57 @@ static void ValidateKeepDims(const Tensor* input, int64_t keepdims) {
ValidateKeepDims(input->Shape(), keepdims);
}
template <typename AGG>
bool check_and_reduce_empty_set_input(OpKernelContext* ctx, const gsl::span<const int64_t> axes, bool keepdims) {
const Tensor* input = ctx->Input<Tensor>(0);
const TensorShape& input_shape = input->Shape();
if (input_shape.Size() != 0) {
return false;
}
// input is an empty set
std::vector<int64_t> input_axes;
if (ctx->InputCount() == 2) {
ORT_ENFORCE(axes.empty(), "Axes input and attribute should not both be present for reduction.");
// second input holds the axes.
const Tensor* axes_tensor = ctx->Input<Tensor>(1);
auto nDims = static_cast<size_t>(axes_tensor->Shape()[0]);
const auto* data = axes_tensor->Data<int64_t>();
input_axes.insert(input_axes.begin(), data, data + nDims);
} else {
input_axes.resize(axes.size());
std::copy(axes.begin(), axes.end(), input_axes.begin());
}
gsl::span<const int64_t> shape_dims = input_shape.GetDims();
const int64_t input_shape_size = narrow<int64_t>(shape_dims.size());
TensorShapeVector output_shape_vector;
for (int64_t i = 0; i < input_shape_size; ++i) {
if (input_axes.empty() || std::find(input_axes.begin(), input_axes.end(), i) != input_axes.end()) {
if (keepdims) {
output_shape_vector.push_back(1);
}
} else {
output_shape_vector.push_back(input_shape[onnxruntime::narrow<size_t>(i)]);
}
}
TensorShape output_shape(output_shape_vector);
Tensor* output = ctx->Output(0, output_shape);
if (output_shape.Size() != 0) {
AGG::fill_for_empty_set(*output);
}
return true;
}
template <typename AGG>
void CommonReduce1Loop(OpKernelContext* ctx,
const gsl::span<const int64_t>& axes_, int64_t keepdims_,
bool noop_with_empty_axes) {
if (check_and_reduce_empty_set_input<AGG>(ctx, axes_, keepdims_ != 0)) {
return;
}
FastReduceKind fast_kind;
TensorShapeVector fast_shape;
TensorShapeVector output_shape;
@ -838,8 +907,8 @@ void CommonReduce1Loop(OpKernelContext* ctx,
const Tensor* input = ctx->Input<Tensor>(0);
Tensor* output = ctx->Output(0, output_shape);
if (fast_kind == FastReduceKind::kEmpty) {
const TensorShape& new_input_shape = input->Shape();
if (new_input_shape.Size() == 1) {
const TensorShape& input_shape = input->Shape();
if (input_shape.Size() == 1) {
const typename AGG::input_type* from_data = input->Data<typename AGG::input_type>();
typename AGG::value_type* to_data = output->MutableData<typename AGG::value_type>();
AGG agg(1, *from_data);
@ -859,6 +928,10 @@ template <typename AGG>
void CommonReduce2Loops(OpKernelContext* ctx,
const gsl::span<const int64_t>& axes_, int64_t keepdims_,
bool noop_with_empty_axes) {
if (check_and_reduce_empty_set_input<AGG>(ctx, axes_, keepdims_ != 0)) {
return;
}
FastReduceKind fast_kind;
TensorShapeVector fast_shape, output_shape, fast_axes;
if (CommonFastReduce<AGG>(ctx, axes_, keepdims_, noop_with_empty_axes,
@ -869,8 +942,8 @@ void CommonReduce2Loops(OpKernelContext* ctx,
const Tensor* input = ctx->Input<Tensor>(0);
Tensor* output = ctx->Output(0, output_shape);
if (fast_kind == FastReduceKind::kEmpty) {
const TensorShape& new_input_shape = input->Shape();
if (new_input_shape.Size() == 1) {
const TensorShape& input_shape = input->Shape();
if (input_shape.Size() == 1) {
const typename AGG::input_type* from_data = input->Data<typename AGG::input_type>();
typename AGG::value_type* to_data = output->MutableData<typename AGG::value_type>();
AGG agg(1, *from_data);

View file

@ -11,8 +11,10 @@
#include "core/providers/cpu/containers.h"
#include "core/util/math.h"
#endif
#include "core/framework/math.h"
#include "core/util/math_cpuonly.h"
#include "core/platform/threadpool.h"
#include "core/providers/cpu/reduction/reduction_kernel_base.h"
#include "core/common/safeint.h"
#include <cmath>
@ -178,6 +180,7 @@ class ReduceAggregator : public ReduceAggregatorBase {
inline void update0(const T&) {}
inline TVAL aggall(const T*) {}
inline TVAL get_value() { return accumulator_; }
static void fill_for_empty_set(Tensor&) { ORT_NOT_IMPLEMENTED(); }
protected:
static void CommonFastReduceRKR(const Tensor& input, const gsl::span<const int64_t>& fast_shape,
@ -217,6 +220,10 @@ class ReduceAggregatorSum : public ReduceAggregator<T, T> {
return aggall(from_data, this->N_);
}
static void fill_for_empty_set(Tensor& output) {
EigenMap<T>(output).array() = static_cast<T>(0);
}
// Fast reduction
static inline FastReduceKind WhichFastReduce() {
return FastReduceKind::kKR | FastReduceKind::kRK | FastReduceKind::kKRK | FastReduceKind::kRKR;
@ -290,6 +297,9 @@ class ReduceAggregatorSumSquare : public ReduceAggregator<T, TVAL> {
return Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, 1>>(from_data, onnxruntime::narrow<size_t>(this->N_)).squaredNorm();
}
inline void update(const T& v) { this->accumulator_ += v * v; }
static void fill_for_empty_set(Tensor& output) {
EigenMap<T>(output).array() = static_cast<T>(0);
}
};
template <typename T>
@ -363,7 +373,11 @@ class ReduceAggregatorMax : public ReduceAggregator<T> {
public:
inline ReduceAggregatorMax(int64_t N, const T& init) : ReduceAggregator<T, T>(N, init) {}
static T aggall(const T* from_data, int64_t size) {
return Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, 1>>(from_data, onnxruntime::narrow<size_t>(size)).maxCoeff();
if constexpr (std::is_same_v<bool, T>) { /* bool specific impl */
return Eigen::Map<const Eigen::Matrix<bool, Eigen::Dynamic, 1>>(from_data, onnxruntime::narrow<size_t>(size)).cast<int>().maxCoeff();
} else { /* generic impl */
return Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, 1>>(from_data, onnxruntime::narrow<size_t>(size)).maxCoeff();
}
}
inline T aggall(const T* from_data) {
return aggall(from_data, this->N_);
@ -383,10 +397,19 @@ class ReduceAggregatorMax : public ReduceAggregator<T> {
concurrency::ThreadPool::TryParallelFor(
tp, onnxruntime::narrow<std::ptrdiff_t>(fast_shape[0]), ParallelReduceFastCost(1, stridei, sizeof(T), 6),
[data, stridei, out](std::ptrdiff_t first, std::ptrdiff_t last) {
EigenVectorMap<T>(out + first, last - first) = ConstEigenMatrixMap<T>(
data + first * stridei, onnxruntime::narrow<size_t>(stridei), last - first)
.colwise()
.maxCoeff();
if constexpr (std::is_same_v<bool, T>) { /* bool specific impl */
EigenVectorMap<bool>(out + first, last - first) = ConstEigenMatrixMap<bool>(
data + first * stridei, onnxruntime::narrow<size_t>(stridei), last - first)
.cast<unsigned char>()
.colwise()
.maxCoeff()
.cast<bool>();
} else {
EigenVectorMap<T>(out + first, last - first) = ConstEigenMatrixMap<T>(
data + first * stridei, onnxruntime::narrow<size_t>(stridei), last - first)
.colwise()
.maxCoeff();
}
});
}
@ -405,8 +428,12 @@ class ReduceAggregatorMax : public ReduceAggregator<T> {
for (int64_t row = 1; row < n_rows; ++row) {
p = data + row * N;
for (int64_t j = begin; j < end; ++j) {
if (out[j] < p[j])
out[j] = p[j];
if constexpr (std::is_same_v<bool, T>) { /* bool specific impl */
out[j] = out[j] || p[j];
} else {
if (out[j] < p[j])
out[j] = p[j];
}
}
}
});
@ -422,11 +449,21 @@ class ReduceAggregatorMax : public ReduceAggregator<T> {
tp, onnxruntime::narrow<std::ptrdiff_t>(fast_shape[0]), ParallelReduceFastCost(fast_shape[1], fast_shape[2], sizeof(T), 6),
[data, fast_shape, stridei, strideo, out](ptrdiff_t begin, ptrdiff_t end) {
for (ptrdiff_t j = begin; j < end; ++j) {
EigenVectorMap<T>(out + j * strideo, onnxruntime::narrow<size_t>(strideo)) =
ConstEigenMatrixMap<T>(
data + j * stridei, onnxruntime::narrow<size_t>(fast_shape[2]), onnxruntime::narrow<size_t>(fast_shape[1]))
.rowwise()
.maxCoeff();
if constexpr (std::is_same_v<bool, T>) { /* bool specific impl */
EigenVectorMap<bool>(out + j * strideo, onnxruntime::narrow<size_t>(strideo)) =
ConstEigenMatrixMap<bool>(
data + j * stridei, onnxruntime::narrow<size_t>(fast_shape[2]), onnxruntime::narrow<size_t>(fast_shape[1]))
.cast<unsigned char>()
.rowwise()
.maxCoeff()
.cast<bool>();
} else {
EigenVectorMap<T>(out + j * strideo, onnxruntime::narrow<size_t>(strideo)) =
ConstEigenMatrixMap<T>(
data + j * stridei, onnxruntime::narrow<size_t>(fast_shape[2]), onnxruntime::narrow<size_t>(fast_shape[1]))
.rowwise()
.maxCoeff();
}
}
});
}
@ -438,8 +475,12 @@ class ReduceAggregatorMax : public ReduceAggregator<T> {
[=](const T* p) -> T { return p[0]; },
[=](T& value, const T* p, int64_t size) {
T v = aggall(p, size);
if (v > value)
value = v;
if constexpr (std::is_same_v<bool, T>) { /* bool specific impl */
value = value || v;
} else {
if (v > value)
value = v;
}
});
}
};
@ -545,6 +586,14 @@ class ReduceAggregatorMin : public ReduceAggregator<T, T> {
}
inline void update(const T& v) { this->accumulator_ = v < this->accumulator_ ? v : this->accumulator_; }
static void fill_for_empty_set(Tensor& output) {
if constexpr (std::is_same_v<bool, T>) { /* bool specific impl */
ORT_NOT_IMPLEMENTED();
} else {
EigenMap<T>(output).array() = std::numeric_limits<T>::infinity();
}
}
// Fast reduction
static inline FastReduceKind WhichFastReduce() {
return FastReduceKind::kKR | FastReduceKind::kRK | FastReduceKind::kKRK | FastReduceKind::kRKR;
@ -558,10 +607,19 @@ class ReduceAggregatorMin : public ReduceAggregator<T, T> {
concurrency::ThreadPool::TryParallelFor(
tp, onnxruntime::narrow<std::ptrdiff_t>(fast_shape[0]), ParallelReduceFastCost(1, stridei, sizeof(T), 6),
[data, stridei, out](std::ptrdiff_t first, std::ptrdiff_t last) {
EigenVectorMap<T>(out + first, last - first) = ConstEigenMatrixMap<T>(
data + first * stridei, onnxruntime::narrow<size_t>(stridei), last - first)
.colwise()
.minCoeff();
if constexpr (std::is_same_v<bool, T>) { /* bool specific impl */
EigenVectorMap<bool>(out + first, last - first) = ConstEigenMatrixMap<bool>(
data + first * stridei, onnxruntime::narrow<size_t>(stridei), last - first)
.cast<unsigned char>()
.colwise()
.minCoeff()
.cast<bool>();
} else {
EigenVectorMap<T>(out + first, last - first) = ConstEigenMatrixMap<T>(
data + first * stridei, onnxruntime::narrow<size_t>(stridei), last - first)
.colwise()
.minCoeff();
}
});
}
@ -580,8 +638,12 @@ class ReduceAggregatorMin : public ReduceAggregator<T, T> {
for (int64_t row = 1; row < n_rows; ++row) {
p = data + row * N;
for (int64_t j = begin; j < end; ++j) {
if (out[j] > p[j])
out[j] = p[j];
if constexpr (std::is_same_v<bool, T>) { /* bool specific impl */
out[j] = out[j] && p[j];
} else {
if (out[j] > p[j])
out[j] = p[j];
}
}
}
});
@ -597,11 +659,21 @@ class ReduceAggregatorMin : public ReduceAggregator<T, T> {
tp, onnxruntime::narrow<std::ptrdiff_t>(fast_shape[0]), ParallelReduceFastCost(fast_shape[1], fast_shape[2], sizeof(T), 6),
[data, fast_shape, stridei, strideo, out](ptrdiff_t begin, ptrdiff_t end) {
for (ptrdiff_t j = begin; j < end; ++j) {
EigenVectorMap<T>(out + j * strideo, onnxruntime::narrow<size_t>(strideo)) =
ConstEigenMatrixMap<T>(
data + j * stridei, onnxruntime::narrow<size_t>(fast_shape[2]), onnxruntime::narrow<size_t>(fast_shape[1]))
.rowwise()
.minCoeff();
if constexpr (std::is_same_v<bool, T>) { /* bool specific impl */
EigenVectorMap<bool>(out + j * strideo, onnxruntime::narrow<size_t>(strideo)) =
ConstEigenMatrixMap<bool>(
data + j * stridei, onnxruntime::narrow<size_t>(fast_shape[2]), onnxruntime::narrow<size_t>(fast_shape[1]))
.cast<unsigned char>()
.rowwise()
.minCoeff()
.cast<bool>();
} else {
EigenVectorMap<T>(out + j * strideo, onnxruntime::narrow<size_t>(strideo)) =
ConstEigenMatrixMap<T>(
data + j * stridei, onnxruntime::narrow<size_t>(fast_shape[2]), onnxruntime::narrow<size_t>(fast_shape[1]))
.rowwise()
.minCoeff();
}
}
});
}
@ -613,8 +685,12 @@ class ReduceAggregatorMin : public ReduceAggregator<T, T> {
[=](const T* p) -> T { return p[0]; },
[=](T& value, const T* p, int64_t size) {
T v = aggall(p, size);
if (v < value)
value = v;
if constexpr (std::is_same_v<bool, T>) { /* bool specific impl */
value = value && v;
} else {
if (v < value)
value = v;
}
});
}
};
@ -627,6 +703,9 @@ class ReduceAggregatorProd : public ReduceAggregator<T, T> {
return Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, 1>>(from_data, onnxruntime::narrow<size_t>(this->N_)).prod();
}
inline void update(const T& v) { this->accumulator_ *= v; }
static void fill_for_empty_set(Tensor& output) {
EigenMap<T>(output).array() = static_cast<T>(1);
}
};
template <typename T>
@ -637,6 +716,10 @@ class ReduceAggregatorL1 : public ReduceAggregator<T, T> {
return Eigen::Map<const Eigen::Matrix<T, Eigen::Dynamic, 1>>(from_data, onnxruntime::narrow<size_t>(this->N_)).cwiseAbs().sum();
}
inline void update(const T& v) { this->accumulator_ += v > 0 ? v : -v; }
static void fill_for_empty_set(Tensor& output) {
EigenMap<T>(output).array() = static_cast<T>(0);
}
};
template <typename T>
@ -648,6 +731,9 @@ class ReduceAggregatorL2 : public ReduceAggregator<T, T> {
}
inline void update(const T& v) { this->accumulator_ += v * v; }
inline T get_value() { return reduce_sqrt<T>(this->accumulator_); }
static void fill_for_empty_set(Tensor& output) {
EigenMap<T>(output).array() = static_cast<T>(0);
}
};
template <typename T>
@ -659,6 +745,9 @@ class ReduceAggregatorLogSum : public ReduceAggregator<T, T> {
}
inline void update(const T& v) { this->accumulator_ += v; }
inline T get_value() { return reduce_log<T>(this->accumulator_); }
static void fill_for_empty_set(Tensor& output) {
EigenMap<T>(output).array() = -std::numeric_limits<T>::infinity();
}
};
template <typename T>
@ -682,6 +771,9 @@ class ReduceAggregatorLogSumExp : public ReduceAggregator<T, T> {
}
inline void update(const T& v) { this->accumulator_ += reduce_exp(v - max_); }
inline T get_value() { return reduce_log<T>(this->accumulator_) + max_; }
static void fill_for_empty_set(Tensor& output) {
EigenMap<T>(output).array() = -std::numeric_limits<T>::infinity();
}
};
void NoTransposePrepareForReduce(const TensorShape& new_input_shape,
@ -710,35 +802,6 @@ void CommonReduce2Loops(OpKernelContext* ctx,
const gsl::span<const int64_t>& axes_, int64_t keepdims_,
bool noop_with_empty_axes = false);
template <bool allow_multi_axes>
class ReduceKernelBase {
protected:
ReduceKernelBase(const OpKernelInfo& info, optional<int64_t> keepdims_override = {}) {
if (allow_multi_axes) {
axes_ = ToShapeVector(info.GetAttrsOrDefault<int64_t>("axes"));
} else {
auto v = info.GetAttrOrDefault<int64_t>("axis", 0);
axes_.push_back(v);
}
int64_t keepdims = 1;
if (keepdims_override.has_value()) {
keepdims = *keepdims_override;
} else {
ORT_ENFORCE(info.GetAttr("keepdims", &keepdims).IsOK());
}
keepdims_ = (keepdims == 1);
int64_t noop_with_empty_axes = info.GetAttrOrDefault<int64_t>("noop_with_empty_axes", 0);
noop_with_empty_axes_ = (noop_with_empty_axes == 1);
int64_t select_last_index = info.GetAttrOrDefault<int64_t>("select_last_index", 0);
select_last_index_ = (select_last_index != 0);
}
TensorShapeVector axes_;
bool keepdims_;
bool noop_with_empty_axes_;
bool select_last_index_;
};
template <bool allow_multi_axes>
class ReduceKernel : public OpKernel, public ReduceKernelBase<allow_multi_axes> {
protected:

View file

@ -4,7 +4,7 @@
#pragma once
#include "core/common/optional.h"
#include "core/providers/cuda/cuda_kernel.h"
#include "core/providers/cpu/reduction/reduction_ops.h"
#include "core/providers/cpu/reduction/reduction_kernel_base.h"
#include "core/providers/cuda/reduction/reduction_functions.h"
namespace onnxruntime {

View file

@ -954,7 +954,6 @@ std::unique_ptr<std::set<BrokenTest>> GetBrokenTests(const std::string& provider
{"reduce_log_sum_exp_empty_set_expanded", "unknown version", {}},
{"reduce_prod_empty_set", "unknown version", {}},
{"reduce_sum_empty_set", "unknown version", {}},
{"reduce_sum_square_empty_set", "unknown version", {}},
{"reduce_sum_square_empty_set_expanded", "unknown version", {}},
#ifdef ENABLE_TRAINING_CORE
{"adagrad", "not a registered function/op", {}}, // Op not registered.
@ -1352,6 +1351,7 @@ std::unique_ptr<std::set<BrokenTest>> GetBrokenTests(const std::string& provider
broken_tests->insert({"gridsample_volumetric_nearest_align_corners_0", "unknown version"});
broken_tests->insert({"gridsample_volumetric_nearest_align_corners_1", "unknown version"});
broken_tests->insert({"spacetodepth", "result differs"});
broken_tests->insert({"reduce_sum_square_empty_set_expanded", "unknown version"});
// Fails with QNN SDK 2.17.0:
// expected 7.70947 (40f6b3f3), got 7.84096 (40fae920), diff: 0.131491, tol=0.00870947 idx=419. 100 of 1715 differ
broken_tests->insert({"facedetection_op8_qdq", "result differs"});

View file

@ -924,7 +924,280 @@ TEST(ReductionOpTest, ReduceMax_default_axes_do_not_keep_dims) {
55.0f, 1.0f,
60.0f, 2.0f});
test.AddOutput<float>("reduced", {}, {60.0f});
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); // TensorRT: full reduce without keepDimensions is not supported with explicit batch //TensorRT: axis must be 0
test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); // TensorRT: full reduce without keepDimensions is not supported with explicit batch //TensorRT: axis must be 0
}
TEST(ReductionOpTest, test_bool_ReduceMax_0) {
OpTester test("ReduceMax", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(0));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {2}, {-1, 1});
test.AddOutput<bool>("reduced", {2}, {true, true});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMin_1) {
OpTester test("ReduceMin", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(0));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {2}, {-1, 1});
test.AddOutput<bool>("reduced", {2}, {false, false});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMax_2) {
OpTester test("ReduceMax", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(1));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {2}, {-1, 1});
test.AddOutput<bool>("reduced", {2, 1, 1}, {true, true});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
}
);
}
TEST(ReductionOpTest, test_bool_ReduceMin_3) {
OpTester test("ReduceMin", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(1));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {2}, {-1, 1});
test.AddOutput<bool>("reduced", {2, 1, 1}, {false, false});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMax_4) {
OpTester test("ReduceMax", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(0));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {2}, {2, 1});
test.AddOutput<bool>("reduced", {2}, {true, true});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMin_5) {
OpTester test("ReduceMin", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(0));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {2}, {2, 1});
test.AddOutput<bool>("reduced", {2}, {false, false});
test.Run();
}
TEST(ReductionOpTest, test_bool_ReduceMax_6) {
OpTester test("ReduceMax", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(1));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {2}, {2, 1});
test.AddOutput<bool>("reduced", {2, 1, 1}, {true, true});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMin_7) {
OpTester test("ReduceMin", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(1));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {2}, {2, 1});
test.AddOutput<bool>("reduced", {2, 1, 1}, {false, false});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMax_8) {
OpTester test("ReduceMax", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(0));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {1}, {0});
test.AddOutput<bool>("reduced", {3, 2}, {false, true, true, true, false, true});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMin_9) {
OpTester test("ReduceMin", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(0));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {1}, {0});
test.AddOutput<bool>("reduced", {3, 2}, {false, false, false, true, false, true});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMax_10) {
OpTester test("ReduceMax", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(1));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {1}, {0});
test.AddOutput<bool>("reduced", {1, 3, 2}, {false, true, true, true, false, true});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMin_11) {
OpTester test("ReduceMin", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(1));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {1}, {0});
test.AddOutput<bool>("reduced", {1, 3, 2}, {false, false, false, true, false, true});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMax_12) {
OpTester test("ReduceMax", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(0));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {1}, {2});
test.AddOutput<bool>("reduced", {2, 3}, {false, true, true, true, true, true});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMin_13) {
OpTester test("ReduceMin", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(0));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {1}, {2});
test.AddOutput<bool>("reduced", {2, 3}, {false, true, false, false, false, false});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMax_14) {
OpTester test("ReduceMax", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(1));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {1}, {2});
test.AddOutput<bool>("reduced", {2, 3, 1}, {false, true, true, true, true, true});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMin_15) {
OpTester test("ReduceMin", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(1));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddInput<int64_t>("axes", {1}, {2});
test.AddOutput<bool>("reduced", {2, 3, 1}, {false, true, false, false, false, false});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMax_16) {
OpTester test("ReduceMax", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(0));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddOutput<bool>("reduced", {}, {true});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMin_17) {
OpTester test("ReduceMin", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(0));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddOutput<bool>("reduced", {}, {false});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMax_18) {
OpTester test("ReduceMax", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(1));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddOutput<bool>("reduced", {1, 1, 1}, {true});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, test_bool_ReduceMin_19) {
OpTester test("ReduceMin", 20);
test.AddAttribute("keepdims", static_cast<int64_t>(1));
test.AddInput<bool>("data", {2, 3, 2}, {false, false, true, true, false, true, false, true, false, true, false, true});
test.AddOutput<bool>("reduced", {1, 1, 1}, {false});
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kOpenVINOExecutionProvider,
});
}
TEST(ReductionOpTest, ReduceMax_do_not_keepdims) {
@ -3254,7 +3527,7 @@ TEST(ReductionOpTest, OptimizeShapeForFastReduce_ReduceDimWithZero1b) {
// test that PrepareForReduce handles this case. Called by all reduction ops so any op can be used in the test
TEST(ReductionOpTest, ReduceDimWithZero1) {
// TODO: Unskip when fixed #41968513
if (DefaultDmlExecutionProvider().get() != nullptr) {
if (DefaultDmlExecutionProvider().get() != nullptr || DefaultRocmExecutionProvider().get() != nullptr) {
GTEST_SKIP() << "Skipping because of the following error: Expected output shape [{1,0,1}] did not match run output shape [{1,1,1}] for reduced";
}
@ -3264,8 +3537,12 @@ TEST(ReductionOpTest, ReduceDimWithZero1) {
tester.Run(expect, error_msg,
// exclude EPs that don't handle this
// TODO: fix reduce kernel for zero set cases. see: https://github.com/microsoft/onnxruntime/issues/18588
{
kCoreMLExecutionProvider,
kCudaExecutionProvider,
kDnnlExecutionProvider,
kMIGraphXExecutionProvider,
kOpenVINOExecutionProvider,
kQnnExecutionProvider,
kTensorrtExecutionProvider,
@ -3275,9 +3552,8 @@ TEST(ReductionOpTest, ReduceDimWithZero1) {
// reduce on all axes keeping dims. should allow the 0 to be the reduced value
OpTester test("ReduceSum", 10);
test.AddAttribute("keepdims", int64_t(1));
test.AddShapeToTensorData(true, 1); // make second dim symbolic so that we don't break during shape inferencing
test.AddInput<float>("data", {3, 0, 2}, {});
test.AddOutput<float>("reduced", {1, 0, 1}, {});
test.AddOutput<float>("reduced", {1, 1, 1}, {0.0f});
run(test);
}
@ -3301,8 +3577,8 @@ TEST(ReductionOpTest, OptimizeShapeForFastReduce_ReduceDimWithZero2) {
TEST(ReductionOpTest, ReduceDimWithZero2) {
// TODO: Unskip when fixed #41968513
if (DefaultDmlExecutionProvider().get() != nullptr) {
GTEST_SKIP() << "Skipping because of the following error: Can't reduce on dim with value of 0 if 'keepdims' is false. Invalid output shape would be produced. input_shape:{3,0,2}";
if (DefaultDmlExecutionProvider().get() != nullptr || DefaultRocmExecutionProvider().get() != nullptr) {
GTEST_SKIP() << "Skipping because of the following error: Can't reduce on dim with value of 0 if 'keepdims' is false. Invalid output shape would be produced. input_shape:{?,0,?}";
}
auto run = [](OpTester& tester, const std::string& error_msg = "") {
@ -3311,23 +3587,25 @@ TEST(ReductionOpTest, ReduceDimWithZero2) {
tester.Run(expect, error_msg,
// exclude EPs that don't handle this
// TODO: fix reduce kernel for zero set cases. see: https://github.com/microsoft/onnxruntime/issues/18588
{
kCoreMLExecutionProvider,
kCudaExecutionProvider,
kDnnlExecutionProvider,
kMIGraphXExecutionProvider,
kOpenVINOExecutionProvider,
kQnnExecutionProvider,
kTensorrtExecutionProvider,
kCoreMLExecutionProvider,
});
};
// reduction without keeping dims on all axes. can't reduce on an axis with value of 0
// reducing on all axes including one or more with 0 dimension, with keepdims=0, results a scalar of 0.
OpTester test2("ReduceSum", 10);
test2.AddAttribute("keepdims", int64_t(0));
test2.AddShapeToTensorData(true, 1);
test2.AddInput<float>("data", {3, 0, 2}, {});
test2.AddOutput<float>("reduced", {}, {0.f});
run(test2,
"Can't reduce on dim with value of 0 if 'keepdims' is false. "
"Invalid output shape would be produced. input_shape:{3,0,2}");
test2.AddOutput<float>("reduced", {}, {0.0f});
run(test2);
}
TEST(ReductionOpTest, OptimizeShapeForFastReduce_ReduceDimWithZero3) {
@ -5478,5 +5756,101 @@ TEST(ReductionOpTest, ReduceSum_RKRK_keepdims) {
test.Run();
}
void test_empty_set(const std::string& op, int opset, bool axes_as_input, float empty_value) {
OpTester test(op, opset);
std::vector<int64_t> input_shape = {2, 0, 4};
int64_t input_size = std::accumulate(input_shape.begin(), input_shape.end(), static_cast<int64_t>(1), std::multiplies<int64_t>());
std::vector<float> data(input_size);
test.AddInput("data", input_shape, data);
std::vector<int64_t> axes = {1};
if (axes_as_input) {
test.AddInput("axes", {(int64_t)(axes.size())}, axes);
} else {
test.AddAttribute("axes", axes);
}
std::vector<int64_t> output_shape = {2, 1, 4};
int64_t output_size = std::accumulate(output_shape.begin(), output_shape.end(), static_cast<int64_t>(1), std::multiplies<int64_t>());
std::vector<float> reduced(output_size, empty_value);
test.AddOutput<float>("reduced", output_shape, reduced);
test.Run(
OpTester::ExpectResult::kExpectSuccess,
"",
{
kCoreMLExecutionProvider,
kCudaExecutionProvider,
kDmlExecutionProvider,
kDnnlExecutionProvider,
kMIGraphXExecutionProvider,
kOpenVINOExecutionProvider,
kQnnExecutionProvider,
kRocmExecutionProvider,
kTensorrtExecutionProvider,
});
}
TEST(ReductionOpTest, empty_set_ReduceL1) {
test_empty_set("ReduceL1", 20, true, 0);
}
TEST(ReductionOpTest, empty_set_ReduceL1_13) {
test_empty_set("ReduceL1", 13, false, 0);
}
TEST(ReductionOpTest, empty_set_ReduceL2) {
test_empty_set("ReduceL2", 20, true, 0);
}
TEST(ReductionOpTest, empty_set_ReduceL2_13) {
test_empty_set("ReduceL2", 13, false, 0);
}
TEST(ReductionOpTest, empty_set_ReduceLogSum) {
test_empty_set("ReduceLogSum", 20, true, -std::numeric_limits<float>::infinity());
}
TEST(ReductionOpTest, empty_set_ReduceLogSum_13) {
test_empty_set("ReduceLogSum", 13, false, -std::numeric_limits<float>::infinity());
}
TEST(ReductionOpTest, empty_set_ReduceLogSumExp) {
test_empty_set("ReduceLogSumExp", 20, true, -std::numeric_limits<float>::infinity());
}
TEST(ReductionOpTest, empty_set_ReduceLogSumExp_13) {
test_empty_set("ReduceLogSumExp", 13, false, -std::numeric_limits<float>::infinity());
}
TEST(ReductionOpTest, empty_set_ReduceMin) {
test_empty_set("ReduceMin", 20, true, std::numeric_limits<float>::infinity());
}
TEST(ReductionOpTest, empty_set_ReduceMin_13) {
test_empty_set("ReduceMin", 13, false, std::numeric_limits<float>::infinity());
}
TEST(ReductionOpTest, empty_set_ReduceProd) {
test_empty_set("ReduceProd", 20, true, 1.0f);
}
TEST(ReductionOpTest, empty_set_ReduceProd_13) {
test_empty_set("ReduceProd", 13, false, 1.0f);
}
TEST(ReductionOpTest, empty_set_ReduceSum) {
test_empty_set("ReduceSum", 20, true, 0.0f);
}
TEST(ReductionOpTest, empty_set_ReduceSum_13) {
test_empty_set("ReduceSum", 11, false, 0.0f);
}
TEST(ReductionOpTest, empty_set_ReduceSumSquare) {
test_empty_set("ReduceSumSquare", 20, true, 0.0f);
}
TEST(ReductionOpTest, empty_set_ReduceSumSquare_13) {
test_empty_set("ReduceSumSquare", 13, false, 0.0f);
}
} // namespace test
} // namespace onnxruntime

View file

@ -262,22 +262,18 @@
"^test_string_split_empty_tensor",
"^test_string_split_maxsplit",
"^test_string_split_no_delimiter",
"^test_reduce_max_bool_inputs",
"^test_reduce_min_bool_inputs",
"^test_reduce_min_empty_set",
"^test_reduce_l1_empty_set",
"^test_reduce_l1_empty_set_expanded",
"^test_reduce_l2_empty_set",
"^test_reduce_l2_empty_set_expanded",
"^test_reduce_log_sum_empty_set",
"^test_reduce_log_sum_empty_set_expanded",
"^test_reduce_log_sum_exp_empty_set",
"^test_reduce_log_sum_exp_empty_set_expanded",
"^test_reduce_prod_empty_set",
"^test_reduce_sum_empty_set",
"^test_reduce_sum_empty_set_non_reduced_axis_zero",
"^test_reduce_sum_square_empty_set",
"^test_reduce_sum_square_empty_set_expanded"
"^test_reduce_l1_empty_set_cuda",
"^test_reduce_l1_empty_set_expanded_cuda",
"^test_reduce_l2_empty_set_cuda",
"^test_reduce_l2_empty_set_expanded_cuda",
"^test_reduce_log_sum_empty_set_cuda",
"^test_reduce_log_sum_empty_set_expanded_cuda",
"^test_reduce_log_sum_exp_empty_set_cuda",
"^test_reduce_log_sum_exp_empty_set_expanded_cuda",
"^test_reduce_prod_empty_set_cuda",
"^test_reduce_sum_empty_set_cuda",
"^test_reduce_sum_square_empty_set_cuda",
"^test_reduce_sum_square_empty_set_expanded_cuda"
],
"current_failing_tests_x86": [
"^test_vgg19",
@ -377,7 +373,23 @@
"^test_constantofshape_int_zeros",
// https://dev.azure.com/onnxruntime/onnxruntime/_build/results?buildId=1141563&view=logs&j=a018b46d-e41a-509d-6581-c95fdaa42fcd&t=d61c1d37-f101-5d28-982f-e5931b720302
"^test_gelu_tanh_2_cpu",
"^test_gelu_tanh_2_expanded_cpu"
"^test_gelu_tanh_2_expanded_cpu",
"^test_reduce_max_bool_inputs",
"^test_reduce_min_bool_inputs",
"^test_reduce_min_empty_set",
"^test_reduce_l1_empty_set",
"^test_reduce_l1_empty_set_expanded",
"^test_reduce_l2_empty_set",
"^test_reduce_l2_empty_set_expanded",
"^test_reduce_log_sum_empty_set",
"^test_reduce_log_sum_empty_set_expanded",
"^test_reduce_log_sum_exp_empty_set",
"^test_reduce_log_sum_exp_empty_set_expanded",
"^test_reduce_prod_empty_set",
"^test_reduce_sum_empty_set",
"^test_reduce_sum_empty_set_non_reduced_axis_zero",
"^test_reduce_sum_square_empty_set",
"^test_reduce_sum_square_empty_set_expanded"
],
"current_failing_tests_NNAPI": [
"^test_maxpool_2d_uint8",
@ -498,7 +510,8 @@
"test_range_int32_type_negative_delta_expanded_cpu", // Error but not a failure.
"test_range_float_type_positive_delta_expanded_cpu", // Error but not a failure.
"test_scan_sum_cpu", // Disabled due to output mismatch with tolerance.
"test_scan9_sum_cpu" // Disabled due to output mismatch with tolerance.
"test_scan9_sum_cpu", // Disabled due to output mismatch with tolerance.
"test_reduce_max_bool_inputs_cpu"
],
"current_failing_tests_OPENVINO_NPU_FP16": [
"^test_prelu_broadcast",
@ -656,8 +669,10 @@
"^test_affine_grid_3d_expanded",
"^test_constantofshape_float_ones",
"^test_constantofshape_int_shape_zero",
"^test_constantofshape_int_zeros"
"^test_constantofshape_int_zeros",
"^test_reduce_log_sum_empty_set_cpu",
"^test_reduce_log_sum_exp_empty_set_cpu",
"^test_reduce_prod_empty_set_cpu"
],
// ORT first supported opset 7, so models with nodes that require versions prior to opset 7 are not supported
"tests_with_pre_opset7_dependencies": [