torch.jit._fuser 的源代码
# mypy: 允许未类型化定义
导入 contextlib
导入
火炬
@contextlib.contextmanager
def 优化执行(should_optimize):
控制 JIT 执行器在执行函数之前是否运行优化的上下文管理器。
存储标志 =
火炬._C._get_graph_executor_optimize()
火炬._C._set_graph_executor_optimize(should_optimize)
尝试:
产生
最后:
火炬._C._set_graph_executor_optimize(
存储标志)
@contextlib.contextmanager
def 燃烧器(
名称):
后端融合器切换的上下文管理器
有效名称:
* ``fuser0`` - 仅启用传统融合器
* ``fuser1`` - 仅启用 NNC
* ``fuser2`` - 仅启用 nvFuser
* ``fuser3`` - 启用 oneDNN Graph
"文档"
旧 CPU 融合 =
火炬._C._jit_can_fuse_on_cpu()
旧 GPU 融合 =
火炬._C._jit_can_fuse_on_gpu()
旧 texpr_fuser_state =
火炬._C._jit_texpr_fuser_enabled()
旧_nvfuser 状态 =
火炬._C._jit_nvfuser_enabled()
旧_llga 状态 =
火炬._C._jit_llga_enabled()
如果
名称 ==
fuser0:
# 旧版 fuser
火炬._C._jit_override_can_fuse_on_cpu(
是)
火炬._C._jit_override_can_fuse_on_gpu(
是)
火炬._C._jit_set_texpr_fuser_enabled(
错误)
火炬._C._jit_set_nvfuser_enabled(
错误)
火炬._C._jit_set_llga_enabled(
错误)
如果...否则
名称 ==
fuser1: # NNC
旧配置执行器 =
火炬._C.
_jit 设置配置执行器(
是)
旧配置模式 =
火炬._C.
_获取图执行器优化选项(
是)
火炬._C.
_jit 覆盖 CPU 上可融合(
是)
火炬._C.
_jit 覆盖 GPU 上可融合(
是)
火炬._C._jit_set_texpr_fuser_enabled(
是)
火炬._C._jit_set_nvfuser_enabled(
错误)
火炬._C._jit_set_llga_enabled(
错误)
如果...否则
名称 ==
fuser2: # nvFuser
火炬._C._jit_override_can_fuse_on_cpu(
错误)
火炬._C._jit_override_can_fuse_on_gpu(
错误)
火炬._C._jit_set_texpr_fuser_enabled(
错误)
火炬._C._jit_set_nvfuser_enabled(
是)
火炬._C._jit_set_llga_enabled(
错误)
如果...否则
名称 ==
fuser3:
# oneDNN 图
旧配置执行器 =
火炬._C.
_jit 设置配置执行器(
是)
旧配置模式 =
火炬._C.
_获取图执行器优化选项(
是)
火炬._C._jit_override_can_fuse_on_cpu(
是)
火炬._C._jit_override_can_fuse_on_gpu(
错误)
火炬._C._jit_set_texpr_fuser_enabled(
是)
火炬._C._jit_set_nvfuser_enabled(
错误)
火炬._C._jit_set_llga_enabled(
是)
如果...否则
名称 ==
无:
# 关闭 Pytorch fuser
火炬._C._jit_override_can_fuse_on_cpu(
错误)
火炬._C._jit_override_can_fuse_on_gpu(
错误)
火炬._C._jit_set_texpr_fuser_enabled(
错误)
火炬._C._jit_set_nvfuser_enabled(
错误)
火炬._C._jit_set_llga_enabled(
错误)
else:
提升
异常(f
"未识别的 fuser 选项(名称:"{
名称})")
# 无需注意:TRY002
尝试:
产生
最后:
如果
名称
在 [
fuser1,
fuser3]:
# NNC 或 oneDNN 图
火炬._C._jit_set_profiling_executor(
旧配置执行器) # type: ignore[possibly-undefined]
火炬._C.
_获取图执行器优化(
旧配置模式) # type: ignore[possibly-undefined]
# 恢复之前的值
火炬._C.
_jit 覆盖 CPU 上可融合(
旧 CPU 熔合)
火炬._C.
_jit Override 可以在 GPU 上熔合(
旧 GPU 熔合)
火炬._C.
_jit 设置 texpr 熔合器启用(
旧_texpr_fuser 状态)
火炬._C.
_jit 设置 nvfuser 启用(
旧_nvfuser 状态)
火炬._C.
_jit 设置 llga 启用(
旧_llga_state)
最后执行优化的图 =
火炬._C.
_最后执行优化的图_
def _获取可微分图节点_(
节点, diff_node):
如果
节点.
类型() ==
prim::可微图:
diff_node.append(节点)
else:
为 block
在
节点.
块():
为 n
在
块.
节点():
_获取可微分图节点(n,
差分节点)
def _graph_for(我, *
参数, **kwargs):
返回 _script_method_graph_for(
我,
我, *
参数, **kwargs)
def _script_method_graph_for(我,
父节点, *
参数, **kwargs):
尝试:
数据库 =
父节点.
获取调试状态()
eps = 列表(
数据库.
执行计划.
值())
断言
长度(eps) == 1
图 = eps[0].graph.
复制()
可微分节点执行状态
硬件状态 = eps[0].
代码.
可微分操作执行状态()
差分节点:
列表[
火炬._C.
节点] =
输入文本为空,请提供需要翻译的文本
为 n
在 graph.
节点():
获取可微分图节点(n,
差分节点)
断言
长度(
前向状态) ==
长度(
差分节点)
在其执行计划中将每个可区分的图替换为优化图
为 n,
状态
在 zip(
差分节点,
前向状态):
前向执行计划 =
列表(
状态.
执行计划.
值())
# 我们只能在存在唯一执行时更新子图
# 计划。避免断言,以便跳过无法更新的那些,尽力尝试更新其他节点。
# 在尽力更新其他节点的同时,避免更新无法更新的节点。
如果
长度(
火墙执行计划) == 1:
n.g_(子图,
火墙执行计划[0].graph)
返回
图
除了
异常:
# 回退方法,我们刚刚运行了图并返回记录的优化结果
# 图
我(*
参数, **kwargs)
返回
最后执行优化的图()
[文档]def set_fusion_strategy(strategy: list[tuple[str, int]]):
"""设置融合过程中可以发生的类型和特殊化数量。
使用方法:提供一对列表(类型,深度),其中类型为“STATIC”或“DYNAMIC”之一
深度是一个整数。
行为 - 静态与动态:
静态融合中,融合操作被编译为具有固定输入形状。形状由
基于一些初步的运行分析。
在 DYNAMIC 融合中,融合的操作被编译成具有可变输入形状,因此可能存在多种形状。
在这两种情况下,我们也会根据新的步长行为、设备或数据类型重新编译。
在这两种情况下,我们也会根据新的步长行为、设备或数据类型重新编译。
行为 - 回退函数 & 深度
当输入不匹配专用编译操作符所需的格式时,它将运行
一个回退函数。回退函数是递归编译和专门化的
在观察到的张量形状上。由于编译可能很慢,因此提供了“深度”参数以
限制可以编译的专业化数量,在放弃重新编译之前
回退到一个完全未融合、未专业化的实现。
控制着特殊化的类型和数量对的列表
专业分类。例如:[("STATIC", 2), ("DYNAMIC", 2)] 表示第一个
两种特殊化将使用静态融合,以下两种特殊化将使用动态融合,任何不满足上述 4 个选项的输入将运行未融合的实现。
注意:未来随着更多融合后端被添加,可能会有更细致的选项。
未融合的实现。
注意:未来随着更多融合后端被添加,可能会有更细致的选项。
特定融合器的 API
""
返回 torch._C._jit_set_fusion_strategy(strategy)