diff --git a/onnxruntime/core/providers/cpu/math/cumsum.cc b/onnxruntime/core/providers/cpu/math/cumsum.cc index 53a784a031..ccb5546b51 100644 --- a/onnxruntime/core/providers/cpu/math/cumsum.cc +++ b/onnxruntime/core/providers/cpu/math/cumsum.cc @@ -74,74 +74,90 @@ Status GetAxis(const Tensor* axis_tensor, int64_t input_rank, int64_t& axis_out) } // namespace cumsum_op -ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL(CumSum, - 11, - 13, - float, - KernelDefBuilder() - .TypeConstraint("T", DataTypeImpl::GetTensorType()) - .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), DataTypeImpl::GetTensorType()}), - CumSum); +ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL( + CumSum, + 11, + 13, + float, + KernelDefBuilder() + .TypeConstraint("T", DataTypeImpl::GetTensorType()) + .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), + DataTypeImpl::GetTensorType()}), + CumSum); -ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL(CumSum, - 11, - 13, - double, - KernelDefBuilder() - .TypeConstraint("T", DataTypeImpl::GetTensorType()) - .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), DataTypeImpl::GetTensorType()}), - CumSum); +ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL( + CumSum, + 11, + 13, + double, + KernelDefBuilder() + .TypeConstraint("T", DataTypeImpl::GetTensorType()) + .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), + DataTypeImpl::GetTensorType()}), + CumSum); -ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL(CumSum, - 11, - 13, - int32_t, - KernelDefBuilder() - .TypeConstraint("T", DataTypeImpl::GetTensorType()) - .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), DataTypeImpl::GetTensorType()}), - CumSum); +ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL( + CumSum, + 11, + 13, + int32_t, + KernelDefBuilder() + .TypeConstraint("T", DataTypeImpl::GetTensorType()) + .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), + DataTypeImpl::GetTensorType()}), + CumSum); -ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL(CumSum, - 11, - 13, - int64_t, - KernelDefBuilder() - .TypeConstraint("T", DataTypeImpl::GetTensorType()) - .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), DataTypeImpl::GetTensorType()}), - CumSum); +ONNX_CPU_OPERATOR_VERSIONED_TYPED_KERNEL( + CumSum, + 11, + 13, + int64_t, + KernelDefBuilder() + .TypeConstraint("T", DataTypeImpl::GetTensorType()) + .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), + DataTypeImpl::GetTensorType()}), + CumSum); // Opset 14 kernels -ONNX_CPU_OPERATOR_TYPED_KERNEL(CumSum, - 14, - float, - KernelDefBuilder() - .TypeConstraint("T", DataTypeImpl::GetTensorType()) - .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), DataTypeImpl::GetTensorType()}), - CumSum); +ONNX_CPU_OPERATOR_TYPED_KERNEL( + CumSum, + 14, + float, + KernelDefBuilder() + .TypeConstraint("T", DataTypeImpl::GetTensorType()) + .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), + DataTypeImpl::GetTensorType()}), + CumSum); -ONNX_CPU_OPERATOR_TYPED_KERNEL(CumSum, - 14, - double, - KernelDefBuilder() - .TypeConstraint("T", DataTypeImpl::GetTensorType()) - .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), DataTypeImpl::GetTensorType()}), - CumSum); +ONNX_CPU_OPERATOR_TYPED_KERNEL( + CumSum, + 14, + double, + KernelDefBuilder() + .TypeConstraint("T", DataTypeImpl::GetTensorType()) + .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), + DataTypeImpl::GetTensorType()}), + CumSum); -ONNX_CPU_OPERATOR_TYPED_KERNEL(CumSum, - 14, - int32_t, - KernelDefBuilder() - .TypeConstraint("T", DataTypeImpl::GetTensorType()) - .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), DataTypeImpl::GetTensorType()}), - CumSum); +ONNX_CPU_OPERATOR_TYPED_KERNEL( + CumSum, + 14, + int32_t, + KernelDefBuilder() + .TypeConstraint("T", DataTypeImpl::GetTensorType()) + .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), + DataTypeImpl::GetTensorType()}), + CumSum); -ONNX_CPU_OPERATOR_TYPED_KERNEL(CumSum, - 14, - int64_t, - KernelDefBuilder() - .TypeConstraint("T", DataTypeImpl::GetTensorType()) - .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), DataTypeImpl::GetTensorType()}), - CumSum); +ONNX_CPU_OPERATOR_TYPED_KERNEL( + CumSum, + 14, + int64_t, + KernelDefBuilder() + .TypeConstraint("T", DataTypeImpl::GetTensorType()) + .TypeConstraint("T2", std::vector{DataTypeImpl::GetTensorType(), + DataTypeImpl::GetTensorType()}), + CumSum); template CumSum::CumSum(const OpKernelInfo& info) : OpKernel(info), exclusive_(), reverse_() { @@ -223,7 +239,8 @@ Status CumSum::Compute(OpKernelContext* ctx) const { ::ZeroOutSliceAtIndex(output_tensor, rank, axis, index, slice_dims, steps, slice_size); --index; } - { + + if (index >= 0) { // The next slice is a copy of the input (if exclusive == false then this is the first slice) auto input_starts(::GetStarts(rank, axis, dim - 1)); auto output_starts(::GetStarts(rank, axis, index)); diff --git a/onnxruntime/test/providers/cpu/math/cumsum_test.cc b/onnxruntime/test/providers/cpu/math/cumsum_test.cc index 2149e27472..cbf2d2fa2b 100644 --- a/onnxruntime/test/providers/cpu/math/cumsum_test.cc +++ b/onnxruntime/test/providers/cpu/math/cumsum_test.cc @@ -12,12 +12,12 @@ namespace test { TEST(CumSumTest, _1DTest) { OpTester test("CumSum", 11, onnxruntime::kOnnxDomain); test.AddInput("x", {5}, {1., 2., 3., 4., 5.}); - // Pass in 0D Axis for all OpenVINO tests, and keep one 1D Axis test for coverage. - #ifdef USE_OPENVINO +// Pass in 0D Axis for all OpenVINO tests, and keep one 1D Axis test for coverage. +#ifdef USE_OPENVINO test.AddInput("axis", {}, {0}); - #else +#else test.AddInput("axis", {1}, {0}); - #endif +#endif test.AddOutput("y", {5}, {1., 3., 6., 10., 15.}); test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); } @@ -52,6 +52,30 @@ TEST(CumSumTest, _1DTestExclusive) { test.AddOutput("y", {5}, {0., 1., 3., 6., 10.}); test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); } + +// GH13165. +TEST(CumSumTest, _1DTestExclusiveAxisHasSingleValue) { + { + // forward + OpTester test("CumSum", 11, onnxruntime::kOnnxDomain); + test.AddAttribute("exclusive", 1); + test.AddInput("x", {1, 2}, {1., 2.}); + test.AddInput("axis", {}, {0}); // dim value of axis is 1 + test.AddOutput("y", {1, 2}, {0., 0.}); + test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); + } + { + // reverse + OpTester test("CumSum", 11, onnxruntime::kOnnxDomain); + test.AddAttribute("exclusive", 1); + test.AddAttribute("reverse", 1); + test.AddInput("x", {1, 2}, {1., 2.}); + test.AddInput("axis", {}, {0}); // dim value of axis is 1 + test.AddOutput("y", {1, 2}, {0., 0.}); + test.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider}); + } +} + TEST(CumSumTest, _2DTestAxis0) { OpTester test("CumSum", 11, onnxruntime::kOnnxDomain); test.AddInput("x", {2, 3}, {1., 2., 3., 4., 5., 6.});