From 29eaaa1237e58fa8539903c8642488bbcaeb0384 Mon Sep 17 00:00:00 2001 From: zoooo0820 Date: Wed, 15 Nov 2023 08:43:18 +0000 Subject: [PATCH 1/6] first fix the UT --- test/legacy_test/test_zero_dim_tensor.py | 2 ++ test/xpu/test_zero_dim_tensor_xpu.py | 1 + 2 files changed, 3 insertions(+) diff --git a/test/legacy_test/test_zero_dim_tensor.py b/test/legacy_test/test_zero_dim_tensor.py index 10954ed59c60d7..9fb80fae82c2da 100644 --- a/test/legacy_test/test_zero_dim_tensor.py +++ b/test/legacy_test/test_zero_dim_tensor.py @@ -830,6 +830,7 @@ def test_setitem(self): np.testing.assert_allclose(out[1, 2, 3, 4], np.array(10)) self.assertEqual(x.grad.shape, [2, 3, 4, 5]) x_grad_expected = np.ones((2, 3, 4, 5)) * 2 + x_grad_expected[1, 2, 3, 4] = 0 np.testing.assert_allclose(x.grad, x_grad_expected) # case2: 0-D Tensor indice in some axis @@ -847,6 +848,7 @@ def test_setitem(self): self.assertEqual(out.shape, x.shape) np.testing.assert_allclose(out[1, 1], np.ones((4, 5)) * 0.5) x_grad_expected = np.ones((2, 3, 4, 5)) + x_grad_expected[1, 1] = 0 np.testing.assert_allclose(x.grad, x_grad_expected) # case3:0-D Tensor indice in some axis, value is a Tensor diff --git a/test/xpu/test_zero_dim_tensor_xpu.py b/test/xpu/test_zero_dim_tensor_xpu.py index 08c3bc8a1814a4..a836e2e7fb58ed 100644 --- a/test/xpu/test_zero_dim_tensor_xpu.py +++ b/test/xpu/test_zero_dim_tensor_xpu.py @@ -441,6 +441,7 @@ def test_setitem(self): np.testing.assert_allclose(out[1, 2, 3, 4], np.array(10)) self.assertEqual(x.grad.shape, [2, 3, 4, 5]) x_grad_expected = np.ones((2, 3, 4, 5)) * 2 + x_grad_expected[1, 2, 3, 4] = 0 np.testing.assert_allclose(x.grad, x_grad_expected) # case2: 0-D Tensor indice in some axis From 8a5f39f8c1bd92c8aa17f613f128c28398486d02 Mon Sep 17 00:00:00 2001 From: zoooo0820 Date: Wed, 15 Nov 2023 10:38:03 +0000 Subject: [PATCH 2/6] fix set value grad --- paddle/fluid/operators/set_value_op.cc | 35 +++--- paddle/phi/api/yaml/legacy_backward.yaml | 6 +- .../phi/kernels/cpu/set_value_grad_kernel.cc | 17 +++ .../phi/kernels/gpu/set_value_grad_kernel.cu | 17 +++ .../kernels/impl/set_value_grad_kernel_impl.h | 93 ++++++++++++++++ paddle/phi/kernels/set_value_grad_kernel.h | 10 ++ .../phi/kernels/xpu/set_value_grad_kernel.cc | 103 ++++++++++++++++++ 7 files changed, 258 insertions(+), 23 deletions(-) diff --git a/paddle/fluid/operators/set_value_op.cc b/paddle/fluid/operators/set_value_op.cc index 16864b80b5c765..4da4e6b8962eef 100644 --- a/paddle/fluid/operators/set_value_op.cc +++ b/paddle/fluid/operators/set_value_op.cc @@ -151,31 +151,26 @@ class SetValueGradMaker : public framework::SingleGradOpMaker { protected: void Apply(GradOpPtr op) const override { - if (this->HasInput("ValueTensor")) { - op->SetType("set_value_grad"); + op->SetType("set_value_grad"); + op->SetInput(framework::GradVarName("Out"), this->OutputGrad("Out")); + if (this->HasInput("StartsTensorList")) { + op->SetInput("StartsTensorList", this->Input("StartsTensorList")); + } + if (this->HasInput("EndsTensorList")) { + op->SetInput("EndsTensorList", this->Input("EndsTensorList")); + } + if (this->HasInput("StepsTensorList")) { + op->SetInput("StepsTensorList", this->Input("StepsTensorList")); + } - op->SetInput(framework::GradVarName("Out"), this->OutputGrad("Out")); - op->SetInput("ValueTensor", this->Input("ValueTensor")); - if (this->HasInput("StartsTensorList")) { - op->SetInput("StartsTensorList", this->Input("StartsTensorList")); - } - if (this->HasInput("EndsTensorList")) { - op->SetInput("EndsTensorList", this->Input("EndsTensorList")); - } - if (this->HasInput("StepsTensorList")) { - op->SetInput("StepsTensorList", this->Input("StepsTensorList")); - } + op->SetAttrMap(this->Attrs()); - op->SetAttrMap(this->Attrs()); + op->SetOutput(framework::GradVarName("Input"), this->InputGrad("Input")); + if (this->HasInput("ValueTensor")) { + op->SetInput("ValueTensor", this->Input("ValueTensor")); op->SetOutput(framework::GradVarName("ValueTensor"), this->InputGrad("ValueTensor")); - op->SetOutput(framework::GradVarName("Input"), this->InputGrad("Input")); - - } else { - op->SetType("assign"); - op->SetInput("X", this->OutputGrad("Out")); - op->SetOutput("Out", this->InputGrad("Input")); } } }; diff --git a/paddle/phi/api/yaml/legacy_backward.yaml b/paddle/phi/api/yaml/legacy_backward.yaml index 924d07d9daf8ea..551912697152e1 100755 --- a/paddle/phi/api/yaml/legacy_backward.yaml +++ b/paddle/phi/api/yaml/legacy_backward.yaml @@ -612,14 +612,14 @@ - backward_op : set_value_grad forward : set_value (Tensor x, IntArray starts, IntArray ends, IntArray steps, int64_t[] axes, int64_t[] decrease_axes, int64_t[] none_axes, int64_t[] shape, Scalar[] values) -> Tensor(out) - args : (Tensor out_grad) + args : (Tensor out_grad, IntArray starts, IntArray ends, IntArray steps, int64_t[] axes, int64_t[] decrease_axes, int64_t[] none_axes) output : Tensor(x_grad) infer_meta: func: UnchangedInferMeta param: [out_grad] kernel: - func: assign - param: [out_grad] + func: set_value_with_scalar_grad + param: [out_grad, starts, ends, steps, axes, decrease_axes, none_axes] - backward_op : set_value_with_tensor_grad forward: set_value_with_tensor (Tensor x, Tensor values, IntArray starts, IntArray ends, IntArray steps, int64_t[] axes, int64_t[] decrease_axes, int64_t[] none_axes) -> Tensor(out) diff --git a/paddle/phi/kernels/cpu/set_value_grad_kernel.cc b/paddle/phi/kernels/cpu/set_value_grad_kernel.cc index ed35513d985505..237a892dbb356c 100644 --- a/paddle/phi/kernels/cpu/set_value_grad_kernel.cc +++ b/paddle/phi/kernels/cpu/set_value_grad_kernel.cc @@ -35,3 +35,20 @@ PD_REGISTER_KERNEL(set_value_grad, phi::dtype::float16, phi::dtype::complex, phi::dtype::complex) {} + +PD_REGISTER_KERNEL(set_value_with_scalar_grad, + CPU, + ALL_LAYOUT, + phi::SetValueWithScalarGradKernel, + float, + double, + int, + int64_t, + bool, + int16_t, + uint8_t, + int8_t, + phi::dtype::bfloat16, + phi::dtype::float16, + phi::dtype::complex, + phi::dtype::complex) {} diff --git a/paddle/phi/kernels/gpu/set_value_grad_kernel.cu b/paddle/phi/kernels/gpu/set_value_grad_kernel.cu index 66688b417ae307..42ff5b912eccd0 100644 --- a/paddle/phi/kernels/gpu/set_value_grad_kernel.cu +++ b/paddle/phi/kernels/gpu/set_value_grad_kernel.cu @@ -35,3 +35,20 @@ PD_REGISTER_KERNEL(set_value_grad, phi::dtype::bfloat16, phi::dtype::complex, phi::dtype::complex) {} + +PD_REGISTER_KERNEL(set_value_with_scalar_grad, + GPU, + ALL_LAYOUT, + phi::SetValueWithScalarGradKernel, + float, + double, + int, + int64_t, + bool, + int16_t, + uint8_t, + int8_t, + phi::dtype::float16, + phi::dtype::bfloat16, + phi::dtype::complex, + phi::dtype::complex) {} diff --git a/paddle/phi/kernels/impl/set_value_grad_kernel_impl.h b/paddle/phi/kernels/impl/set_value_grad_kernel_impl.h index 3d2a0a3d0db67c..42ecc4c3a1eb00 100644 --- a/paddle/phi/kernels/impl/set_value_grad_kernel_impl.h +++ b/paddle/phi/kernels/impl/set_value_grad_kernel_impl.h @@ -341,4 +341,97 @@ void SetValueGradKernel(const Context& dev_ctx, } } +template +void SetValueWithScalarGradKernel(const Context& dev_ctx, + const DenseTensor& out_grad, + const IntArray& starts, + const IntArray& ends, + const IntArray& steps, + const std::vector& axes, + const std::vector& decrease_axes, + const std::vector& none_axes, + DenseTensor* x_grad) { + const int rank = out_grad.dims().size(); + + switch (rank) { + case 1: + SetValueGradImpl(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); + break; + case 2: + SetValueGradImpl(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); + break; + case 3: + SetValueGradImpl(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); + break; + case 4: + SetValueGradImpl(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); + break; + case 5: + SetValueGradImpl(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); + break; + case 6: + SetValueGradImpl(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); + break; + default: + PADDLE_THROW(phi::errors::InvalidArgument( + "The rank of set_value_with_scalar_grad's input should be less than " + "7, but " + "received %d.", + rank)); + } +} } // namespace phi diff --git a/paddle/phi/kernels/set_value_grad_kernel.h b/paddle/phi/kernels/set_value_grad_kernel.h index e4dad683e40a9d..04592cd2002d19 100644 --- a/paddle/phi/kernels/set_value_grad_kernel.h +++ b/paddle/phi/kernels/set_value_grad_kernel.h @@ -32,4 +32,14 @@ void SetValueGradKernel(const Context& dev_ctx, DenseTensor* x_grad, DenseTensor* value_grad); +template +void SetValueWithScalarGradKernel(const Context& dev_ctx, + const DenseTensor& out_grad, + const IntArray& starts, + const IntArray& ends, + const IntArray& steps, + const std::vector& axes, + const std::vector& decrease_axes, + const std::vector& none_axes, + DenseTensor* x_grad); } // namespace phi diff --git a/paddle/phi/kernels/xpu/set_value_grad_kernel.cc b/paddle/phi/kernels/xpu/set_value_grad_kernel.cc index d80a2a97da8cfe..16c16899f215b5 100644 --- a/paddle/phi/kernels/xpu/set_value_grad_kernel.cc +++ b/paddle/phi/kernels/xpu/set_value_grad_kernel.cc @@ -397,6 +397,100 @@ void SetValueGradKernel(const Context& dev_ctx, } } +template +void SetValueWithScalarGradKernel(const Context& dev_ctx, + const DenseTensor& out_grad, + const IntArray& starts, + const IntArray& ends, + const IntArray& steps, + const std::vector& axes, + const std::vector& decrease_axes, + const std::vector& none_axes, + DenseTensor* x_grad) { + const int rank = out_grad.dims().size(); + + switch (rank) { + case 1: + SetValueGradImpl(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); + break; + case 2: + SetValueGradImpl(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); + break; + case 3: + SetValueGradImpl(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); + break; + case 4: + SetValueGradImpl(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); + break; + case 5: + SetValueGradImpl(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); + break; + case 6: + SetValueGradImpl(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); + break; + default: + PADDLE_THROW(phi::errors::InvalidArgument( + "The rank of set_value_with_scalar_grad's input should be less than " + "7, but " + "received %d.", + rank)); + } +} + } // namespace phi PD_REGISTER_KERNEL(set_value_grad, @@ -407,3 +501,12 @@ PD_REGISTER_KERNEL(set_value_grad, phi::dtype::float16, int, int64_t) {} + +PD_REGISTER_KERNEL(set_value_with_scalar_grad, + XPU, + ALL_LAYOUT, + phi::SetValueWithScalarGradKernel, + float, + phi::dtype::float16, + int, + int64_t) {} From c8337702e15cf69ff50cf77d9d2a1fb61a8bbf58 Mon Sep 17 00:00:00 2001 From: zoooo0820 Date: Thu, 16 Nov 2023 12:52:54 +0000 Subject: [PATCH 3/6] polish code --- paddle/fluid/operators/set_value_op.cc | 17 ++-- .../kernels/impl/set_value_grad_kernel_impl.h | 93 +++---------------- .../phi/kernels/xpu/set_value_grad_kernel.cc | 92 ++---------------- 3 files changed, 31 insertions(+), 171 deletions(-) diff --git a/paddle/fluid/operators/set_value_op.cc b/paddle/fluid/operators/set_value_op.cc index 4da4e6b8962eef..31035445db626b 100644 --- a/paddle/fluid/operators/set_value_op.cc +++ b/paddle/fluid/operators/set_value_op.cc @@ -151,8 +151,17 @@ class SetValueGradMaker : public framework::SingleGradOpMaker { protected: void Apply(GradOpPtr op) const override { - op->SetType("set_value_grad"); + if (this->HasInput("ValueTensor")) { + op->SetType("set_value_grad"); + op->SetInput("ValueTensor", this->Input("ValueTensor")); + op->SetOutput(framework::GradVarName("ValueTensor"), + this->InputGrad("ValueTensor")); + } else { + op->SetType("set_value_with_scalar_grad"); + } + op->SetInput(framework::GradVarName("Out"), this->OutputGrad("Out")); + if (this->HasInput("StartsTensorList")) { op->SetInput("StartsTensorList", this->Input("StartsTensorList")); } @@ -166,12 +175,6 @@ class SetValueGradMaker : public framework::SingleGradOpMaker { op->SetAttrMap(this->Attrs()); op->SetOutput(framework::GradVarName("Input"), this->InputGrad("Input")); - - if (this->HasInput("ValueTensor")) { - op->SetInput("ValueTensor", this->Input("ValueTensor")); - op->SetOutput(framework::GradVarName("ValueTensor"), - this->InputGrad("ValueTensor")); - } } }; diff --git a/paddle/phi/kernels/impl/set_value_grad_kernel_impl.h b/paddle/phi/kernels/impl/set_value_grad_kernel_impl.h index 42ecc4c3a1eb00..a6fab63ded29a9 100644 --- a/paddle/phi/kernels/impl/set_value_grad_kernel_impl.h +++ b/paddle/phi/kernels/impl/set_value_grad_kernel_impl.h @@ -351,87 +351,16 @@ void SetValueWithScalarGradKernel(const Context& dev_ctx, const std::vector& decrease_axes, const std::vector& none_axes, DenseTensor* x_grad) { - const int rank = out_grad.dims().size(); - - switch (rank) { - case 1: - SetValueGradImpl(dev_ctx, - out_grad, - starts, - ends, - steps, - axes, - decrease_axes, - none_axes, - x_grad, - nullptr); - break; - case 2: - SetValueGradImpl(dev_ctx, - out_grad, - starts, - ends, - steps, - axes, - decrease_axes, - none_axes, - x_grad, - nullptr); - break; - case 3: - SetValueGradImpl(dev_ctx, - out_grad, - starts, - ends, - steps, - axes, - decrease_axes, - none_axes, - x_grad, - nullptr); - break; - case 4: - SetValueGradImpl(dev_ctx, - out_grad, - starts, - ends, - steps, - axes, - decrease_axes, - none_axes, - x_grad, - nullptr); - break; - case 5: - SetValueGradImpl(dev_ctx, - out_grad, - starts, - ends, - steps, - axes, - decrease_axes, - none_axes, - x_grad, - nullptr); - break; - case 6: - SetValueGradImpl(dev_ctx, - out_grad, - starts, - ends, - steps, - axes, - decrease_axes, - none_axes, - x_grad, - nullptr); - break; - default: - PADDLE_THROW(phi::errors::InvalidArgument( - "The rank of set_value_with_scalar_grad's input should be less than " - "7, but " - "received %d.", - rank)); - } + SetValueGradKernel(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); } + } // namespace phi diff --git a/paddle/phi/kernels/xpu/set_value_grad_kernel.cc b/paddle/phi/kernels/xpu/set_value_grad_kernel.cc index 16c16899f215b5..a81e3d28947068 100644 --- a/paddle/phi/kernels/xpu/set_value_grad_kernel.cc +++ b/paddle/phi/kernels/xpu/set_value_grad_kernel.cc @@ -407,88 +407,16 @@ void SetValueWithScalarGradKernel(const Context& dev_ctx, const std::vector& decrease_axes, const std::vector& none_axes, DenseTensor* x_grad) { - const int rank = out_grad.dims().size(); - - switch (rank) { - case 1: - SetValueGradImpl(dev_ctx, - out_grad, - starts, - ends, - steps, - axes, - decrease_axes, - none_axes, - x_grad, - nullptr); - break; - case 2: - SetValueGradImpl(dev_ctx, - out_grad, - starts, - ends, - steps, - axes, - decrease_axes, - none_axes, - x_grad, - nullptr); - break; - case 3: - SetValueGradImpl(dev_ctx, - out_grad, - starts, - ends, - steps, - axes, - decrease_axes, - none_axes, - x_grad, - nullptr); - break; - case 4: - SetValueGradImpl(dev_ctx, - out_grad, - starts, - ends, - steps, - axes, - decrease_axes, - none_axes, - x_grad, - nullptr); - break; - case 5: - SetValueGradImpl(dev_ctx, - out_grad, - starts, - ends, - steps, - axes, - decrease_axes, - none_axes, - x_grad, - nullptr); - break; - case 6: - SetValueGradImpl(dev_ctx, - out_grad, - starts, - ends, - steps, - axes, - decrease_axes, - none_axes, - x_grad, - nullptr); - break; - default: - PADDLE_THROW(phi::errors::InvalidArgument( - "The rank of set_value_with_scalar_grad's input should be less than " - "7, but " - "received %d.", - rank)); - } + SetValueGradKernel(dev_ctx, + out_grad, + starts, + ends, + steps, + axes, + decrease_axes, + none_axes, + x_grad, + nullptr); } } // namespace phi From 6cc1f71c9bb932ef5a8217ebf8229c3affcb007f Mon Sep 17 00:00:00 2001 From: zoooo0820 Date: Fri, 17 Nov 2023 08:34:43 +0000 Subject: [PATCH 4/6] add static mode backward test --- test/legacy_test/test_set_value_op.py | 54 +++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/test/legacy_test/test_set_value_op.py b/test/legacy_test/test_set_value_op.py index 65c9f69765d116..12a6fe6651cf97 100644 --- a/test/legacy_test/test_set_value_op.py +++ b/test/legacy_test/test_set_value_op.py @@ -1978,5 +1978,59 @@ def test_check_grad(self): self.check_grad_with_place(place, ['Input'], 'Out', check_dygraph=False) +class TestSetValueWithScalarInStatic(unittest.TestCase): + def setUp(self): + paddle.enable_static() + self.shape = (10, 2) + self.exe = paddle.static.Executor() + self.train_program = paddle.static.Program() + self.startup_program = paddle.static.Program() + + def test_value_input_is_scalar(self): + with paddle.static.program_guard( + self.train_program, self.startup_program + ): + x = paddle.ones(self.shape) + x.stop_gradient = False + y = x * 1 + + # mock test case x[0, 0] = 10 with no ValueTensor input + inputs = { + 'Input': y, + } + attrs = { + 'axes': [0, 1], + 'starts': [0, 0], + 'ends': [1, 1], + 'steps': [1, 1], + 'values': [10], + 'shape': [1], + } + + helper = LayerHelper("set_value") + out = helper.create_variable_for_type_inference(dtype=y.dtype) + + helper.append_op( + type="set_value", + inputs=inputs, + outputs={'Out': out}, + attrs=attrs, + ) + + np_data = np.ones(self.shape).astype('float32') + + paddle.static.append_backward(out.sum()) + res = self.exe.run( + self.train_program, fetch_list=[out, x.grad_name] + ) + + np_data[0, 0] = 10 + expected_x_grad = np.ones(self.shape) + expected_x_grad[0, 0] = 0 + + np.testing.assert_array_equal(res[0], np_data) + np.testing.assert_array_equal(res[1], expected_x_grad) + + if __name__ == '__main__': unittest.main() From 5005daf8c9c975efc645a3a85c0162133051d498 Mon Sep 17 00:00:00 2001 From: zoooo0820 Date: Wed, 20 Dec 2023 10:33:20 +0000 Subject: [PATCH 5/6] always has input valuetensor --- paddle/fluid/operators/set_value_op.cc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/paddle/fluid/operators/set_value_op.cc b/paddle/fluid/operators/set_value_op.cc index 31035445db626b..a0aa1f589191ff 100644 --- a/paddle/fluid/operators/set_value_op.cc +++ b/paddle/fluid/operators/set_value_op.cc @@ -151,14 +151,10 @@ class SetValueGradMaker : public framework::SingleGradOpMaker { protected: void Apply(GradOpPtr op) const override { - if (this->HasInput("ValueTensor")) { - op->SetType("set_value_grad"); - op->SetInput("ValueTensor", this->Input("ValueTensor")); - op->SetOutput(framework::GradVarName("ValueTensor"), - this->InputGrad("ValueTensor")); - } else { - op->SetType("set_value_with_scalar_grad"); - } + op->SetType("set_value_grad"); + op->SetInput("ValueTensor", this->Input("ValueTensor")); + op->SetOutput(framework::GradVarName("ValueTensor"), + this->InputGrad("ValueTensor")); op->SetInput(framework::GradVarName("Out"), this->OutputGrad("Out")); From f24fd45b52a57c531b9d25f8ec7534aa4ea9afb0 Mon Sep 17 00:00:00 2001 From: zoooo0820 Date: Thu, 21 Dec 2023 02:50:22 +0000 Subject: [PATCH 6/6] add dygraph test --- test/legacy_test/test_set_value_op.py | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/legacy_test/test_set_value_op.py b/test/legacy_test/test_set_value_op.py index 12a6fe6651cf97..c42026fb9caee1 100644 --- a/test/legacy_test/test_set_value_op.py +++ b/test/legacy_test/test_set_value_op.py @@ -2032,5 +2032,33 @@ def test_value_input_is_scalar(self): np.testing.assert_array_equal(res[1], expected_x_grad) +class TestSetValueWithScalarInDygraph(unittest.TestCase): + def setUp(self): + paddle.disable_static() + self.shape = (10, 2) + + def test_value_input_is_scalar(self): + x = paddle.ones(self.shape) + x.stop_gradient = False + y = x * 1 + + # mock test case x[0, 0] = 10 with no ValueTensor input + out = paddle._C_ops.set_value( + y, [0, 0], [1, 1], [1, 1], [0, 1], [], [], [1], [10.0] + ) + + loss = out.sum() + loss.backward() + + np_data = np.ones(self.shape).astype('float32') + np_data[0, 0] = 10 + + expected_x_grad = np.ones(self.shape) + expected_x_grad[0, 0] = 0 + + np.testing.assert_array_equal(out, np_data) + np.testing.assert_array_equal(x.grad, expected_x_grad) + + if __name__ == '__main__': unittest.main()