diff --git a/docs/OperatorKernels.md b/docs/OperatorKernels.md
index 114ab09b5a..8427dfaef4 100644
--- a/docs/OperatorKernels.md
+++ b/docs/OperatorKernels.md
@@ -295,7 +295,8 @@ Do not modify directly.*
|||13|**T** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)
**shape** = tensor(int64)|
|||[5, 12]|**T** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)
**shape** = tensor(int64)|
|||[1, 4]|**T** = tensor(bfloat16), tensor(bool), tensor(double), tensor(float), tensor(float16), tensor(int16), tensor(int32), tensor(int64), tensor(int8), tensor(string), tensor(uint16), tensor(uint32), tensor(uint64), tensor(uint8)|
-|Resize|*in* X:**T**
*in* scales:**tensor(float)**
*out* Y:**T**
or
*in* X:**T1**
*in* roi:**T2**
*in* scales:**tensor(float)**
*in* sizes:**tensor(int64)**
*out* Y:**T1**|18+|**T1** = tensor(float), tensor(int32), tensor(int8), tensor(uint8)|
+|Resize|*in* X:**T**
*in* scales:**tensor(float)**
*out* Y:**T**
or
*in* X:**T1**
*in* roi:**T2**
*in* scales:**tensor(float)**
*in* sizes:**tensor(int64)**
*out* Y:**T1**|19+|**T1** = tensor(float), tensor(int32), tensor(int8), tensor(uint8)|
+|||18|**T1** = tensor(float), tensor(int32), tensor(int8), tensor(uint8)|
|||[13, 17]|**T1** = tensor(float), tensor(int32), tensor(int8), tensor(uint8)|
|||[11, 12]|**T1** = tensor(float), tensor(int32), tensor(int8), tensor(uint8)|
|||10|**T** = tensor(float), tensor(int32), tensor(int8), tensor(uint8)|
diff --git a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc
index 8e1b412dd2..96f2590624 100644
--- a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc
+++ b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc
@@ -840,10 +840,10 @@ class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain,
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 17, double, LayerNormalization);
// Opset 18
-class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, float, Resize);
-class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int32_t, Resize);
-class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int8_t, Resize);
-class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, uint8_t, Resize);
+class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 18, float, Resize);
+class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 18, int32_t, Resize);
+class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 18, int8_t, Resize);
+class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, 18, uint8_t, Resize);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, float, ReduceL1);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int32_t, ReduceL1);
class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, int64_t, ReduceL1);
@@ -922,6 +922,11 @@ class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, Op
class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 18, OptionalGetElement);
#endif
+class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 19, float, Resize);
+class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 19, int32_t, Resize);
+class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 19, int8_t, Resize);
+class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 19, uint8_t, Resize);
+
// !!PLEASE READ BELOW!! Following that, add new entries above this comment
/* *** IMPORTANT! ***
@@ -2175,15 +2180,14 @@ Status RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) {
LayerNormalization)>,
// Opset 18
- BuildKernelCreateInfo,
- BuildKernelCreateInfo,
- BuildKernelCreateInfo,
- BuildKernelCreateInfo,
-
+ BuildKernelCreateInfo,
+ BuildKernelCreateInfo,
+ BuildKernelCreateInfo,
+ BuildKernelCreateInfo,
BuildKernelCreateInfo,
BuildKernelCreateInfo,
BuildKernelCreateInfo,
#endif
+ BuildKernelCreateInfo,
+ BuildKernelCreateInfo,
+ BuildKernelCreateInfo,
+ BuildKernelCreateInfo,
};
for (auto& function_table_entry : function_table) {
diff --git a/onnxruntime/core/providers/cpu/tensor/resize.cc b/onnxruntime/core/providers/cpu/tensor/resize.cc
index fbe8076f4f..d092bfbd97 100644
--- a/onnxruntime/core/providers/cpu/tensor/resize.cc
+++ b/onnxruntime/core/providers/cpu/tensor/resize.cc
@@ -93,32 +93,63 @@ ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL(
KernelDefBuilder().TypeConstraint("T1", DataTypeImpl::GetTensorType()),
Resize);
-ONNX_CPU_OPERATOR_TYPED_KERNEL(
+ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL(
Resize,
18,
+ 18,
+ float,
+ KernelDefBuilder().TypeConstraint("T1", DataTypeImpl::GetTensorType()),
+ Resize);
+
+ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL(
+ Resize,
+ 18,
+ 18,
+ int32_t,
+ KernelDefBuilder().TypeConstraint("T1", DataTypeImpl::GetTensorType()),
+ Resize);
+
+ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL(
+ Resize,
+ 18,
+ 18,
+ int8_t,
+ KernelDefBuilder().TypeConstraint("T1", DataTypeImpl::GetTensorType()),
+ Resize);
+
+ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL(
+ Resize,
+ 18,
+ 18,
+ uint8_t,
+ KernelDefBuilder().TypeConstraint("T1", DataTypeImpl::GetTensorType()),
+ Resize);
+
+ONNX_CPU_OPERATOR_TYPED_KERNEL(
+ Resize,
+ 19,
float,
KernelDefBuilder().TypeConstraint("T1", DataTypeImpl::GetTensorType()),
Resize);
ONNX_CPU_OPERATOR_TYPED_KERNEL(
Resize,
- 18,
+ 19,
int32_t,
KernelDefBuilder().TypeConstraint("T1", DataTypeImpl::GetTensorType()),
Resize);
ONNX_CPU_OPERATOR_TYPED_KERNEL(
Resize,
- 18,
+ 19,
int8_t,
KernelDefBuilder().TypeConstraint("T1", DataTypeImpl::GetTensorType()),
Resize);
ONNX_CPU_OPERATOR_TYPED_KERNEL(
Resize,
- 18,
+ 19,
uint8_t,
KernelDefBuilder().TypeConstraint("T1", DataTypeImpl::GetTensorType()),
Resize);
-
} // namespace onnxruntime
diff --git a/onnxruntime/core/providers/cpu/tensor/upsamplebase.h b/onnxruntime/core/providers/cpu/tensor/upsamplebase.h
index 72948ae263..c13c9d42dd 100644
--- a/onnxruntime/core/providers/cpu/tensor/upsamplebase.h
+++ b/onnxruntime/core/providers/cpu/tensor/upsamplebase.h
@@ -41,7 +41,7 @@ enum ResizeCoordinateTransformationMode {
TF_HALF_PIXEL_FOR_NN = 3,
ALIGN_CORNERS = 4,
TF_CROP_AND_RESIZE = 5,
- CoordinateTransformationModeCount = 6,
+ HALF_PIXEL_SYMMETRIC = 6,
};
enum ResizeNearestMode {
@@ -50,7 +50,6 @@ enum ResizeNearestMode {
ROUND_PREFER_CEIL = 2,
FLOOR = 3,
CEIL = 4,
- NearestModeCount = 5,
};
enum class AspectRatioPolicy {
@@ -237,6 +236,9 @@ class UpsampleBase {
if (coordinate_transform_mode_name == "half_pixel") {
return HALF_PIXEL;
}
+ if (coordinate_transform_mode_name == "half_pixel_symmetric") {
+ return HALF_PIXEL_SYMMETRIC;
+ }
ORT_THROW("coordinate_transform_mode:[" + coordinate_transform_mode_name + "] is not supportted!");
}
@@ -267,6 +269,15 @@ class UpsampleBase {
: 0.5 * (roi_start + roi_end) * (length_original - 1);
return static_cast(orig);
};
+ case HALF_PIXEL_SYMMETRIC:
+ return [](float x_resized, float x_scale, float length_resized, float length_original, float, float) {
+ float output_width = x_scale * length_original;
+ float adjustment = length_resized / output_width;
+ float center = length_original / 2;
+ float offset = center * (1 - adjustment);
+ auto orig = offset + (x_resized + 0.5) / x_scale - 0.5;
+ return static_cast(orig);
+ };
default: // "half_pixel"
return [](float x_resized, float x_scale, float, float, float, float) {
return ((x_resized + 0.5f) / x_scale) - 0.5f;
diff --git a/onnxruntime/test/providers/cpu/tensor/resize_op_test.cc b/onnxruntime/test/providers/cpu/tensor/resize_op_test.cc
index 25d1acbbd6..832a8a744c 100644
--- a/onnxruntime/test/providers/cpu/tensor/resize_op_test.cc
+++ b/onnxruntime/test/providers/cpu/tensor/resize_op_test.cc
@@ -1772,6 +1772,48 @@ TEST(ResizeOpTest, ResizeOpTypeCheck_Ver18) {
ResizeOpTypeCheck_Ver_11_13_18(18);
}
+TEST(ResizeOpTest, ResizeOpHalfPixelSymmetricDownSample_ver19) {
+ OpTester test("Resize", 19);
+ test.AddAttribute("mode", "linear");
+ test.AddAttribute("coordinate_transformation_mode", "half_pixel_symmetric");
+
+ constexpr int64_t N = 1, C = 1, H = 1, W = 4;
+ std::vector X = {1.0f, 2.0f, 3.0f, 4.0f};
+ test.AddInput("X", {N, C, H, W}, X);
+ std::vector roi{};
+ test.AddInput("roi", {0}, roi);
+ std::vector scales{1.0f, 1.0f, 1.0f, 0.6f};
+ test.AddInput("scales", {4}, scales);
+
+ std::vector Y = {1.666667f, 3.333333f};
+
+ test.AddOutput("Y", {N, C, static_cast(H * scales[2]), static_cast(W * scales[3])}, Y);
+ test.Run();
+}
+
+TEST(ResizeOpTest, ResizeOpHalfPixelSymmetricUpSample_ver19) {
+ OpTester test("Resize", 19);
+ test.AddAttribute("mode", "linear");
+ test.AddAttribute("coordinate_transformation_mode", "half_pixel_symmetric");
+
+ constexpr int64_t N = 1, C = 1, H = 2, W = 2;
+ std::vector X = {1.0f, 2.0f, 3.0f, 4.0f};
+
+ test.AddInput("X", {N, C, H, W}, X);
+ std::vector roi{};
+ test.AddInput("roi", {0}, roi);
+ std::vector scales{1.0f, 1.0f, 2.3f, 2.94f};
+ test.AddInput("scales", {4}, scales);
+
+ std::vector Y = {1.0f, 1.159864f, 1.5f, 1.840136f, 2.0f,
+ 1.565217f, 1.725081f, 2.065217f, 2.405353f, 2.565217f,
+ 2.434782f, 2.594647f, 2.934783f, 3.274919f, 3.434783f,
+ 3.0f, 3.159864f, 3.5f, 3.840136f, 4.0f};
+
+ test.AddOutput("Y", {N, C, static_cast(H * scales[2]), static_cast(W * scales[3])}, Y);
+ test.Run();
+}
+
/*
* Most of TestCase against Anti-aliasing will have the attribute of "exclude_outside" as 1.
* It's as Pillow 's Resize is corresponding to ONNX op with exclude_outside equaling 1.
@@ -2186,6 +2228,5 @@ TEST(ResizeOpTest, Antialias_Use_Extrapolation) {
},
{4, 4, 4}, X, {3, 3, 3}, Y);
}
-
} // namespace test
} // namespace onnxruntime