• 文档 >
  • 模块代码 >
  • torch >
  • torch 测试._比较
快捷键

torch.testing._comparison 的源代码

# mypy: 允许未类型化定义
导入 abc
导入 cmath
导入 collections.abc
导入 contextlib
from collections.abc 导入 收藏, 序列
from 打字 导入 任何, 可调用, 无返回值, 可选, 联合
from typing_extensions 导入 已弃用

导入 火炬


尝试:
    导入 numpy  np

    HAS_NUMPY = 真实
除了 模块未找到错误:
    HAS_NUMPY = 
    np =   # 类型:忽略[赋值]


 错误元数据(异常):
    "内部测试异常,该异常携带错误元数据。"

    定义 __init__(
        , 类型: 类型[异常] 信息: 字符串, *, id: 元组[任何, ...] = ()
    ) -> :
        超级().__init__(
            "如果您是用户,在正常操作期间看到此消息,"
            "请在此处提交问题:https://github.com/pytorch/pytorch/issues。"
            "如果您是开发者并且正在处理比较函数,请使用 `raise ErrorMeta.to_error()`。"
            "面向用户的错误。"
        )
        .类型 = 类型
        .msg = msg
        .标识符 = 标识符

    定义 to_error(
        , 信息: 可选[联盟[字符串, 可调用[[字符串], 字符串]]] = 
    ) -> 异常:
        如果  isinstance(信息, 字符串):
            生成的消息 = .msg
            如果 .id:
                生成消息 += f"\n\n
\n\n失败发生于项目{请提供需要翻译的文本.连接(字符串[项目]) for 项目  .id)}"

            msg = 信息(生成消息) 如果 可调用(信息) 否则 生成消息

        返回 .类型(信息)


# 关于通过 test_torch.py 的日志测试进行的容差度分析可以在此找到
# https://github.com/pytorch/pytorch/pull/32538.
# {dtype: (相对容差, 绝对容差)}
_DTYPE_PRECISIONS = {
    火把.float16: (0.001, 0.00001),
    火把.bfloat16: (0.016, 0.00001),
    火把.float32: (0.0000013, 0.00001),
    火把.float64: (1e-7, 1e-7),
    火把.complex32: (0.001, 0.00001),
    火把.complex64: (0.0000013, 0.00001),
    火把.complex128: (1e-7, 1e-7),
}
火炬张量浮点数类型的默认容差用于量化数据类型,因为量化张量是在其去量化后的浮点数表示中进行比较的。有关详细信息,请参阅 `TensorLikePair._compare_quantized_values`
对于更多详细信息,请参阅 `TensorLikePair._compare_quantized_values`
数据类型精度.更新(
    字典.fromkeys(
        (火把.quint8, 火把.quint2x4, 火把.quint4x2, 火把.qint8, 火把.qint32),
        数据类型精度[火把.float32]
    )
)


定义 默认公差(
    *输入: 联盟[火把.张量, 火把.数据类型]
    dtype 精度: 可选[字典[火把.数据类型, 元组[float, float]]] = ,
) -> 元组[float, float]:
    根据数据类型,返回一组输入的默认绝对和相对测试容差。

查看 :func:`assert_close` 以获取每个数据类型的默认容差表。

返回:
(元组[浮点数,浮点数]): 所有输入数据类型的宽松容差。
"文档"
    数据类型 = 输入文本为空,请提供需要翻译的文本
    for 输入  输入:
        如果 isinstance(输入, 火把.张量):
            数据类型.append(输入.数据类型)
        elif isinstance(输入, 火把.数据类型):
            数据类型.append(输入)
        else:
            raise 类型错误(
                f期望得到一个 torch.Tensor 或一个 torch.dtype,但得到{类型(输入)}而不是。"
            )
    数据类型精度 = 数据类型精度 或者 _DTYPE_PRECISIONS
    相对误差容限, 绝对误差容限 = zip(*[数据类型精度.获取(数据类型, (0.0, 0.0)) for dtype  数据类型])
    返回 最大值(相对误差容限), 最大值(绝对误差容限)


