VSCode 配置 PyTorch C++ 源码开发环境(编译与调试)
版本信息
- OS:Ubuntu 22.04.5 LTS (通过 SSH 远程连接)
- GCC:11.4.0
- VSCode 版本:1.95.0
环境准备
创建目录,下载源代码
mkdir pytorch_dev
cd pytorch_dev
git clone --recursive https://github.com/pytorch/pytorch
创建虚拟环境
conda create -y -n pytorch_dev python==3.12
conda activate pytorch_dev
安装编译依赖,包括一些编译加速工具(ccache)
pip install mkl-static mkl-include
pip install -r pytorch/requirements.txt
conda install -y cmake ninja
conda install -y ccache -c conda-forge
# 配置 ccache 存储上限
ccache -M 25Gi
ccache -F 0
源码编译
MAX_JOBS 的大小请自行调整(建议按照 CPU 内存比 1:4 来调,避免 OOM,比如 16 核 32 GB 的机器可以设置成 8。作者的机器是 128 核 128GB 内存,因此设置为 32)
export CMAKE_PREFIX_PATH="${CONDA_PREFIX:-'$(dirname $(which conda))/../'}:${CMAKE_PREFIX_PATH}"
cd pytorch
DEBUG=1 MAX_JOBS=32 python setup.py install
其他编译选项可以参考 pytorch/CONTRIBUTING.md at main · pytorch/pytorch
在 pytorch_dev 下创建测试文件 test.py
|
|
运行
python test.py
如果没有问题,则会输出以下内容(cuda 是否可用取决于具体情况,本文不介绍如何安装 cuda)
tensor([[25.3774, 25.7640, 27.0730, ..., 25.3814, 22.5268, 26.2766],
[25.5186, 24.3556, 25.2432, ..., 25.7233, 22.3721, 25.9354],
[23.4678, 22.8769, 24.5955, ..., 22.7279, 20.1115, 23.8574],
...,
[28.4061, 27.1574, 28.1965, ..., 26.7858, 23.3654, 27.7717],
[21.5448, 22.8987, 23.0728, ..., 20.8371, 19.4624, 23.0139],
[22.8249, 22.4210, 24.9273, ..., 23.4396, 21.3405, 25.5342]])
True
此时目录结构为
~/pytorch_dev$ ls
pytorch test.py
把 pytorch 源码放在子目录,让测试代码和它同级的目的是可以在 VSCode 中正确地跳转,否则 VSCode 调试过程中无法进入到 pytorch 的 python 源码中。这和 python setup.py 是使用 install 还是 develop 有关,本文统一使用 install 。(欢迎勘误)
C++ 源码跳转
由于早期 C/C++ 插件存在内存泄漏问题,因此个人现在偏向于使用 clangd,这会与 C/C++ 插件冲突。如果读者已使用 C/C++ 插件,那么以下内容可能不适合你。并且在 C++ 源码调试时,需要修改成 cppdbg,具体请自行搜索。如果有更好用的 C++ 插件,也可以在评论区指出或者联系我。
PyTorch 编译后之后,在 build 文件夹中会生成 compile_commands.json 文件,我们可以使用它来进行函数定义的跳转。
在系统上安装 clangd
sudo apt install clangd
安装 VSCode 扩展 clangd(llvm-vs-code-extensions.vscode-clangd)
打开 clangd 扩展设置,在远程选项卡中找到 Clangd: Path,其默认值为 clangd,我们修改为 /usr/bin/clangd 来解决 VSCode 提示找不到 clangd 的问题。(虽然我不知道为什么会这样,但这个问题在我这里经常发生,这是一个有效的解决方法)
然后重新加载窗口,可以使用 Ctrl+Shift+P 打开命令面板,输入 reload window 来选择。
重新加载窗口后可以看到界面左下角 clangd 会开始索引,等待完成后就可以进行跳转。
调试
使用 VSCode 打开 pytorch_dev 目录
code pytorch_dev
python 代码调试
前提:安装 Python 扩展(ms-python.python)
创建配置文件
mkdir -p .vscode
touch .vscode/launch.json
保存以下内容
|
|
在 VSCode 界面,代码行数左边进行设置断点,如下图设置了两处断点
使用 F5 启动调试,可以看到程序在第三行暂停
可以使用中间上方悬浮的工具条进行控制,也可以使用快捷键:继续(F5)、逐过程(F10)、单步调试(F11)、单步跳出(Shift+F11)、重启(Ctrl+Shift+F5)、停止(Shift+F5)
先按一次 F11,发现 torch.rand 函数无法进入,直接跳到了 R = M.mm(M)
再按一次 F11,发现 M.mm(M) 也无法进入,直接跳到了 print(R),同时左侧变量一栏显示了当前的 M 和 R 的值
继续按一次 F11,发现可以跳转到 Tensor 对象的 __repr__ 方法,这是被 print 函数间接调用的。
使用 Shift+F11 单步跳出,回到 test.py 中,再使用 F5 继续运行,可以看到终端正常输出了 R 的值,并且程序暂停在第六行代码。
再使用 F11 单步调试,发现可以正常进入到 is_available 函数的内部实现
这里是想说明单步调试进入内部实现存在限制:必须是我们可以直接跳转过去的函数,而不能有多个定义。比如我们日常想查看 torch.rand 函数时,VSCode 会弹出小框表示存在多个定义。所以在调试时,torch.rand 就无法正确跳转进入。(个人理解,如果有解决办法欢迎联系)
C++ 代码调试
前提:安装 CodeLLDB 扩展(vadimcn.vscode-lldb)
先在终端设置 ptrace,允许任意进程调试其他进程
sudo sysctl -w kernel.yama.ptrace_scope=0
修改 .vscode/launch.json 文件,加入 LLDB 调试
|
|
设置断点,这次要在我们的 python 文件和想要查看的 C++ 文件中同时设置。
例如,python 中断点
C++ 中断点
设置好断点后,先在运行和调试中启动 python 调试器
可以看到和之前一样,程序正确地在第四行暂停了
接着切换到 LLDB 调试器,点击启动
这时会有一个弹窗来选择进程,我们输入运行的文件名(test.py)进行搜索,然后选择第二个
可以看到在左下界面中,调用堆栈中多了一个 LLDB: Attach,并且状态是正在运行
此时我们切换回 Python 调试器,选择继续
此时可以观察到调用堆栈中 LLDB: Attach 的状态变为:因 BREAKPOINT 已暂停。
我们切换到 C++ 文件中查看,可以看到断点处有黄色阴影。(至于为什么左边那个点还是红色的,我觉得可能是 bug,不影响调试)
将调试器切换回 LLDB,即可正常地在 C++ 中调试。
下图是逐过程一步之后的结果,左下角调用堆栈中可以正常显示函数的调用情况
本站不记录浏览量,但如果您觉得本内容有帮助,请点个小红心,让我知道您的喜欢。