# 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,
)