diff --git a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc index 8c4e30847c..8550611e6e 100644 --- a/onnxruntime/core/providers/cpu/cpu_execution_provider.cc +++ b/onnxruntime/core/providers/cpu/cpu_execution_provider.cc @@ -407,7 +407,10 @@ class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Ga class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, uint8_t, BitShift); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, uint32_t, BitShift); class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, uint64_t, BitShift); -class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Pad); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, float, Pad); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, double, Pad); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, int32_t, Pad); +class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, int64_t, Pad); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, GatherND); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Range); class ONNX_OPERATOR_KERNEL_CLASS_NAME(kCpuExecutionProvider, kOnnxDomain, 11, Unique); @@ -1059,7 +1062,10 @@ Status RegisterOnnxOperatorKernels(KernelRegistry& kernel_registry) { BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, - BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, + BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, BuildKernelCreateInfo, diff --git a/onnxruntime/core/providers/cpu/tensor/pad.cc b/onnxruntime/core/providers/cpu/tensor/pad.cc index 4ef26f0759..e969e07dd0 100644 --- a/onnxruntime/core/providers/cpu/tensor/pad.cc +++ b/onnxruntime/core/providers/cpu/tensor/pad.cc @@ -20,6 +20,7 @@ namespace contrib { // once Keras Mask RCNN is shipped with all ONNX domain ops // Currently this kernel is required to support Keras Mask-RCNN +// only float type is supported ONNX_OPERATOR_KERNEL_EX(Pad, kMSDomain, 1, @@ -31,6 +32,7 @@ ONNX_OPERATOR_KERNEL_EX(Pad, #endif +// only float type is supported for opset-10 ONNX_CPU_OPERATOR_VERSIONED_KERNEL( Pad, 2, 10, @@ -40,11 +42,30 @@ ONNX_CPU_OPERATOR_VERSIONED_KERNEL( // The interface for the 'Pad' op was changed in opset-11 // 'pads' and 'value' (attributes previously) became inputs in this version // The core logic remains the same -ONNX_CPU_OPERATOR_KERNEL( + +ONNX_CPU_OPERATOR_TYPED_KERNEL( Pad, 11, - KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), - Pad); + float, + KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), Pad); + +ONNX_CPU_OPERATOR_TYPED_KERNEL( + Pad, + 11, + double, + KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), Pad); + +ONNX_CPU_OPERATOR_TYPED_KERNEL( + Pad, + 11, + int32_t, + KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), Pad); + +ONNX_CPU_OPERATOR_TYPED_KERNEL( + Pad, + 11, + int64_t, + KernelDefBuilder().TypeConstraint("T", DataTypeImpl::GetTensorType()), Pad); // This is the general padding method to n-dimensionally do edge or reflection padding (based on the inputDelta values) template @@ -115,12 +136,12 @@ static void ReshapePads(const std::vector& src_pad, size_t src_dim_coun reshaped_pad[inner_axis + new_dim_count] = src_pad[inner_axis + src_dim_count] * inner_no_pad_size; } -template <> -Status PadCpuImpl(OpKernelContext* ctx, - const std::vector& pads, - const std::vector& slices, - const Mode& mode, - float value) { +template +Status PadCpuImpl(OpKernelContext* ctx, + const std::vector& pads, + const std::vector& slices, + const Mode& mode, + T2 value) { const auto& input_tensor = *ctx->Input(0); std::vector output_dims(input_tensor.Shape().GetDims()); size_t data_rank = output_dims.size(); @@ -160,11 +181,11 @@ Status PadCpuImpl(OpKernelContext* ctx, TensorShape output_shape(output_dims); TensorShape input_shape(reshaped_input_dims); - SliceIterator input(input_tensor, input_shape, input_starts, input_extents, {}); + SliceIterator input(input_tensor, input_shape, input_starts, input_extents, {}); // output_shape need to keep original. auto& output_tensor = *ctx->Output(0, output_shape); - auto* output = output_tensor.template MutableData(); + auto* output = output_tensor.template MutableData(); TensorPitches output_pitches(reshaped_output_dims); size_t alignSkip = 0; // Amount to skip to align to where the next input tensor data needs to be written @@ -183,24 +204,24 @@ Status PadCpuImpl(OpKernelContext* ctx, while (input_counters) { output += alignSkip; { - float* axisStart = output; + T1* axisStart = output; output = input.CopyInnermostAxisSolitaryInnerStep(output); int64_t prePad = reshaped_pad[inner_axis]; int64_t postPad = reshaped_pad[inner_axis + new_dims_count]; - PadAxisConstant(axisStart - prePad, value, prePad); - PadAxisConstant(output, value, postPad); + PadAxisConstant(axisStart - prePad, static_cast(value), prePad); + PadAxisConstant(output, static_cast(value), postPad); output += postPad; alignSkip = prePad; } // Calculate the size of the next block of padding (skipping over the innermost axis since that's already done) while (input_counters.Increment()) { ptrdiff_t inner_pitch = output_pitches[input_counters.Axis()]; - float* axisStart = output - inner_pitch * input_extents[input_counters.Axis()]; + T1* axisStart = output - inner_pitch * input_extents[input_counters.Axis()]; int64_t prePad = reshaped_pad[input_counters.Axis()]; int64_t postPad = reshaped_pad[input_counters.Axis() + new_dims_count]; - PadAxisConstant(axisStart - prePad * inner_pitch, value, prePad * inner_pitch); - PadAxisConstant(output, value, postPad * inner_pitch); + PadAxisConstant(axisStart - prePad * inner_pitch, static_cast(value), prePad * inner_pitch); + PadAxisConstant(output, static_cast(value), postPad * inner_pitch); output += inner_pitch * postPad; alignSkip += inner_pitch * prePad; } @@ -214,7 +235,7 @@ Status PadCpuImpl(OpKernelContext* ctx, while (input_counters) { output += alignSkip; { - float* axisStart = output; + T1* axisStart = output; output = input.CopyInnermostAxisSolitaryInnerStep(output); int64_t prePad = reshaped_pad[inner_axis]; @@ -227,7 +248,7 @@ Status PadCpuImpl(OpKernelContext* ctx, // Calculate the size of the next block of padding (skipping over the innermost axis since that's already done) while (input_counters.Increment()) { ptrdiff_t inner_pitch = output_pitches[input_counters.Axis()]; - float* axisStart = output - inner_pitch * input_extents[input_counters.Axis()]; + T1* axisStart = output - inner_pitch * input_extents[input_counters.Axis()]; int64_t prePad = reshaped_pad[input_counters.Axis()]; int64_t postPad = reshaped_pad[input_counters.Axis() + new_dims_count]; PadAxis(axisStart - prePad * inner_pitch, axisStart, 1, -inner_pitch, inner_pitch, prePad); @@ -245,7 +266,7 @@ Status PadCpuImpl(OpKernelContext* ctx, while (input_counters) { output += alignSkip; { - float* axisStart = output; + T1* axisStart = output; output = input.CopyInnermostAxisSolitaryInnerStep(output); int64_t prePad = reshaped_pad[inner_axis]; @@ -258,7 +279,7 @@ Status PadCpuImpl(OpKernelContext* ctx, // Calculate the size of the next block of padding (skipping over the innermost axis since that's already done) while (input_counters.Increment()) { ptrdiff_t inner_pitch = output_pitches[input_counters.Axis()]; - float* axisStart = output - inner_pitch * input_extents[input_counters.Axis()]; + T1* axisStart = output - inner_pitch * input_extents[input_counters.Axis()]; int64_t prePad = reshaped_pad[input_counters.Axis()]; int64_t postPad = reshaped_pad[input_counters.Axis() + new_dims_count]; PadAxis(axisStart - prePad * inner_pitch, axisStart + prePad * inner_pitch, 1, -inner_pitch * 2, inner_pitch, prePad); @@ -273,8 +294,8 @@ Status PadCpuImpl(OpKernelContext* ctx, return Status::OK(); } -template <> -Status Pad::Compute(OpKernelContext* ctx) const { +template +Status Pad::Compute(OpKernelContext* ctx) const { // kOnnxDomain Pad opset >= 11 (Or) kMsDomain opset == 1 if (is_dynamic_) { const Tensor& input_tensor = *ctx->Input(0); @@ -307,19 +328,21 @@ Status Pad::Compute(OpKernelContext* ctx) const { } } - float value = 0; + T value = 0; const Tensor* value_tensor = ctx->Input(2); if (nullptr != value_tensor) { - ORT_ENFORCE(value_tensor->DataType() == DataTypeImpl::GetType() && + ORT_ENFORCE(value_tensor->DataType() == DataTypeImpl::GetType() && value_tensor->Shape().Size() == 1, "Value tensor should be a 1D tensor of size 1 with the same type as that of the input tensor"); - value = value_tensor->template Data()[0]; + value = value_tensor->template Data()[0]; } - return PadCpuImpl(ctx, pads, slices, mode_, value); + return PadCpuImpl(ctx, pads, slices, mode_, value); } else { // kOnnxDomain Pad opset < 11 - return PadCpuImpl(ctx, pads_, slices_, mode_, value_); + // In the earlier opset versions of Pad, the type for 'value' attribute was always float, + // irrespective of the data type of the actual input to be padded + return PadCpuImpl(ctx, pads_, slices_, mode_, value_); } } }; // namespace onnxruntime diff --git a/onnxruntime/test/onnx/main.cc b/onnxruntime/test/onnx/main.cc index 4f5d2c3c93..9fb9d9f9c8 100644 --- a/onnxruntime/test/onnx/main.cc +++ b/onnxruntime/test/onnx/main.cc @@ -435,8 +435,6 @@ int real_main(int argc, char* argv[], Ort::Env& env) { {"resize_upsample_sizes_nearest_round_prefer_ceil_asymmetric", "Bad onnx test output. Needs test fix."}, {"bitshift_right_uint16", "BitShift(11) uint16 support not enabled currently"}, {"bitshift_left_uint16", "BitShift(11) uint16 support not enabled currently"}, - {"reflect_pad", "Pad(11) int32 support not enabled currently"}, - {"edge_pad", "Pad(11) int32 support not enabled currently"}, {"maxunpool_export_with_output_shape", "Invalid output in ONNX test. See https://github.com/onnx/onnx/issues/2398" }, }; diff --git a/onnxruntime/test/providers/cpu/tensor/pad_test.cc b/onnxruntime/test/providers/cpu/tensor/pad_test.cc index 32412f5f85..a0ae25ee11 100644 --- a/onnxruntime/test/providers/cpu/tensor/pad_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/pad_test.cc @@ -7,7 +7,30 @@ namespace onnxruntime { namespace test { -static void RunTest( +// There is support for int32, int64, float, and double types for opset-11 Pad alone in ORT +template +static void RunOpset11TypedTest( + const std::vector& input_dims, + const std::vector& input, + const std::vector& pads, + T value, + const std::vector& output_dims, + const std::vector& output, + std::string mode = "constant") { + // ONNX domain opset-11 + OpTester test("Pad", 11); + if (mode != "constant") + test.AddAttribute("mode", mode); + test.AddInput("data", input_dims, input); + test.AddInput("pads", {static_cast(pads.size())}, pads); + test.AddInput("value", {1}, {value}); + test.AddOutput("output", output_dims, output); + // NGraph and TensorRT do not yet support opset-11 and builds break on this test, hence exclude the EP + test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kNGraphExecutionProvider, kTensorrtExecutionProvider}); +} + +// There is only support for float type for opset-10 and MSDomain kernel in ORT +static void RunAllOpsetAllDomainPadTests( const std::vector& input_dims, const std::vector& input, const std::vector& pads, @@ -25,17 +48,16 @@ static void RunTest( test1.Run(); // ONNX domain opset-11 - OpTester test2("Pad", 11); - if (mode != "constant") test2.AddAttribute("mode", mode); - test2.AddInput("data", input_dims, input); - test2.AddInput("pads", {static_cast(pads.size())}, pads); - test2.AddInput("value", {1}, {value}); - test2.AddOutput("output", output_dims, output); - // NGraph and TensorRT do not yet support opset-11 and builds break on this test, hence exclude the EP - test2.Run(OpTester::ExpectResult::kExpectSuccess, "", {kNGraphExecutionProvider, kTensorrtExecutionProvider}); + RunOpset11TypedTest(input_dims, + input, + pads, + value, + output_dims, + output, + mode); + +#ifndef DISABLE_CONTRIB_OPS - #ifndef DISABLE_CONTRIB_OPS - // MSFT domain opset-1 (contrib op) OpTester test3("Pad", 1, kMSDomain); if (mode != "constant") test3.AddAttribute("mode", mode); @@ -46,144 +68,237 @@ static void RunTest( //TensorRT does not support pads as an input test3.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); - #endif +#endif } // Some of the tests can't run on TensorrtExecutionProvider because only constant mode and value 0 of "Pad" node is supported. // Those tests will fallback to other EP. TEST(TensorOpTest, Pad_Spec_Example) { - RunTest({3, 2}, - {1.0f, 1.2f, 2.3f, 3.4f, 4.5f, 5.7f}, - {0, 2, 0, 0}, - 0.f, - {3, 4}, - {0.0f, 0.0f, 1.0f, 1.2f, 0.0f, 0.0f, 2.3f, 3.4f, 0.0f, 0.0f, 4.5f, 5.7f}); + RunAllOpsetAllDomainPadTests({3, 2}, + {1.0f, 1.2f, 2.3f, 3.4f, 4.5f, 5.7f}, + {0, 2, 0, 0}, + 0.f, + {3, 4}, + {0.0f, 0.0f, 1.0f, 1.2f, 0.0f, 0.0f, 2.3f, 3.4f, 0.0f, 0.0f, 4.5f, 5.7f}); +} + +TEST(TensorOpTest, Pad_Constant_1D_int) { + std::vector X = {1, 2, 3, 4, 5, 6}; + int32_t value = 1234; + std::vector Y = {1234, 1234, 1, 2, 1234, 1234, 3, 4, 1234, 1234, 5, 6}; + RunOpset11TypedTest({3, 2}, + X, + {0, 2, 0, 0}, + value, + {3, 4}, + Y); +} + +TEST(TensorOpTest, Pad_Constant_1D_long) { + std::vector X = {1, 2, 3, 4, 5, 6}; + int64_t value = 1234; + std::vector Y = {1234, 1234, 1, 2, 1234, 1234, 3, 4, 1234, 1234, 5, 6}; + RunOpset11TypedTest({3, 2}, + X, + {0, 2, 0, 0}, + value, + {3, 4}, + Y); +} + +TEST(TensorOpTest, Pad_Constant_1D_double) { + std::vector X = {1., 2., 3., 4., 5., 6.}; + double value = 0.; + std::vector Y = {0., 0., 1., 2., 0., 0., 3., 4., 0., 0., 5., 6.}; + RunOpset11TypedTest({3, 2}, + X, + {0, 2, 0, 0}, + value, + {3, 4}, + Y); } TEST(TensorOpTest, Pad_Constant_1D) { - RunTest({2}, - {1.0f, 2.0f}, - {1, 2}, - 1234.f, - {5}, - {1234.0f, 1.0f, 2.0f, 1234.0f, 1234.0f}); + RunAllOpsetAllDomainPadTests({2}, + {1.0f, 2.0f}, + {1, 2}, + 1234.f, + {5}, + {1234.0f, 1.0f, 2.0f, 1234.0f, 1234.0f}); } TEST(TensorOpTest, Pad_Constant_1D_Zero) { - RunTest({2}, - {1.0f, 2.0f}, - {0, 0}, - 1234.f, - {2}, - {1.0f, 2.0f}); + RunAllOpsetAllDomainPadTests({2}, + {1.0f, 2.0f}, + {0, 0}, + 1234.f, + {2}, + {1.0f, 2.0f}); } TEST(TensorOpTest, Pad_Constant_2D) { - RunTest({2, 2}, - {11.0f, 21.0f, - 12.0f, 22.0f}, - {1, 2, 1, 2}, - 1234.f, - {4, 6}, - {1234.0f, 1234.0f, 1234.0f, 1234.0f, 1234.0f, 1234.0f, - 1234.0f, 1234.0f, 11.0f, 21.0f, 1234.0f, 1234.0f, - 1234.0f, 1234.0f, 12.0f, 22.0f, 1234.0f, 1234.0f, - 1234.0f, 1234.0f, 1234.0f, 1234.0f, 1234.0f, 1234.0f}); + RunAllOpsetAllDomainPadTests({2, 2}, + {11.0f, 21.0f, + 12.0f, 22.0f}, + {1, 2, 1, 2}, + 1234.f, + {4, 6}, + {1234.0f, 1234.0f, 1234.0f, 1234.0f, 1234.0f, 1234.0f, + 1234.0f, 1234.0f, 11.0f, 21.0f, 1234.0f, 1234.0f, + 1234.0f, 1234.0f, 12.0f, 22.0f, 1234.0f, 1234.0f, + 1234.0f, 1234.0f, 1234.0f, 1234.0f, 1234.0f, 1234.0f}); } TEST(TensorOpTest, Pad_Constant_2D_negative) { - RunTest({2, 3}, - {11.0f, 21.0f, 31.0f, - 12.0f, 22.0f, 32.0f}, - {1, 2, 1, -1}, - 1234.f, - {4, 4}, - {1234.0f, 1234.0f, 1234.0f, 1234.0f, - 1234.0f, 1234.0f, 11.0f, 21.0f, - 1234.0f, 1234.0f, 12.0f, 22.0f, - 1234.0f, 1234.0f, 1234.0f, 1234.0f}); + RunAllOpsetAllDomainPadTests({2, 3}, + {11.0f, 21.0f, 31.0f, + 12.0f, 22.0f, 32.0f}, + {1, 2, 1, -1}, + 1234.f, + {4, 4}, + {1234.0f, 1234.0f, 1234.0f, 1234.0f, + 1234.0f, 1234.0f, 11.0f, 21.0f, + 1234.0f, 1234.0f, 12.0f, 22.0f, + 1234.0f, 1234.0f, 1234.0f, 1234.0f}); } TEST(TensorOpTest, Pad_3D_complex) { - RunTest({2, 2, 2}, - {111.0f, 112.0f, - 121.0f, 122.0f, + RunAllOpsetAllDomainPadTests({2, 2, 2}, + {111.0f, 112.0f, + 121.0f, 122.0f, - 211.0f, 212.0f, - 221.0f, 222.0f}, - {1, 0, 0, -1, 0, 0}, - 0.f, - {2, 2, 2}, - {0.0f, 0.0f, - 0.0f, 0.0f, + 211.0f, 212.0f, + 221.0f, 222.0f}, + {1, 0, 0, -1, 0, 0}, + 0.f, + {2, 2, 2}, + {0.0f, 0.0f, + 0.0f, 0.0f, - 111.0f, 112.0f, - 121.0f, 122.0f}); + 111.0f, 112.0f, + 121.0f, 122.0f}); } TEST(TensorOpTest, Pad_Edge_2D) { - RunTest({2, 3}, - {11.0f, 21.0f, 31.0f, - 12.0f, 22.0f, 32.0f}, - {2, 2, 2, 2}, - 0.f, - {6, 7}, - {11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, - 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, - 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, - 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, - 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, - 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f}, - "edge"); + RunAllOpsetAllDomainPadTests({2, 3}, + {11.0f, 21.0f, 31.0f, + 12.0f, 22.0f, 32.0f}, + {2, 2, 2, 2}, + 0.f, + {6, 7}, + {11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, + 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, + 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, + 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, + 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, + 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f}, + "edge"); } TEST(TensorOpTest, Pad_Edge_3D) { - RunTest({1, 2, 3}, - {11.0f, 21.0f, 31.0f, - 12.0f, 22.0f, 32.0f}, - {1, 2, 2, 1, 2, 2}, - 0.f, - {3, 6, 7}, - {11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, - 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, - 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, - 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, - 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, - 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, + RunAllOpsetAllDomainPadTests({1, 2, 3}, + {11.0f, 21.0f, 31.0f, + 12.0f, 22.0f, 32.0f}, + {1, 2, 2, 1, 2, 2}, + 0.f, + {3, 6, 7}, + {11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, + 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, + 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, + 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, + 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, + 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, - 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, - 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, - 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, - 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, - 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, - 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, + 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, + 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, + 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, + 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, + 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, + 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, - 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, - 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, - 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, - 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, - 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, - 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f}, - "edge"); + 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, + 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, + 11.0f, 11.0f, 11.0f, 21.0f, 31.0f, 31.0f, 31.0f, + 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, + 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f, + 12.0f, 12.0f, 12.0f, 22.0f, 32.0f, 32.0f, 32.0f}, + "edge"); } TEST(TensorOpTest, Pad_Reflect_2D) { - RunTest({3, 3}, - {11.0f, 21.0f, 31.0f, - 12.0f, 22.0f, 32.0f, - 13.0f, 23.0f, 33.0f}, - {2, 2, 2, 2}, - 0.f, - {7, 7}, - {33.0f, 23.0f, 13.0f, 23.0f, 33.0f, 23.0f, 13.0f, - 32.0f, 22.0f, 12.0f, 22.0f, 32.0f, 22.0f, 12.0f, - 31.0f, 21.0f, 11.0f, 21.0f, 31.0f, 21.0f, 11.0f, - 32.0f, 22.0f, 12.0f, 22.0f, 32.0f, 22.0f, 12.0f, - 33.0f, 23.0f, 13.0f, 23.0f, 33.0f, 23.0f, 13.0f, - 32.0f, 22.0f, 12.0f, 22.0f, 32.0f, 22.0f, 12.0f, - 31.0f, 21.0f, 11.0f, 21.0f, 31.0f, 21.0f, 11.0f}, - "reflect"); + RunAllOpsetAllDomainPadTests({3, 3}, + {11.0f, 21.0f, 31.0f, + 12.0f, 22.0f, 32.0f, + 13.0f, 23.0f, 33.0f}, + {2, 2, 2, 2}, + 0.f, + {7, 7}, + {33.0f, 23.0f, 13.0f, 23.0f, 33.0f, 23.0f, 13.0f, + 32.0f, 22.0f, 12.0f, 22.0f, 32.0f, 22.0f, 12.0f, + 31.0f, 21.0f, 11.0f, 21.0f, 31.0f, 21.0f, 11.0f, + 32.0f, 22.0f, 12.0f, 22.0f, 32.0f, 22.0f, 12.0f, + 33.0f, 23.0f, 13.0f, 23.0f, 33.0f, 23.0f, 13.0f, + 32.0f, 22.0f, 12.0f, 22.0f, 32.0f, 22.0f, 12.0f, + 31.0f, 21.0f, 11.0f, 21.0f, 31.0f, 21.0f, 11.0f}, + "reflect"); +} + +TEST(TensorOpTest, Pad_Constant_2D_int) { + std::vector X = {11, 21, 31, + 12, 22, 32}; + int32_t value = 0; + std::vector Y = {11, 11, 11, 21, 31, 31, 31, + 11, 11, 11, 21, 31, 31, 31, + 11, 11, 11, 21, 31, 31, 31, + 12, 12, 12, 22, 32, 32, 32, + 12, 12, 12, 22, 32, 32, 32, + 12, 12, 12, 22, 32, 32, 32}; + RunOpset11TypedTest({2, 3}, + X, + {2, 2, 2, 2}, + value, + {6, 7}, + Y, + "edge"); +} + +TEST(TensorOpTest, Pad_Constant_2D_long) { + std::vector X = {11, 21, 31, + 12, 22, 32}; + int64_t value = 0; + std::vector Y = {11, 11, 11, 21, 31, 31, 31, + 11, 11, 11, 21, 31, 31, 31, + 11, 11, 11, 21, 31, 31, 31, + 12, 12, 12, 22, 32, 32, 32, + 12, 12, 12, 22, 32, 32, 32, + 12, 12, 12, 22, 32, 32, 32}; + RunOpset11TypedTest({2, 3}, + X, + {2, 2, 2, 2}, + value, + {6, 7}, + Y, + "edge"); +} + +TEST(TensorOpTest, Pad_Constant_2D_double) { + std::vector X = {11., 21., 31., + 12., 22., 32.}; + double value = 0.; + std::vector Y = {11., 11., 11., 21., 31., 31., 31., + 11., 11., 11., 21., 31., 31., 31., + 11., 11., 11., 21., 31., 31., 31., + 12., 12., 12., 22., 32., 32., 32., + 12., 12., 12., 22., 32., 32., 32., + 12., 12., 12., 22., 32., 32., 32.}; + RunOpset11TypedTest({2, 3}, + X, + {2, 2, 2, 2}, + value, + {6, 7}, + Y, + "edge"); } } // namespace test diff --git a/onnxruntime/test/python/onnx_backend_test_series.py b/onnxruntime/test/python/onnx_backend_test_series.py index 7d9b8219b6..8cc57cee74 100644 --- a/onnxruntime/test/python/onnx_backend_test_series.py +++ b/onnxruntime/test/python/onnx_backend_test_series.py @@ -93,9 +93,7 @@ def other_tests_failing_permanently_filters(): def test_with_types_disabled_due_to_binary_size_concerns_filters(): filters = ['^test_bitshift_right_uint16_cpu', - '^test_bitshift_left_uint16_cpu', - '^test_edge_pad_cpu', - '^test_reflect_pad_cpu'] + '^test_bitshift_left_uint16_cpu'] return filters @@ -137,7 +135,9 @@ def create_backend_test(testname=None): '^test_reduce_[a-z1-9_]*_negative_axes_.*', 'test_squeeze_negative_axes_cpu', 'test_unsqueeze_negative_axes_cpu', - 'test_constant_pad_cpu'] + 'test_constant_pad_cpu', + 'test_edge_pad_cpu', + 'test_reflect_pad_cpu'] if c2.supports_device('MKL-DNN'): current_failing_tests += ['^test_range_float_type_positive_delta_expanded_cpu',