定义 获取绝对值和相对值,用于数值比较。(
    *输入: 联盟[火把.张量, 火把.数据类型]
    相对误差: 可选[float]
    精度: 可选[float]
    id: 元组[任何, ...] = (),
) -> 元组[float, float]
    如果同时指定了 `rtol` 和 `atol`,则此操作不执行任何操作。如果两者都没有指定,则使用 `:func:`default_tolerances` 的返回值。

如果同时指定了 `rtol` 和 `atol`,则此操作不执行任何操作。如果两者都没有指定,则使用 `:func:`default_tolerances` 的返回值。
如果同时指定了 `rtol` 和 `atol`,则此操作不执行任何操作。如果两者都没有指定,则使用 `:func:`default_tolerances` 的返回值。

抛出异常:
ErrorMeta: 使用 :class:`ValueError`,如果只指定了 ``rtol`` 或 ``atol``。

返回:
(Tuple[float, float]): 有效的绝对和相对容差。
"文档"
    如果 (rtol  ) ^ (容差  ):
        # 我们要求省略或指定两个容差,因为只指定一个可能会导致意外。
        # 结果。想象一下设置 atol=0.0,但 rtol>0.0 时张量仍然匹配。
        raise 错误元数据(
            ValueError,
            f"两者 'rtol' 和 'atol' 必须指定或省略,"
            f"但得到了没有"{'rtol' 如果 rtol   否则 'atol'}.",
            id=id,
        )
    elif rtol    并且 容差   :
        返回 相对误差, 容差
    else:
        返回 默认公差(*输入)


定义 制作不匹配信息(
    *,
    默认标识符: 字符串,
    标识符: 可选[联盟[字符串, 可调用[[字符串] 字符串]]] = ,
    额外: 可选[字符串] = ,
    绝对差: float,
    绝对差索引: 可选[联盟[整数, 元组[整数, ...]]] = ,
    精度: float,
    相对差: float,
    相对差索引: 可选[联盟[整数, 元组[整数, ...]]] = ,
    相对误差: float,
) -> 字符串:
    为数值创建一个不匹配的错误信息。

参数:
default_identifier (str): 相比较值的默认描述,例如 "Tensor-likes"。
identifier (Optional[Union[str, Callable[[str], str]]]): 可选的标识符,用于覆盖
``default_identifier``。如果传递为可调用对象,则它将被调用,并传入
在运行时创建描述的 ``默认标识符``。
extra(可选[str]):放置在消息标题和错配统计信息之后的额外信息。
abs_diff(float):绝对差异。
abs_diff_idx(可选[Union[int, Tuple[int, ...]]]):绝对差异的可选索引。
atol (浮点数): 允许的绝对容差。只有在它或 `rtol` 大于 0 时才会添加到不匹配统计中。
``> 0``。
rel_diff (浮点数): 相对差异。
rel_diff_idx (Optional[Union[int, Tuple[int, ...]]]): 相对差异的索引(可选)。
rtol(浮点数):允许的相对容差。只有在它或 ``atol`` 大于 ``0`` 时才会添加到不匹配统计中。
``> 0``。
"文档"
    相等性 = rtol == 0 并且 容差 == 0

    定义 make_diff_msg(
        *,
        类型: 字符串,
        差异: float,
        索引: 可选[联盟[整数, 元组[整数, ...]],
        容差: float,
    ) -> 字符串:
        如果 索引  :
            msg = f"{类型.标题()}差异:{差异}"
        else:
            msg = f"最伟大的{类型}差异:{差异}在索引{索引}"
        如果  相等:
            msg += f"(最多"{容差}允许的)"
        返回 msg + "输入文本翻译为简体中文为:\n"

    如果 标识符  :
        标识符 = 默认标识符
    elif 可调用(标识符):
        标识符 = 标识符(默认标识符)

    msg = f"{标识符}不再{相等 如果 平等 否则 接近}!\n\n
\n\n"

    如果 额外:
        msg += f"{额外.strip()}输入文本翻译为简体中文为:\n"

    msg += 制作差异消息(类型=绝对, 差异=绝对差, 索引=绝对差索引, 容差=精度)
    msg += 创建差异消息(类型=相对, 差异=相对差异, 索引=相对差异索引, 容差=相对误差)

    返回 信息.strip()


定义 创建标量不匹配信息(
    实际: 联盟[布尔, 整数, float, 复杂]
    预期: 联盟[布尔, 整数, float, 复杂]
    *,
    相对误差: float,
    精度: float,
    标识符: 可选[联盟[字符串, 可调用[[str] 字符串]]] = ,
) -> 字符串:
    创建一个用于标量不匹配错误的错误信息。

参数:
实际(Union[bool, int, float, complex]):实际标量。
预期(Union[bool, int, float, complex]):预期标量。
相对容差(浮点数):相对容差
atol(float):绝对容差。
标识符(可选[Union[str, Callable[[str], str]]]):可选的标量描述。可以是可调用的,在这种情况下,它将使用默认值在运行时创建描述。
作为可调用的传入,在这种情况下,它将使用默认值调用以在运行时创建描述。
默认为“标量”。
"文档"
    绝对差分 = 绝对值(实际 - 预期)
    相对差异 = float("无穷大") 如果 预期 == 0 否则 绝对差异 / 绝对值(预期)
    返回 _生成不匹配信息_(
        默认标识符=标量,
        标识符=标识符,
        额外的=f预期{预期}但是得到了{实际的}.",
        绝对差异=绝对差异,
        精度=精度,
        相对差异=相对差异,
        相对误差=相对误差,
    )


定义 创建张量不匹配信息(
    实际: 火把.张量,
    预期: 火把.张量,
    匹配: 火把.张量,
    *,
    相对误差: float,
    精度: float,
    标识符: 可选[联盟[字符串, 可调用[[字符串] 字符串]]] = ,
):
    为张量生成一个不匹配的错误信息。

参数:
实际(torch.Tensor):实际张量。
预期(torch.Tensor):预期张量。
matches (torch.Tensor):与 ``actual`` 和 ``expected`` 形状相同的布尔掩码,指示匹配的位置。
匹配的位置。
rtol (float):相对容差。
atol (float):绝对容差。
identifier(可选[Union[str, Callable[[str], str]]]):可选的用于张量的描述。可以是可调用的,在这种情况下,它将使用默认值在运行时创建描述。
作为可调用的传入,在这种情况下,它将使用默认值调用以在运行时创建描述。
默认为“Tensor-likes”。
"文档"

    定义 unravel_flat_index(平面索引: 整数) -> 元组[整数, ...]:
        如果  匹配.shape:
            返回 ()

        逆索引 = 输入文本为空,请提供需要翻译的文本
        for 大小  匹配.shape[::-1]:
            除法, 修饰 = divmod 函数(平面索引, 尺寸)
            平面索引 = div
            逆索引.append(模块)

        返回 元组(逆索引输入文本:
  [::

翻译:
  [::-1])

    元素数量 = 匹配.元素数量()
    总错误匹配数 = 元素数量 - 整数(火把.总和(匹配))
    额外 = (
        f"元素不匹配:{总不匹配数} / {元素数量} "
        f“(”{总错配数 / 元素数量:.1%})"
    )

    实际平面 = 实际.展平()
    预期平坦 = 预期.展平()
    匹配平坦 = 匹配.展平()

    如果  实际.数据类型.是否为浮点数 并且  实际.数据类型.是复杂的:
        # TODO: 而不是总是向上转换为 int64,只需转换为下一个更高的数据类型即可避免
        # 溢出
        实际平坦 = 实际平坦.(火把.int64)
        预期平坦 = 预期平坦.(火把.int64)

    绝对差 = 火把.绝对值(实际平面 - 预期平坦)
    仅使用不匹配项进行最大绝对差值计算
    最大绝对差值[匹配项平坦化] = 0
    最大绝对差值, 最大绝对差值索引 = 火把.最大值(绝对差, 0)

    相对差 = 绝对差 / 火把.绝对值(预期平坦)
    # 确保只使用不匹配项进行最大相关差异计算
    相关差异[匹配平坦] = 0
    最大相对差异, 最大相对差异平坦索引 = 火把.最大值(相对差异, 0)
    返回 _生成不匹配信息(
        默认标识符=张量类,
        标识符=标识符,
        额外=额外,
        绝对差=最大绝对差.项目(),
        绝对差索引=展平索引展开(整数(最大绝对差值索引)),
        精度=精度,
        相对差=最大相对差.项目(),
        相对差索引=解开平面索引(整数(max_rel_diff_flat_idx)),
        相对误差=相对误差,
    )


 不支持的输入(异常):  # noqa: B903
    在构建一个 :class:`Pair` 时抛出的异常,如果它不支持这些输入。


 配对(abc.ABC):
    ABC 用于与:func:`assert_equal`一起使用的所有比较对

每个子类都需要重写执行实际比较的 :meth:`Pair.compare` 方法。

每对都接收 **所有** 选项,因此请选择适用于子类的选项,并将其余的传递给
父类。在构造过程中引发 :class:`UnsupportedInputs` 异常表示该对无法处理输入,并将尝试下一个对类型。
如果输入无法处理,则会在构造过程中引发 :class:`UnsupportedInputs` 异常,并将尝试下一个对类型。

所有其他错误应抛出为 :class:`ErrorMeta`。实例化后,:meth:`Pair._make_error_meta` 可以
自动处理使用用户提供的消息和 id 处理。
"文档"

    定义 __init__(
        ,
        实际: 任何,
        预期: 任何,
        *,
        id: 元组[任何, ...] = (),
        **未知参数: 任何,
    ) -> :
        .实际 = 实际
        .预期 = 预期
        .标识符 = 标识符
        .未知参数 = 未知参数

    @staticmethod
    定义 不支持输入() -> 无返回:
        raise 不支持的输入

    @staticmethod
    定义 _检查输入是否为给定类的实例(*输入: 任何, : 联盟[类型, 元组[类型, ...]]:
        检查所有输入是否为给定类的实例,否则引发 :class:`不支持的输入` 异常。
        如果  所有(isinstance(输入, ) for 输入  输入):
            .不支持输入()

    定义 _fail(
        , 类型: 类型[异常] 信息: 字符串, *, id: 元组[任何, ...] = ()
    ) -> NoReturn:
        从给定的异常类型和消息以及存储的 ID 抛出一个 :class:`ErrorMeta`。

.. 警告::

如果你在构造函数中调用 ``super().__init__(...)`` 之前使用此方法,你必须显式地传递 ``id``。
明确地。
"文档"
        raise 错误元数据(类型, 信息, id=.标识符 如果  标识符 并且 有属性(, id) 否则 id)

    @abc.抽象方法
    定义 比较() -> :
        比较输入并引发一个 :class`错误元数据` 异常,如果它们不匹配。

    定义 额外表示() -> 序列[联盟[字符串, 元组[字符串, 任何]]]:
        返回将包含在表示中的额外信息。

应由所有使用附加选项的子类覆盖。对象的表示只有在遇到意外错误时才会显示,因此有助于调试问题。可以是键值对或属性名称的序列。
如果遇到意外错误,则将显示出来,从而有助于调试问题。可以是键值对或属性名称的序列。
可以是键值对或属性名称的序列。
"文档"
        返回 输入文本为空,请提供需要翻译的文本

    定义 __repr__() -> 字符串:
        头部 = f"{类型().__name__}(
         = )"
        身体 = [
            f"    {名称}={}
            for 名称,   [
                (id, .id),
                (实际, .实际),
                (预期, .预期),
                *[
                    (额外, getattr(, 额外)) 如果 isinstance(额外, 字符串) 否则 额外
                    for 额外  .额外表示()
                ]
            ]
        ]
        返回 "输入文本翻译为简体中文为:\n".连接((, *主体, *))


 对象对():
    对于任何类型的输入,该对将被用于与 `==` 操作符进行比较。

.. 注意::

由于这将针对任何类型的输入实例化,因此它只能在所有其他对之后用作后备。
无法处理输入。

"文档"

    定义 比较() -> :
        尝试:
            相等 = .实际 == .预期
        除了 异常  错误:
            # 我们在这里不使用 `self._raise_error_meta`,因为我们需要异常链
            raise 错误元(
                ValueError,
                f"{.实际} == {.预期}失败:输入文本翻译为简体中文为:\n{错误}.",
                id=.id,
            ) from 错误

        如果  平等:
            ._fail(断言错误, f"{.实际} != {.预期}")


 NonePair(Pair):
    """Pair for ``None`` inputs."""

    定义 __init__(, 实际: 任何, 预期: 任何, **其他参数: 任何) -> :
        如果  (实际   或者 预期  ):
            .不支持输入()

        超级().__init__(实际, 预期, **其他参数)

    定义 比较() -> :
        如果  (.实际   并且 .预期  ):
            ._fail(
                断言错误, f"无匹配:"{.实际}不是{.预期}"
            )


 布尔对():
    """对布尔输入。"""

.. 注意::

如果有 ``numpy``,也处理 :class:`numpy.bool_` 输入。

"文档"

    定义 __init__(
        ,
        实际: 任何,
        预期: 任何,
        *,
        id: 元组[任何, ...]
        **其他参数: 任何,
    ) -> :
        实际, 预期 = .处理输入(实际, 预期, id=id)
        超级().__init__(实际, 预期, **其他参数)

    @property
    定义 支持的类型() -> 元组[类型, ...]:
        : 列表[类型] = [布尔]
        如果 HAS_NUMPY:
            .append(numpy.布尔_)
        返回 元组()

    定义 处理输入(
        , 实际: 任何, 预期: 任何, *, id: 元组[任何, ...]
    ) -> 元组[布尔, 布尔]:
        ._检查输入是否为实例(实际, 预期, =.支持的类型)
        实际, 预期 = (
            ._to_bool(布尔类型或类似值, id=id) for 布尔类型  (实际的, 预期)
        )
        返回 实际的, 预期

    定义 _转换为布尔值(, 布尔类型: 任何, *, id: 元组[任何, ...]) -> 布尔:
        如果 isinstance(布尔类型, 布尔):
            返回 布尔类型
        elif isinstance(布尔类型, numpy.布尔_):
            返回 布尔类型.项目()
        else:
            raise 错误元数据(
                类型错误, f"未知布尔类型"{类型(布尔类型)}.", id=标识符
            )

    定义 比较() -> :
        如果 .实际的   .预期:
            ._fail(
                断言错误,
                f布尔值不匹配:{.实际}不是{.预期}",
            )


 数字对():
    Python 数字(:class:`int`、:class:`float`和:class:`complex`)的配对。

.. 注意::

如果``numpy``可用,也处理:class:`numpy.number`输入。

参数:
rtol(可选[浮点数]):相对容差。如果指定,则必须也指定``atol``。如果省略,则默认
根据类型选择以下表格中的值。
atol(可选[float]):绝对容差。如果指定了 ``rtol``,则必须也指定 ``atol``。如果省略,则使用默认值。
根据类型选择以下表格中的值。
equal_nan(bool):如果为 ``True``,则认为两个 ``NaN`` 值相等。默认为 ``False``。
check_dtype (布尔值): 如果为 ``True``,则将检查输入的类型是否相等。默认为 ``False``。

下表显示了 Python 数字类型与 ``torch.dtype`` 之间的对应关系。请参见
func:`assert_close` 以获取相应的容差。

    +------------------+-------------------------------+
| ``类型``         | 对应的 ``torch.dtype`` |
    +==================+===============================+
    | :class:`int`     | :attr:`~torch.int64`          |
    +------------------+-------------------------------+
    | :class:`float`   | :attr:`~torch.float64`        |
    +------------------+-------------------------------+
    | :class:`complex` | :attr:`~torch.complex64`      |
    +------------------+-------------------------------+
"文档"

    类型转数据类型 = {
        整数: 火把.int64,
        float: 火把.float64,
        复杂: 火把.complex128,
    }
    类型数量 = 元组(类型转数据类型.())

    定义 __init__(
        ,
        实际: 任何,
        预期: 任何,
        *,
        id: 元组[任何, ...] = (),
        相对误差: 可选[float] = ,
        精度: 可选[float] = ,
        等于 NaN: 布尔 = 错误,
        检查数据类型: 布尔 = 错误,
        **其他参数: 任何,
    ) -> :
        实际, 预期 = .处理输入(实际, 预期, id=id)
        超级().__init__(实际, 预期, id=id, **其他参数)

        .相对误差, .容差 = 获取公差(
            *[._类型到数据类型[类型(输入)] for 输入  (实际, 预期)],
            相对误差=相对误差,
            精度=精度,
            id=id,
        )
        .等于非数字 = 等于非数字
        .检查数据类型 = 检查数据类型

    @property
    定义 支持的类型() -> 元组[类型, ...]:
         = 列表(.数字类型)
        如果 HAS_NUMPY:
            .append(numpy.数字)
        返回 元组()

    定义 处理输入(
        , 实际的: 任何, 预期: 任何, *, id: 元组[任何, ...]
    ) -> 元组[联盟[整数, float, 复杂] 联盟[整数, float, 复杂]]
        ._check_inputs_isinstance(实际, 预期, =._supported_types)
        实际, 预期 = (
            .转换为数字(数字类型, id=id) for 数字  (实际的, 预期)
        )
        返回 实际的, 预期

    定义 转换为数字(
        , 数字类: 任何, *, id: 元组[任何, ...]
    ) -> 联盟[整数, float, 复杂]:
        如果 HAS_NUMPY 并且 isinstance(数字类, numpy.数字):
            返回 类数字.项目()
        elif isinstance(类数字, ._数字类型):
            返回 数字类型  # 类型:忽略[返回值]
        else:
            raise 错误元数据(
                类型错误, f"未知数字类型"{类型(数字类型)}.", id=标识符
            )

    定义 比较() -> :
        如果 .检查数据类型 并且 类型(.实际)   类型(.预期):
            ._fail(
                断言错误,
                f"数据类型不匹配:{类型(.实际)} != {类型(.预期)}.",
            )

        如果 .实际 == .预期:
            返回

        如果 .等于 NaN 并且 cmath.isnan(.实际) 并且 cmath.isnan(.预期):
            返回

        绝对差分 = 绝对值(.实际 - .预期)
        容差 = .容差 + .相对容差 * 绝对值(.预期)

        如果 复数数学.是有限的(绝对差值) 并且 绝对差分  容差:
            返回

        ._fail(
            断言错误,
            生成标量不匹配信息(
                .实际, .预期, 相对误差=.相对误差, 精度=.容差
            ),
        )

    定义 额外表示() -> 序列[字符串]:
        返回 (
            "rtol",
            "atol",
            "equal_nan",
            "check_dtype",
        )


 TensorLikePair(Pair):
    """Pair 用于 :class:`torch.Tensor`-like 输入。

参数:
allow_subclasses (bool): 允许子类 (布尔值)
rtol (Optional[float]): 相对容差。如果指定,则必须也指定 ``atol``。如果省略,则默认
根据类型选择值。有关详细信息,请参阅 :func:assert_close:
atol (Optional[float]): 绝对容差。如果指定,则必须也指定 ``rtol``。如果省略,则默认
根据类型选择值。有关详细信息,请参阅 :func:assert_close:。
equal_nan (布尔值): 如果为 ``True``,则认为两个 ``NaN`` 值相等。默认为 ``False``。
check_device (布尔值): 如果为 ``True``(默认),则断言相应的张量位于同一
attr:`~torch.Tensor.device`。如果禁用此检查,则位于不同
`torch.Tensor.device` 的设备在比较之前被移动到 CPU。
检查 dtype(布尔值):如果为 ``True``(默认值),则断言相应的张量具有相同的 ``dtype``。如果为
检查被禁用,不同 ``dtype`` 的张量被提升到公共 ``dtype``(根据)
在比较之前,先使用 `torch.promote_types` 函数提升类型。
检查布局(bool):如果为 ``True``(默认值),则断言相应的张量具有相同的 ``layout``。如果这
检查被禁用,具有不同 `layout` 的张量在转换为 strided 张量之前
比较。
检查步长(布尔值):如果为 ``True`` 且相应的张量是步进张量,则断言它们具有相同的步长。
"文档"

    定义 __init__(
        ,
        实际: 任何,
        预期: 任何,
        *,
        id: 元组[任何, ...] = (),
        允许子类: 布尔 = ,
        相对误差: 可选[float] = ,
        精度: 可选[float] = ,
        等于 NaN: 布尔 = 错误,
        检查设备: 布尔 = ,
        检查数据类型: 布尔 = ,
        检查布局: 布尔 = ,
        检查步长: 布尔 = 错误,
        **其他参数: 任何,
    ):
        实际, 预期 = .处理输入(
            实际, 预期, id=id, 允许子类=允许子类
        )
        超级().__init__(实际的, 预期, id=id, **其他参数)

        .相对误差, .容差 = 获取公差(
            实际, 预期, 相对误差=相对误差, 精度=精度, id=.标识符
        )
        .等于非数字 = 等于非数字
        .检查设备 = 检查设备
        .检查数据类型 = 检查数据类型
        .检查布局 = 检查布局
        .检查步长 = 检查步长

    定义 处理输入(
        , 实际: 任何, 预期: 任何, *, id: 元组[任何, ...] 允许子类: 布尔
    ) -> 元组[火把.张量, 火把.张量]:
        直接相关 = isinstance(实际, 类型(预期)) 或者 isinstance(
            预期, 类型(实际)
        )
        如果  直接相关:
            .不支持输入()

        如果  允许子类 并且 类型(实际的)   类型(预期):
            .不支持输入()

        实际, 预期 = (.转换为张量(输入) for 输入  (实际, 预期))
        for 张量  (实际, 预期):
            .检查支持(张量, id=id)
        返回 实际, 预期

    定义 转换为张量(, 类似于张量: 任何) -> 火把.张量:
        如果 isinstance(张量类似, 火把.张量):
            返回 张量类似

        尝试:
            返回 火把.as_tensor(张量类似)
        除了 异常:
            .不支持输入参数()

    定义 检查支持(, 张量: 火把.张量, *, id: 元组[任何, ...]) -> :
        如果 张量.布局   {
            火把.strided,
            火把.错落有致,
            火把.稀疏 COO,
            火把.稀疏压缩存储格式,
            火把.稀疏压缩存储格式,
            火把.稀疏_bsr,
            火把.稀疏矩阵,
        }:
            raise 错误元数据(
                ValueError, f"不支持的张量布局"{张量.布局}", id=标识符
            )

    定义 比较() -> :
        实际, 预期 = .实际, .预期

        ._比较属性(实际, 预期)
        如果 任何(输入.设备.类型 == 元数据 for 输入  (实际, 预期)):
            返回

        实际, 预期 = ._均衡属性(实际, 预期)
        .比较值(实际, 预期)

    定义 比较属性(
        ,
        实际: 火把.张量,
        预期: 火把.张量,
    ) -> :
        检查两个张量的属性是否匹配。

总是进行检查

- 检查 :attr:`~torch.Tensor.shape` ,
- 是否两个输入都进行了量化,
- 以及它们是否使用了相同的量化方案。

检查:

- :attr:`~torch.Tensor.layout`,
- :meth:`~torch.Tensor.stride`
- :attr:`~torch.Tensor.device` 和
        - :attr:`~torch.Tensor.dtype`

这些是可选的,并且可以在构建对时通过相应的 `check_*` 标志禁用。
"文档"

        定义 引发不匹配错误(
            属性名称: 字符串, 实际值: 任何, 预期值: 任何
        ) -> 无返回值:
            ._fail(
                断言错误,
                f"属性值的'{属性名}'不匹配:'{实际值} != {预期值}.",
            )

        如果 实际.形状 != 预期.shape:
            引发不匹配错误("形状", 实际.shape, 预期.shape)

        如果 实际.是否量化 != 预期.是否量化:
            引发不匹配错误(
                "is_quantized", 实际.是否量化, 预期.是否量化
            )
        elif 实际.是否量化 并且 实际.q 方案() != 预期.q 方案():
            引发不匹配错误("qscheme()", 实际.q 方案(), 预期.q 方案())

        如果 实际.布局 != 预期.布局:
            如果 .检查布局:
                引发不匹配错误(布局, 实际.布局, 预期.布局)
        elif (
            实际.布局 == 火把.稀疏的
            并且 .检查步长
            并且 实际.步长() != 预期.步长()
        ):
            引发不匹配错误("步长()", 实际.步长(), 预期.步长())

        如果 .检查设备 并且 实际.设备 != 预期.设备:
            引发不匹配错误("设备", 实际.设备, 预期.设备)

        如果 .检查数据类型 并且 实际.dtype != 预期.数据类型:
            引发不匹配错误("dtype", 实际.数据类型, 预期.数据类型)

    定义 _均衡属性(
        , 实际: 火把.张量, 预期: 火把.张量
    ) -> 元组[火把.张量, 火把.张量]:
        平衡两个张量的某些属性以进行值比较。

如果 `实际` 和 `预期` ...

- ... 不在相同的 :attr:`~torch.Tensor.device` 上,它们将被移动到 CPU 内存。
- ... 不具有相同的 `dtype`,它们将被提升到公共 `dtype`(根据 ...
`torch.promote_types`)。
- ...它们不是同一 ``layout``,将被转换为带偏移的张量。

参数:
实际(Tensor):实际张量。
预期(Tensor):预期张量。

返回:
(Tuple[Tensor, Tensor]): 均衡张量。
"文档"
        # 比较逻辑使用了 MPS 后端当前不支持的操作符。
        # 详细信息请见 https://github.com/pytorch/pytorch/issues/77144。
        # TODO: 一旦所有操作都原生支持 MPS 后端,则删除此转换。
        如果 实际.是_mps 或者 预期.是 mps:  # 类型: 忽略[attr-defined]
            实际 = 实际.cpu()
            预期 = 预期.cpu()

        如果 实际.设备 != 预期.设备:
            实际 = 实际.cpu()
            预期 = 预期.cpu()

        如果 实际.dtype != 预期.数据类型:
            实际数据类型 = 实际.dtype
            预期数据类型 = 预期.dtype
            # 对于 uint64,在一般情况下并不适用,这就是为什么 promote_types 不
            # 允许这样做,但在方便测试的情况下,我们不太可能混淆
            # 大的 uint64 溢出到负的 int64
            如果 实际数据类型  [火把.uint64, 火把.uint32, 火把.uint16]:
                实际数据类型 = 火把.int64 类型
            如果 预期数据类型  [火把.uint64, 火把.uint32, 火把.uint16]:
                预期数据类型 = 火把.int64 类型
            dtype = 火把.推广类型(实际数据类型, 预期数据类型)
            实际 = 实际.(数据类型)
            预期 = 预期.(数据类型)

        如果 实际.布局 != 预期.布局:
            # 这些检查是必要的,因为 Tensor.to_dense()在已经分块的张量上会失败
            实际 = 实际.转换为稠密格式() 如果 实际.布局 != 火把.稀疏的 否则 实际
            预期 = (
                预期.转换为稠密格式() 如果 预期.布局 != 火把.稀疏的 否则 预期
            )

        返回 实际, 预期

    定义 比较值(, 实际: 火把.张量, 预期: 火把.张量) -> :
        如果 实际.是否量化:
            比较函数 = ._比较量化值
        elif 实际.is_sparse:
            compare_fn = ._compare_sparse_coo_values
        elif actual.布局  {
            火把.稀疏压缩存储格式,
            火把.稀疏压缩存储格式,
            火把.稀疏_bsr,
            火把.稀疏矩阵,
        }:
            compare_fn = .比较稀疏压缩值
        elif 实际.布局 == 火把.错落有致:
            实际, 预期 = 实际.(), 预期.()
            比较函数 = ._比较常规值接近
        else:
            比较函数 = .比较常规值接近

        比较函数(
            实际的, 预期, 相对误差=.相对误差, 精度=.精度, 等于 NaN=.等于非数字
        )

    定义 比较量化值(
        ,
        实际的: 火把.张量,
        预期: 火把.张量,
        *,
        相对误差: float,
        精度: float,
        等于 NaN: 布尔,
    ) -> :
        通过比较量化张量的去量化变体来比较其接近程度。

.. 注意::

详细讨论了为什么只检查去量化变体的接近程度,而不是检查量化参数的接近程度和整数表示的相等性。
关于为什么只检查去量化变体的接近程度,而不是检查量化参数的接近程度和整数表示的相等性,可以参考 https://github.com/pytorch/pytorch/issues/68548。
详细讨论了为什么只检查去量化变体的接近程度,而不是检查量化参数的接近程度和整数表示的相等性,可以参考 https://github.com/pytorch/pytorch/issues/68548。
"文档"
        返回 .比较常规值接近(
            实际.反量化(),
            预期.反量化(),
            相对误差=相对误差,
            精度=精度,
            等于 NaN=等于 NaN,
            标识符=lambda 默认标识符: f"量化"{默认标识符.小写()}",
        )

    定义 比较稀疏 COO 张量(
        ,
        实际: 火把.张量,
        预期: 火把.张量,
        *,
        相对误差: float,
        精度: float,
        等于 NaN: 布尔,
    ) -> :
        比较稀疏 COO 张量,通过比较

- 稀疏维度数量,
- 非零元素(nnz)数量是否相等,
等价的索引,
距离的值。
"文档"
        如果 实际.稀疏维度() != 预期.稀疏维度():
            ._fail(
                断言错误,
                (
                    f"稀疏 COO 张量中稀疏维度的数量不匹配:"
                    f"{实际.稀疏维度()} != {预期.稀疏维度()}"
                ),
            )

        如果 实际._nnz() != 预期._nnz():
            ._fail(
                断言错误,
                (
                    f"稀疏 COO 张量中指定的值数量不匹配:"
                    f"{实际._nnz()} != {预期._nnz()}"
                ),
            )

        .比较常规值是否相等(
            实际.索引(),
            预期.索引(),
            标识符=稀疏 COO 索引,
        )
        .比较常规值是否接近(
            实际.(),
            预期.(),
            相对误差=相对误差,
            精度=精度,
            等于 NaN=等于 NaN,
            标识符=稀疏 COO 值,
        )

    定义 比较稀疏压缩值(
        ,
        实际: 火把.张量,
        预期: 火把.张量,
        *,
        相对误差: float,
        精度: float,
        等于 NaN: 布尔,
    ) -> :
        比较稀疏压缩张量,通过比较

- 非零元素(nnz)的数量是否相等,
- 索引是否相等,
- 压缩索引是否相等,以及
亲近度的值。
"文档"
        格式名称, 压缩索引方法, 纯索引方法 = {
            火把.稀疏压缩存储格式: (
                CSR,
                火把.张量.鸡索引,
                火把.张量.列索引,
            ),
            火把.稀疏压缩存储格式: (
                CSC,
                火把.张量.c 列索引,
                火把.张量.行索引,
            ),
            火把.稀疏_bsr: (
                BSR,
                火把.张量.鸡索引,
                火把.张量.列索引,
            ),
            火把.稀疏矩阵: (
                BSC,
                火把.张量.c 列索引,
                火把.张量.行索引,
            ),
        }实际.布局]

        如果 实际._nnz() != 预期._nnz():
            ._fail(
                断言错误,
                (
                    f稀疏矩阵中指定的值数量{格式名称}张量不匹配:
                    f"{实际._nnz()} != {预期._nnz()}"
                ),
            )

        压缩和稀疏格式 CSR / CSC / BSR / BSC 中的索引可以是`torch.int32` _或_
        `torch.int64`。虽然单个张量的压缩和普通索引强制使用相同的 dtype,它
        两个张量之间可能不同。因此,我们需要将它们转换为相同的 dtype,否则比较将
        失败。
        实际压缩索引 = 压缩索引方法(实际)
        预期压缩索引 = 压缩索引方法(预期)
        索引数据类型 = 火把.推广类型(
            实际压缩索引.数据类型, 预期压缩索引.dtype
        )

        .比较常规值是否相等(
            实际压缩索引.(索引数据类型),
            预期压缩索引.(索引数据类型),
            标识符=f稀疏{格式名称} {压缩索引方法.__name__}",
        )
        .比较常规值是否相等(
            索引方法(实际).(索引数据类型),
            索引方法(预期).(索引数据类型),
            标识符=f稀疏{格式名称} {索引方法.__name__}",
        )
        .比较常规值关闭(
            实际.(),
            预期.(),
            相对误差=相对误差,
            精度=精度,
            等于 NaN=等于 NaN,
            标识符=f稀疏{格式名称},
        )

    定义 比较常规值是否相等(
        ,
        实际: 火把.张量,
        预期: 火把.张量,
        *,
        等于 NaN: 布尔 = 错误,
        标识符: 可选[联盟[字符串, 可调用[[字符串] 字符串]]] = ,
    ) -> :
        检查两个张量的值是否相等。
        ._比较常规值是否接近(
            实际, 预期, 相对误差=0, 精度=0, 等于 NaN=等于 NaN, 标识符=标识符
        )

    定义 _比较常规值是否接近(
        ,
        实际: 火把.张量,
        预期: 火把.张量,
        *,
        相对误差: float,
        精度: float,
        等于 NaN: 布尔,
        标识符: 可选[联盟[字符串, 可调用[[字符串] 字符串]]] = ,
    ) -> :
        检查两个张量的值是否在期望的容差范围内接近。
        匹配项 = 火把.isclose(
            实际, 预期, 相对误差=相对误差, 精度=精度, 等于 NaN=等于非数字
        )
        如果 火把.所有(匹配):
            返回

        如果 实际的.形状 == 火把.尺寸空数组
            msg = 创建标量不匹配信息(
                实际的.项目(),
                预期.项目(),
                相对误差=相对误差,
                精度=精度,
                标识符=标识符,
            )
        else:
            msg = make_tensor_mismatch_msg(
                实际的, 预期, 匹配, 相对误差=相对误差, 精度=精度, 标识符=identifier
            )
        ._fail(断言错误, 信息)

    定义 额外表示() -> 序列[字符串]:
        返回 (
            "rtol",
            "atol",
            "equal_nan",
            "check_device",
            检查数据类型,
            检查布局,
            检查步长,
        )


定义 生成配对(
    实际: 任何,
    预期: 任何,
    *,
    对应类型: 序列[类型[Pair]],
    序列类型: 元组[类型, ...] = (集合.abc.序列,),
    映射类型: 元组[类型, ...] = (集合.abc.映射,),
    id: 元组[任何, ...] = (),
    **选项: 任何,
) -> 列表[Pair]:
    从单个输入中生成对。

``实际`` 和 ``预期`` 可能是嵌套的 :class:`~collections.abc.Sequence` 或 :class:`~collections.abc.Mapping`。在这种情况下,对是通过递归遍历它们生成的。
class:`~collections.abc.Mapping` 的。在这种情况下,对是通过递归遍历它们生成的。

参数:
实际 (Any):实际输入。
预期(任何):预期输入。
pair_types(Type[Pair]序列):将尝试与输入构建的配对类型序列。
第一个成功的配对将被使用。
sequence_types(Type 元组...):作为序列处理的可选类型,将逐元素进行检查。
mapping_types (Tuple[Type, ...]): 作为映射处理的可选类型,将逐元素进行检查。
id (Tuple[Any, ...]): 将包含在错误信息中的可选对 id。
**options (Any): 构造每个对时传递的选项。

抛出异常:
ErrorMeta: 如果输入是 :class:`~collections.abc.Sequence` 的实例,则使用 :class`AssertionError`,但它们的
长度不匹配。
错误元信息:如果输入是 :class:`~collections.abc.Mapping` 类型的,但它们的键集不匹配。
键不匹配。
错误元信息:如果没有一对能够处理输入。
错误元数据:在构建一对时发生的任何预期异常。

返回:
(List[Pair]):原始对。
"文档"
    # 我们在这里明确排除 str,因为它们是自引用的,会导致无限递归循环:
    # "a" == "a"[0][0]...
    如果 (
        isinstance(实际, 序列类型)
        并且  isinstance(实际, 字符串)
        并且 isinstance(预期, 序列类型)
        并且  isinstance(预期, 字符串)
    ):
        实际长度 = 长度(实际)  # type: ignore[arg-type]
        预期长度 = 长度(预期)  # type: ignore[arg-type]
        如果 实际长度 != 预期长度:
            raise 错误元(
                断言错误,
                f序列长度不匹配:{实际长度} != {预期长度}",
                id=id,
            )

         = 输入文本为空,请提供需要翻译的文本
        for 索引  范围(实际长度):
            pairs.扩展(
                原句对:原句对(
                    实际[索引]  忽略索引
                    预期[索引]  忽略索引
                    对偶类型=对偶类型,
                    序列类型=序列类型,
                    映射类型=映射类型,
                    id=(*id, 索引),
                    **选项,
                )
            )
        返回 

    elif isinstance(实际, 映射类型) 并且 isinstance(预期, 映射类型):
        实际键 = 设置(实际.())  # 类型: 忽略[attr-defined]
        预期键 = 设置(预期.())  # 类型: 忽略[attr-defined]
        如果 实际键 != 预期键:
            缺少键 = 预期键 - 实际键
            附加键 = 实际键 - 预期键
            raise 错误元(
                断言错误,
                (
                    f"映射的键不匹配:"输入文本翻译为简体中文为:\n"
                    f"实际映射中缺少键:"{排序(缺少键)}输入文本翻译为简体中文为:\n"
                    f"实际映射中多余的键:"{排序(额外键)}"
                ),
                id=id,
            )

        : 集合 = 实际键
        由于原始操作在第一次失败后就会中止,所以我们尝试保持确定性
         contextlib.抑制(异常):
             = 排序()

         = 输入文本为空,请提供需要翻译的文本
        for key  :
            pairs.扩展(
                原始对(
                    实际[]  忽略索引
                    预期[]  忽略索引
                    对类型=对类型,
                    序列类型=序列类型,
                    映射类型=映射类型,
                    id=(*id, ),
                    **选项,
                )
            )
        返回 

    else:
        for 对类型  对应类型:
            尝试:
                返回 [对应类型项(实际, 预期, id=id, **选项)]
            在生成过程中抛出 `UnsupportedInputs` 异常表示该对应类型无法处理输入。
            因此,我们尝试下一个对应类型。
            除了 不支持的输入:
                continue
            在发起过程中抛出`ErrorMeta`是正常终止的方式,所以我们只是简单地重新抛出它。
            这只是在一个单独的分支中,因为下面的那个也会捕获它。
            除了 错误元:
                raise
            在发起过程中引发任何其他异常是不预期的,并将提供有关发生情况的一些额外信息。
            如果适用,未来应预期该异常。
            除了 异常  错误:
                raise 运行时错误(
                    f"发起一个"{对应类型.__name__}()在项目处{请提供需要翻译的文本.连接(字符串[项目]) for 项目  id)}以及\n\n
\n\n"
                    f"{类型(实际).__name__}(): {实际}\n\n
\n\n"
                    f"并且"\n\n
\n\n"
                    f"{类型(预期).__name__}(): {预期}\n\n
\n\n"
                    f"导致了上述意外的异常。"
                    f"如果您是用户并且在正常操作期间看到此消息,"
                    "请在此处提交问题:https://github.com/pytorch/pytorch/issues。"
                    "如果你是一名开发者,正在编写比较函数,"
                    "请捕获之前的错误,并抛出一个表达式的 `ErrorMeta` 异常。"
                ) from 错误
        else:
            raise 错误元(
                类型错误,
                f"没有比较对能够处理类型为 not_close_error_metas 的输入。"{类型(实际)}{类型(预期)}.",
                id=id,
            )


定义 not_close_error_metas(
    实际: 任何,
    预期: 任何,
    *,
    配对类型: 序列[类型[配对]] = (对象对,),
    序列类型: 元组[类型, ...] = (集合.abc.序列,),
    映射类型: 元组[类型, ...] = (集合.abc.映射,),
    **选项: 任何,
) -> 列表[错误元]:
    断言输入相等。

``实际`` 和 ``预期`` 可能是嵌套的 :class:`~collections.abc.Sequence`'s
class:`~collections.abc.Mapping`'s。在这种情况下,比较是逐元素进行的,通过递归遍历它们。

参数:
实际 (Any): 实际输入。
预期 (Any): 预期输入。
pair_types (Sequence[Type[Pair]]): 尝试构建的 :class:`Pair` 类型序列
输入。将使用第一个成功的配对。默认仅使用 :class:`ObjectPair`。
sequence_types (Tuple[Type, ...]): 可选的序列类型,将逐元素进行检查
mapping_types (Tuple[Type, ...]): 可选的映射类型,将逐元素进行检查
**选项(任意):构造每个对时传递的选项。
"文档"
    # 从 `pytest` 的回溯中隐藏此函数
    __tracebackhide__ = 真实

    尝试:
        pairs = 原句对:原句对(
            实际,
            预期,
            对偶类型=对偶类型,
            序列类型=序列类型,
            映射类型=映射类型,
            **选项,
        )
    除了 ErrorMeta  错误元数据:
        # 显式地从 None 提升到隐藏内部跟踪
        raise 元数据错误.转换错误() from   # noqa: RSE102

    错误元数据: 列表[错误元] = 输入文本为空,请提供需要翻译的文本
    for   pairs:
        尝试:
            .比较()
        除了 错误元信息  错误元数据:
            错误元数据列表.append(错误元数据)
        在比较时除了`ErrorMeta`之外抛出任何异常都是意外的,并且会提供一些额外信息
        关于发生的事情。如果适用,未来应预期异常。
        除了 异常  错误:
            raise 运行时错误(
                f比较\n\n
\n\n"
                f"{}\n\n
\n\n"
                f"导致上述意外的异常。"
                f如果您是用户,在正常操作期间看到此消息
                "请在此处提交问题:https://github.com/pytorch/pytorch/issues。"
                "如果您是开发者并且正在处理比较函数,"
                "请捕获之前的错误并抛出一个表达性的 `ErrorMeta` 异常。"
            ) from 错误

    # [ErrorMeta 循环]
    此列表中的 ErrorMeta 对象捕获
    跟踪到该函数框架的异常。
    本地变量 `error_metas` 指的是错误元数据
    对象,创建一个引用循环。跟踪回溯中的帧
    # 测试中会持续占用 cuda 内存,直到周期收集。
    # 我们通过移除 error_meta 对象的引用来打破循环
    # 在返回此帧时。
    error_metas = [错误元数据]
    返回 错误元数据.流行()


[文档]定义 断言关闭( 实际: 任何, 预期: 任何, *, 允许子类: 布尔 = , 相对误差: 可选[float] = , 精度: 可选[float] = , 等于 NaN: 布尔 = 错误, 检查设备: 布尔 = , 检查数据类型: 布尔 = , 检查布局: 布尔 = , 检查步长: 布尔 = 错误, 信息: 可选[联盟[字符串, 可调用[[字符串] 字符串]]] = , ): r断言“实际”和“预期”值接近。 如果 `actual` 和 `expected` 是跨距、非量化、实值和有限的,则它们被认为是接近的。 .. math:: \lvert \text{actual} - \text{expected} \rvert \le \texttt{atol} + \texttt{rtol} \cdot \lvert \text{expected} \rvert 非有限值(`-inf` 和 `inf`)只有在它们相等的情况下才被认为是接近的。"NaN" 只有在 `equal_nan` 为 `True` 时才被认为是相等的。 只有在 `equal_nan` 为 `True` 时才被认为是相等的。 此外,只有它们相同才被认为是接近的 - :attr:`~torch.Tensor.device`(如果 `check_device` 为 `True`), - ``dtype``(如果 ``check_dtype`` 为 ``True``), - ``layout``(如果 ``check_layout`` 为 ``True``),以及 - 步长(如果 ``check_stride`` 为 ``True``)。 如果 ``actual`` 或 ``expected`` 是元张量,则只执行属性检查。 如果 ``actual`` 和 ``expected`` 是稀疏的(无论是 COO、CSR、CSC、BSR 或 BSC 布局),它们的步长成员是 逐个检查。索引,即 COO 的`indices`,CSR 和 BSR 的`crow_indices`和`col_indices`。 或 ``ccol_indices`` 和 ``row_indices`` 分别用于 CSC 和 BSC 布局 始终根据上述定义检查值之间的接近程度,而等式则始终检查相等性。 如果 `actual` 和 `expected` 被量化,它们被认为是接近的,如果它们具有相同的 `torch.Tensor.qscheme` 和 `torch.Tensor.dequantize` 的结果根据上述定义非常接近。 定义如上。 ``实际`` 和 ``预期`` 可以是 `torch.Tensor` 或任何可以由 `torch.as_tensor` 构造的来自 `torch.Tensor` 的张量或标量。 除了 Python 标量之外,输入类型可以是 `torch.Tensor`。 实际和预期必须直接相关。此外,``实际``和``预期``可以是:class:`~collections.abc.Sequence`的实例 或者:class:`~collections.abc.Mapping`的实例,在这种情况下,如果它们的结构匹配并且所有元素都根据上述定义被认为是接近的,则它们被认为是接近的 Python 标量是类型关系要求的例外,因为它们的:func:`type`,即 .. 注意:: Python 标量是类型关系要求的例外,因为它们的:func:`type`,即 `int`, `float` 和 `complex` 类型的 Python 标量等价于张量类的 `dtype`。因此, 可以检查不同类型的 Python 标量,但需要设置 `check_dtype=False`。 参数: 实际(Any):实际输入。 预期(Any):预期输入。 允许子类(布尔值):如果为 ``True``(默认值)并且除了 Python 标量之外,直接相关类型的输入 允许。否则需要类型相等。 rtol(可选[浮点数]):相对容差。如果指定了,则必须也指定 ``atol``。如果省略,则默认 基于`:attr:`~torch.Tensor.dtype`的值,使用下表选择。 atol(可选 float):绝对容差。如果指定,则必须也指定 rtol。如果省略,则使用默认值 根据以下表格选择基于:attr〜`torch.Tensor.dtype`的值。 equal_nan(Union[bool, str]):如果为 True,则两个 NaN 值将被视为相等。 check_device(bool):如果为 True(默认),则断言相应的张量位于同一设备上 `:attr:`~torch.Tensor.device`. 如果此检查被禁用,则不同设备上的张量将被移动到 CPU 进行比较。 `:attr:`~torch.Tensor.device`'s 将在比较之前移动到 CPU。 check_dtype (bool): 如果为 ``True``(默认值),则断言相应的张量具有相同的 ``dtype``。如果此检查被禁用,则不同 ``dtype`` 的张量将被提升到公共 ``dtype``(根据 check 是否禁用,具有不同 ``dtype`` 的张量将被提升到公共 ``dtype``(根据 在比较之前使用 :func:`torch.promote_types`) 进行类型提升。 check_layout (bool): 如果为 ``True``(默认值),则断言相应的张量具有相同的 ``layout``。如果此检查被禁用,则具有不同 ``layout`` 的张量在比较之前将被转换为斜列张量。 check is disabled, tensors with different ``layout``'s are converted to strided tensors before being compared. 比较之前,具有不同 ``layout`` 的张量将被转换为斜列张量。 check_stride (bool): 如果为 ``True`` 并且相应的张量是跨步的,则断言它们具有相同的跨步。 msg (Optional[Union[str, Callable[[str], str]]]): 可选的错误消息,在比较过程中发生失败时使用。 the comparison. Can also passed as callable in which case it will be called with the generated message and should return the new message. 抛出异常: ValueError:如果无法从输入构造出 :class:`torch.Tensor`。 ValueError:如果只指定了 ``rtol`` 或 ``atol``。 AssertionError:如果对应的输入既不是 Python 标量也不是直接相关的。 AssertionError:如果 ``allow_subclasses`` 为 ``False``,但对应的输入既不是 Python 标量也不是 Python 标量。 不同类型。 AssertionError:如果输入是 :class:`~collections.abc.Sequence` 类型的,但它们的长度不匹配。 AssertionError:如果输入是 :class:`~collections.abc.Mapping` 类型的,但它们的键集不匹配。 AssertionError:如果对应的张量没有相同的 :attr:`~torch.Tensor.shape`。 AssertionError:如果 ``check_layout`` 为 ``True``,但对应的张量没有相同的 attr:`~torch.Tensor.layout`。 AssertionError:如果只有对应的一个张量进行了量化。 AssertionError:如果对应的张量都进行了量化,但它们的 :meth:`~torch.Tensor.qscheme` 不同。 AssertionError:如果 ``check_device`` 为 ``True``,但相应的张量不在同一设备上。 attr:`~torch.Tensor.device`。 AssertionError:如果 ``check_dtype`` 为 ``True``,但相应的张量不具有相同的 ``dtype``。 AssertionError:如果 ``check_stride`` 为 ``True``,但相应的具有不同步长的张量不具有相同的步长。 断言错误:如果根据上述定义,对应张量的值不相近。 下表显示了不同 ``dtype`` 的默认 ``rtol`` 和 ``atol``。在 ``dtype`` 不匹配的情况下,使用两者容忍度的最大值。 ``dtype`` 不匹配时,使用两者容忍度的最大值。 +---------------------------+------------+----------+ | ``dtype`` | ``rtol`` | ``atol`` | +===========================+============+==========+ | :attr:`~torch.float16` | ``1e-3`` | ``1e-5`` | +---------------------------+------------+----------+ | :attr:`~torch.bfloat16` | ``1.6e-2`` | ``1e-5`` | +---------------------------+------------+----------+ | :attr:`~torch.float32` | ``1.3e-6`` | ``1e-5`` | +---------------------------+------------+----------+ | :attr:`~torch.float64` | ``1e-7`` | ``1e-7`` | +---------------------------+------------+----------+ | :attr:`~torch.complex32` | ``1e-3`` | ``1e-5`` | +---------------------------+------------+----------+ | :attr:`~torch.complex64` | ``1.3e-6`` | ``1e-5`` | +---------------------------+------------+----------+ | :attr:`~torch.complex128` | ``1e-7`` | ``1e-7`` | +---------------------------+------------+----------+ | :attr:`~torch.quint8` | `1.3e-6` | `1e-5` | +---------------------------+------------+----------+ | :attr:`~torch.quint2x4` | `1.3e-6` | `1e-5` | +---------------------------+------------+----------+ | :attr:`~torch.quint4x2` | `1.3e-6` | `1e-5` | +---------------------------+------------+----------+ | :attr:`~torch.qint8` | `1.3e-6` | `1e-5` | +---------------------------+------------+----------+ | :attr:`~torch.qint32` | ``1.3e-6`` | ``1e-5`` | +---------------------------+------------+----------+ | 其他 | ``0.0`` | ``0.0`` | +---------------------------+------------+----------+ .. 注意:: func:`~torch.testing.assert_close` 具有高度可配置性,默认设置严格。用户应鼓励 将其 :func:`~functools.partial` 化以适应其使用场景。例如,如果需要进行等价性检查,则可能 默认情况下为每个 ``dtype`` 使用零容忍度的 ``assert_equal`` 定义: >>> 导入 functools >>> assert_equal = functools.partial(torch.testing.assert_close, rtol=0, atol=0) >>> assert_equal(1e-9, 1e-10) Traceback (most recent call last): ... 断言错误:标量不相等! <BLANKLINE> 期望为 1e-10,但得到 1e-09。 绝对差值:9.000000000000001e-10 相对差异:9.0 示例: >>> # 张量到张量的比较 >>> expected = torch.tensor([1e0, 1e-1, 1e-2]) >>> actual = torch.acos(torch.cos(expected)) >>> torch.testing.assert_close(actual, expected) >>> # 标量到标量的比较 >>> 导入 math 模块 >>> expected = math.sqrt(2.0) >>> actual = 2.0 / math.sqrt(2.0) >>> torch.testing.assert_close(actual, expected) >>> # numpy 数组到 numpy 数组的比较 >>> import numpy as np >>> expected = np.array([1e0, 1e-1, 1e-2]) >>> actual = np.arccos(np.cos(expected)) >>> torch.testing.assert_close(actual, expected) >>> # sequence to sequence comparison >>> import numpy as np >>> # 序列类型不必匹配,只需长度相同,且元素也要匹配。 >>> # # 长度必须相同,且元素也要匹配。 >>> 预期结果 = [torch.tensor([1.0]), 2.0, np.array(3.0)] >>> 实际结果 = tuple(预期结果) >>> torch.testing.assert_close(实际结果, 预期结果) >>> # 映射到映射比较 >>> 从 collections 导入 OrderedDict >>> import numpy as np >>> foo = torch.tensor(1.0) >>> bar = 2.0 >>> baz = np.array(3.0) >>> # 映射的类型和可能的顺序不必匹配。它们只需要 >>> # 必须具有相同的键集,并且它们的元素必须匹配。 >>> expected = OrderedDict([("foo", foo), ("bar", bar), ("baz", baz)]) >>> actual = {"baz": baz, "bar": bar, "foo": foo} >>> torch.testing.assert_close(actual, expected) >>> expected = torch.tensor([1.0, 2.0, 3.0]) >>> actual = expected.clone() >>> # 默认情况下,直接相关的实例可以进行比较 >>> torch.testing.assert_close(torch.nn.Parameter(actual), expected) >>> 此检查可以更严格,设置 allow_subclasses=False >>> torch.testing.assert_close( ... torch.nn.Parameter(actual), expected, allow_subclasses=False ... ) Traceback (most recent call last): ... 类型错误:没有比较对能够处理输入类型 和 。 如果输入不是直接相关的,它们永远不会被认为是接近的 >>> torch.testing.assert_close(actual.numpy(), expected) Traceback (most recent call last): ... 类型错误:没有比较对能够处理类型为 和 的输入。 以及。 >>> # 这些规则的例外是 Python 标量。如果 check_dtype=False,则可以检查它们的类型。 >>> # 如果 check_dtype=False,则可以检查它们的类型,而不考虑它们的类型。 >>> torch.testing.assert_close(1.0, 1, check_dtype=False) >>> # NaN != NaN by default. >>> expected = torch.tensor(float("Nan")) >>> actual = expected.clone() >>> torch.testing.assert_close(实际,期望) Traceback (most recent call last): ... 断言错误:标量值不相等! <BLANKLINE> 预期得到非数值但得到了非数值。 绝对差值:非数字(允许 1e-05 以内) 相对差值:非数字(允许 1.3e-06 以内) >>> torch.testing.assert_close(actual, expected, equal_nan=True) >>> expected = torch.tensor([1.0, 2.0, 3.0]) >>> actual = torch.tensor([1.0, 4.0, 5.0]) >>> # 默认的错误信息可以被覆盖。 >>> torch.testing.assert_close(actual, expected, msg="Argh,张量不相近!") Traceback (most recent call last): ... AssertionError: Argh,张量不相近! >>> 如果 msg 是一个可调用对象,则可以使用它来增强生成的消息并添加额外信息 >>> >>> torch.testing.assert_close( ... 实际,预期,msg=lambda msg: f"Header\n\n{msg}\n\nFooter" ... ) Traceback (most recent call last): ... 断言错误:标题 <BLANKLINE> 张量相似度不接近! <BLANKLINE> 元素不匹配:2 / 3(66.7%) 最大的绝对差值:2.0 在索引(1,)处(允许误差高达 1e-05) 最大的相对差值:1.0 在索引(1,)处(允许误差高达 1.3e-06) <BLANKLINE> 页脚 "文档" 隐藏此函数以避免在 `pytest` 的跟踪回溯中显示 __tracebackhide__ = 真实 错误元数据 = 未关闭错误元数据( 实际的, 预期, 配对类型=( NonePair, 布尔配对, 数字对, 张量类似对, ), 允许子类=允许子类, 相对误差=相对误差, 精度=精度, 等于 NaN=等于 NaN, 检查设备=检查设备, 检查数据类型=检查数据类型, 检查布局=检查布局, 检查步长=检查步长, 信息=信息, ) 如果 错误元数据: # TODO: 将所有元数据组合成一个 AssertionError raise 错误元数据[0].to_error(信息)
[文档]@已弃用( "``torch.testing.assert_allclose()``自 1.12 版本开始已弃用,将在未来的版本中移除。" "请使用``torch.testing.assert_close()``代替。" 您可以在 https://github.com/pytorch/pytorch/issues/61844. 找到详细的升级说明。 category=未来警告, ) def assert_allclose( actual: 任何, expected: 任何, rtol: 可选的浮点数 = None, atol: 可选的浮点数 = None, equal_nan: 布尔 = True, msg: 字符串 = "", ) -> 无: """ ..警告:: `torch.testing.assert_allclose` 自 1.12 版本开始已弃用,将在未来的版本中删除。 请使用 :func:`torch.testing.assert_close` 代替。您可以在此处找到详细的升级说明 `这里 `_。 """ 如果实际参数不是 torch.Tensor 类型: 实际参数 = torch.tensor(actual) 如果预期参数不是 torch.Tensor 类型: expected = torch.tensor(expected, dtype=actual.dtype) 如果 rtol 为 None 且 atol 为 None: rtol, atol = default_tolerances( 实际, 预期, dtype 精度={ torch.float16: (1e-3, 1e-3), torch.float32: (1e-4, 1e-5), torch.float64: (1e-5, 1e-8), }, ) torch.testing.assert_close( 实际, 预期, 相对误差=rtol, 绝对误差=atol, equal_nan=equal_nan, check_device=True, check_dtype=False, check_stride=False, msg=msg 或 None, )

© 版权所有 PyTorch 贡献者。

使用 Sphinx 构建,并使用 Read the Docs 提供的主题。

文档

查看 PyTorch 的全面开发者文档

查看文档

教程

深入了解初学者和高级开发者的教程

查看教程

资源

查找开发资源,获取您的疑问解答

查看资源