assert_close

paddle.testing. assert_close ( actual: Any, expected: Any, *, allow_subclasses: bool = True, rtol: Optional[float] = None, atol: Optional[float] = None, equal_nan: bool = False, check_device: bool = True, check_dtype: bool = True, msg: Optional[Union[str, Callable[[str], str]]] = None ) → None [source]

Asserts that actual and expected are close.

If actual and expected are real-valued, and finite, they are considered close if

\[\lvert \text{actual} - \text{expected} \rvert \le \texttt{atol} + \texttt{rtol} \cdot \lvert \text{expected} \rvert\]

Non-finite values (-inf and inf) are only considered close if and only if they are equal. NaN’s are only considered equal to each other if equal_nan is True.

In addition, they are only considered close if they have the same

  • place (if check_device is True),

  • dtype (if check_dtype is True),

In static graph mode, only the check_dtype attribute verification will be performed.

actual and expected can be Tensor’s or any tensor-or-scalar-likes from which paddle.Tensor’s can be constructed with paddle.to_tensor(). Except for Python scalars the input types have to be directly related. In addition, actual and expected can be Sequence’s or Mapping’s in which case they are considered close if their structure matches and all their elements are considered close according to the above definition.

Note

Python scalars are an exception to the type relation requirement, because their type(), i.e. int, float, and complex, is equivalent to the dtype of a tensor-like. Thus, Python scalars of different types can be checked, but require check_dtype=False.

Parameters
  • actual (Any) – Actual input.

  • expected (Any) – Expected input.

  • allow_subclasses (bool) – If True (default) and except for Python scalars, inputs of directly related types are allowed. Otherwise type equality is required.

  • rtol (float, optional) – Relative tolerance. If specified atol must also be specified. If omitted, default values based on the dtype are selected with the below table.

  • atol (float, optional) – Absolute tolerance. If specified rtol must also be specified. If omitted, default values based on the dtype are selected with the below table.

  • equal_nan (bool|str, optional) – If True, two NaN values will be considered equal.

  • check_device (bool) – If True (default), asserts that corresponding tensors are on the same place. If this check is disabled, tensors on different place’s are moved to the CPU before being compared.

  • check_dtype (bool) – If True (default), asserts that corresponding tensors have the same dtype. If this check is disabled, tensors with different dtype’s are promoted to a common dtype before being compared.

  • msg (str|Callable[[str], str], optional) – Optional error message to use in case a failure occurs during the comparison. Can also be passed as callable in which case it will be called with the generated message and should return the new message.

The following table displays the default rtol and atol for different dtype’s. In case of mismatching dtype’s, the maximum of both tolerances is used.

dtype

rtol

atol

float16

1e-3

1e-5

bfloat16

1.6e-2

1e-5

float32

1.3e-6

1e-5

float64

1e-7

1e-7

complex64

1.3e-6

1e-5

complex128

1e-7

1e-7

other

0.0

0.0

Note

This function is highly configurable with strict default settings. Users are encouraged to partial() it to fit their use case.

Examples

>>> import paddle
>>> import numpy as np
>>> import functools

>>> # tensor to tensor comparison
>>> expected = paddle.to_tensor([1e0, 1e-1, 1e-2])
>>> actual = paddle.acos(paddle.cos(expected))
>>> paddle.testing.assert_close(actual, expected)

>>> # scalar to scalar comparison
>>> import math
>>> expected = math.sqrt(2.0)
>>> actual = 2.0 / math.sqrt(2.0)
>>> paddle.testing.assert_close(actual, expected)

>>> # numpy array to numpy array comparison
>>> expected = np.array([1e0, 1e-1, 1e-2])
>>> actual = np.arccos(np.cos(expected))
>>> paddle.testing.assert_close(actual, expected)

>>> # sequence to sequence comparison
>>> # The types of the sequences do not have to match. They only have to have the same
>>> # length and their elements have to match.
>>> expected = [paddle.to_tensor([1.0]), 2.0, np.array(3.0)]
>>> actual = tuple(expected)
>>> paddle.testing.assert_close(actual, expected)

>>> # mapping to mapping comparison
>>> from collections import OrderedDict
>>> foo = paddle.to_tensor(1.0)
>>> bar = 2.0
>>> baz = np.array(3.0)
>>> # The types and a possible ordering of mappings do not have to match. They only
>>> # have to have the same set of keys and their elements have to match.
>>> expected = OrderedDict([("foo", foo), ("bar", bar), ("baz", baz)])
>>> actual = {"baz": baz, "bar": bar, "foo": foo}
>>> paddle.testing.assert_close(actual, expected)

>>> # Customize the error message
>>> expected = paddle.to_tensor([1.0, 2.0, 3.0])
>>> actual = paddle.to_tensor([1.0, 4.0, 5.0])
>>> try:
...     paddle.testing.assert_close(actual, expected, msg="Argh, the tensors are not close!")
... except AssertionError as e:
...     print(e)
Argh, the tensors are not close!

>>> # Using functools to create strict equality check
>>> assert_equal = functools.partial(paddle.testing.assert_close, rtol=0, atol=0)
>>> try:
...     assert_equal(1e-9, 1e-10)
... except AssertionError as e:
...     print(e)
Scalars are not equal!

Expected 1e-10 but got 1e-09.
Absolute difference: 9.000000000000001e-10
Relative difference: 9.0

>>> # NaN check
>>> expected = paddle.to_tensor(float("Nan"))
>>> actual = expected.clone()
>>> # NaN != NaN by default, so this raises AssertionError
>>> try:
...     paddle.testing.assert_close(actual, expected)
... except AssertionError as e:
...     print("Assertion Failed")
Assertion Failed
>>> # Pass equal_nan=True to succeed
>>> paddle.testing.assert_close(actual, expected, equal_nan=True)