mock cuda runtime api
Project description
cuda-rt-hook(cuda_mock)
cuda-rt-hook(cuda_mock)是一个用于拦截CUDA/XPU Runtime接口(例如,cudaMalloc
和xpu_malloc
)调用的Python库,通过修改PLT(Procedure Linkage Table)来实现动态拦截,无需重新编译PyTorch、Paddle等复杂框架,安装后即可使用,在调用堆栈追踪、调用耗时统计以及Paddle/PyTorch训练和推理的精度调试和性能优化等场景下非常有用。
本项目的灵感来自于plthook项目,项目的初衷是通过拦截CUDA的Runtime调用转为调用mock函数,可以在没有CUDA和GPU环境的情况下运行和调试triton等项目,因而项目取名cuda_mock。后续增加了多个功能,使得cuda_mock项目可以用于模型的调试和性能分析。
安装
直接安装(建议)
pip install cuda_mock
从源码构建
git clone --recursive https://github.com/lipracer/cuda-rt-hook
cd cuda-rt-hook
python setup.py sdist bdist_wheel
pip install dist/*.whl
# 或者:
# python setup.py install
快速开始
找到Paddle/PyTorch模型的训练/推理脚本入口,在首次import torch
/import paddle
之后添加如下代码:
import paddle
import cuda_mock; cuda_mock.xpu_initialize() # 加入这一行
或者
import torch
import cuda_mock; cuda_mock.xpu_initialize() # 加入这一行
根据实际的需求和场景设置cuda_mock的功能环境变量(参考功能使用演示章节),接着按照训练/推理脚本原有的执行方式运行脚本即可。
功能使用演示
功能1: 统计各个so库调用Runtime接口的次数和总耗时
LOG_LEVEL=WARN python run.py
在程序运行结束之后会显示:
功能2: 打印xpu_wait
的C++、C和Python调用堆栈
HOOK_ENABLE_TRACE="xpu_wait=1" python run.py
在程序运行结束之后会显示:
功能3: 统计模型训练/推理过程中的峰值内存
LOG_LEVEL=WARN python run.py
在程序运行结束之后会显示:
功能4: 打印Runtime接口的耗时
LOG_SYNC_MODE=1 LOG_LEVEL=PROFILE=INFO python run.py
在程序运行过程中会显示:
功能5:打印Runtime的参数
HOOK_ENABLE_TRACE=xpu_malloc=0b10 python run.py
HOOK_ENABLE_TRACE=xpu_malloc=0x2 python run.py
在程序运行过程中会显示:
功能6: 收集CUDA算子调用堆栈
- 找到nvcc安装路径
which nvcc
- 用我们的nvcc替换系统的nvcc(我们只是在编译选项加了
-g
)
mv /usr/local/bin/nvcc /usr/local/bin/nvcc_b
chmod 777 tools/nvcc
cp tools/nvcc /usr/local/bin/nvcc
- 构建并且安装pytorch
- 构建并且安装cuda_mock
- 注意要在import torch之后import cuda_mock
- 开始跑你的训练脚本
- 我们将会把堆栈打印到控制台
环境变量
环境变量 | 默认值 | 简短说明 |
---|---|---|
LOG_LEVEL | WARN | 设置全局和各个日志模块的日志级别 |
HOOK_ENABLE_TRACE | 全部接口默认值为0(关闭backtrace) | 是否开启backtrace或参数打印 |
LOG_OUTPUT_PATH | "" | 是否将日志重定向到文件 |
LOG_SYNC_MODE | 0 | 是否使用同步日志输出 |
LOG_LEVEL
- 用法示例:
export LOG_LEVEL=WARN,TRACE=INFO
- 可选值:
- 日志级别: INFO, WARN, ERROR, FATAL
- 日志模块: PROFILE, TRACE, HOOK, PYTHON
- 默认值:
- 全局日志级别: WARN
- 各个日志模块的默认日志级别: WARN
- 说明: 设置全局和各个日志模块的日志级别
HOOK_ENABLE_TRACE
- 用法示例:
export HOOK_ENABLE_TRACE='xpu_memcpy=1,xpu_set_device=0,xpu_wait=0x1'
- 可选值: xpu_malloc, xpu_free, xpu_wait, xpu_memcpy, xpu_set_device, xpu_current_device, xpu_launch_async
- 默认值: 所有接口的默认值均为0,即所有接口默认关闭backtrace
- 说明: 是否开启backtrace和参数打印
HOOK_ENABLE_TRACE
可接收十进制、二进制和十六进制的数字,不同的位作为不同的开关
Bit | 开关说明 |
---|---|
0 | 是否开启backtrace |
1 | 是否开启参数打印 |
LOG_OUTPUT_PATH
- 用法示例:
export LOG_OUTPUT_PATH='/tmp/'
- 可选值: 日志输出文件夹
- 默认值: ""
- 说明: 是否将日志重定向到文件, 默认是输出到标准输出
LOG_SYNC_MODE
- 用法示例:
export LOG_SYNC_MODE=1
- 可选值: 0 或 1
- 默认值: 0
- 说明: 是否使用同步日志输出,同步日志输出可能会影响主线程的执行时间,但可以使CUDA_MOCK输出的日志与其它日志系统输出保序
高级功能
实现自定义hook函数
实现自定义hook installer例子:
class PythonHookInstaller(cuda_mock.HookInstaller):
def is_target_lib(self, name):
return name.find("libcuda_mock_impl.so") != -1
def is_target_symbol(self, name):
return name.find("malloc") != -1
lib = cuda_mock.dynamic_obj(cpp_code, True).appen_compile_opts('-g').compile().get_lib()
installer = PythonHookInstaller(lib)
- 实现hook回调接口
PythonHookInstaller
- 构造函数需要传入自定义hook函数的库路径(绝对路径 并且 传入库中必须存在与要替换的函数名字以及类型一致的函数 在hook发生过程中,将会把原函数的地址写入以
__origin_
为开头目标symbol
接口的变量中,方便用户拿到原始函数地址 参考:test/py_test/test_import_mock.py:15
处定义) is_target_lib
是否是要hook的目标函数被调用的libraryis_target_symbol
是否是要hook的目标函数名字(上面接口返回True才回调到这个接口)new_symbol_name
构造函数中传入共享库中的新的用于替换的函数名字,参数name
:当前准备替换的函数名字dynamic_obj
可以运行时编译c++ code,支持引用所有模块:logger
、statistics
贡献代码
调试编译
# 编译
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=`$pwd/`build -DENABLE_BUILD_WITH_GTEST=ON -GNinja
cmake --build build
# 运行单测
cd build
ctest -R
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Hashes for cuda_mock-1.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | d9add0ecc402a2a867c297e2e5213e8fba8b24c1b78e270831bda8f4010ff184 |
|
MD5 | 65312c4789c247cab594795b3945d9e7 |
|
BLAKE2b-256 | e11d5a4553d5fcd535948a8364cf9decbc20e6de7fb87946b7d7bb357eac906a |
Hashes for cuda_mock-1.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9e836549aa6186b858ef2d7bdf96f96946eeb765c3d44279f217383bc0a65b8a |
|
MD5 | 36219ad25c5a393ff74a476563b4d746 |
|
BLAKE2b-256 | 2381054ab0a4cffd1d7a63045ca6ca9ed1ba05d00484b31588d1f23578533b8a |
Hashes for cuda_mock-1.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5fbc131e1166d7b3ee912e3f2410ce0379501968fec294ea39d05c9243956fb9 |
|
MD5 | c077a3f810dcfd700f3463041172dac3 |
|
BLAKE2b-256 | 51dfba8c7ec1a8239cfac66b2596c11331f7c8c06732050417f552636d22f7cd |
Hashes for cuda_mock-1.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f0c8ea8d6cda72bb829dba9f94e4d498cd4625bfc8bca3ff0851c296eed3453b |
|
MD5 | fcd724b4cfde07844eca54a30ab99ef8 |
|
BLAKE2b-256 | 7d619a008691441aa61fa6f27ca39fb3d0e5d3e30c7d1501d942091d60ba58ed |
Hashes for cuda_mock-1.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | de95f9bf05329969706ca16b0b06e05bd5508cacd668473d583137430600e64d |
|
MD5 | 17024675cac94575c5c227ffb6ce7d05 |
|
BLAKE2b-256 | 540a5e8e24bf2e974d1c262a9f2517779c1ea8bb05a6d2afdfcfc9bd17e2220b |
Hashes for cuda_mock-1.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 56666d3902ab6a2200b7059e7a67de1eeb3382361324bf36c31791f3cdc9becb |
|
MD5 | cb622b6abeb12bf835b2b62968118269 |
|
BLAKE2b-256 | 31a7480a517ffbc5c67977e3846819742e549e4eb20f3c41eadc805eb410e47d |
Hashes for cuda_mock-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | b60c1ad9d94352e1b8795fed6b42c0f0cf047cd3e7320bcc503718d3fab2b4b7 |
|
MD5 | 6ab28fbe307394513ae244b9706ff26d |
|
BLAKE2b-256 | 5775ec2a186f2ee52d82cacb000c6e928e37860e9b79f00a112ccaf0518c398d |
Hashes for cuda_mock-1.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2a25d19021b7731cfdd7ad4a7387ee15da43774f7e0c67a7b44669cb47ef5e86 |
|
MD5 | 33f6e48c15be7809d7bbecb5cd3038c9 |
|
BLAKE2b-256 | 68f1244321a972f91f3527344746037cf90cad406dd27a9680cc9ff02de2396e |
Hashes for cuda_mock-1.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4aad2f7948077c02f5b12336348556d3ab7d7ece906b72f03f68457a0311cf7f |
|
MD5 | dabe1f371a66da726596f1d96879f35a |
|
BLAKE2b-256 | 6714e4d02a591bd7d91f36c7cd4881b3d7ab0f64933e935013aa7a064dcf2be9 |
Hashes for cuda_mock-1.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 732feaf8bb3e9f7d4e20d91240c391dc6a52b9201112e85b3084ba9f84965bd9 |
|
MD5 | b0b21f182cc67d0f6395af59014fc3e0 |
|
BLAKE2b-256 | e57fa6fdf4d2152fc7b0e974b92a524dfc86b60eec23a1b170a65c7e80aff31a |
Hashes for cuda_mock-1.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 97e8d022a930cc5651ddacae142c2566b6ebe921158f7e735571b03c430d34ad |
|
MD5 | bf26e369f97898644933a91ad5bc08d9 |
|
BLAKE2b-256 | 3e383e9aaffac844e5224d22fe4211e3aadb79549039692fc0070ed61c1bedad |
Hashes for cuda_mock-1.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 221a9af805b528a987e2dcace0e5c92b09967ae040f760bbd9d5ade45bd8ae02 |
|
MD5 | 7406a785f645fa6c4bc61500502fad23 |
|
BLAKE2b-256 | 0196b4260091abe9cdf8d8cbc328483f53e6c0dfa304d3726be73f94cb0918cc |
Hashes for cuda_mock-1.0.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3c569d170055112d0a075598801fddac959e33d7f4b9321c9ebea29aa0a1471d |
|
MD5 | c5e17b86da6f2b61da12c356a3e35130 |
|
BLAKE2b-256 | 40a230c6ecd17cb0601eea3383b99dd2f9858098f4a581065e88c977e0cb076a |