""
torch 包包含多维张量的数据结构
并在这些张量上定义了数学运算。
此外,它还提供了许多用于高效序列化的实用工具。
张量、任意类型以及其他有用工具。
它有一个 CUDA 对应版本,允许您在具有计算能力>=3.0 的 NVIDIA GPU 上运行张量计算。
在 NVIDIA GPU 上运行,计算能力需大于等于 3.0。
""
# mypy: 允许未类型化定义
导入
内置函数
导入 ctypes
导入
全局
导入
导入库
导入
检查
导入
数学
导入
操作系统
导入
平台
导入
系统
导入
文本换行
导入
线程
from 打字
导入 (
任何 as
任意,
可调用 as
可调用,
获取源 as
_获取原始,
可选 as
可选,
超载 as
超载_,
类型检查,
类型变量 as
_类型变量,
联合 as
联合,
)
from typing_extensions 导入
参数规范 as
_参数规范
如果
类型检查:
from .类型
导入
沉浸式类型
# multipy/deploy 在导入 torch 之前设置此导入,这是最重要的
可靠的方法来检测我们是否在部署中运行。
# https://github.com/pytorch/multipy/blob/d60f34ad38c371e441fe7ffdb77a3c3dda5a5d19/multipy/runtime/interpreter/interpreter_impl.cpp#L134-L137
定义
_运行时使用部署() -> builtins.bool:
返回
系统模块.
模块.
获取("torch._meta_registrations",
无)
是
对象
from torch._utils 导入 (
功能化同步 as
同步_,
导入点名称,
类属性,
)
from torch._utils_internal 导入 (
获取文件路径,
准备多进程环境,
使用全局依赖项,
使用 libtorch 的 RTLD_GLOBAL,
)
# TODO(torch_deploy) 在 fbcode 构建中找出如何冻结 version.py
如果
_运行时使用部署():
__version__ = "torch-deploy-1.8"
# TODO: 在部署类型扩展更新到 4.10+后删除这个丑陋的解决方案
如果 not
类型检查:
导入 typing_extensions
_类型是 = typing_extensions.TypeGuard
typing_extensions.类型是 =
_类型是
否则:
from typing_extensions 导入
类型是 as
_类型是
from torch.torch_version 导入 __version__ as __version__
全部 = [
"布尔存储",
布尔张量,
字节存储,
字节张量,
字符存储,
"Char 张量",
"双精度存储",
"双精度张量",
"浮点存储",
浮点张量,
梯度缩放器,
整数存储,
整数张量,
长存储,
长张量,
短存储,
短张量,
"符号布尔",
"SymFloat",
"符号整数",
"张量",
"类型存储",
"无类型存储",
"是否启用了确定性算法",
"自动转换",
"块",
"编译",
"条件",
"启用梯度",
"导出",
"获取默认设备",
"获取确定性调试模式",
"获取设备模块",
"获取 float32 矩阵乘法精度",
"获取随机数生成器状态",
"推理模式",
"初始种子",
"是否仅警告确定算法启用",
"是否存储",
"是否是张量",
"是否总是启用警告",
载入,
lobpcg,
"手动播种",
矩阵乘法,
"关闭梯度",
随机,
"randn",
"save",
种子,
"set_default_device",
"set_default_tensor_type",
设置确定性调试模式,
设置 float32 矩阵乘法精度,
设置打印选项,
"设置随机数生成器状态",
设置总是警告,
"拆分",
"堆栈",
"符号浮点",
"符号新鲜大小",
"对称整数",
"对称迭代",
"对称最大值",
"对称最小值",
"sym_not",
"sym_sum",
"typename",
"unravel_index",
使用确定性算法,
vmap,
]
# 请保持此列表排序
断言
全部 ==
排序(__all__)
################################################################################
# 加载扩展模块
################################################################################
如果
系统模块.
平台 ==
win32:
定义 _load_dll_libraries() ->
无:
导入 sysconfig
from torch 版本
导入 cuda as cuda_version
程序文件路径 = os.
获取环境变量(
程序文件, r
C:\程序文件)
py_dll_path = os.路径.
连接(
系统模块.exec_prefix, "Library",
bin)
th_dll_path = os.路径.
连接(os.
路径.
目录名(__file__),
库)
使用基本路径 = os.
路径.
连接(
sysconfig.get_config_var(用户库),
库,
二进制文件
)
当用户创建一个继承基本环境的虚拟环境时,
我们需要将相应的库目录添加到
DLL 搜索目录中。否则,它将依赖于`PATH`,
这取决于用户设置。
如果
系统模块.exec_prefix !=
系统模块.base_exec_prefix:
base_py_dll_path = os.路径.
连接(
系统模块.base_exec_prefix,
图书馆,
bin)
否则:
base_py_dll_path = 请提供需要翻译的文本
dll_paths = [
p
对于 p
进入 (th_dll_path, py_dll_path, base_py_dll_path,
使用基本路径)
如果 os.
路径.
存在(p)
]
如果 not builtins.
任何(
os.路径.
存在(os.
路径.
连接(p,
nvToolsExt64_1.dll))
对于 p
进入 dll_paths
):
nvtoolsext_dll_path = os.路径.
连接(
os.获取环境变量(
"NVTOOLSEXT_PATH",
os.路径.
连接(
文件路径,
英伟达公司, "NvToolsExt"),
),
bin,
"x64",
)
否则:
nvtoolsext_dll_path = 请提供需要翻译的文本
如果 cuda_version
以及 builtins.
所有(
not 球.
球(os.
路径.
连接(p,
cudart64*.dll))
对于 p
进入 dll_paths
):
cuda_version_1 = cuda 版本.
替换(
“。”,
“下划线”)
cuda_path_var = “CUDA_PATH_V” + cuda_version_1
默认路径 = os.
路径.
连接(
文件路径,
"NVIDIA GPU 计算工具包", "CUDA", f
"v"{
cuda 版本}"
)
cuda_path
CUDA 路径 = os.路径.
连接(os.
获取环境变量(
cuda 路径变量,
默认路径),
bin)
否则:
cuda_path
CUDA 路径 = 请提供需要翻译的文本
dll_paths.扩展(
p 对于 p
进入 (
nvtoolsext_dll 路径,
cuda 路径)
如果 os.
路径.
存在(p)
)
核心库 32 = ctypes.WinDLL(
kernel32.dll,
使用最后错误=True)
使用加载库标志 =
有属性(kernel32,
添加 DLL 目录)
前错误模式 = kernel32.
设置错误模式(
1)
kernel32.LoadLibraryW.restype = ctypes.c_void_p
如果 with_load_library_flags:
kernel32.LoadLibraryExW.restype = ctypes.c_void_p
对于 dll_path
进入 dll_paths:
os.添加 DLL 目录(
DLL 路径)
尝试:
ctypes.CDLL(vcruntime140.dll)
ctypes.CDLL(msvcp140.dll)
如果
平台.
机器() !=
ARM64:
ctypes.CDLL(vcruntime140_1.dll)
除了 OSError:
打印(
textwrap.dedent(
""
微软 Visual C++ redistributable 未安装,这可能导致 DLL 加载失败。
它可以从 https://aka.ms/vs/16/release/vc_redist.x64.exe 下载
"""
).strip()
)
动态链接库 =
球.
球(os.
路径.
连接(th_dll_path, "*.dll"))
path_patched = 假
对于
动态链接库
进入
动态链接库:
is_loaded = 假
如果 with_load_library_flags:
res = kernel32.LoadLibraryExW(动态链接库,
无,
4352)
最后错误 = ctypes.
获取最后错误()
如果 res
是
无。
以及
最后错误 != 126:
错误 = ctypes.
Win 错误(
最后错误)
错误.strerror += (
f'错误加载 "'{
动态链接库}
'或其依赖项之一。'
)
抛出
错误
elif res 是 not
无:
is_loaded = 真实
如果 not
已加载:
如果 not
路径已修复:
os.环境[
环境变量 PATH] =
分号.
连接(dll_paths + [os.
环境[
环境变量 PATH]])
path_patched = 真实
res = kernel32.LoadLibraryW(动态链接库)
如果 res
是
无:
错误 = ctypes.
Win 错误(ctypes.
获取最后错误())
错误.strerror += (
f'错误加载 "'{
动态链接库}
'或其依赖项之一。'
)
抛出
错误
kernel32.设置错误模式(prev_error_mode)
_load_dll_libraries()
删除 _load_dll_libraries
定义
获取 CUDA 依赖路径(
路径: str,
库文件夹: str,
库名: str) ->
列表[str
]
# 库可以位于 path/nvidia/lib_folder/lib 或 path/lib_folder/lib
nvidia 库路径 =
球.
球(
os.路径.
连接(
路径,
英伟达,
库文件夹,
库,
库名)
)
库路径 =
球.
球(os.
路径.
连接(
路径,
库文件夹,
库,
库名))
返回
nvidia 库路径 +
库路径
定义
预加载 CUDA 依赖(
库文件夹: str,
库名: str) ->
无:
预加载 CUDA 依赖,如果否则找不到的话。
只有在默认路径解析失败的情况下才应在 Linux 上调用。
断言
平台.
系统() == "Linux",
"仅在 Linux 上调用"
库路径 =
无。
对于
路径
进入
系统模块.
路径:
候选库路径 =
获取 CUDA 依赖路径(
路径,
库文件夹,
库名)
如果
候选库路径:
库路径 =
候选库路径[0]
断开
如果 not
库路径:
抛出
值错误(f"{
库名}
在系统路径中未找到{
系统模块.
路径}")
ctypes.CDLL(库路径)
# 参见全局依赖项说明
定义
加载全局依赖() ->
无:
如果
_运行时使用部署()
或者
平台.
系统() ==
Windows:
返回
# 根据平台确定文件扩展名
lib_ext = ".dylib" 如果
平台.
系统() ==
达尔文
否则
.so
库名 = f
libtorch 全局依赖{
库扩展}"
这里 = os.
路径.
绝对路径(__file__)
全局依赖库路径 = os.
路径.
连接(os.
路径.
目录名(
这里),
库,
库名)
尝试:
ctypes.CDLL(全局依赖库路径,
模式=ctypes.RTLD_GLOBAL)
解决 cusparse 和 cudnn 中 slim-wheel CUDA 依赖性错误,通过预加载 nvjitlink
# 和 nvrtc。在 CUDA-12.4+ 中,cusparse 依赖于 nvjitlink,但没有 rpath 时
作为轮子发货,导致操作系统选择了错误的/较旧的 nvjitlink 库版本
如果已定义 `LD_LIBRARY_PATH`,请参阅 https://github.com/pytorch/pytorch/issues/138460
在 cudnn 中存在类似问题,动态加载 nvrtc 时,不了解其相对路径。
请参阅 https://github.com/pytorch/pytorch/issues/145580
尝试:
替换为
打开(
/proc/self/maps) as f:
地图 = f.
阅读()
# libtorch_global_deps.so 总是依赖于 cudart,检查是否通过 wheel 安装
如果 "nvidia/cuda_runtime/lib/libcudart.so" not
进入
_地图:
返回
# 如果满足上述所有条件,则预加载 nvrtc 和 nvjitlink
# 请注意,对于 CUDA-11.8,顺序很重要,因为其中不存在 nvjitlink
预加载 CUDA 依赖("cuda_nvrtc", "libnvrtc.so.*[0-9]")
预加载 CUDA 依赖(
nvjitlink,
libnvJitLink.so.*[0-9])
除了
异常:
通过
除了 OSError as
错误:
# 只会发生在带有 cuda 库作为 PYPI 依赖的轮子上
# 因为 PyTorch 不是纯库,而是 nvidia-*-cu12
from torch 版本
导入 cuda as cuda_version
cuda_libs: 字典[str, str] = {
cublas:
libcublas.so.*[0-9],
cudnn:
libcudnn.so.*[0-9],
"cuda_nvrtc": "libnvrtc.so.*[0-9]",
"cuda_runtime": "libcudart.so.*[0-9]",
"cuda_cupti": "libcupti.so.*[0-9]",
"cufft": "libcufft.so.*[0-9]",
"curand": "libcurand.so.*[0-9]",
nvjitlink:
libnvJitLink.so.*[0-9],
"cusparse": "libcusparse.so.*[0-9]",
"cusparselt": "libcusparseLt.so.*[0-9]",
"cusolver": "libcusparse.so.*[0-9]",
"nccl": "libnccl.so.*[0-9]",
"nvtx": "libnvToolsExt.so.*[0-9]",
}
# cufiile 仅在 cuda 12+ 上可用
# TODO: 一旦 CUDA 11.8 二进制文件被弃用,请删除
如果 cuda_version
是 not
无:
版本号 =
cuda 版本.
分割(
“。”)
主版本 = int(
版本号[0]) # type: ignore[operator]
如果
主翻译
≥ 12:
cuda_libs[cufile] =
libcufile.so.*[0-9]
是否为 CUDA 库错误 = [
库
对于
库
进入 cuda_libs.
值()
如果
库.
分割(
“。”
)]0]
进入
错误.
参数[0]
]
如果 not is_cuda_lib_err:
抛出
错误
对于
库文件夹,
库名
进入 cuda_libs.
项目():
预加载 CUDA 依赖(
库文件夹,
库名)
ctypes.CDLL(全局依赖库路径,
模式=ctypes.RTLD_GLOBAL)
如果 (
使用 libtorch 全局 RTLD
或者 os.
获取环境变量(
火炬使用全局 RTLD))
以及 (
_运行时使用部署()
或者
平台.
系统() !=
Windows
):
用笨方法来做。你可能想用 RTLD_GLOBAL 加载 libtorch。
# 很少情况下:
#
你在一个构建环境(例如,fbcode)中
但是 libtorch_global_deps 不可用,你仍然需要
将 mkl 链接到 RTLD_GLOBAL,否则它将无法工作。
。
#
在尝试在 UBSAN 下运行 PyTorch 时,你需要确保只加载一个 libtorch 副本,以便 vptr 检查能够正常工作
如果你使用此设置,你必须验证所有库
都已正确加载
#
如果您使用此设置,您必须验证所有库
# 你始终如一地使用相同的 libstdc++,或者你可能会有
# 神秘的段错误。
#
旧旗帜 =
系统模块.getdlopenflags()
系统模块.
设置动态链接库标志(os.RTLD_GLOBAL | os.RTLD_LAZY)
from torch._C 导入 * # noqa: F403
系统模块.
设置动态链接库标志(
旧旗帜)
删除
旧旗帜
否则:
# 简单方法。你大多数时候都想要这样做,因为它将防止
C++从 libtorch 中覆盖了来自其他库的 C++符号
# 库,导致神秘的段错误。
#
如果在一个没有 libtorch_global_deps 可用的环境中构建
# 类似于 fbsource 的部分,但 RTLD_GLOBAL 导致段错误时,您将
# want USE_RTLD_GLOBAL_WITH_LIBTORCH = False and USE_GLOBAL_DEPS = False
#
# 参见全局依赖项说明
如果
使用全局依赖项:
加载全局依赖()
from torch._C 导入 * # noqa: F403
[文档]
类 SymInt:
""
像一个 int(包括魔术方法),但将所有操作重定向到
包装的节点。这特别用于符号记录操作
在符号形状工作流程中。
"""
定义 __init__(
我,
节点):
# 此字段必须命名为节点;C++ 绑定代码假定此
类有一个名为 node 的字段,用于存储 SymNode
我.
节点 =
节点
定义 __bool__(
我):
返回 builtins.bool(self != 0)
定义 __int__(
我):
返回
我.
节点.
整数()
定义
__索引__(
我):
返回
我.
节点.
整数()
torch.fx.experimental.sym_node 安装的魔法方法
定义 __round__(
我, ndigits=
无):
返回 self
定义 __truediv__(
我,
其他):
如果 isinstance(
其他, (builtins.float, SymFloat)):
返回 sym_float(
我).__float_truediv__(
其他)
如果 not isinstance(
其他, (builtins.int, SymInt)):
返回 NotImplemented
返回
我.
真实除法(
其他)
定义
反真实除法(
我,
其他):
如果 isinstance(
其他, (builtins.float, SymFloat)):
返回 sym_float(
我).__rfloat_truediv__(
其他)
如果 not isinstance(
其他, (builtins.int, SymInt)):
返回 NotImplemented
返回
我.__rint_truediv__(
其他)
定义 __floordiv__(
我,
其他):
如果 isinstance(
其他, (builtins.float, SymFloat)):
返回 sym_float(
数学.
向下取整(sym_float(
我) /
其他))
如果 not isinstance(
其他, (builtins.int, SymInt)):
返回 NotImplemented
返回
我.__int_floordiv__(
其他)
定义 __rfloordiv__(
我,
其他):
如果 isinstance(
其他, (builtins.float, SymFloat)):
返回 sym_float(
数学.
向下取整(
其他 / sym_float(
我)))
如果 not isinstance(
其他, (builtins.int, SymInt)):
返回 NotImplemented
返回
我.__rint_floordiv__(
其他)
# nb: 复杂的无法正确处理,哈哈,太困难了
# 负底数和积分浮点需要区分语义,
# 总是返回复数。哈哈,假装这个问题
# 不存在
定义 __pow__(
我,
其他):
如果 isinstance(
其他, (builtins.float, SymFloat)):
返回 sym_float(
我).__pow__(
其他)
如果 not isinstance(
其他, (builtins.int, SymInt)):
返回 NotImplemented
# 守卫!这个守卫是必要的,因为我们需要知道它
# 以确定这个操作的输出类型
如果
其他
≥ 0:
返回
我.__pow_by_natural__(
其他)
否则:
幸运的是,当指数为负数时,Python 会将其提升为双精度浮点数,然后执行 float pow:
# to doubles and does a float pow:
#
# 如果 (Py_SIZE(b) < 0 且 c 为 NULL) {
# /* 如果指数为负且没有模数:
# 返回一个浮点数。这之所以可行,是因为我们知道
# 这将调用 float_pow(),它将转换其
# 双重参数传递。*/
# Py_DECREF(a);
# Py_DECREF(b);
# return PyFloat_Type.tp_as_number->nb_power(v, w, x);
# }
返回 sym_float(
我).__pow__(sym_float(
其他))
定义 __rpow__(
我,
其他):
如果 isinstance(
其他, (builtins.float, SymFloat)):
返回 sym_float(
我).__rpow__(
其他)
如果 not isinstance(
其他, (builtins.int, SymInt)):
返回 NotImplemented
如果 self
≥ 0:
# 自身为指数
返回
我.__rpow_by_natural__(
其他)
否则:
返回 sym_float(
我).__rpow__(sym_float(
其他))
定义
__等于__(
我,
其他:
对象) -> builtins.bool:
抛出
类型错误(
"类型存根未覆盖")
定义 __lt__(
我,
其他) -> builtins.bool:
抛出
类型错误(
"类型存根未覆盖")
定义 __gt__(
我,
其他) -> builtins.bool:
抛出
类型错误(
"类型存根未覆盖")
定义 __le__(
我,
其他) -> builtins.bool:
抛出
类型错误(
"类型存根未覆盖")
定义 __ge__(
我,
其他) -> builtins.bool:
抛出
类型错误(
"类型存根未覆盖")
定义 __add__(
我,
其他) ->
"符号整数":
抛出
类型错误(
"类型存根未覆盖")
定义 __radd__(
我,
其他) ->
"符号整数":
抛出
类型错误(
"类型存根未覆盖")
定义
矢量乘(
我,
其他) ->
"符号整数":
抛出
类型错误(
"类型存根未覆盖")
定义 __mod__(
我,
其他: "IntLikeType") ->
"符号整数":
抛出
类型错误(
"类型存根未覆盖")
定义 __mul__(
我,
其他) ->
"符号整数":
抛出
类型错误(
"类型存根未覆盖")
定义 __pow_by_natural__(
我,
其他) ->
"符号整数":
抛出
类型错误(
"类型存根未覆盖")
定义 __rpow_by_natural__(
我,
其他) ->
"符号整数":
抛出
类型错误(
"类型存根未覆盖")
定义
真实除法(
我,
其他) -> "SymFloat":
抛出
类型错误(
"类型存根未覆盖")
定义 __rint_truediv__(
我,
其他) -> "SymFloat":
抛出
类型错误(
"类型存根未覆盖")
定义 __int_floordiv__(
我,
其他) -> "SymFloat":
抛出
类型错误(
"类型存根未覆盖")
定义 __rint_floordiv__(
我,
其他) -> "SymFloat":
抛出
类型错误(
"类型存根未覆盖")
定义 __sym_max__(
我,
其他):
抛出
类型错误(
"类型存根未覆盖")
定义 __sym_min__(
我,
其他):
抛出
类型错误(
"类型存根未覆盖")
定义 __sym_float__(
我):
抛出
类型错误(
"类型存根未覆盖")
定义 __neg__(
我):
抛出
类型错误(
"类型存根未覆盖")
定义 __sub__(
我,
其他: "IntLikeType") ->
"符号整数":
抛出
类型错误(
"类型存根未覆盖")
定义 __rsub__(
我,
其他: "IntLikeType") ->
"符号整数":
抛出
类型错误(
"类型存根未覆盖")
定义 __and__(
我,
其他) ->
"符号整数":
抛出
类型错误(
"类型存根未覆盖")
定义 __or__(
我,
其他) ->
"符号整数":
抛出
类型错误(
"类型存根未覆盖")
定义 __repr__(
我):
返回
我.
节点._graph_repr()
定义 _sympy_(
我):
返回
我.
节点.
表达式
定义
__哈希__(
我) -> builtins.int:
如果
我.
节点.
是否嵌套整型():
返回
哈希(
我.
节点.
嵌套整型())
否则:
# 我们可以支持常量 SymInts,但现在不这么做
抛出
类型错误(
"不可哈希的类型:非嵌套的 SymInt")
# TODO: 强制特化
因为这里的 TypeError 是承载性的,所以无法完成
用于 einops
https://github.com/arogozhnikov/einops/blob/6181e1e95dc58c00a3143c1726da1c6ee0463164/einops/einops.py#L237
返回 hash(builtins.int(self))
[文档] def as_integer_ratio(self) -> tuple["SymInt", builtins.int]:
"""将此整数表示为精确的整数比"""
return self, 1
定义
比特长度(
我) -> builtins.int:
# TODO: 这里可以采用更宽松的保护措施,其中保护到
# 允许所有导致相同位数的整数数量
# 长度。我们还可以专门为 Sympy 创建一个函数
计算这个量并用符号表示。
返回 builtins.int(
我).
比特长度()
定义
动词变位(
我) ->
"符号整数":
返回
我
[文档]
类 SymFloat:
""
类似于浮点数(包括魔术方法),但将所有操作重定向到
包装的节点。这特别用于符号记录操作
在符号形状工作流程中。
"""
定义 __init__(
我,
节点):
# 此字段必须命名为节点;C++ 绑定代码假定此
类有一个名为 node 的字段,用于存储 SymNode
我.
节点 =
节点
定义 __truediv__(
我,
其他):
如果 not isinstance(
其他, (builtins.int, builtins.float, SymInt, SymFloat)):
返回 NotImplemented
返回
我.__float_truediv__(sym_float(
其他))
定义
反真实除法(
我,
其他):
如果 not isinstance(
其他, (builtins.int, builtins.float, SymInt, SymFloat)):
返回 NotImplemented
返回
我.__rfloat_truediv__(sym_float(
其他))
定义 __floordiv__(
我,
其他):
如果 not isinstance(
其他, (builtins.int, builtins.float, SymInt, SymFloat)):
返回 NotImplemented
返回 sym_float(
数学.
向下取整(self / sym_float(
其他)))
定义 __rfloordiv__(
我,
其他):
如果 not isinstance(
其他, (builtins.int, builtins.float, SymInt, SymFloat)):
返回 NotImplemented
返回 sym_float(
数学.
向下取整(sym_float(
其他) /
我))
定义 __bool__(
我):
返回
我.
节点.
布尔_()
定义
浮点(
我):
返回
我.
节点.
守护浮点(
输入文本翻译为简体中文为:"", 0)
符号幂不适用于负底数,这是为了避免
可能的复杂输出
定义 __pow__(
我,
其他):
如果 not isinstance(
其他, (builtins.int, builtins.float, SymInt, SymFloat)):
返回 NotImplemented
PyTorch.
_检查(self
≥ 0)
返回
我.__float_pow__(
其他)
定义 __rpow__(
我,
其他):
如果 not isinstance(
其他, (builtins.int, builtins.float, SymInt, SymFloat)):
返回 NotImplemented
PyTorch.
_检查(
其他
≥ 0)
返回
我.__rfloat_pow__(
其他)
torch.fx.experimental.sym_node 安装的魔法方法
定义
__等于__(
我,
其他:
对象) -> builtins.bool:
抛出
类型错误(
"类型存根未覆盖")
定义 __lt__(
我,
其他) -> builtins.bool:
抛出
类型错误(
"类型存根未覆盖")
定义 __gt__(
我,
其他) -> builtins.bool:
抛出
类型错误(
"类型存根未覆盖")
定义 __le__(
我,
其他) -> builtins.bool:
抛出
类型错误(
"类型存根未覆盖")
定义 __ge__(
我,
其他) -> builtins.bool:
抛出
类型错误(
"类型存根未覆盖")
定义 __float_pow__(
我,
其他) -> "SymFloat":
抛出
类型错误(
"类型存根未覆盖")
定义 __rfloat_pow__(
我,
其他) -> "SymFloat":
抛出
类型错误(
"类型存根未覆盖")
定义 __float_truediv__(
我,
其他) -> "SymFloat":
抛出
类型错误(
"类型存根未覆盖")
定义 __rfloat_truediv__(
我,
其他) -> "SymFloat":
抛出
类型错误(
"类型存根未覆盖")
定义
截断(
我):
抛出
类型错误(
"类型存根未覆盖")
定义 __sym_max__(
我,
其他):
抛出
类型错误(
"类型存根未覆盖")
定义 __sym_min__(
我,
其他):
抛出
类型错误(
"类型存根未覆盖")
定义 __sym_int__(
我):
抛出
类型错误(
"类型存根未覆盖")
[文档] def 是整数(self):
"""返回 True 如果浮点数是整数。"""
raise TypeError("类型存根未覆盖")
[文档] def as_integer_ratio(self) -> tuple[builtins.int, builtins.int]:
将此浮点数表示为精确的整数比
return builtins.float(self).as_integer_ratio()
定义 __repr__(
我):
返回
我.
节点._graph_repr()
定义 _sympy_(
我):
返回
我.
节点.
表达式
定义
__哈希__(
我):
返回
哈希(builtins.float(
我))
[文档] def conjugate(self) -> "SymFloat":
翻译:[文档] def conjugate(self) -> "对称浮点数":
返回浮点数的复共轭。
返回 self
[文档] def hex(self) -> str:
返回浮点数的十六进制表示。
返回 self.node.guard_float("", 0).hex()
[文档]
类
符号布尔值:
""
就像布尔值(包括魔术方法),但将所有操作重定向到
包装的节点。这特别用于符号记录操作
在符号形状工作流程中。
与常规布尔值不同,常规布尔运算符将强制执行额外的守卫
使用位运算符来处理此问题。
"""
定义 __init__(
我,
节点):
# 此字段必须命名为节点;C++ 绑定代码假定此
类有一个名为 node 的字段,用于存储 SymNode
我.
节点 =
节点
定义 __bool__(
我):
返回
我.
节点.
布尔_()
定义 __int__(
我):
返回 builtins.int(
我.
节点.
布尔_())
torch.fx.experimental.sym_node 安装的魔法方法
定义 __and__(
我,
其他) ->
"符号布尔":
抛出
类型错误(
"类型存根未覆盖")
定义 __or__(
我,
其他) ->
"符号布尔":
抛出
类型错误(
"类型存根未覆盖")
我们非常谨慎地定义 __sym_not__,而不是其他许多
可能的替代方案:
#
- 我们不重载 __not__,因为这并不是真正的魔法
方法;你不能覆盖非内置方法的含义
Python。我们使用名称'sym_not'来明确指出,在用户代码中不能使用内置的 not 或 operator.not_或 operator.__not__,否则会触发这个魔法方法;你必须使用我们自定义的 sym_not 运算符。
我们没有重写__invert__方法,因为 SymBool 是
我们必须使用我们自定义的 sym_not 运算符。
#
我们没有重写__invert__方法,因为 SymBool 是
# 在期望布尔值的情况下,可以使用。然而,
# 按位非~a 对布尔值做错了事(因为
# bool 是 int 的子类,所以~1 = -2,这不是假的。)
# 这将是一个巨大的陷阱,所以我们通过定义
我们自己的操作符。注意,位与或操作符的行为正确,
因此我们在这里重用传统的操作符以提高可读性。
#
定义 __sym_not__(
我) ->
"符号布尔":
抛出
类型错误(
"类型存根未覆盖")
定义 __sym_ite__(
我, then_val, else_val):
抛出
类型错误(
"类型存根未覆盖")
定义
__等于__(
我,
其他) -> builtins.bool:
抛出
类型错误(
"类型存根未覆盖")
定义 __repr__(
我):
返回
我.
节点._graph_repr()
定义 _sympy_(
我):
返回
我.
节点.
表达式
定义
__哈希__(
我):
如果
我.
节点.
是否为常量():
返回
哈希(
我.
节点.
布尔_())
否则:
强制特化
返回
哈希(builtins.bool(
我))
[文档]def sym_not(a):
r"""SymInt 感知的逻辑否定工具。
Args:
a (SymBool 或 bool): 要取反的对象
"""
导入 sympy
如果 overrides.has_torch_function_unary(a):
返回 overrides.handle_torch_function(sym_not, (a,), a)
if hasattr(a, "__sym_not__"):
return a.__sym_not__()
if isinstance(a, sympy.Basic):
return ~a # type: ignore[operator]
返回非 a
[文档]def sym_float(a):
r"""SymInt 感知的浮点转换实用工具。
参数:
一个(SymInt、SymFloat 或对象):要转换的对象
"""
如果 overrides.has_torch_function_unary(a):
返回 overrides.handle_torch_function(sym_float, (a,), a)
如果 isinstance(a, SymFloat):
返回 a
elif hasattr(a, "__sym_float__"):
返回 a.__sym_float__()
返回 builtins.float(a) # type: ignore[operator]
[文档]def sym_int(a):
r"""SymInt 感知的整型转换实用工具。
Args:
a (SymInt, SymFloat 或对象): 要转换的对象
"""
如果 overrides 具有针对 a 的 torch 函数
返回 overrides 处理 torch 函数的结果 (sym_int, (a,), a)
如果 a 是 SymInt 类型
返回一个
如果 a 是 SymFloat 类型:
返回 math.trunc(a)的整数部分
返回 builtins.int(a)(忽略操作符错误) # type: ignore[operator]
[文档]def sym_max(a, b):
"""
SymInt 感知的 max 实用工具,避免在 a < b 时分支。
与内置的 max()不同,此函数仅适用于 int/float,并且始终
如果任何参数是浮点数,则将其提升为浮点数(与内置的 max 函数不同,后者
会忠实地保留输入参数的类型)。
"""
如果 overrides.has_torch_function((a, b)):
return overrides.handle_torch_function(sym_max, (a, b), a, b)
if isinstance(a, (SymInt, SymFloat)):
return a.__sym_max__(b)
elif isinstance(b, (SymInt, SymFloat)):
由于促销语义,此运算符是交换律的:
max(1, 1.0) === max(1.0, 1) === 1.0
return b.__sym_max__(a)
# TODO: 可能也可以让 bool 工作,只是懒惰
all_types, float_types = __all_and_float_types__()
assert isinstance(a, all_types), type(a)
assert isinstance(b, all_types), type(b)
if isinstance(a, float_types) or isinstance(b, float_types):
return builtins.float(builtins.max(a, b)) # 忽略[调用重载]
else:
return builtins.max(a, b) # 忽略[调用重载]
定义 __all_and_float_types() ->
元组[
元组[
类型, ...
]
元组[
类型, ...
]]
尝试:
导入 numpy as np
所有类型:
元组[
类型, ...] = (
numpy.
整数,
numpy.
浮点,
builtins.int,
builtins.float,
)
浮点类型:
元组[
类型, ...] = (
numpy.
浮点, builtins.float)
除了
模块未找到错误:
所有类型 = (builtins.int, builtins.float)
浮点类型 = (builtins.float,)
返回
所有类型,
浮点类型
[文档]def sym_min(a, b):
"""SymInt 感知的 min()实用工具。"""
if overrides.has_torch_function((a, b)):
return overrides.handle_torch_function(sym_min, (a, b), a, b)
如果 a 是(SymInt, SymFloat)类型:
返回 a.__sym_min__(b)
elif b 是(SymInt, SymFloat)类型:
返回 b.__sym_min__(a)
all_types, float_types = __all_and_float_types__()
assert isinstance(a, all_types), type(a)
assert isinstance(b, all_types), type(b)
if isinstance(a, float_types) or isinstance(b, float_types):
return builtins.float(builtins.min(a, b)) # 忽略[调用重载]
else:
return builtins.min(a, b) # 忽略[调用重载]
[文档]def sym_sum(args):
""
多元加法,对于长列表来说比迭代二进制加法计算更快。
仅对整数执行特殊操作。
""
if overrides.has_torch_function(args):
return overrides.handle_torch_function(sym_sum, args, args)
found = None
for a in args:
如果不是 isinstance(a, (SymInt, builtins.int)) 类型:
返回 builtins.sum(args)
如果 isinstance(a, SymInt) 类型:
found = a.node
如果找到为 None:
返回内置函数 sum(args)
从 torch.fx.experimental.sym_node 导入 to_node, wrap_node
返回 wrap_node(found.sym_sum(tuple(to_node(found, a) for a in args)))
math.sqrt、math.sin、math.cos 等函数的替换
定义 _get_sym_math_fn(
名称):
定义 fn(a):
如果
覆盖.has_torch_function_unary(a):
返回
覆盖.handle_torch_function(fn, (a,), a)
如果 isinstance(a, SymInt):
a = PyTorch.sym_float(a)
如果
有属性(a, f
"__sym_"{
名称}
__):
返回 getattr(a, f
"__sym_"{
名称}
__)()
返回 getattr(
数学,
名称)(a)
返回 fn
函数名,
名称,
__sym_name__ =
无,
输入文本翻译为简体中文为:"",
请提供需要翻译的文本
对于 __name
进入 (
平方根,
余弦,
余弦,
正弦,
双曲正弦,
正切,
双曲正切,
反正弦,
反余弦,
反正切,
"以 2 为底的对数",
):
__sym_name__ = f
"_sym_"{
名称}"
__fn = _get_sym_math_fn(名称)
函数名.__qualname__ =
函数名.__name__ =
__sym_name__
全局变量()[
符号名] = __fn
删除
函数名,
名称,
符号名,
获取符号数学函数
添加临时快捷方式
sym_sqrt = 全局变量()[
_sym_sqrt]
__all__.添加("sym_sqrt")
[文档]def sym_ite(b, t, f):
if overrides.has_torch_function((b, t, f)):
return overrides.handle_torch_function(sym_ite, (b, t, f), b, t, f)
assert isinstance(b, (SymBool, builtins.bool)) and type(t) == type(f)
if isinstance(b, SymBool):
return b.__sym_ite__(t, f)
return t if b else f
从一个(可能未包装的整数)表达式创建一个全新的未包装整数。
[文档]def sym_fresh_size(expr):
return torch.tensor(expr).item()
检查是否可以加载 C 扩展,如果不能,请提供一些可能问题的指导。
关于问题的可能原因。
尝试:
(任意选择)_initExtension 作为哨兵。
from torch._C 导入
初始化扩展
除了
导入错误:
导入 torch._C as _C_for_compiled_check
仅 Python 3.7 及以上版本中的__file__检查才有效。
如果
编译检查的_C_函数.__file__
是
无:
抛出
导入错误(
textwrap.dedent(
""
加载 PyTorch C 扩展失败:
看起来 PyTorch 已加载了`torch/_C`文件夹
而不是预期在`torch._C`命名空间中的 C 扩展
这在使用`install`工作流程时可能发生
例如
$ python setup.py install && python -c "import torch"
这个错误通常可以通过使用 `develop` 工作流程来解决
$ python setup.py develop && python -c "import torch" # 这应该会成功
或者通过从不同的目录运行 Python 来解决
"""
).strip()
) from 无。
抛出
如果 __file__ 不为 None,原因未知,因此只需重新抛出。
torch._C 子模块已经通过 `from torch._C import *` 在上面加载。
为了满足代码检查工具,请显式引用 _C 子模块。
from 火炬
导入 _C as _C
名称, __obj =
输入文本翻译为简体中文为:"",
无。
对于 __name
进入
目录(_C):
如果
名称[0] !=
_
以及 not
名称.
以...结尾(
基础):
__all__.添加(
名称)
__obj = getattr(_C, 名称)
如果
可调用(__obj)
或者
检查.
是否为类(__obj):
如果 __obj.__module__ != __name__: # "torch"
# TODO: fix their module from C++ side
如果 __name not
进入 {
禁用 TorchFunction 子类,
禁用 TorchFunction,
生成器,
}:
__obj.__module__ = __name__ # "torch"
elif __name == "TensorBase":
# issue 109438 / pr 109940. 防止 TensorBase 被复制到 torch。
delattr(系统模块.
模块[__name__
]
名称)
删除
名称, __obj
如果 not
类型检查:
# issue 38137 和 Python issue 43367。C 扩展的子模块
非标准,并且这些子模块的属性无法被序列化
# pickle 期望能够将它们导入为 "from _C.sub import attr"
# 失败:_C 不是一个包
定义
导入扩展到系统模块(
模块,
描述=
无):
如果
备忘录
是
无:
备忘录 =
设置()
如果
模块
进入
描述:
返回
描述.
添加(
模块)
模块名称 =
模块.__name__
对于
名称
进入
目录(
模块):
成员 = getattr(
模块,
名称)
成员名称 = getattr(
成员,
"__名称__",
输入文本翻译为简体中文为:"")
如果
检查.
是否为模块(
成员)
以及
成员名称.
以...开头(
模块名称):
系统模块.
模块.setdefault(
成员名称,
成员)
# 递归处理子模块(例如,`_C._dynamo.eval_frame`)
导入扩展到系统模块(
成员,
描述)
导入扩展到系统模块(_C)
删除
_导入扩展到 sys_modules
################################################################################
# 定义基本工具
################################################################################
定义
类型名(
对象:
任意, /) -> str:
""
对象类型的字符串表示。
此函数返回对象类型的完全限定字符串表示。
参数:
obj(对象):表示类型的对象
返回值:
str:对象 `o` 的类型
示例:
>>> x = torch.tensor([1, 2, 3])
>>> torch.typename(x)
'torch.LongTensor'
>>> torch.typename(torch.nn.Parameter)
torch.nn.parameter.Parameter
"""
如果 isinstance(
对象,
PyTorch.
张量):
返回
对象.
类型()
模块 = getattr(
对象, "__module__",
输入文本翻译为简体中文为:"")
或者
请提供需要翻译的文本
qualname = 请提供需要翻译的文本
如果
有属性(
对象, "__qualname__"):
qualname = 对象.__qualname__
elif 有属性(
对象,
"__名称__"):
qualname = 对象.__name__
否则:
模块 =
对象.
类.__module__
或者
请提供需要翻译的文本
qualname = 对象.
类.__qualname__
如果
模块
进入 {
输入文本翻译为简体中文为:"",
内建函数}:
返回 qualname
返回 f"{
模块}.{qualname}"
[文档]def is_tensor(obj: _Any, /) -> _TypeIs["torch.Tensor"]:
r"""返回 True 如果 `obj` 是 PyTorch 张量。"""
注意这个函数只是简单地执行 `isinstance(obj, Tensor)`。
使用这个 `isinstance` 检查更适合与 mypy 进行类型检查,
并且更加明确 - 因此建议使用它而不是 `is_tensor`。
``。
Args:
obj (对象): 待测试的对象
示例::
>>> x = torch.tensor([1, 2, 3])
>>> torch.is_tensor(x)
True
"""
return isinstance(obj, torch.Tensor)
[文档]def is_storage(obj: _Any, /) -> _TypeIs[_Union["TypedStorage", "UntypedStorage"]]:
r"""判断`obj`是否为 PyTorch 存储对象。
Args:
obj (对象): 要测试的对象
"``"
返回对象的类型是否在_storage_classes 中
_全局设备上下文 =
线程.local()
[文档]def get_default_device() -> "torch.device":
r"""获取默认要在 ``device`` 上分配的 ``torch.Tensor``"""
global _GLOBAL_DEVICE_CONTEXT
如果 hasattr(_GLOBAL_DEVICE_CONTEXT, "device_context"):
device = _GLOBAL_DEVICE_CONTEXT.device_context.device
如果 device.index 不是 None:
返回 device
否则:
# TODO: 调用与 get_device_index() 方法对应的
每个设备类型
返回 torch.tensor([]).device
else:
返回 torch.device("cpu")
[文档]
定义 set_default_device(
设备:
可选[
联合[
torch.device, str, builtins.int]],
) -> 无:
设置默认的 ``torch.Tensor`` 在 ``device`` 上分配。
不影响使用显式调用的工厂函数调用
设备参数。工厂调用将像对待
将 ``device`` 作为参数传递。
只需临时更改默认设备,而不是全局设置,请使用 `with torch.device(device):`。
默认设备最初是 `cpu`。如果您要将默认张量设备设置为另一个设备(例如,`cuda`)而没有设备索引,张量
将默认张量设备设置为另一个设备(例如,`cuda`)而没有设备索引,张量
将默认张量设备设置为另一个设备(例如,`cuda`)而没有设备索引,张量
将分配给当前设备上的设备类型
即使在调用 :func:`torch.cuda.set_device` 之后
..警告:
此函数会对每个 Python 调用产生轻微的性能开销
调用 torch API(不仅仅是工厂函数)。如果这
造成了您的问题,请评论
https://github.com/pytorch/pytorch/issues/92701
.. 注意:
这不会影响创建与输入共享相同内存的张量的函数,例如:
`torch.from_numpy` 和 `torch.frombuffer`
参数:
device (设备或字符串): 设置为默认的设备
示例::
>>> # xdoctest: +SKIP("需要 cuda,改变全局状态")
>>> torch.get_default_device()
device(type='cpu')
>>> torch.set_default_device('cuda') # 当前设备是 0
>>> torch.get_default_device()
device(type='cuda', index=0)
>>> torch.set_default_device('cuda')
>>> torch.cuda.set_device('cuda:1') # 当前设备为 1
>>> torch.get_default_device()
device(type='cuda', index=1)
>>> torch.set_default_device('cuda:1')
>>> torch.get_default_device()
device(type='cuda', index=1)
"""
全局
_全局设备上下文
如果
有属性(
全局设备上下文,
设备上下文):
设备上下文 =
全局设备上下文.
设备上下文
如果
设备上下文
是 not
无:
设备上下文.
__退出__(
无,
无,
无)
如果
设备
是
无:
设备上下文 =
无。
否则:
from torch.utils._device 导入
设备上下文
设备上下文 =
设备上下文(
设备)
设备上下文.
__进入__()
全局设备上下文.
设备上下文 =
设备上下文
[文档]def set_default_tensor_type(t: _Union[type["torch.Tensor"], str], /) -> None:
r"""
..警告::
该函数自 PyTorch 2.1 版本开始已弃用,请使用:func:`torch.set_default_dtype()`和
func:`torch.set_default_device()`作为替代方案。
将默认的`torch.Tensor`类型设置为浮点张量类型
``t``. 此类型也将用作默认浮点类型。
在 :func:`torch.tensor` 中进行类型推断。
默认浮点张量类型最初为 ``torch.FloatTensor``。
参数:
t (类型或字符串):浮点张量类型或其名称
示例::
>>> # xdoctest: +SKIP("其他测试可能已更改默认类型。我们能重置它吗?")
>>> torch.tensor([1.2, 3]).dtype # 初始默认浮点类型为 torch.float32
torch.float32
>>> torch.set_default_tensor_type(torch.DoubleTensor)
>>> torch.tensor([1.2, 3]).dtype # 创建一个新的浮点数张量
torch.float64
"""
如果 isinstance(t, str):
t = _import_dotted_name(t)
_C._set_default_tensor_type(t)
[文档]
定义
设置默认数据类型(d:
torch 数据类型, /) ->
无:
r""
设置默认浮点数据类型为:attr:`d`。支持浮点数据类型
输入。其他数据类型会导致 torch 抛出异常。
当 PyTorch 初始化时,其默认浮点数据类型是 torch.float32,
set_default_dtype(torch.float64)的目的是为了方便 NumPy-like
类型推断。默认浮点数据类型用于:
1. 默认复杂数据类型隐式确定。当默认浮点类型为 float16 时,
默认复杂数据类型为 complex32。对于 float32,默认复杂数据类型为 complex64。
对于 float64,则为 complex128。对于 bfloat16,将引发异常,因为没有对应的复杂数据类型。
对于 bfloat16 没有对应的复杂数据类型。
2. 推断使用 Python 浮点数或复数 Python 构建的张量的 dtype
数字。以下为示例。
3. 确定布尔和整数张量之间类型提升的结果
Python 浮点数和复数 Python 数。
参数:
d (:class:`torch.dtype`): 设置默认的浮点数据类型。
示例:
>>> # xdoctest: +SKIP("其他测试可能已更改默认类型。我们能重置它吗?")
>>> # 浮点数的初始默认值是 torch.float32
>>> # Python 浮点数被解释为 float32
>>> torch.tensor([1.2, 3]).dtype
torch.float32
>>> # 浮点数默认为 torch.complex64
>>> # 复数 Python 数字被解释为 complex64
>>> torch.tensor([1.2, 3j]).dtype
torch.complex64
>>> torch.set_default_dtype(torch.float64)
>>> # Python 浮点数现在被解释为 float64
>>> torch.tensor([1.2, 3]).dtype # 一个新的浮点张量
torch.float64
>>> # 复杂的 Python 数字现在被解释为 complex128
>>> torch.tensor([1.2, 3j]).dtype # 一个新的复数张量
torch.complex128
>>> torch.set_default_dtype(torch.float16)
>>> # Python 浮点数现在被解释为 float16
>>> torch.tensor([1.2, 3]).dtype # 一个新的浮点张量
torch.float16
>>> # 复杂的 Python 数字现在被解释为 complex128
>>> torch.tensor([1.2, 3j]).dtype # 一个新的复数张量
torch.complex32
"""
_C._set_default_dtype(d)
[文档]
定义
使用确定性算法(
模式: builtins.bool,
*,
仅警告: builtins.
布尔值 = False,
) -> 无:
r设置 PyTorch 操作是否必须使用“确定性”算法。也就是说,给定相同的输入,在相同的软件和硬件上运行时,总是产生相同输出的算法。
当启用时,操作将使用可用的确定性算法。
当启用时,操作将使用可用的确定性算法。
当启用时,操作将使用可用的确定性算法。
如果只有非确定性算法可用,它们将抛出
class:`RuntimeError` 异常。
.. note:: 仅此设置并不总是足以使应用程序可重复。
请参阅 :ref:`可重复性` 获取更多信息。
.. note:: `torch.set_deterministic_debug_mode` 提供了一种替代方案
界面为此功能。
以下通常是不可预测的操作将起作用
确定性翻译时 ``mode=True``:
当在 CUDA 张量上调用 * :class:`torch.nn.Conv1d`
当在 CUDA 张量上调用 * :class:`torch.nn.Conv2d`
当在 CUDA 张量上调用 * :class:`torch.nn.Conv3d`
当在 CUDA 张量上调用 * :class:`torch.nn.ConvTranspose1d`
当在 CUDA 张量上调用时,* :class:`torch.nn.ConvTranspose2d`
当在 CUDA 张量上调用时,* :class:`torch.nn.ConvTranspose3d`
当尝试对 CUDA 张量进行微分时,* :class:`torch.nn.ReplicationPad2d`
当在稀疏-稠密 CUDA 张量上调用时,* :func:`torch.bmm`
当尝试对 CPU 张量进行微分时,* :func:`torch.Tensor.__getitem__`
并且索引是一个张量列表
* :func:`torch.Tensor.index_put` 使用 `accumulate=False`
* :func:`torch.Tensor.index_put` 使用 `accumulate=True` 当在 CPU 上调用时
张量
当在 CPU 上调用时,使用 `accumulate=True` 的 `* :func:`torch.Tensor.put_`
张量
当在 CUDA 张量上调用时,使用 `* :func:`torch.Tensor.scatter_add_`
* 当在需要梯度的 CUDA 张量上调用 :func:`torch.gather`
* 当在 CUDA 张量上调用 :func:`torch.index_add`
* 在尝试对 CUDA 张量进行微分时调用 :func:`torch.index_select`
* 在尝试对 CUDA 张量进行微分时调用 :func:`torch.repeat_interleave`
当在 CPU 或 CUDA 张量上调用时,* :func:`torch.Tensor.index_copy`
当`src`类型为 Tensor 且在 CUDA 张量上调用时,* :func:`torch.Tensor.scatter`
当`reduce='sum'`或`reduce='mean'`且在 CUDA 张量上调用时,* :func:`torch.Tensor.scatter_reduce`
以下通常非确定性的操作将抛出
当 `mode=True` 时抛出 `RuntimeError` 异常:
* 在尝试对 CUDA 张量进行微分时,使用 `torch.nn.AvgPool3d`:
* 在尝试对 CUDA 张量进行微分时,使用 `torch.nn.AdaptiveAvgPool2d`:
* 在尝试对 CUDA 张量进行微分时,使用 `torch.nn.AdaptiveAvgPool3d`:
当尝试对 CUDA 张量进行微分时,* :class:`torch.nn.MaxPool3d`
当尝试对 CUDA 张量进行微分时,* :class:`torch.nn.AdaptiveMaxPool2d`
当尝试对 CUDA 张量进行微分时,* :class:`torch.nn.FractionalMaxPool2d`
当尝试对 CUDA 张量进行微分时,* :class:`torch.nn.FractionalMaxPool3d`
* :class:`torch.nn.MaxUnpool1d`
* :class:`torch.nn.MaxUnpool2d`
* :class:`torch.nn.MaxUnpool3d`
* :func:`torch.nn.functional.interpolate` 当尝试对 CUDA 张量进行微分时
使用以下任一模式之一:
- ``线性``
- ``双线性``
- ``双三次``
三线性
当尝试对 CUDA 张量进行微分时,使用 :class:`torch.nn.ReflectionPad1d`
当尝试对 CUDA 张量进行微分时,使用 :class:`torch.nn.ReflectionPad2d`
当尝试对 CUDA 张量进行微分时,使用 :class:`torch.nn.ReflectionPad3d`
当尝试对 CUDA 张量进行微分时,* :class:`torch.nn.ReplicationPad1d`
当尝试对 CUDA 张量进行微分时,* :class:`torch.nn.ReplicationPad3d`
当调用 CUDA 张量时,* :class:`torch.nn.NLLLoss`
当尝试对 CUDA 张量进行微分时,* :class:`torch.nn.CTCLoss`
当尝试对 CUDA 张量进行微分时,* :class:`torch.nn.EmbeddingBag`
``mode='max'`'
* :func:`torch.Tensor.put_` 当 `accumulate=False`
* :func:`torch.Tensor.put_` 当 `accumulate=True` 并在 CUDA 张量上调用
当在 CUDA 张量上调用 * :func:`torch.histc`
当在 CUDA 张量上调用 * :func:`torch.bincount` 并提供 `weights`
给定张量
当在 CUDA 张量上调用 * :func:`torch.kthvalue`
* :func:`torch.median` 在对 CUDA 张量调用时输出索引
* :func:`torch.nn.functional.grid_sample` 在尝试对 CUDA 张量求导时
* :func:`torch.cumsum` 在对 CUDA 张量调用时,当数据类型为浮点型或复数时
* :func:`torch.Tensor.scatter_reduce` 当 `reduce='prod'` 并在 CUDA 张量上调用时
* :func:`torch.Tensor.resize_` 当与量化张量一起调用时
此外,几个操作会在此设置时填充未初始化的内存
已开启并当
torch.utils.deterministic.fill_uninitialized_memory 已开启。
请参阅该属性的文档以获取更多信息。
如果 CUDA 版本为 10.2 或更高,则有一些 CUDA 操作是非确定性的,
除非设置了环境变量`CUBLAS_WORKSPACE_CONFIG=:4096:8`或`CUBLAS_WORKSPACE_CONFIG=:16:8`。
请参阅 CUDA 文档以获取更多信息。
详情: ``_
如果这些环境变量配置中有一个未设置,则抛出 :class:`RuntimeError` 异常
当使用 CUDA 张量调用时,将从中提升:
* :func:`torch.mm`
* :func:`torch.mv`
* :func:`torch.bmm`
注意确定性操作的性能通常比非确定性操作差。
非确定性操作。
.. 注意:
此标志无法检测或防止非确定性行为
通过在具有内部内存的张量上调用原地操作
重叠或通过将这样的张量作为:attr:`out`参数提供
操作。在这些情况下,可能非确定性的多次写入可能针对
单个内存位置,且写入顺序无法保证。
参数:
mode (:class:`bool`): 如果为 True,则可能产生非确定性
将操作切换为确定性算法或抛出运行时错误。
如果为 False,允许非确定性操作。
关键字参数:
warn_only(:class:`bool`,可选):如果为 True,则不执行不正确的操作。
具有确定性实现的将抛出警告而不是错误。
默认值:``False``
示例::
>>> # xdoctest: +SKIP
>>> torch.use_deterministic_algorithms(True)
# 前向模式非确定性错误
>>> torch.randn(10, device='cuda').kthvalue(1)
...
RuntimeError: kthvalue CUDA 没有确定性实现...
# 向后模式非确定性错误
>>> torch.nn.AvgPool3d(1)(torch.randn(3, 4, 5, 6, requires_grad=True).cuda()).sum().backward()
...
运行时错误:avg_pool3d_backward_cuda 没有确定性实现...
"""
_C._set_deterministic_algorithms(模式,
仅警告=
仅警告)
[文档]def are_deterministic_algorithms_enabled() -> builtins.bool:
r"""返回全局确定性标志是否开启。请参阅
`torch.use_deterministic_algorithms`函数文档,更多详情请参阅。
"""
返回 `_C._get_deterministic_algorithms()`
[文档]def is_deterministic_algorithms_warn_only_enabled() -> builtins.bool:
返回全局确定性标志设置为仅警告时的 True。
请参阅 :func:`torch.use_deterministic_algorithms` 文档以获取更多详细信息。
详细信息。
"""
返回 _C._get_deterministic_algorithms_warn_only()
[文档]def set_deterministic_debug_mode(debug_mode: _Union[builtins.int, str]) -> None:
r"""设置确定性操作的调试模式。
.. note:: 这是另一个接口,用于
:func:`torch.use_deterministic_algorithms`。请参阅该函数的
文档中关于受影响操作的详细信息。
参数:
debug_mode(str or int): 如果为 "default" 或 0,则不报错或警告
非确定操作。如果为"warn"或 1,则警告
非确定操作。如果为"error"或 2,则错误
非确定操作。
"""
# 注意:这里使用 builtins.int 是因为此作用域中的 int 解析为内置类型
# to 火炬.int
如果 debug_mode 不是内置的 int 或 str 类型
引发 TypeError("debug_mode 必须是 str 或 int,但得到{type(debug_mode)}")
if isinstance(debug_mode, str):
if debug_mode == "default":
debug_mode = 0
elif debug_mode == "warn":
debug_mode = 1
elif debug_mode == "error":
debug_mode = 2
else:
raise RuntimeError(
"无效的 debug_mode 值,期望的是 `default`,`warn`,`error` 之一,但得到的是 {debug_mode}"
f"`warn`,`error` 之一,但得到的是 {debug_mode}"
)
if debug_mode == 0:
_C._set_deterministic_algorithms(False)
elif debug_mode == 1:
_C._set_deterministic_algorithms(True, warn_only=True)
elif 调试模式 == 2:
_C._set_deterministic_algorithms(True)
else:
raise RuntimeError(
无效的 debug_mode 值,预期为 0、1 或 2,但得到 {debug_mode}
)
[文档]def get_deterministic_debug_mode() -> builtins.int:
返回当前 debug 模式的值,用于确定性
操作。请参阅:func:`torch.set_deterministic_debug_mode`
查阅更多详细信息。
"""
如果 _C._get_deterministic_algorithms():
如果_C_._get_deterministic_algorithms_warn_only()():
返回 1
否则:
返回 2
else:
return 0
[文档]def get_float32_matmul_precision() -> str:
r"""返回当前 float32 矩阵乘法精度的值。请参阅
`torch.set_float32_matmul_precision` 文档中了解更多详情。
"""
返回 _C._get_float32_matmul_precision()
[文档]
定义 set_float32_matmul_precision(precision: str) ->
无:
r设置浮点 32 矩阵乘法的内部精度。
在较低的精度下运行浮点 32 矩阵乘法可能会显著提高性能,
在某些程序中,精度的损失可能影响微乎其微。
支持三种设置:
最高,float32 矩阵乘法使用 float32 数据类型(24 尾数)
位(其中 23 位显式存储)用于内部计算。
* "高",float32 矩阵乘法要么使用 TensorFloat32 数据类型(10
显式存储的尾数位(或将每个 float32 数字视为两个 bfloat16 数字之和)
(大约 16 位尾数位,其中 14 位显式存储),如果提供了适当的快速矩阵乘法算法。否则,float32 矩阵乘法将按“最高精度”计算
。如果没有这些算法,则 float32 矩阵乘法将按“最高精度”计算
。有关 bfloat16 的更多信息,请参阅下文
方法。
* "medium", float32 矩阵乘法使用 bfloat16 数据类型(8 位尾数)
7 位显式存储的比特位(用于内部计算),如果有一个快速的矩阵乘法算法
使用该数据类型内部可用。否则 float32
矩阵乘法在精度为“高”的情况下进行计算。
当使用“高”精度时,float32 乘法可能会使用基于 bfloat16 的算法
该算法比简单地截断到一些较小的数尾数位(例如,TensorFloat32 的 10 位,bfloat16 显式存储的 7 位)更复杂
。请参阅 [Henry2019]_ 获取完整信息
该算法的描述。在此简要说明,第一步是实现
我们可以将单个 float32 浮点数完美编码为三个 bfloat16 数的和(因为 float32 有 23 位尾数位,而 bfloat16 有 7 位显式存储,两者都有相同数量的指数位)。这意味着两个 float32 数的乘积可以
因为 float32 有 23 位尾数位,而 bfloat16 有 7 位显式存储,两者都有相同数量的指数位)。这意味着两个 float32 数的乘积可以
因为 float32 有 23 位尾数位,而 bfloat16 有 7 位显式存储,两者都有相同数量的指数位)。这意味着两个 float32 数的乘积可以
bfloat16 数字的九个乘积之和给出。然后我们可以进行交易
通过降低一些产品的精度来提高速度。"高"精度算法
专门只保留三个最重要的产品,从而方便地排除了
所有涉及任一输入的最后 8 位尾数的所有产品。这意味着
我们可以将我们的输入表示为两个 bfloat16 数字的和,而不是三个。
因为 bfloat16 融合乘加(FMA)指令通常比 10 倍快
float32 ones,使用 bfloat16 进行三次乘法和两次加法会更快
精度比用 float32 精度进行一次乘法操作要高。
.. [Henry2019] http://arxiv.org/abs/1904.06376
.. 注意:
这不会改变 float32 矩阵乘法的输出数据类型
它控制矩阵乘法内部计算如何执行。
.. 注意:
这不会改变卷积操作的精度。其他标志,例如 `torch.backends.cudnn.allow_tf32`,可能控制卷积操作的精度。
例如,`torch.backends.cudnn.allow_tf32`,可能控制卷积操作的精度。
操作。
.. 注意:
此标志目前仅影响一种本地设备类型:CUDA。
如果设置为“高”或“中”,则将使用 TensorFloat32 数据类型
在计算 float32 矩阵乘法时使用,相当于设置
`torch.backends.cuda.matmul.allow_tf32 = True`. 当选择“最高”(默认)
如果设置,则内部计算使用 float32 数据类型,相当于设置`torch.backends.cuda.matmul.allow_tf32 = False`。
相当于设置`torch.backends.cuda.matmul.allow_tf32 = False`。
参数:
precision(str): 可以设置为 "最高"(默认)、"高" 或 "中等"(见上文)。
"""
_C._set_float32_matmul_precision(precision)
[文档]def set_warn_always(b: builtins.bool, /) -> None:
r"""当此标志为 False(默认)时,一些 PyTorch 警告可能只
在每个进程中出现一次。这有助于避免过多的警告信息。
将其设置为 True 会导致这些警告始终出现,这可能会
帮助调试时很有用。
Args:
b (:class:`bool`): 如果为 True,强制警告始终被发出
如果为 False,设置为默认行为
"""
_C._set_warnAlways(b)
[文档]def is_warn_always_enabled() -> builtins.bool:
r"""返回全局 warn_always 标志是否开启。请参阅
`torch.set_warn_always`函数文档,更多详情请参阅。
"""
返回 _C._get_warnAlways()
################################################################################
定义错误检查函数
################################################################################
这些错误检查函数必须与它们的 C++版本保持一致
它们的 C++等价函数将在适当位置提及
定义 _check_with(
错误类型,
条件:
联合[builtins.bool,
符号布尔值
]
消息:
可调用
[] str
]
): # noqa: F811
如果 not isinstance(
条件, (builtins.bool,
符号布尔值)):
抛出
类型错误(f
"cond 必须是布尔值,但得到了{
类型(
条件)}")
from torch.fx.experimental.symbolic_shapes 导入
预期为真
如果
预期为真(
条件):
返回
# 错误类型必须是 Exception 的子类,而不是 Warning 的子类
断言
派生类(
错误类型,
异常)
以及 not
派生类(
错误类型,
警告)
如果
消息
是
无:
消息评估 = (
预期条件为 True,但得到 False。(这个错误是否可能是...)
消息可以改进吗?如果可以,请提交一个增强请求
到 PyTorch。)
)
否则:
如果 not
可调用(
消息):
抛出
类型错误(
"消息必须是一个可调用的")
消息评估 = str(
消息())
抛出
错误类型(
消息评估)
定义
_检查(
条件,
消息=
无): # noqa: F811
r抛出包含可选消息的错误,如果指定的条件
是错误的。
错误类型:``RuntimeError``
C++ 等价函数:``TORCH_CHECK``
参数:
cond (:class:`bool`): 如果为 False,则抛出错误
message (Callable, 可选): 可调用对象,返回字符串或
具有用于错误信息的 ``__str__()`` 方法的对象
默认值:``None``
"""
_check_with(RuntimeError, 条件,
消息)
定义
检查是否为大小(i,
消息=
无, *,
最大值=
无):
检查给定的整数是否为有效大小(即非负)。
应该使用这个而不是 `_check(i >= 0)`,因为它可以防止通过选择进入替代语义来处理值 0 和 1 的 `GuardOnDataDependentSymNode` 异常。
为 `guard_size_oblivious` 测试选择替代语义,这些测试将值 0 和 1 视为特殊情况,从而防止 `GuardOnDataDependentSymNode` 异常。
为 `guard_size_oblivious` 测试选择替代语义,这些测试将值 0 和 1 视为特殊情况。
等价于所有其他值。
当 max 不为 None 时,这指定了一个上限,等价于
``_check(i <= max)``。这个上限也受到交替语义的影响:
在``guard_size_oblivious``测试中,我们假设有一个常数上限
与所有其他值等效处理。符号最大边界尚未支持。
不支持。
注意:不要在-1 大小有效(表示从上下文中推断大小,或者应该回绕或截断)的上下文中使用此功能。
或者如果你应该包装或截断的情况下使用。
仅在此唯一有效值为货真价实的尺寸时使用。
"""
这负责 expect_true
_检查(i
≥ 0,
消息)
from torch.fx.experimental.symbolic_shapes 导入
建议大小
建议大小(i)
如果
最大
是 not
无:
_检查(i <=
最大值,
消息)
from torch.fx.experimental.symbolic_shapes 导入 _advise_is_bounded
建议是有界限的(i,
最大值)
定义
检查索引(
条件,
消息=
无): # noqa: F811
r抛出包含可选消息的错误,如果指定的条件
是错误的。
错误类型:``IndexError``
C++等效:`TORCH_CHECK_INDEX`
参数:
cond (:class:`bool`): 如果为 False,则抛出错误
message (Callable, 可选): 可调用对象,返回字符串或
具有用于错误信息的 ``__str__()`` 方法的对象
默认值:``None``
"""
_check_with(索引错误,
条件,
消息)
定义
检查值(
条件,
消息=
无): # noqa: F811
r抛出包含可选消息的错误,如果指定的条件
是错误的。
错误类型:`ValueError`
C++ 等价:``TORCH_CHECK_VALUE``
参数:
cond (:class:`bool`): 如果为 False,则抛出错误
message (Callable, 可选): 可调用对象,返回字符串或
具有用于错误信息的 ``__str__()`` 方法的对象
默认值:``None``
"""
_check_with(值错误,
条件,
消息)
定义
_检查类型(
条件,
消息=
无): # noqa: F811
r抛出包含可选消息的错误,如果指定的条件
是错误的。
错误类型:``TypeError``
C++等效:``TORCH_CHECK_TYPE``
参数:
cond (:class:`bool`): 如果为 False,则抛出错误
message (Callable, 可选): 可调用对象,返回字符串或
具有用于错误信息的 ``__str__()`` 方法的对象
默认值:``None``
"""
_check_with(类型错误,
条件,
消息)
定义
_未实现检查(
条件,
消息=
无): # noqa: F811
r抛出包含可选消息的错误,如果指定的条件
是错误的。
错误类型:`NotImplementedError`
C++ 等价:`TORCH_CHECK_NOT_IMPLEMENTED`
参数:
cond (:class:`bool`): 如果为 False,则抛出错误
message (Callable, 可选): 可调用对象,返回字符串或
具有用于错误信息的 ``__str__()`` 方法的对象
默认值:``None``
"""
_check_with(不支持的操作异常,
条件,
消息)
定义 _check_tensor_all_with(
错误类型,
条件,
消息=
无): # noqa: F811
如果 not is_tensor(
条件):
抛出
类型错误(f
"条件必须是一个张量,但得到了"{
类型(
条件)}")
如果 not
条件.dtype ==
PyTorch.bool:
抛出
类型错误(f
"cond tensor 必须具有 dtype torch.bool 类型,但得到了{
条件.
数据类型}")
_check_with(错误类型,
条件.
全部为真().
项目(),
消息) # type: ignore[arg-type]
# C++ 等价: `TORCH_CHECK_TENSOR_ALL`
定义 _check_tensor_all(
条件,
消息=
无): # noqa: F811
r抛出包含可选消息的错误,如果指定的条件
是错误的。
错误类型:``RuntimeError``
C++ 等价:``TORCH_CHECK_TENSOR_ALL``
参数:
cond (:class:`torch.Tensor`): Tensor of dtype ``torch.bool``. If any
element is ``False``,throw error
message (Callable, 可选): 可调用对象,返回字符串或
具有用于错误信息的 ``__str__()`` 方法的对象
默认值:``None``
"""
_check_tensor_all_with(RuntimeError, 条件,
消息)
################################################################################
# 定义数值常量
################################################################################
# 对于 Python 数组 API(https://data-apis.org/array-api/latest/API_specification/constants.html)和
# NumPy 一致性(https://numpy.org/devdocs/reference/constants.html)
from 数学
导入 e,
无穷,
纳尼,
圆周率
新轴:
无。 =
无。
__all__.扩展
["e",
"π",
"非数字",
"无穷大",
"新轴"])
################################################################################
# 定义存储和张量类
################################################################################
from torch._tensor 导入
张量
# usort: 跳过
需要在定义 torch.Tensor 之后才能避免循环依赖
from 火炬
导入
存储 as
存储
# usort: 跳过
from torch.storage 导入 (
_LegacyStorage,
_StorageBase,
警告:类型化存储移除,
类型化存储,
未类型化存储,
)
# 备注:不应添加新的 Storage 类。当添加新
# dtype,直接使用 torch.storage.TypedStorage。
[文档]类 ByteStorage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.uint8
[文档]class DoubleStorage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.double
[文档]class FloatStorage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.float
[文档]class HalfStorage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.half
[文档]class LongStorage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty def _dtype(self): return torch.long
类属性 _dtype(self): 返回 torch.long
[文档]class IntStorage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.int
[文档]class ShortStorage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.short
[文档]class CharStorage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.int8
[文档]class BoolStorage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.bool
[文档]class BFloat16Storage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.bfloat16
[文档]class ComplexDoubleStorage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.cdouble
[文档]class ComplexFloatStorage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.cfloat
[文档]class QUInt8Storage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.quint8
[文档]class QInt8Storage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.qint8
[文档]class QInt32Storage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.qint32
[文档]class QUInt4x2Storage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.quint4x2
[文档]class QUInt2x4Storage(_LegacyStorage):
[文档] @类属性
def dtype(self):
_warn_typed_storage_removal(stacklevel=3)
return self._dtype
@classproperty
def _dtype(self):
return torch.quint2x4
_storage_classes: 设置[
类型[
联合[
类型化存储,
未类型化存储]]] = {
未类型化存储,
双倍存储,
浮点存储,
长存储,
整数存储,
短存储,
字符存储,
字节存储,
半字节存储,
布尔存储,
有符号无符号 8 位整数存储,
QInt8 存储,
QInt32 存储,
BFloat16 存储,
ComplexFloat 存储,
复杂双存储,
Q 无符号 4x2 存储,
Q 无符号 2x4 存储,
类型化存储,
}
通过调用 initialize_python_bindings 初始化_tensor_classes 集合。
_tensor_classes: 设置[
类型[
torch.Tensor]] =
设置()
# 如果您编辑了这些导入,请同时更新 torch/__init__.py.in
from 火炬
导入
自动混合精度 as
转换,
随机 as
随机,
序列化 as
序列化
from torch._tensor_str 导入
设置打印选项
from torch.amp 导入
自动播,
梯度缩放器
from torch.random 导入
获取随机数生成器状态,
初始种子,
手动播种,
种子,
设置随机数生成器状态
from torch 序列化
导入
加载,
保存
################################################################################
初始化扩展
################################################################################
共享内存管理器需要知道管理器可执行文件的准确位置
定义
_管理器路径():
如果
_运行时使用部署()
或者
平台.
系统() ==
Windows:
返回 b
请提供需要翻译的文本
路径 =
获取文件路径(
torch,
bin,
torch_shm_manager)
准备多进程环境(
获取文件路径(
torch))
如果 not os.
路径.
存在(
路径):
抛出 RuntimeError(
无法找到 torch_shm_manager +
路径)
返回
路径.
编码(
utf-8)
_C._初始化扩展(
_管理器路径())
删除 _manager_path
# 满足类型检查器:它无法处理直接设置全局变量。
# 注意,以这种方式重新导出时,我们会看到“太多”的函数;
这不是解决问题的好方法。也许,尝试重新设计 VariableFunctions
以便这个导入足够好
如果
类型检查:
# 从 _VariableFunctions 中拉取的一些类型签名与此处冲突
已导入签名。目前这些冲突被忽略;详情见
PR #43339。
from torch._C._VariableFunctions 导入 * # type: ignore[assignment, misc] # noqa: F403
# 修复 segment_reduce 透明度
_segment_reduce = 段落减少
删除
段落减少 # noqa: F821
# 不应在 `torch` 命名空间中公开的操作,
主要为辅助操作。
私有操作 = (
唯一维度,)
名称, __obj =
输入文本翻译为简体中文为:"",
无。
对于 __name
进入
目录(_C.
_变量函数):
如果
名称.
以...开头("__")
或者 __name
进入 PRIVATE_OPS:
continue
__obj = getattr(_C._变量函数,
名称)
__obj.__module__ = __name__ # "torch"
隐藏不应公开的一些 API
如果 __name == "segment_reduce":
# TODO: 一旦通过未记录的 FC 窗口,删除下面的行
全局变量()[
名称] = __obj
__name = _ + __name
全局变量()[
名称] = __obj
如果 not
名称.
以...开头(
“下划线”):
__all__.添加(
名称)
删除
名称, __obj
################################################################################
将 torch.dtype 实例添加到公共 API 中
################################################################################
导入
火炬
__all__.扩展(
名称
对于
名称
进入
目录(
PyTorch)
如果 isinstance(getattr(
PyTorch,
名称),
PyTorch.
数据类型)
)
################################################################################
导入 TorchDynamo 的延迟 API 以避免循环依赖
################################################################################
需要在 from torch.functional import *之前,以避免循环依赖
from torch._compile 导入
禁用 dynamo
# usort: 跳过
################################################################################
# 导入在 Python 中定义的接口函数
################################################################################
# 需要放在上面的 ATen 绑定之后,这样我们才能从 Python 端覆盖
from 火炬
导入 _VF as _VF,
功能性 as
功能性
# usort: 跳过
from torch.functional 导入 *
# usort: 跳过 # noqa: F403
################################################################################
# 删除不必要的成员
################################################################################
删除
_存储基类
删除
_遗留存储
################################################################################
# 定义 _assert
################################################################################
# 需要放在子模块导入之前以避免循环依赖
[文档]def _assert(condition, message):
r"""Python 的 assert 的包装器,具有符号可追踪性。"""
if type(condition) is not torch.Tensor and overrides.has_torch_function(
(condition,)
):
return overrides.handle_torch_function(
_assert, (condition,), condition, message
)
断言条件,信息
################################################################################
导入最常见的子包
################################################################################
使用冗余形式,以便类型检查器知道这些是公共 API 的一部分
“常规”导入行仅用于在运行时向导入模块的成员添加对其他用户的副作用
仅为了向导入模块的成员添加对其他用户的副作用
在导入 torch.nn 之前需要放置
from torch 自动微分
导入 (
# usort: 跳过
enable_grad as 启用梯度,
推理模式 as inference_mode,
no_grad as 不梯度,
设置梯度启用 as
设置梯度启用,
)
from 火炬
导入 (
配置 as
配置,
未来 as
未来,
等待 as
等待,
加速器 as
加速器,
自动微分 as
自动微分,
后端 as
后端,
cpu as cpu,
cuda as cuda,
分布式 as
分布式,
分布 as
分布式,
快速傅里叶变换 as
快速傅里叶变换,
期货 as
期货,
花市 as
花市,
算子 as
算子,
线性代数 as
线性代数,
会员 as
会员,
管理培训师 as
管理培训师,
多进程 as
多进程,
嵌套 as
嵌套,
神经网络 as
神经网络,
优化 as
优化,
覆盖规则 as
覆盖,
分析器 as
分析器,
稀疏的 as
稀疏,
特别 as
特别,
测试 as
测试,
类型 as
类型,
工具 as
工具,
xpu as xpu,
)
from torch.signal 导入 windows as windows
# 量化、稀疏、AO 等应最后导入,因为它们没有
# 预期依赖于它们。
from 火炬
导入 ao as ao
# usort: 跳过
# nn.quant* 依赖于 ao -- 因此应在那些之后
导入 torch.nn.intrinsic
导入 torch.nn.qat
导入 torch.nn.quantizable
导入 torch.nn.quantized
_C._init_names(列表(_storage_classes))
将文档字符串附加到 torch 和 tensor 函数
from 火炬
导入 _size_docs,
_存储文档,
_tensor 文档,
_torch 文档
删除
_torch 文档,
_tensor 文档,
_存储文档,
_文档大小
[文档]def 使用_cxx11_abi 编译() -> builtins.bool:
r"""返回 PyTorch 是否使用 _GLIBCXX_USE_CXX11_ABI=1 进行编译"""
return _C._GLIBCXX_USE_CXX11_ABI
from 火炬
导入
库 as
库,
操作 as
操作
导入 "namespace" 的 ops 和 classes
from torch._ops 导入 ops as ops
# usort: 跳过
from torch._classes 导入 classes as classes
# usort: 跳过
系统模块.
模块.setdefault(f"{__name__}.ops",
操作)
系统模块.
模块.setdefault(f"{__name__}
.类",
类别)
# 量化依赖于 torch.fx 和 torch.ops
# 导入量化
from 火炬
导入
量化 as
量化
# usort: 跳过
# 导入准随机采样器
from 火炬
导入
近似随机 as
近似随机
# usort: 跳过
# 如果您看到这个,这意味着这个调用点没有检查
# 内存格式是否可以保留,并且已切换到旧默认值
连续行为
旧连续格式 =
连续格式
由 _C._initExtension() 定义
注册 fork 处理程序以初始化子进程中的 OpenMP(参见 gh-28389)
from torch.multiprocessing._atfork 导入
fork 之后注册
注册 fork 之后(
PyTorch.
获取线程数)
删除
fork 之后注册
# 导入需要完全导入 torch 的工具(用于应用
# torch.jit.script 作为装饰器,例如):
from torch._lobpcg 导入 lobpcg as lobpcg
这些之前已在 native_functions.yaml 中定义并出现
torch 命名空间,但我们将它们移动到 c10 调度以方便自定义
类使用。我们在这里添加这些行以保持向后兼容性。
量化 LSTM =
操作.aten.
量化 LSTM
量化 GRU =
操作.aten.
量化 GRU
# 导入实验性掩码操作支持。详见
# [RFC-0016](https://github.com/pytorch/rfcs/pull/27) 了解更多
信息
from 火炬
导入
隐藏 as
隐藏
# 移除带有移除错误信息的操作
from torch._linalg_utils 导入 (
# 类型:忽略[杂项]
_symeig as 特征值,
特征向量,
最小二乘法,
矩阵秩,
求解,
)
from torch.utils.dlpack 导入
从 dlpack 转换,
转换为 dlpack
类 _TorchCompileInductorWrapper:
编译器名称 =
"电感器"
定义 __init__(
我,
模式,
选项,
动态):
from torch._inductor.编译器二分器
导入
编译器二分器
我.
配置:
字典[str,
任意] = {}
我.
动态 =
动态
我.
应用模式(
模式)
我.
应用选项(
选项)
我.
应用选项(
编译器二分器.
获取配置更改(
电感器))
如果
我.
配置.
获取(
triton.cuDAG 图, False):
os.环境[
"禁用 CUPTI 懒加载初始化"] =
1
# FIXME: CUDA 图形与 CUPTI 清理工作不兼容。
# 1) 在清理工作后第一次懒加载 CUPTI 重新初始化时崩溃(CUDA 11)
# 2) 在清理工作后第二次非懒加载 CUPTI 重新初始化时崩溃(CUDA 12)
# 解决方案:当使用 CUDA 图形时,关闭 CUPTI 清理工作。
os.环境[
"CUPTI 解构"] =
"零"
定义
__等于__(
我,
其他):
返回 (
isinstance(其他, _TorchCompileInductorWrapper)
以及
我.
配置 ==
其他.
配置
以及
我.
动态 ==
其他.
动态
)
定义
应用模式(
我,
模式:
可选[str
)]
如果
模式
以及
模式 !=
默认:
from torch._inductor 导入
列出模式选项
我.
应用选项(
列出模式选项(
模式,
我.
动态))
定义
应用选项(
我,
选项:
可选[
字典[str,
任意
]]:
如果 not
选项:
返回
from torch._inductor 导入
配置
当前配置:
字典[str,
任意] =
配置.
获取配置副本()
对于
键, val
进入
选项.
项目():
属性名称 =
键.
替换(
破折号,
“下划线”)
如果
属性名称 not
进入
当前配置:
抛出 RuntimeError(
f意外优化选项{
键}
逗号,已知选项为{
列表(
当前配置.
键())}"
)
属性类型 =
配置.
获取类型(
属性名称)
# 类型:忽略[已定义]
# 可变通用的类型不支持 isinstance,因此跳过类型检查
# 检查。似乎没有好的方法来检查成员资格而不使用
# 第三方库。
如果
_获取原始(
属性类型)
是
无:
如果 not isinstance(val,
属性类型):
值类型字符串 =
类型(val).__name__
预期类型字符串 =
类型(
当前配置[
属性名称]).__name__
抛出 RuntimeError(
f"意外的属性类型{
键}
,获得{val_type_str}
应该是{expected_type_str}"
)
我.
配置[
属性名称] = val
定义
__调用__(
我,
模型_,
输入_):
from torch._inductor.compile_fx 导入
编译_fx
返回
编译_fx(
模型_,
输入_,
配置修补=
我.
配置)
定义
获取编译器配置(
我):
from torch._inductor.compile_fx 导入
获取修补后的配置字典
返回
获取修补后的配置字典(
配置修补=
我.
配置)
定义
重置(
我):
from torch._inductor 导入
配置
如果
triton.cudagraphs
进入
我.
配置
或者
配置.
三叉戟.
cuDAG 图:
如果
我.
配置.
获取(
triton.cuDAG 图, True):
from torch._inductor.cudagraph_trees 导入
重置_cudagraph_trees
重置_cudagraph_trees()
类 _TorchCompileWrapper:
定义 __init__(
我,
后端,
模式,
选项,
动态):
from torch._dynamo.backends.registry 导入 lookup_backend
如果 isinstance(
后端, str):
我.
编译器名称 =
后端
elif 有属性(
后端,
"__名称__"):
我.
编译器名称 =
后端.__name__
否则:
我.
编译器名称 = str(
后端)
我.
动态 =
动态
我.
编译器函数 =
查找后端(
后端)
我.kwargs = {}
仅传递非空参数
如果
模式
以及
模式 !=
默认:
我.
关键字参数[
模式] =
模式
如果
选项:
我.
关键字参数[
选项] =
选项
定义
__等于__(
我,
其他):
返回 (
isinstance(其他, _TorchCompileWrapper)
以及
我.
编译器函数 ==
其他.
编译器函数
以及
我.kwargs ==
其他.kwargs
以及
我.
动态 ==
其他.
动态
)
定义
__调用__(
我,
模型_,
输入_):
返回
我.
编译器函数(
模型_,
输入_, **
我.
关键字参数)
定义
重置(
我):
如果
有属性(
我.
编译器函数,
重置):
我.
编译器函数.
重置()
输入 T =
参数规范(
"_输入 T")
返回 T =
_类型变量("_RetT")
@_overload
定义
编译(
模型:
可调用[
输入 T,
返回 T
]
*,
全图: builtins.
布尔值 = False,
动态:
可选[builtins.bool] =
无,
后端:
联合[str,
可调用] =
电感器,
模式:
联合[str,
无] =
无,
选项:
可选[
字典[str,
联合[str, builtins.int, builtins.bool]]] =
无,
禁用: builtins.
布尔值 = False,
) -> 可调用[
输入 T,
返回 T
] ...
@_overload
定义
编译(
模型:
无。 =
无,
*,
全图: builtins.
布尔值 = False,
动态:
可选[builtins.bool] =
无,
后端:
联合[str,
可调用] =
电感器,
模式:
联合[str,
无] =
无,
选项:
可选[
字典[str,
联合[str, builtins.int, builtins.bool]]] =
无,
禁用: builtins.
布尔值 = False,
) -> 可调用[[
可调用[
输入 T,
返回 T]],
可调用[
输入 T,
返回 T
]] ...
[文档]
定义
编译(
模型:
可选[
可调用] =
无,
*,
全图: builtins.
布尔值 = False,
动态:
可选[builtins.bool] =
无,
后端:
联合[str,
可调用] =
电感器,
模式:
联合[str,
无] =
无,
选项:
可选[
字典[str,
联合[str, builtins.int, builtins.bool]]] =
无,
禁用: builtins.
布尔值 = False,
) -> 联合[
可调用[[
可调用[
输入 T,
返回 T]],
可调用[
输入 T,
返回 T]],
可调用[
输入 T,
返回 T
]
]
""
使用 TorchDynamo 和指定的后端优化给定的模型/函数。
如果您正在编译一个 :class:`torch.nn.Module`,您还可以使用 :meth:`torch.nn.Module.compile`。
在不改变其结构的情况下就地编译模块。
具体来说,对于编译区域内的每一帧执行,我们将尝试
编译它并将编译结果缓存到代码对象中供将来使用
使用。单个帧可能被编译多次,如果之前已编译
结果不适用于后续调用(这被称为“守卫”)
失败),您可以使用 TORCH_LOGS=guards 来调试这些情况。
多个编译结果可以与一个帧关联
torch._dynamo.config.recompile_limit,默认为 8;在哪个
我们将回退到急切模式。注意,编译缓存是按
*代码对象*,而非框架;如果您动态创建多个副本,
函数,它们将共享相同的代码缓存。
参数:
模型(Callable):用于优化的模块/函数
fullgraph(布尔值):如果为 False(默认),torch.compile 将尝试发现可编译的区域
在它将优化的函数中。如果为 True,则我们要求整个函数
可捕捉成一个单一图。如果这不可能(即存在图断裂),
则会引发错误。
动态(bool 或 None):使用动态形状跟踪。当此值为 True 时,我们将提前尝试
生成尽可能动态的内核,以避免在重新编译时
尺寸发生变化。这不一定总是有效,因为某些操作/优化可能不会
强制专业化;使用 TORCH_LOGS=dynamic 来调试过度专业化。
当此值为 False 时,我们永远不会生成动态内核,我们总是专业化。
默认情况下(None),我们会自动检测是否发生了动态性,并编译更
重新编译时的动态内核。
backend (str 或 Callable):要使用的后端。
- "电感器" 是默认的后端,它在性能和开销之间取得了良好的平衡。
- 非实验性树内后端可以通过 `torch._dynamo.list_backends()` 查看
- 实验性或调试树内后端可以通过 `torch._dynamo.list_backends(None)` 查看
- 要注册树外自定义后端:
https://maskerprc.github.io/docs/main/torch.compiler_custom_backends.html#registering-custom-backends
模式 (str): 可以是 "default", "reduce-overhead", "max-autotune" 或 "max-autotune-no-cudagraphs"
- “default” 是默认模式,它在性能和开销之间取得了良好的平衡
- “reduce-overhead” 是一种减少 Python 使用 CUDA 图形开销的模式
- 对于小批量来说很有用。减少开销可能会以增加内存使用为代价
- 因为我们将缓存调用所需的工作空间内存,所以可能会增加内存使用
不必在后续运行中重新分配它。减少开销并不保证
以工作;今天,我们只为不改变输入的 CUDA 图减少开销。
还有一些情况下 CUDA 图不适用;使用 TORCH_LOG=perf_hints 进行调试。
。
- "max-autotune" 是一种利用 Triton 或模板矩阵乘法的模式
在支持的设备和基于 Triton 的 GPU 卷积上。
默认情况下,在 GPU 上启用 CUDA 图。
- "max-autotune-no-cudagraphs" 是一种类似于 "max-autotune" 的模式,但没有 CUDA 图表
- 要查看每个模式设置的精确配置,可以调用 `torch._inductor.list_mode_options()`
options (dict): 要传递给后端的选项字典。一些值得尝试的选项包括
- `epilogue_fusion`,它将点操作融合到模板中。需要同时设置 `max_autotune`
- `max_autotune`,它将进行性能分析以选择最佳的矩阵乘法配置
- `fallback_random`,在调试准确性问题时很有用
- `shape_padding`,用于填充矩阵形状,以便更好地在 GPU 上对齐负载,特别是对于张量核心
- `triton.cudagraphs`,将减少 Python 与 CUDA 图的开销
- `trace.enabled`,这是最有用的调试标志之一,可以打开
- `trace.graph_diagram` 将显示融合后的图形
- 对于电感器,您可以通过调用 `torch._inductor.list_options()` 来查看它支持的全部配置列表
disable (bool): 将 torch.compile() 转换为无操作以进行测试
示例::
@torch.compile(options={"triton.cudagraphs": True}, fullgraph=True)
def foo(x):
return torch.sin(x) + torch.cos(x)
"""
导入 sysconfig
_C._log_api_usage_once(torch.compile)
如果
系统模块.version_info
≥ (3, 14):
抛出 RuntimeError(
"torch.compile 不支持 Python 3.14+")
elif sysconfig.get_config_var("禁用 Py_GIL") == 1:
抛出 RuntimeError(
"不支持在禁用 GIL 的 Python 上使用 torch.compile"
)
# 装饰器模式
如果
模型
是
无:
定义 fn(
模型:
可调用[
输入 T,
返回 T]) ->
可调用[
输入 T,
返回 T
]
如果
模型
是
无:
抛出 RuntimeError(
"模型不能为空")
返回
编译(
模型,
全图=
全图,
动态=
动态,
后端=
后端,
模式=
模式,
选项=
选项,
禁用=
禁用,
)
返回 fn
如果
模式
是 not
无。
以及
选项
是 not
无:
抛出 RuntimeError(
"可以指定模式或选项,但不能同时指定两者。"
)
如果
模式
是
无。
以及
选项
是
无:
模式 =
"默认"
from torch._inductor.编译器二分器
导入
编译器二分器
如果
二分查找后端 :=
编译器二分器.
获取后端():
后端 =
二分查找后端
如果
后端 ==
电感器:
后端 = _TorchCompileInductorWrapper(
模式,
选项,
动态)
否则:
后端 = _TorchCompileWrapper(
后端,
模式,
选项,
动态)
返回
PyTorch._dynamo.
优化(
后端=
后端,
无 Python=
全图,
动态=
动态,
禁用=
禁用,
)(模型) # type: ignore[return-value]
定义
注册设备模块(
设备类型,
模块):
r注册特定 :attr:`设备类型` 的外部运行时模块
支持由 torch 提供。
在正确注册`:attr:`module`之后,用户可以引用
外部运行时模块作为 torch 的一部分,使用属性 torch.xxx 进行引用。
"""
确保 device_type 代表 torch 支持的设备类型。
设备类型 =
PyTorch.
设备(
设备类型).
类型
m = 系统模块.
模块[__name__]
如果
有属性(m,
设备类型):
抛出 RuntimeError(
f"运行时模块的 '"{
设备类型}
已经被注册了
f"注册在 '"{getattr(m,
设备类型)}
)
setattr(m, 设备类型,
模块)
火炬模块名称 =
“。”.
连接
[__name__,
设备类型])
系统模块.
模块[
火炬模块名称] =
模块
from 火炬
导入 (
导出 as
导出,
函数 as
函数,
库 as
图书馆,
返回类型 as
返回类型,
)
from torch._高阶操作
导入 cond as
条件,
while 循环 as
while 循环
from torch.func 导入 vmap as vmap
如果 not
类型检查:
from 火炬
导入
_元注册
# 启用 CUDA 检查器
如果 "TORCH_CUDA_SANITIZER"
进入 os.
环境:
导入 torch.cuda._sanitizer as csan
csan.enable_cuda_sanitizer()
在 SymInt 和 SymFloat 上填充魔法方法
导入 torch.fx.experimental.sym_node
from 火炬
导入 fx as fx
# 注册 MPS 特定分解
PyTorch.
后端.
会员.
_初始化()
如果 not
_运行时使用部署():
from 火炬
导入
编译器 as
编译器
类
三叉戟库:
库 =
PyTorch.
图书馆.
库(
triton, "DEF")
操作表:
字典[
元组[str, str
]
可调用] = {}
@classmethod
定义
注册操作(cls,
op 键,
完整模式,
op 实现,
分发键):
如果 (
op 键,
分发键) not
进入 cls.
操作表:
cls.库.
定义(
完整模式)
cls.库.
实现(
triton:: +
op 键,
op 实现,
分发键)
cls.操作表
[
op 键,
分发键)] = op_impl
返回 cls.
操作表
[
op 键,
分发键)]
# 已废弃属性
_已废弃属性 = {
"具有_mps":
PyTorch.
后端.
会员.
是否构建,
has_cuda:
PyTorch.
后端.cuda.
是否构建,
具有 cudnn:
PyTorch.
后端.cudnn.
是否可用,
支持 mkldnn:
PyTorch.
后端.mkldnn.
是否可用,
}
如果
类型检查:
# 在类型检查期间导入以下模块以启用代码智能功能,
# 例如在 pylance 等工具中的自动补全,即使这些模块没有明确地
# imported in user code.
from 火炬
导入 (
_dynamo as _dynamo,
_inductor as 电磁感抗,
子类 as
子类,
onnx as onnx,
)
否则:
_lazy_modules = {
_dynamo,
_inductor,
导出,
# ONNX 必须在导入_dynamo, _ops, _subclasses, fx, func 和 jit 之后
onnx,
}
定义 __getattr__(
名称):
已弃用属性
替代方案 =
_已弃用属性.
获取(
名称)
如果
替代方案
是 not
无:
导入
警告
警告.
警告(
f''{
名称}
'已弃用,请使用 '{
替换.
__模块__}.{
替换.__name__}
()'',
栈级别=2,
)
返回
替换()
懒加载模块
如果
名称
进入
_懒加载模块:
返回 importlib.
导入模块(f
“。”{
名称}", __name__)
抛出
属性错误(f
“模块”{__name__}
“没有属性”{
姓名}
“”)
[文档]def get_device_module(device: _Optional[_Union[torch.device, str]] = None):
"""
返回与指定设备关联的模块(例如,torch.device('cuda'),"mtia:0","xpu",...)。
如果未指定设备,则返回当前加速器或不存在时返回 CPU 的模块。
"""
如果 device 是 torch.device 类型:
device_module_name = device.type
elif isinstance(device, str):
device_module_name = torch.device(device).type
elif device is None:
# 使用默认加速器类型。如果没有可用的加速器,它将自动返回 CPU 设备。
device_module_name = torch._C._get_accelerator().type
else:
raise RuntimeError(
f"设备'{device}'的值无效,预期 torch.device、str 或 None"
)
device_module = getattr(torch, device_module_name, None)
if device_module is None:
raise RuntimeError(
f"设备 '{device_module_name}' 未注册为 'torch.{device_module_name}' 的对应模块。"
)
返回设备模块
定义
限制为大小(
符号,
最小值:
可选[builtins.int] =
无,
最大值:
可选[builtins.int] =
无,
):
""
这表示给定的整数具有大小属性,可以在任何需要大小的上下文中使用。
您通常会在从张量中读取整数时使用它,例如 max.item() 或 lengths.tolist()。
然后需要将这些断言用作张量构造函数。将这些断言提供给 PyTorch 可以帮助在导出时解决 GuardOnDataDependentSymNode 错误,因为我们无法对未备份的 SymInts 进行保护。
导出时出现 GuardOnDataDependentSymNode 错误,因为我们无法在未备份的 SymInts 上进行保护。
在某些情况下,此函数在框架中具有不寻常的语义。
在代码中,我们将这个整型视为 >= 2(当我们执行一个大小无关的守卫时)。
这使得在大小上下文中使用无背存储的整型更加方便,
因为我们经常尝试在大小为零/一时进行守卫。
(例如,在计算张量的连续性或测试广播是否可以发生时),这不会在未备份的 SymInts 上工作。
然而,如果我们保守地假设大小不是零/一,我们最终会得到一个即使大小是零/一也能正常工作的图。
然而,如果我们保守地假设大小不是零/一,我们最终会得到一个即使大小是零/一也能正常工作的图。
然而,如果我们保守地假设大小不是零/一,我们最终会得到一个即使大小是零/一也能正常工作的图。
更多详情请参阅 https://docs.google.com/document/d/1HSuTTVvYH1pTew89Rtpeu84Ht3nQEFTYhAX3Ypa_xJs/edit
```
"""
PyTorch.sym_constrain_range_for_size(
符号,
最小值=
最小值,
最大值=
最大值)
from 火炬
导入 _logging
_日志记录.
_初始化日志()
定义
_导入设备后端():
""
利用 Python 插件机制加载树外设备扩展。
请参阅此 RFC:https://github.com/pytorch/pytorch/issues/122468
"""
from importlib.metadata 导入 entry_points
group_name = torch 后端
如果
系统模块.version_info < (3, 10):
后端扩展 =
入口点().
获取(
群组名称, ())
否则:
后端扩展 =
入口点(
组=
群组名称)
对于
后端扩展
进入
后端扩展:
尝试:
加载扩展
入口 =
后端扩展.
加载()
调用入口点
入口()
除了
异常 as
错误:
抛出 RuntimeError(
f"加载后端扩展失败:"{
后端扩展.
名称}
.
f"您可以通过设置 TORCH_DEVICE_BACKEND_AUTOLOAD=0 来禁用扩展自动加载。"
) from 错误
定义
设备后端自动加载已启用() -> builtins.bool:
""
是否启用了自动加载树外设备扩展。
该开关取决于环境变量的值。
`TORCH_DEVICE_BACKEND_AUTOLOAD`
返回值:
bool:是否启用自动加载扩展。默认启用。
示例:
>>> torch._is_device_backend_autoload_enabled()
True
"""
默认启用
返回 os.
获取环境变量("TORCH_DEVICE_BACKEND_AUTOLOAD", "1") ==
1
定义 _as_tensor_fullprec(t):
""
与 torch.as_tensor 类似,但给定 Python 数据类型时,它会保持
全精度。用于 Dynamo 的调用约定。
"""
ty = 类型(t)
如果 ty
是 builtins.float:
返回
PyTorch.as_tensor(t,
数据类型=
PyTorch.float64)
elif ty 是 builtins.int:
返回
PyTorch.as_tensor(t,
数据类型=
PyTorch.int64)
否则:
返回
火炬.as_tensor(t)
`_import_device_backends` 应该放在最后,以确保
# 本模块中可能被其他所有函数访问的
自动加载的后端被定义
如果
设备后端自动加载已启用():
_导入设备后端()