在 Vortex FPGA 加速器上运行 PyTorch ResNet18 模型一、背景与前提条件硬件与驱动准备(需提前完成)二、端到端调用流程三、操作步骤1、创建目录2、设置环境变量3. 直接通过 XDMA 驱动启动内核(底层验证)3.1、生成代码3.2、编译3.3、生成可执行内核(向量加法)3.4、执行测试4. 构建 Vortex 驱动插件 `libvortex-xdma.so`4.1、生成驱动源码 `vortex.cpp`4.2、编译驱动动态库5. 编译 POCL(启用 Vortex 后端)5.1、下载并切换分支5.2、应用必要补丁5.3、打补丁5.4、编译安装 POCL6. 编译 pytorch_dlprim(OpenCL 后端适配)6.1、下载并准备代码6.2、应用补丁6.3、打补丁6.4、编译 pytorch_dlprim7. 完整环境变量配置8. 验证:运行小型 PyTorch 模型9. 最终目标:运行 ResNet18 推理9.1、生成模型推理脚本9.2、误差对比脚本9.3、执行并对比一、背景与前提条件Vortex是一套基于 RISC-V 的通用 GPU 架构,可通过 Vivado 工具综合为 FPGA 比特流,实现可编程的并行计算 IP。本文介绍在已部署好 Vortex 硬件环境的 Ubuntu 主机上,端到端地运行 PyTorch 中的 ResNet18 推理,验证软硬件全栈的正确性。硬件与驱动准备(需提前完成)生成 Vortex IP:使用 Vortex 提供的工具生成带有 AXI 接口的加速器 IP,并连接到 DDR 控制器与 PCIe 端点。生成比特流与烧录:通过 Vivado 编译工程生成.bit文件,烧录到 FPGA。此时 FPGA 会被主机识别为一个 PCIe 设备。安装 XDMA 驱动:在主机侧加载 Xilinx 的 XDMA 内核驱动,为用户态程序提供字符设备(如/dev/xdma0_user、/dev/xdma0_h2c_0、/dev/xdma0_c2h_0),用于访问 Vortex 的寄存器空间以及通过 DMA 读写 DDR 内存。本文后续操作均假定上述环境已就绪。二、端到端调用流程整个软件栈从 PyTorch 到 FPGA 的调用链路如下,每一级均将上层 API 转换为下层可执行的形式:内核启动流程构造参数结构体,参数个数与DDR地址通过 H2C 上传内核代码 输入数据和参数到 DDR配置 DCR 寄存器告知内核地址与参数地址写 AP_START 位到 AP_CTRL轮询 AP_CTRL等待 AP_DONE 置位通过 C2H 回读结果到主机软件栈层次PyTorch张量设备: privateuseonepytorch_dlprimATen算子-OpenCL 内核libOpenCL.soICD 加载器POCL/etc/OpenCL/vendors/pocl.icd加载 libpocl-devices-vortex.solibvortex.soVortex Runtime APIlibvortex-xdma.soVortex XDMA 驱动插件XDMA 字符设备/dev/xdma0_user/dev/xdma0_h2c_0/dev/xdma0_c2h_0FPGA Vortex IPRISC-V 核心 + DDR 内存PyTorch 适配层PyTorch 通过PrivateUseOne机制注册自定义后端。当张量设备类型为privateuseone时,ATen 算子的调用会进入pytorch_dlprim库的实现。pytorch_dlprimpytorch_dlprim将 ATen 算子映射为 OpenCL 内核调用,内部链接并调用系统的 OpenCL 库(/usr/lib/x86_64-linux-gnu/libOpenCL.so)。OpenCL ICD 加载器系统 OpenCL 库根据/etc/OpenCL/vendors/pocl.icd配置文件,动态加载POCL(Portable Computing Language)作为 OpenCL 实现。POCL Vortex 设备插件POCL 通过设备专用动态库libpocl-devices-vortex.so提供对 Vortex 硬件的支持。编译 OpenCL 内核时,POCL 利用环境变量POCL_VORTEX_CFLAGS、POCL_VORTEX_LDFLAGS和POCL_VORTEX_BINTOOL来指定 RISC-V 交叉编译工具链及链接脚本,生成 Vortex 可执行的机器码。Vortex Runtime APIlibpocl-devices-vortex.so调用 Vortex 运行时库libvortex.so,后者提供统一的设备管理、内存分配、内核启停等 API。Vortex 驱动层libvortex.so根据环境变量VORTEX_DRIVER加载具体的驱动插件(本文为libvortex-xdma.so)。该插件通过 XDMA 字符设备与 FPGA 上的 Vortex IP 通信。内核启动流程(硬件视角)在 Vortex 驱动内部,启动一个计算内核会执行以下步骤:构造参数结构体,包含参数个数及各参数在 DDR 上的地址。将内核代码和输入数据通过 H2C 通道(/dev/xdma0_h2c_0)上传到 FPGA 的 DDR。将参数结构体也上传到 DDR 指定位置。配置DCR 寄存器:DCR_STARTUP_ADDR0指向内核代码在 DDR 的地址,DCR_STARTUP_ARG0指向参数结构体地址。向AP_CTRL寄存器写入AP_START位,启动 Vortex 核心。轮询AP_CTRL寄存器,直到AP_DONE位置位,表明执行完成。通过 C2H 通道(/dev/xdma0_c2h_0)将 DDR 中的结果回读到主机内存,并与 CPU 参考结果进行误差比对。三、操作步骤1、创建目录mkdirvortex_torchcdvortex_torch2、设置环境变量exportVORTEX_HOME=/data/vortex_xlen64exportROOT_DIR=$PWD3. 直接通过 XDMA 驱动启动内核(底层验证)本节先绕过所有上层框架,用 C 语言直接操作 XDMA 设备文件,完成一次向量加法的内核调用,验证驱动和硬件通路正常。3.1、生成代码catvortex_demo.c'EOF'#define_GNU_SOURCE#includestdio.h#includestdlib.h#includestring.h#includestdint.h#includeunistd.h#includefcntl.h#includeerrno.h#includetime.h#includestdint.h#includestring.h#includestddef.h#includesys/types.h#includesys/mman.h/* ── Hardware constants ─────────────────────────────────── */#defineDDR_KERNEL_ADDR0x20000/* kernel code in DDR4 */#defineDDR_SRC0_ADDR0x80000000ULL/* src0[] input data */#defineDDR_SRC1_ADDR0x90000000ULL/* src1[] input data */#defineDDR_DST_ADDR0xa0000000ULL/* dst[] output data */#defineDDR_ARG_ADDR0x000B0000ULL/* kernel_arg_t struct */#defineKERNEL_ARG_SIZE32/* sizeof(kernel_arg_t) *//* ── VX_axi_ctrl register offsets (byte) ────────────────── */#defineREG_AP_CTRL0x00#defineREG_DEV_00x10#defineREG_DEV_10x14#defineREG_ISA_00x18#defineREG_ISA_10x1C#defineREG_DCR_00x20#defineREG_DCR_10x24#defineAP_START(10)#defineAP_DONE(11)#defineAP_IDLE(12)#define
在 Vortex FPGA 加速器上运行 PyTorch ResNet18 模型
发布时间:2026/7/5 6:38:53
在 Vortex FPGA 加速器上运行 PyTorch ResNet18 模型一、背景与前提条件硬件与驱动准备(需提前完成)二、端到端调用流程三、操作步骤1、创建目录2、设置环境变量3. 直接通过 XDMA 驱动启动内核(底层验证)3.1、生成代码3.2、编译3.3、生成可执行内核(向量加法)3.4、执行测试4. 构建 Vortex 驱动插件 `libvortex-xdma.so`4.1、生成驱动源码 `vortex.cpp`4.2、编译驱动动态库5. 编译 POCL(启用 Vortex 后端)5.1、下载并切换分支5.2、应用必要补丁5.3、打补丁5.4、编译安装 POCL6. 编译 pytorch_dlprim(OpenCL 后端适配)6.1、下载并准备代码6.2、应用补丁6.3、打补丁6.4、编译 pytorch_dlprim7. 完整环境变量配置8. 验证:运行小型 PyTorch 模型9. 最终目标:运行 ResNet18 推理9.1、生成模型推理脚本9.2、误差对比脚本9.3、执行并对比一、背景与前提条件Vortex是一套基于 RISC-V 的通用 GPU 架构,可通过 Vivado 工具综合为 FPGA 比特流,实现可编程的并行计算 IP。本文介绍在已部署好 Vortex 硬件环境的 Ubuntu 主机上,端到端地运行 PyTorch 中的 ResNet18 推理,验证软硬件全栈的正确性。硬件与驱动准备(需提前完成)生成 Vortex IP:使用 Vortex 提供的工具生成带有 AXI 接口的加速器 IP,并连接到 DDR 控制器与 PCIe 端点。生成比特流与烧录:通过 Vivado 编译工程生成.bit文件,烧录到 FPGA。此时 FPGA 会被主机识别为一个 PCIe 设备。安装 XDMA 驱动:在主机侧加载 Xilinx 的 XDMA 内核驱动,为用户态程序提供字符设备(如/dev/xdma0_user、/dev/xdma0_h2c_0、/dev/xdma0_c2h_0),用于访问 Vortex 的寄存器空间以及通过 DMA 读写 DDR 内存。本文后续操作均假定上述环境已就绪。二、端到端调用流程整个软件栈从 PyTorch 到 FPGA 的调用链路如下,每一级均将上层 API 转换为下层可执行的形式:内核启动流程构造参数结构体,参数个数与DDR地址通过 H2C 上传内核代码 输入数据和参数到 DDR配置 DCR 寄存器告知内核地址与参数地址写 AP_START 位到 AP_CTRL轮询 AP_CTRL等待 AP_DONE 置位通过 C2H 回读结果到主机软件栈层次PyTorch张量设备: privateuseonepytorch_dlprimATen算子-OpenCL 内核libOpenCL.soICD 加载器POCL/etc/OpenCL/vendors/pocl.icd加载 libpocl-devices-vortex.solibvortex.soVortex Runtime APIlibvortex-xdma.soVortex XDMA 驱动插件XDMA 字符设备/dev/xdma0_user/dev/xdma0_h2c_0/dev/xdma0_c2h_0FPGA Vortex IPRISC-V 核心 + DDR 内存PyTorch 适配层PyTorch 通过PrivateUseOne机制注册自定义后端。当张量设备类型为privateuseone时,ATen 算子的调用会进入pytorch_dlprim库的实现。pytorch_dlprimpytorch_dlprim将 ATen 算子映射为 OpenCL 内核调用,内部链接并调用系统的 OpenCL 库(/usr/lib/x86_64-linux-gnu/libOpenCL.so)。OpenCL ICD 加载器系统 OpenCL 库根据/etc/OpenCL/vendors/pocl.icd配置文件,动态加载POCL(Portable Computing Language)作为 OpenCL 实现。POCL Vortex 设备插件POCL 通过设备专用动态库libpocl-devices-vortex.so提供对 Vortex 硬件的支持。编译 OpenCL 内核时,POCL 利用环境变量POCL_VORTEX_CFLAGS、POCL_VORTEX_LDFLAGS和POCL_VORTEX_BINTOOL来指定 RISC-V 交叉编译工具链及链接脚本,生成 Vortex 可执行的机器码。Vortex Runtime APIlibpocl-devices-vortex.so调用 Vortex 运行时库libvortex.so,后者提供统一的设备管理、内存分配、内核启停等 API。Vortex 驱动层libvortex.so根据环境变量VORTEX_DRIVER加载具体的驱动插件(本文为libvortex-xdma.so)。该插件通过 XDMA 字符设备与 FPGA 上的 Vortex IP 通信。内核启动流程(硬件视角)在 Vortex 驱动内部,启动一个计算内核会执行以下步骤:构造参数结构体,包含参数个数及各参数在 DDR 上的地址。将内核代码和输入数据通过 H2C 通道(/dev/xdma0_h2c_0)上传到 FPGA 的 DDR。将参数结构体也上传到 DDR 指定位置。配置DCR 寄存器:DCR_STARTUP_ADDR0指向内核代码在 DDR 的地址,DCR_STARTUP_ARG0指向参数结构体地址。向AP_CTRL寄存器写入AP_START位,启动 Vortex 核心。轮询AP_CTRL寄存器,直到AP_DONE位置位,表明执行完成。通过 C2H 通道(/dev/xdma0_c2h_0)将 DDR 中的结果回读到主机内存,并与 CPU 参考结果进行误差比对。三、操作步骤1、创建目录mkdirvortex_torchcdvortex_torch2、设置环境变量exportVORTEX_HOME=/data/vortex_xlen64exportROOT_DIR=$PWD3. 直接通过 XDMA 驱动启动内核(底层验证)本节先绕过所有上层框架,用 C 语言直接操作 XDMA 设备文件,完成一次向量加法的内核调用,验证驱动和硬件通路正常。3.1、生成代码catvortex_demo.c'EOF'#define_GNU_SOURCE#includestdio.h#includestdlib.h#includestring.h#includestdint.h#includeunistd.h#includefcntl.h#includeerrno.h#includetime.h#includestdint.h#includestring.h#includestddef.h#includesys/types.h#includesys/mman.h/* ── Hardware constants ─────────────────────────────────── */#defineDDR_KERNEL_ADDR0x20000/* kernel code in DDR4 */#defineDDR_SRC0_ADDR0x80000000ULL/* src0[] input data */#defineDDR_SRC1_ADDR0x90000000ULL/* src1[] input data */#defineDDR_DST_ADDR0xa0000000ULL/* dst[] output data */#defineDDR_ARG_ADDR0x000B0000ULL/* kernel_arg_t struct */#defineKERNEL_ARG_SIZE32/* sizeof(kernel_arg_t) *//* ── VX_axi_ctrl register offsets (byte) ────────────────── */#defineREG_AP_CTRL0x00#defineREG_DEV_00x10#defineREG_DEV_10x14#defineREG_ISA_00x18#defineREG_ISA_10x1C#defineREG_DCR_00x20#defineREG_DCR_10x24#defineAP_START(10)#defineAP_DONE(11)#defineAP_IDLE(12)#define