TVM是Python与C++混合编程,通常在Python层提供相关接口,在C++层进行具体实现,兼具灵活与性能。C++代码被编译为动态链接库,在运行时调用。这样给调试带来了不方便,想要调试C++代码就不能通过直接打断点的方式,需要有特殊的处理。本文分享在TVM与VTA的FSIM之间进行python和C++混合调试的方法(其他组件也一样的步骤),使用Vscode实现,亲测有效,整个配置时间大概1小时左右。

编译debug版本的TVM

注意:这里编译之类操作不要在Vscode的终端下操作,直接在Linux的终端下操作,否则安装了一些奇怪的插件后,Vscode在编译时自做主张加东西,可能导致之后的配置失败。

首先删除build目录下除config.cmake以外的所有文件及文件夹。

config.cmake设置以下两个选项,其他默认不变。(本文的目的是调试VTA的FSIM,如果有其他需要,打开对应开关即可,后续步骤通用)

set(USE_LLVM ON)  #启用LLVM,如果没安装LLVM需要安装,参照下文
set(USE_VTA_FSIM ON) #启用VTA的快速仿真器

tvm/build目录下,执行

cmake -DCMAKE_BUILD_TYPE="Debug" ..

make -j8

编译完成后在build目录下出现以下三个文件说明编译成功

libtvm_runtime.so
libtvm.so
libvta_fsim.so #不使用vta的fsim则没有这个文件

安装VsCode扩展

直接通过扩展中心在线安装

  • Python
  • Python Extension Pack
  • C/C++ Extension Pack
  • FFI Navigator

img

通过文件方式安装

Code LLDB(在线安装的话需要下载的东西下载不上)

https://github.com/vadimcn/vscode-lldb/releases 下载对应平台的安装包

img

img

在终端中安装

ffi-navigator

该插件可以实现在python端右键后点击 转到定义 ,直接跳转到与该Python目标关联的C++实现上。

pip install ffi-navigator   #最好在tvm对应的conda环境下安装,记住安装的python地址

设置该python地址。在ffi-navigator扩展设置中,填写安装了ffi-navigator的python的绝对路径(比如我安装给conda中名为tvm的环境,那么这里就设置tvm环境中python的绝对路径)

img

配置VsCode

TVM目录下有一个.vscode文件夹(没有则新建),这里是vscode的运行配置文件,下面提到的文件如果没有就新建,如果有就修改。

launch.json

{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"justMyCode": true,
"preLaunchTask": "myShellCmd"
},
{
"type": "lldb",
"request": "attach",
"name": "Attach-TVM",
"pid": "${command:pickMyProcess}"
}
]
}

tasks.json

{
"version": "2.0.0",
"tasks": [
{
"label": "myShellCmd",
"type": "shell",
"command":"echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope"
}
]
}

c_cpp_properties.json

{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/include"
],
"defines": [],
"compilerPath": "/usr/local/bin/clang",
"cStandard": "c17",
"cppStandard": "c++14",
"intelliSenseMode": "linux-clang-x64",
"compileCommands": "${workspaceFolder}/build/compile_commands.json",
"configurationProvider": "ms-vscode.makefile-tools"
}
],
"version": 4
}

最终配置文件如下:(settings.json文件不用管)

img

调试

在处理完以上配置后,重启Vscode,之后可以进行Python与C++混合的调试。即在Python与C++文件都可以打断点,在Python文件启动程序后,在C++中的断点也会停下。

示例:

1.在tvm/vta/tutorials/vta_get_started.py设置断点,如下

img

2.在tvm/3rdparty/vta-hw/src/sim/sim_driver.cc中设置断点

img

3.在tvm/vta/tutorials/vta_get_started.py启动python debug器。

img

这里会要求输入root密码,在这个界面输入root密码

img

4.在python断点处停下后,需要获取当前进程的pid,步骤如下。

在调试控制台先后输入(输入一条指令回车一次)

import os

os.getpid()

img

会显示一个pid,复制该pid

img

5.启动C++调试器。在这个debug选择器下拉选择Apache TVM。点击运行,会弹出来一个输入框,粘贴刚才的pid号,并选择出现的进程。

img

img

6.此时C++ 调试器也启动。注意取消勾选这两个断点,否则会跳转到汇编中去。

img

7.继续运行直到停到C++断点处,如图。此时C++中的断点也被捕获。可以单步调试C++中sim的执行流程。

img

LLVM安装

# 安装依赖
apt install -y cmake build-essential ninja-build git

# 下载源码并选择版本
git clone https://github.com/llvm/llvm-project.git

cd llvm-project

git checkout llvmorg-14.0.2 #可选择其他tag的版本

# 编译安装
mkdir build && cd build

cmake -G Ninja -DCMAKE_BUILD_TYPE="Release" -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" ../llvm

ninja && ninja install -j4

ninja install

# 检测版本, 测试成功
llvm-as --version
clang --version