未验证 提交 ef6e8d09 编写于 作者: G GGBond8488 提交者: GitHub

【0D output】add_0D_output_support (#52857)

* add 0d support for dist, trace, paddle.linalg.cond test=allcase

* add_0d_output_support_for_det

* test=allcase

* support_0d_output_for_linalg.norm

* support linalg.norm 0d output, test=allcase

* fix 0D test

* fix zero dim test, test=allcase

* fix 0D test

* fix tets,test=allcase

* fix error,test=allcase

* fix errors ,test=allcase

* add static backward , test=allcase

* add static backwward test, test=allcase

* fix pr-ci-build error;test=document_fix (#53060)

* [Cherry-Pick] Unique support float16&bfloat16 (#53023)

unique支持float16和bfloat16数据类型,并完善相关单测。

* slogdet_support_0D_output

* add new case

* fix tests, test=allcase

* fix p_norm related test, test=allcase

* fix some err, test=allcase

* test=allcase

* move out trace

* open some case, test=allcase

* fix norm all case, test=allcase

* fix some test error, test=allcase

* fix typro,test=allcase

* fix test err, test=allcase

* test=allcase

* test

* fix test error, test=allcase

* fix test error, test=allcase

* fallback norm, test=allcase

---------
Co-authored-by: Ntianshuo78520a <707759223@qq.com>
Co-authored-by: NZhang Zheng <32410583+ZzSean@users.noreply.github.com>
上级 6adfcdf6
...@@ -990,7 +990,7 @@ void DistInferMeta(const MetaTensor& x, ...@@ -990,7 +990,7 @@ void DistInferMeta(const MetaTensor& x,
"The Input(Y) has not been initialized properly. The " "The Input(Y) has not been initialized properly. The "
"shape of Input(Y) = [%s].", "shape of Input(Y) = [%s].",
y_dims)); y_dims));
out->set_dims({1}); out->set_dims(phi::make_ddim({}));
out->set_dtype(x.dtype()); out->set_dtype(x.dtype());
} }
......
...@@ -2767,7 +2767,6 @@ void PNormInferMeta(const MetaTensor& x, ...@@ -2767,7 +2767,6 @@ void PNormInferMeta(const MetaTensor& x,
if (reduce_dims.size() == 0) { if (reduce_dims.size() == 0) {
reduce_dims.emplace_back(1); reduce_dims.emplace_back(1);
} }
x_dim[axis] = 1; x_dim[axis] = 1;
} }
......
...@@ -91,10 +91,10 @@ void DeterminantGradKernel(const Context& dev_ctx, ...@@ -91,10 +91,10 @@ void DeterminantGradKernel(const Context& dev_ctx,
" input tensor's, but here differ %d", " input tensor's, but here differ %d",
input_dims_size - out_grad.dims().size())); input_dims_size - out_grad.dims().size()));
} else if (input_dims_size == 2) { } else if (input_dims_size == 2) {
// input dims size 2 and grad dims size 1 is possible // input dims size 2 and grad dims size 0 is possible
PADDLE_ENFORCE_EQ( PADDLE_ENFORCE_EQ(
out_grad.dims().size(), out_grad.dims().size(),
1, 0,
phi::errors::InvalidArgument( phi::errors::InvalidArgument(
"The grad tensor of det dims size should be 2 less than" "The grad tensor of det dims size should be 2 less than"
" input tensor's, but here differ %d", " input tensor's, but here differ %d",
......
...@@ -126,7 +126,7 @@ void DeterminantKernel(const Context& dev_ctx, ...@@ -126,7 +126,7 @@ void DeterminantKernel(const Context& dev_ctx,
out->Resize(output_dims); out->Resize(output_dims);
} else { } else {
// when input is a two-dimension matrix, The det value is a number. // when input is a two-dimension matrix, The det value is a number.
out->Resize({1}); out->Resize(phi::make_ddim({}));
} }
VLOG(10) << "output dim:" << out->dims(); VLOG(10) << "output dim:" << out->dims();
} }
......
...@@ -2616,6 +2616,107 @@ class TestSundryAPI(unittest.TestCase): ...@@ -2616,6 +2616,107 @@ class TestSundryAPI(unittest.TestCase):
self.assertEqual(b.grad.shape, [4, 5]) self.assertEqual(b.grad.shape, [4, 5])
self.assertEqual(c.grad.shape, [5]) self.assertEqual(c.grad.shape, [5])
def test_cov(self):
xt = paddle.randn((3, 4))
xt.stop_gradient = False
xt_1 = paddle.randn((12,))
xt_1.stop_gradient = False
xt_out = paddle.linalg.cov(xt)
xt_out.retain_grads()
xt_out.backward()
self.assertEqual(xt_out.shape, [3, 3])
self.assertEqual(xt.grad.shape, [3, 4])
xt_1_out = paddle.linalg.cov(xt_1)
xt_1.retain_grads()
xt_1_out.backward()
self.assertEqual(xt_1_out.shape, [])
self.assertEqual(xt_1.grad.shape, [12])
def test_det(self):
xt = paddle.randn([3, 3, 3])
xt.stop_gradient = False
xt_1 = paddle.randn([3, 3])
xt_1.stop_gradient = False
xt_out = paddle.linalg.det(xt)
xt.retain_grads()
xt_out.backward()
self.assertEqual(xt_out.shape, [3])
self.assertEqual(xt.grad.shape, [3, 3, 3])
xt_1_out = paddle.linalg.det(xt_1)
xt_1.retain_grads()
xt_1_out.backward()
self.assertEqual(xt_1_out.shape, [])
self.assertEqual(xt_1.grad.shape, [3, 3])
def test_dist(self):
x = paddle.to_tensor([[3, 3], [3, 3]], dtype="float32")
y = paddle.to_tensor([[3, 3], [3, 1]], dtype="float32")
x.stop_gradient = False
y.stop_gradient = False
out = paddle.dist(x, y, 0)
out.backward()
self.assertEqual(out.shape, [])
np.testing.assert_allclose(out, np.array(1))
self.assertEqual(x.grad.shape, [2, 2])
self.assertEqual(y.grad.shape, [2, 2])
def test_linalg_cond(self):
def assert_shape(out):
self.assertEqual(out.shape, [])
# x1 = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x1.stop_gradient = False
# p = 2 : use paddle.sum
# out = paddle.linalg.cond(x1)
# assert_shape(out)
# p = fro : use paddle.sum
# x2 = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x2.stop_gradient = False
# out_fro = paddle.linalg.cond(x2, p='fro')
# assert_shape(out_fro)
# p = nuc : use paddle.sum
# x3 = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x3.stop_gradient = False
# out_nuc = paddle.linalg.cond(x3, p='nuc')
# assert_shape(out_nuc)
# p in (-1, 1) : use paddle.sum
# x4 = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x4.stop_gradient = False
# out_1 = paddle.linalg.cond(x4, p=1)
# assert_shape(out_1)
# x5 = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x5.stop_gradient = False
# out_minus_1 = paddle.linalg.cond(x5, p=-1)
# assert_shape(out_minus_1)
# p in (-2, 2) depends on paddle.sum
# x6 = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x6.stop_gradient = False
# out_2 = paddle.linalg.cond(x6, p=2)
# assert_shape(out_2)
# p in (-inf, inf):use paddle.sum
# x8 = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x8.stop_gradient = False
# out_inf = paddle.linalg.cond(x8, p=float("inf"))
# assert_shape(out_inf)
# depends on paddle.sum
# a = paddle.randn([2, 4, 4])
# a.stop_gradient = False
# a_cond_fro = paddle.linalg.cond(a, p='fro')
# a_cond_fro.backward()
# self.assertEqual(len(a_cond_fro.shape), 1)
# self.assertEqual(a.grad.shape, [2, 4, 4])
def test_trace(self): def test_trace(self):
x = paddle.to_tensor([[3, 2], [1, 9]], dtype="float32") x = paddle.to_tensor([[3, 2], [1, 9]], dtype="float32")
x.stop_gradient = False x.stop_gradient = False
...@@ -4723,6 +4824,148 @@ class TestSundryAPIStatic(unittest.TestCase): ...@@ -4723,6 +4824,148 @@ class TestSundryAPIStatic(unittest.TestCase):
self.assertEqual(res[2].shape, (4, 5)) self.assertEqual(res[2].shape, (4, 5))
self.assertEqual(res[3].shape, (5,)) self.assertEqual(res[3].shape, (5,))
@prog_scope()
def test_cov(self):
xt_1 = paddle.randn((12,))
xt_1.stop_gradient = False
out = paddle.linalg.cov(xt_1)
paddle.static.append_backward(out)
prog = paddle.static.default_main_program()
res = self.exe.run(prog, fetch_list=[out, xt_1.grad_name])
self.assertEqual(res[0].shape, ())
self.assertEqual(res[1].shape, (12,))
@prog_scope()
def test_det(self):
xt_1 = paddle.randn((3, 3))
xt_1.stop_gradient = False
out = paddle.linalg.det(xt_1)
paddle.static.append_backward(out.sum())
prog = paddle.static.default_main_program()
res = self.exe.run(prog, fetch_list=[out, xt_1.grad_name])
self.assertEqual(res[0].shape, ())
self.assertEqual(res[1].shape, (3, 3))
@prog_scope()
def test_dist(self):
x = paddle.to_tensor([[3, 3], [3, 3]], dtype="float32")
y = paddle.to_tensor([[3, 3], [3, 1]], dtype="float32")
x.stop_gradient = False
y.stop_gradient = False
out = paddle.dist(x, y)
paddle.static.append_backward(out)
prog = paddle.static.default_main_program()
res = self.exe.run(prog, fetch_list=[out, x.grad_name, y.grad_name])
self.assertEqual(res[0].shape, ())
self.assertEqual(res[1].shape, (2, 2))
self.assertEqual(res[1].shape, (2, 2))
np.testing.assert_array_equal(res[0], np.array(2).astype(np.float32))
@prog_scope()
def test_linalg_cond(self):
pass
# use paddle.sum
# x = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x.stop_gradient = False
# out = paddle.linalg.cond(x)
# paddle.static.append_backward(out)
# prog = paddle.static.default_main_program()
# res = self.exe.run(prog, fetch_list=[out, x.grad_name])
# self.assertTrue(res[0].shape, ())
# self.assertTrue(res[1].shape, (3, 3))
# p = fro : use paddle.sum
# x2 = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x2.stop_gradient = False
# out_fro = paddle.linalg.cond(x2, p='fro')
# paddle.static.append_backward(out_fro)
# prog = paddle.static.default_main_program()
# res = self.exe.run(prog, fetch_list=[out_fro, x.grad_name])
# self.assertTrue(res[0].shape, ())
# self.assertTrue(res[1].shape, (3, 3))
# p = nuc : use paddle.sum
# x3 = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x3.stop_gradient = False
# out_nuc = paddle.linalg.cond(x3, p='nuc')
# paddle.static.append_backward(out_nuc)
# prog = paddle.static.default_main_program()
# res = self.exe.run(prog, fetch_list=[out_nuc, x.grad_name])
# self.assertTrue(res[0].shape, ())
# self.assertTrue(res[1].shape, (3, 3))
# p in (-1, 1) : use paddle.sum
# x4 = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x4.stop_gradient = False
# out_1 = paddle.linalg.cond(x4, p=1)
# paddle.static.append_backward(out_1)
# prog = paddle.static.default_main_program()
# res = self.exe.run(prog, fetch_list=[out_1, x.grad_name])
# self.assertTrue(res[0].shape, ())
# self.assertTrue(res[1].shape, (3, 3))
# x5 = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x5.stop_gradient = False
# out_minus_1 = paddle.linalg.cond(x5, p=-1)
# paddle.static.append_backward(out_minus_1)
# prog = paddle.static.default_main_program()
# res = self.exe.run(prog, fetch_list=[out_minus_1, x.grad_name])
# self.assertTrue(res[0].shape, ())
# self.assertTrue(res[1].shape, (3, 3))
# p in (-2, 2) depends on paddle.sum
# x6 = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x6.stop_gradient = False
# out_2 = paddle.linalg.cond(x6, p=2)
# paddle.static.append_backward(out_2)
# prog = paddle.static.default_main_program()
# res = self.exe.run(prog, fetch_list=[out_2, x.grad_name])
# self.assertTrue(res[0].shape, ())
# self.assertTrue(res[1].shape, (3, 3))
# p in (-inf, inf):use paddle.sum
# x8 = paddle.to_tensor([[1.0, 0, -1], [0, 1, 0], [1, 0, 1]])
# x8.stop_gradient = False
# out_inf = paddle.linalg.cond(x8, p=float("inf"))
# paddle.static.append_backward(out_inf)
# prog = paddle.static.default_main_program()
# res = self.exe.run(prog, fetch_list=[out_inf, x.grad_name])
# self.assertTrue(res[0].shape, ())
# self.assertTrue(res[1].shape, (3, 3))
# depends on paddle.sum
# a = paddle.randn([2, 4, 4])
# a.stop_gradient = False
# a_cond_fro = paddle.linalg.cond(a, p='fro')
# paddle.static.append_backward(a_cond_fro)
# prog = paddle.static.default_main_program()
# res = self.exe.run(prog, fetch_list=[a_cond_fro, a.grad_name])
# self.assertEqual(res[0].shape, (2,))
# self.assertEqual(res[1].shape, (2, 4, 4))
@prog_scope() @prog_scope()
def test_trace(self): def test_trace(self):
x = paddle.to_tensor([[3, 2], [1, 9]], dtype="float32") x = paddle.to_tensor([[3, 2], [1, 9]], dtype="float32")
......
...@@ -463,7 +463,12 @@ class TestPNormOrig2Prim1(TestElementWiseAddOrig2Prim): ...@@ -463,7 +463,12 @@ class TestPNormOrig2Prim1(TestElementWiseAddOrig2Prim):
} }
self.orig2prim_args = (X,) self.orig2prim_args = (X,)
self.all_ops = ['p_norm', 'reshape_p', 'abs_p', 'reduce_sum_p'] self.all_ops = [
'p_norm',
'reshape_p',
'abs_p',
'reduce_sum_p',
]
self.out_map = {0: self.output['Out']} self.out_map = {0: self.output['Out']}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册