Files
paddlepaddle--paddle/test/legacy_test/test_compat_slogdet.py
T
2026-07-13 12:40:42 +08:00

559 lines
19 KiB
Python

# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
from itertools import product
import numpy as np
from utils import dygraph_guard
import paddle
@unittest.skipIf(
paddle.device.is_compiled_with_cuda()
and paddle.device.is_compiled_with_rocm(),
reason="Skip dcu for error occurs when running on dcu",
)
class TestSlogDet(unittest.TestCase):
def setUp(self) -> None:
self.shapes = [
[2, 2, 5, 5],
[10, 10],
[0, 5, 5],
[0, 0, 0],
[3, 3, 5, 5],
[6, 5, 5],
]
self.dtypes = [
"float32",
"float64",
"complex64",
"complex128",
]
def compiled_with_cuda(self):
return (
paddle.device.is_compiled_with_cuda()
and not paddle.device.is_compiled_with_rocm()
)
def slogdet_backward(self, x, _, grad_logabsdet):
x_inv_T = np.swapaxes(np.linalg.inv(x).conj(), -1, -2)
grad_x = grad_logabsdet * x_inv_T
return grad_x
def test_compat_slogdet(self):
devices = [paddle.device.get_device()]
if (
any(device.startswith("gpu:") for device in devices)
and not paddle.device.is_compiled_with_rocm()
):
devices.append("cpu")
for device in devices:
with paddle.device.device_guard(device), dygraph_guard():
for shape, dtype in product(self.shapes, self.dtypes):
err_msg = f"shape = {shape}, dtype = {dtype}"
# test eager
x = paddle.randn(shape, dtype)
x.stop_gradient = False
out = paddle.compat.slogdet(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
sign, logabsdet = out
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
logdet_grad = paddle.randn_like(logabsdet)
sign_ref, logdet_ref = np.linalg.slogdet(x.numpy())
np.testing.assert_allclose(
sign.numpy(), sign_ref, 1e-5, 1e-5, err_msg=err_msg
)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
err_msg=err_msg,
)
(x_grad,) = paddle.grad(logabsdet, x, logdet_grad)
x_grad_ref = self.slogdet_backward(
x.numpy(),
sign.numpy(),
logdet_grad.numpy()[..., None, None],
)
np.testing.assert_allclose(
x_grad.numpy(), x_grad_ref, 1e-4, 1e-4, err_msg=err_msg
)
# test pir
st_f = paddle.jit.to_static(
paddle.compat.slogdet,
full_graph=True,
)
sign, logabsdet = st_f(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
np.testing.assert_allclose(
sign.numpy(), sign_ref, 1e-5, 1e-5, err_msg=err_msg
)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
err_msg=err_msg,
)
# test pir + dynamic shape
st_f = paddle.jit.to_static(
paddle.compat.slogdet,
full_graph=True,
input_spec=[
paddle.static.InputSpec(
shape=[-1] * len(shape), dtype=dtype
),
],
)
sign, logabsdet = st_f(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
np.testing.assert_allclose(
sign.numpy(), sign_ref, 1e-5, 1e-5, err_msg=err_msg
)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
err_msg=err_msg,
)
def test_error(self):
x = paddle.randn([5], "float32")
with self.assertRaises(ValueError):
sign, logabsdet = paddle.compat.slogdet(x)
def test_out(self):
x = paddle.randn([5, 5], "float32")
sign_, logabsdet_ = paddle.randn([]), paddle.randn([])
sign, logabsdet = paddle.compat.slogdet(x, out=(sign_, logabsdet_))
# skip until multiple outputs are supported for out
# self.assertEqual(sign_.data_ptr(), sign.data_ptr())
# self.assertEqual(logabsdet_.data_ptr(), logabsdet.data_ptr())
def test_singular_matrix(self):
x = paddle.to_tensor(
[
[0, 0, 0],
[1, 1, 1],
[2, 2, 2],
],
dtype="float32",
)
sign, logabsdet = paddle.compat.slogdet(x)
self.assertEqual(sign.item(), 0)
self.assertEqual(logabsdet.item(), -np.inf)
if self.compiled_with_cuda():
with paddle.device.device_guard("cpu"):
x = paddle.to_tensor(
[
[0, 0, 0],
[1, 1, 1],
[2, 2, 2],
],
dtype="float32",
)
sign, logabsdet = paddle.compat.slogdet(x)
self.assertEqual(sign.item(), 0)
self.assertEqual(logabsdet.item(), -np.inf)
def test_invertible_matrix_backward(self):
with paddle.device.device_guard("cpu"):
x = paddle.to_tensor(
[
[0.5, 0, 0],
[0, 0.6, 0],
[0, 0, 0.7],
],
dtype="float32",
place="cpu",
stop_gradient=False,
)
out = paddle.compat.slogdet(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
sign, logabsdet = out
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
logdet_grad = paddle.randn_like(logabsdet)
sign_ref, logdet_ref = np.linalg.slogdet(x.numpy())
np.testing.assert_allclose(sign.numpy(), sign_ref, 1e-5, 1e-5)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
)
(x_grad,) = paddle.grad(logabsdet, x, logdet_grad)
x_grad_ref = self.slogdet_backward(
x.numpy(),
sign.numpy(),
logdet_grad.numpy()[..., None, None],
)
np.testing.assert_allclose(x_grad.numpy(), x_grad_ref, 1e-5, 1e-5)
# test pir + dynamic shape
st_f = paddle.jit.to_static(
paddle.compat.slogdet,
full_graph=True,
input_spec=[
paddle.static.InputSpec(shape=[-1, -1], dtype="float32"),
],
)
sign, logabsdet = st_f(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
np.testing.assert_allclose(sign.numpy(), sign_ref, 1e-5, 1e-5)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
)
def test_batched_invertible_matrix_backward(self):
def run():
x = paddle.to_tensor(
[
[
[0.5, 0, 0],
[0, 0.6, 0],
[0, 0, 0.7],
],
[
[0.2, 0, 0],
[0, 0.3, 0],
[0, 0, 0.4],
],
],
dtype="float32",
place="cpu",
stop_gradient=False,
)
out = paddle.compat.slogdet(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
sign, logabsdet = out
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
logdet_grad = paddle.randn_like(logabsdet)
sign_ref, logdet_ref = np.linalg.slogdet(x.numpy())
np.testing.assert_allclose(sign.numpy(), sign_ref, 1e-5, 1e-5)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
)
(x_grad,) = paddle.grad(logabsdet, x, logdet_grad)
x_grad_ref = self.slogdet_backward(
x.numpy(),
sign.numpy(),
logdet_grad.numpy()[..., None, None],
)
np.testing.assert_allclose(x_grad.numpy(), x_grad_ref, 1e-5, 1e-5)
# test pir + dynamic shape
st_f = paddle.jit.to_static(
paddle.compat.slogdet,
full_graph=True,
input_spec=[
paddle.static.InputSpec(shape=[-1, -1], dtype="float32"),
],
)
sign, logabsdet = st_f(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
np.testing.assert_allclose(sign.numpy(), sign_ref, 1e-5, 1e-5)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
)
run()
if self.compiled_with_cuda():
with paddle.device.device_guard("cpu"):
run()
def test_zero_dim_invertible_matrix_backward(self):
def run():
x = paddle.zeros(
shape=[2, 0, 0],
dtype="float32",
device="cpu",
requires_grad=True,
)
out = paddle.compat.slogdet(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
sign, logabsdet = out
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
logdet_grad = paddle.randn_like(logabsdet)
sign_ref, logdet_ref = np.linalg.slogdet(x.numpy())
np.testing.assert_allclose(sign.numpy(), sign_ref, 1e-5, 1e-5)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
)
(x_grad,) = paddle.grad(logabsdet, x, logdet_grad)
x_grad_ref = self.slogdet_backward(
x.numpy(),
sign.numpy(),
logdet_grad.numpy()[..., None, None],
)
np.testing.assert_allclose(x_grad.numpy(), x_grad_ref, 1e-5, 1e-5)
# test pir + dynamic shape
st_f = paddle.jit.to_static(
paddle.compat.slogdet,
full_graph=True,
input_spec=[
paddle.static.InputSpec(shape=[-1, -1], dtype="float32"),
],
)
sign, logabsdet = st_f(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
np.testing.assert_allclose(sign.numpy(), sign_ref, 1e-5, 1e-5)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
)
run()
if self.compiled_with_cuda():
with paddle.device.device_guard("cpu"):
run()
def test_zero_dim_complex_invertible_matrix_backward(self):
def run():
x = (
paddle.zeros(
shape=[2, 0, 0],
dtype="float32",
device="cpu",
requires_grad=True,
)
+ paddle.randn(
shape=[2, 0, 0],
dtype="float32",
device="cpu",
requires_grad=True,
)
* 1j
)
out = paddle.compat.slogdet(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
sign, logabsdet = out
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
logdet_grad = paddle.randn_like(logabsdet)
sign_ref, logdet_ref = np.linalg.slogdet(x.numpy())
np.testing.assert_allclose(sign.numpy(), sign_ref, 1e-5, 1e-5)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
)
(x_grad,) = paddle.grad(logabsdet, x, logdet_grad)
x_grad_ref = self.slogdet_backward(
x.numpy(),
sign.numpy(),
logdet_grad.numpy()[..., None, None],
)
np.testing.assert_allclose(x_grad.numpy(), x_grad_ref, 1e-5, 1e-5)
# test pir + dynamic shape
st_f = paddle.jit.to_static(
paddle.compat.slogdet,
full_graph=True,
input_spec=[
paddle.static.InputSpec(shape=[-1, -1], dtype="float32"),
],
)
sign, logabsdet = st_f(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
np.testing.assert_allclose(sign.numpy(), sign_ref, 1e-5, 1e-5)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
)
run()
if self.compiled_with_cuda():
with paddle.device.device_guard("cpu"):
run()
def test_det_zero(self):
def run():
x = paddle.to_tensor(
[
[0, 0, 0],
[0, 1, 0],
[0, 0, 1],
],
dtype="float32",
place="cpu",
)
out = paddle.compat.slogdet(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
sign, logabsdet = out
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
sign_ref, logdet_ref = np.linalg.slogdet(x.numpy())
np.testing.assert_allclose(sign.numpy(), sign_ref, 1e-5, 1e-5)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
)
run()
def test_complex_invertible_matrix_backward(self):
def run():
x = (
paddle.randn(
shape=[2, 3, 3],
dtype="float32",
device="cpu",
requires_grad=True,
)
+ paddle.randn(
shape=[2, 3, 3],
dtype="float32",
device="cpu",
requires_grad=True,
)
* 1j
)
out = paddle.compat.slogdet(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
sign, logabsdet = out
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
logdet_grad = paddle.randn_like(logabsdet)
sign_ref, logdet_ref = np.linalg.slogdet(x.numpy())
np.testing.assert_allclose(sign.numpy(), sign_ref, 1e-5, 1e-5)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
)
(x_grad,) = paddle.grad(logabsdet, x, logdet_grad)
x_grad_ref = self.slogdet_backward(
x.numpy(),
sign.numpy(),
logdet_grad.numpy()[..., None, None],
)
np.testing.assert_allclose(x_grad.numpy(), x_grad_ref, 1e-5, 1e-5)
# test pir + dynamic shape
st_f = paddle.jit.to_static(
paddle.compat.slogdet,
full_graph=True,
input_spec=[
paddle.static.InputSpec(shape=[-1, -1], dtype="float32"),
],
)
sign, logabsdet = st_f(x)
self.assertTrue(hasattr(out, "sign"))
self.assertTrue(hasattr(out, "logabsdet"))
self.assertEqual(sign.dtype, x.dtype)
self.assertFalse(logabsdet.is_complex())
np.testing.assert_allclose(sign.numpy(), sign_ref, 1e-5, 1e-5)
np.testing.assert_allclose(
logabsdet.numpy(),
logdet_ref,
1e-5,
1e-5,
)
run()
if self.compiled_with_cuda():
with paddle.device.device_guard("cpu"):
run()
if __name__ == '__main__':
unittest.main()