PyTorch之自定义op扩展编译与加载 —— cpp_extension

前言

在使用PyTorch或者TensorFlow构建网络时,可能会遇到一些不支持的自定义算子或者对原生算子做一些加速工作,这个时候就需要使用深度学习框架提供的扩展op功能。最典型的便是StyleGAN2中自定义的用于加速和节省内存占用的两个算子。
在这里插入图片描述

PyTorch中的op扩展

以PyTorch框架为例,其支持扩展op,支持的函数均在TORCH.UTILS.CPP_EXTENSION中。

load

使用load()方法实时(just-in-time (JIT))生成op扩展并加载:

torch.utils.cpp_extension.load()

在这里插入图片描述
其中编译和生成工具主要使用Ninja,因此需要先安装ninja(pip install ninja)。

运行时会先生成build.ninja文件,其中定义了C++扩展文件(如fused_bias_act.o)和CUDA扩展文件(主要是核函数的实现,如fused_bias_act_kernel.cuda.o)的编译,并定义了扩展文件之间的链接方法。随后执行ninja编译链接过程,最终生成可执行文件(如fused.so)供python脚本调用。

op生成过程中~/.cache/torch_extensions/fused/目录下的文件:

build.ninja  fused_bias_act_kernel.cuda.o  fused_bias_act.o  fused.so

_import_module_from_library

使用_import_module_from_library方法可以加载已经生成好的op扩展(例如fused.so)。
在这里插入图片描述
注:其他方法可以查阅 PyTorch Docs > torch.utils.cpp_extension

op扩展生成过程中的问题

Ninja is required to load C++ extensions

Traceback (most recent call last):
  File "python3.8/site-packages/torch/utils/cpp_extension.py", line 752, in verify_ninja_availability
	raise RuntimeError("Ninja is required to load C++ extensions")
RuntimeError: Ninja is required to load C++ extension

使用torch.utils.cpp_extension.load()方法生成op扩展时,其中编译和生成工具主要使用Ninja,因此需要先安装ninja。

pip install ninja

baton.wait()

使用torch.utils.cpp_extension.load()方法生成op扩展时,偶尔会遇到程序一直卡住的问题。此时如果按Ctrl+C取消运行,则会出现类似下面的报错信息:

Traceback (most recent call last):
  File "test.py", line 5, in <module>
    "./fused_bias_act_kernel.cu",
  File "./env/lib/python3.7/site-packages/torch/utils/cpp_extension.py", line 87, in load
    keep_intermediates=keep_intermediates)
  File "./env/lib/python3.7/site-packages/torch/utils/cpp_extension.py", line 997, in _jit_compile
    baton.wait()
  File "./env/lib/python3.7/site-packages/torch/utils/file_baton.py", line 76, in wait
    time.sleep(self.wait_seconds)

从打印信息推测是一直在等待文件锁被释放。此时查看~/.cache/torch_extensions/fused/目录下的文件,可以发现多了一个lock文件,这是一个读文件锁,如果在某次执行编译中杀掉进程而该锁未被释放,则下次再运行编译则会遇到该lock已经存在的问题,导致进程一直等待从而造成假死状态。此时只需先删掉该lock文件后重新执行程序即可。

兼容运行时生成op和直接加载op

当自定义op一旦编译生成好,则下次运行时即可直接加载使用而不用再执行编译过程,这样可以大大节省编译时间。

fused_bias_act op为例:

import os
from torch.utils.cpp_extension import load, _import_module_from_library

try:
    user_home_path = os.path.expanduser('~')
    fused = _import_module_from_library('fused', user_home_path+'/.cache/torch_extensions/fused', True)
    print(f'Load fused from {user_home_path}/.cache/torch_extensions/fused')
except:
    module_path = os.path.dirname(__file__)
    fused = load(
        'fused',
        sources=[
            os.path.join(module_path, 'fused_bias_act.cpp'),
            os.path.join(module_path, 'fused_bias_act_kernel.cu'),
        ],
    )
    print(f'Build fused from cpp & cu files')

版权说明

本文为原创文章,独家发布在blog.csdn.net/TracelessLe。未经个人允许不得转载。如需帮助请email至tracelessle@163.com
在这里插入图片描述

参考资料

[1] NVlabs/stylegan2: StyleGAN2 - Official TensorFlow Implementation
[2] PyTorch Docs > torch.utils.cpp_extension
[3] python - Ninja is required to load C++ extensions - Stack Overflow
[4] torch.utils.cpp_extension.load卡住无响应_zParquet的博客-CSDN博客
[5] _import_module_from_library

  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 19
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TracelessLe

❀点个赞加个关注再走吧❀

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值