使用 Docker 容器化 Alveo 加速应用
概述
Docker 之所以如此实用,是因为它可以轻松地从中心位置提取即用型镜像。这些镜像还可以包括 Alveo 加速应用,以将容器内的执行环境与主机解耦。Docker 镜像成为一个可共享的对象,可以重复使用和重新分配,因为容器与主机的隔离为整体解决方案增加了稳健性。不过,必须注意确保主机上安装的镜像和驱动程序是兼容的。
使用 Docker 和 Alveo 运行硬件加速的 FFmpeg 插件
在本文中,我们将重点介绍为 Docker 镜像设置 Alveo 卡,假设您已经安装了 Docker,并且可以访问 Alveo 卡。然后,最关键的一点是确保运行容器的主机具有与应用加速器二进制文件 xclbin 文件兼容的驱动程序版本。实际上,用 Vitis 编译的 xclbin 文件需要一个匹配的赛灵思运行时 (XRT) 版本,这样它才能成功执行。该运行时作为 Docker 镜像的一部分安装,而相应版本的驱动程序必须安装在主机上才能部署应用。
Docker 镜像示例
为了演示如何为 Alveo 加速应用创建 Docker 镜像,我们将使用 FFmpeg 插件的示例在硬件上解压编码的 H.264 比特流。赛灵思 github 网站上描述了此 Alveo 插件架构:https://github.com/Xilinx/FFmpeg-xma.
此插件在 Alveo 卡上实现了几个视频解码器,每个解码器可以处理多个通道,最多 4 个。

FFmpeg API 与赛灵思媒体加速器 (XMA) 和赛灵思运行时 (XRT) 进行交互。在较低级别上,XOCL 和 XCLMGMT(分别是用户和管理物理驱动程序)通过 PCIe 链路访问卡(见下图 2)。有关这些驱动程序、XMA 和 XRT 的更多信息,请参见: https://xilinx.github.io/XRT/2019.2/html/index.html.

现在,我们来创建一个 Docker 镜像以便在容器中运行示例:
第1步:设置 Dockerfile 并装配所有必要的包和源
对于我们的 Dockerfile,首先需要从注册表中提取标准的 Ubuntu 版本。
然后,我们将包含所有支持我们应用的相关 Debian 包的目录复制到镜像上。在我们复制好验证脚本之后,最后我们将 xclbin 复制到镜像上。
FROM ubuntu:16.04
COPY ./ubuntu_pkgs/ /pkgs
RUN apt-get update && \
apt-get install -y libxv1 && \
apt-get install -y ffmpeg && \
apt-get install -y /pkgs/xrt_201910.2.2.2173_16.04-xrt.deb && \
apt-get install -y /pkgs/vyuh264-0.0.1-Linux.deb && \
apt-get install -y /pkgs/xffmpeg-3.4.1-Linux.deb && \
apt-get clean
COPY ./scripts ./scripts
COPY ./h264_xclbin /xclbin
COPY ./sdaccel.ini /opt/xilinx/ffmpeg/bin
注意,ffmpeg 和 libxv1 包是 xffmpeg 包的必需依赖项,需要添加到镜像上。XRT 包可从 Alveo 产品页面获得,例如对于 Alveo U200,包括运行时在内的所有必要包都位于: https://www.xilinx.com/products/boards-and-kits/alveo/u200.html#gettingStarted.
Docker 镜像只需要 XRT 包。
第2步:创建镜像
基于 Dockerfile,我们启动命令来创建和标记(通过 –t 开关)镜像:
docker image build -t imagetest:1.0 .
几分钟后,镜像创建成功。
第3步:找到您的 Alveo 设备
现在,我们可以交互式运行镜像以验证应用是否可以通过主机驱动程序访问 PCIe 链路,我们使用Docker –device 选项从容器访问 PCIe。
我们的测试系统有两个 Alveo 卡,我们需要访问端口信息来确定卡的用户和管理端口。可以通过输入“xbutil scan”来提取该信息(见下图4):

在我们的案例中,我们选择以标识码 [1] 为目标卡,我们确定图 4 中报告底部列出的参数,并通过“docker run”的 –device 选项使用它们来启用 PCIe 访问。
第4步:使用预装的驱动程序在主机上交互式运行镜像
运行下面的命令可以让我们通过外壳访问容器:
docker run -it --rm --name test1 --device=/dev/xclmgmt25856:/dev/xclmgmt25856 --device=/dev/dri/renderD128:/dev/dri/renderD128 imagetest:1.0
我们现在可以在容器中测试 Alveo 卡,“xbutil list”命令确认我们成功映射了相关的卡:

我们现在准备启动应用,将压缩比特流从交互式会话解码到容器中:
ffmpeg -y -c:v VYUH264 -i BigBuckBunny_320x180.mp4 -vsync 0 output.yuv
成功执行后,编码比特流通过 Alveo 加速器进行解码并保存在 output.yuv 文件中。
在启动容器时使用 –device 选项的优势在于,我们可以在没有提升权限的情况下访问卡,但也可以通过简单地挂载卷 (-v) 和使用特权模式 (--privileged) 来运行镜像,如下所示:
docker run -it --rm --name test1 -v /dev:/dev -v /sys/bus/pci/devices/:/sys/bus/pci/devices -v /opt/xilinx/dsa:/opt/xilinx/dsa --privileged imagetest:1.0
结论
Alveo 加速应用可以作为 Docker 镜像交付,正如我们在这个视频解压的 FFmpeg 加速器示例中所说明的那样。
与在主机服务器上直接执行相比,使用 Docker 运行加速应用有几个优势,它允许在可共享的镜像中进行独立的、预先验证的设置,该镜像可通过 Docker Hub 轻松分布。