DOCA DPA 全互联应用指南
本指南介绍了在使用 NVIDIA® BlueField®-3 DPU 中的 DPA 加速时,全互联集体操作的示例。
此参考应用程序展示了如何在数据路径加速器 (DPA) 上加速消息传递接口 (MPI) 全互联集体操作。在 MPI 集体操作中,同一作业中的所有进程都调用集体例程。
给定一个 n 个秩的通信器,应用程序执行一个集体操作,其中所有进程从所有进程发送和接收相同数量的数据(因此称为全互联)。
本文档描述了如何使用 DOCA DPA API 运行全互联示例。
全互联是一种 MPI 方法。MPI 是一种标准化的、可移植的消息传递标准,旨在在并行计算架构上运行。MPI 程序是多个进程并行运行的程序。

图中的每个进程将其本地 sendbuf 分成 n 个块(本例中为 4 个),每个块包含 sendcount 个元素(本例中为 4 个)。进程 i 将其本地 sendbuf 的第 k 个块发送到进程 k,后者将数据放置在其本地 recvbuf 的第 i 个块中。
使用 DOCA DPA 实现全互联方法将元素从 srcbuf 复制到 recvbufs 的操作卸载到 DPA,使 CPU 可以自由执行其他计算。
下图描述了基于主机的全互联和 DPA 全互联之间的差异。

在 DPA 全互联中,DPA 线程执行全互联,而 CPU 可以自由执行其他计算
在基于主机的全互联中,CPU 仍然必须在某个时候执行全互联,并且不能完全自由地进行其他计算
需要 NVIDIA BlueField-3 平台
该应用程序可以在目标 BlueField 或主机上运行。
Open MPI 版本 4.1.5rc2 或更高版本(包含在 DOCA 的安装中)。
有关如何安装 BlueField 相关软件的详细信息,请参阅 DOCA Linux 安装指南。
DOCA 参考应用程序的安装包含应用程序的源代码以及匹配的编译说明。这允许“按原样”编译应用程序,并提供修改源代码,然后编译应用程序新版本的能力。
有关应用程序以及开发和编译提示的更多信息,请参阅 DOCA 参考应用程序 页面。
应用程序的源代码可以在应用程序的目录下找到:/opt/mellanox/doca/applications/dpa_all_to_all/
。
编译所有应用程序
所有 DOCA 应用程序都在单个 meson 项目下定义。因此,默认情况下,编译包括所有应用程序。
MPI 用于此应用程序的编译。确保 MPI 已安装在您的设置中(openmpi
作为 DOCA 安装的一部分提供,作为 doca-all
和 doca-ofed
元包的一部分)。
编译应用程序需要更新 LD_LIBRARY_PATH
和 PATH
环境变量以包含 MPI。例如,如果 openmpi
安装在 /usr/mpi/gcc/openmpi-4.1.7rc1
下,则更新环境变量应如下所示
export PATH=/usr/mpi/gcc/openmpi-4.1
.7rc1/bin:${PATH}
export LD_LIBRARY_PATH=/usr/mpi/gcc/openmpi-4.1
.7rc1/lib:${LD_LIBRARY_PATH}
要一起构建所有应用程序,请运行
cd /opt/mellanox/doca/applications/
meson /tmp/build
ninja -C /tmp/build
doca_dpa_all_to_all
在 /tmp/build/dpa_all_to_all/
下创建。
仅编译 DPA 全互联应用程序
要直接仅构建全互联应用程序
cd /opt/mellanox/doca/applications/
meson /tmp/build -Denable_all_applications=false
-Denable_dpa_all_to_all=true
ninja -C /tmp/build
doca_dpa_all_to_all
在 /tmp/build/dpa_all_to_all/
下创建。
或者,可以在 meson_options.txt
文件中设置所需的标志,而不是在编译命令行中提供它们
编辑
/opt/mellanox/doca/applications/meson_options.txt
中的以下标志将
enable_all_applications
设置为false
将
enable_dpa_all_to_all
设置为true
运行以下编译命令
cd /opt/mellanox/doca/applications/ meson /tmp/build ninja -C /tmp/build
信息doca_dpa_all_to_all
在/tmp/build/dpa_all_to_all/
下创建。
故障排除
有关应用程序编译中遇到的任何问题,请参阅 DOCA 故障排除。
先决条件
MPI 用于运行此应用程序。确保 MPI 已安装在您的设置中(openmpi
作为 DOCA 主机安装的一部分提供,作为 doca-all
和 doca-ofed
元包的一部分)。
运行应用程序需要更新 LD_LIBRARY_PATH
和 PATH
环境变量以包含 MPI。例如,如果 openmpi
安装在 /usr/mpi/gcc/openmpi-4.1.7rc1
下,则更新环境变量应如下所示
export PATH=/usr/mpi/gcc/openmpi-4.1
.7rc1/bin:${PATH}
export LD_LIBRARY_PATH=/usr/mpi/gcc/openmpi-4.1
.7rc1/lib:${LD_LIBRARY_PATH}
应用程序执行
DPA 全互联应用程序以源代码形式提供。因此,在执行应用程序之前需要进行编译。
应用程序使用说明
Usage: doca_dpa_all_to_all [DOCA Flags] [Program Flags] DOCA Flags: -h, --help Print a help synopsis -v, --version Print program version information -l, --log-level Set the (numeric) log level
for
the program <10
=DISABLE,20
=CRITICAL,30
=ERROR,40
=WARNING,50
=INFO,60
=DEBUG,70
=TRACE> --sdk-log-level Set the SDK (numeric) log levelfor
the program <10
=DISABLE,20
=CRITICAL,30
=ERROR,40
=WARNING,50
=INFO,60
=DEBUG,70
=TRACE> -j, --json <path> Parse all command flags from an input json file Program Flags: -m, --msgsize <Message size> The message size - the size of the sendbuf and recvbuf (in bytes). Must be in multiplies of integer size. Default is size of one integer times the number of processes. -pf_devs, --pf-devices <PF device name> PF devices names that supports DPA, separated by comma without spaces (max of two devices). If not provided then a random device will be chosen. -rdma_devs, --rdma-devices <RDMA device names> Device names that supports RDMA, separated by comma without spaces (max of two devices). If not provided then a random device will be chosen.信息此用法打印输出可以使用
-h
(或--help
)选项打印到命令行./doca_dpa_all_to_all -h
注意仅当从目标 BlueField 运行应用程序时,
rdma_devs
标志才可用。信息有关更多信息,请参阅“命令行标志”部分。
在主机上运行应用程序的 CLI 示例
注意这是一个 MPI 程序,因此使用
mpirun
运行应用程序(使用-np
标志指定要运行的进程数)。以下命令使用 8 个进程和默认消息大小(进程数,即 8,乘以 1 个整数的大小)以及随机 InfiniBand 设备运行 DPA 全互联应用程序
mpirun -np
8
./doca_dpa_all_to_all以下命令使用 8 个进程、128 字节的消息大小以及
mlx5_0
和mlx5_1
作为 InfiniBand 设备运行 DPA 全互联应用程序mpirun-np
8
./doca_dpa_all_to_all -m128
-d"mlx5_0,mlx5_1"
注意该应用程序最多支持 16 个进程运行。如果您尝试使用更多进程运行,则会打印错误并且应用程序退出。
该应用程序还支持基于 JSON 的部署模式,其中所有命令行参数都通过 JSON 文件提供
./doca_dpa_all_to_all --json [json_file]
例如
./doca_dpa_all_to_all --json ./dpa_all_to_all_params.json
注意在执行之前,请确保使用的 JSON 文件包含正确的配置参数,尤其是 InfiniBand 设备标识符。
命令行标志
标志类型 | 短标志 | 长标志/JSON 键 | 描述 | JSON 内容 |
通用标志 |
|
| 打印帮助概要 | N/A |
|
| 打印程序版本信息 | N/A | |
|
| 设置应用程序的日志级别
|
| |
N/A |
| 设置程序的日志级别
|
| |
|
| 从输入 json 文件解析所有命令标志 | N/A | |
程序标志 |
|
| 消息大小。sendbuf 和 recvbuf 的大小(以字节为单位)。必须是整数的倍数。默认值是 1 个整数的大小乘以进程数。 |
注意
值 -1 是一个占位符,用于使用默认大小,该默认大小仅在运行时才知道(因为它取决于进程数)。 |
|
| 支持 DPA 的 InfiniBand 设备名称,用逗号分隔,不带空格(最多两个设备)。如果 |
|
有关支持的标志和执行模式的更多信息,请参阅 DOCA 参数解析器。
故障排除
有关 DOCA 应用程序的安装或执行中遇到的任何问题,请参阅 DOCA 故障排除。
初始化 MPI。
MPI_Init(&argc, &argv);
解析应用程序参数。
初始化参数解析器资源并注册 DOCA 常规参数。
doca_argp_init();
注册应用程序的参数。
register_all_to_all_params();
解析参数。
doca_argp_start();
msgsize
参数是 sendbuf 和 recvbuf 的大小(以字节为单位)。它必须是整数的倍数,并且至少是进程数乘以整数大小。pf_devices_param
参数是要使用的 InfiniBand 设备的名称(必须支持 DPA)。它可以包含最多两个设备名称。
仅让第一个进程(秩 0)解析参数,然后将其广播到其余进程。
检查并准备
all_to_all
调用所需的资源检查进程数(最大值为 16)。
检查
msgsize
。它必须是整数大小的倍数,并且至少是进程数乘以整数大小。根据
msgsize
分配 sendbuf 和 recvbuf。
准备使用 DOCA DPA 执行全互联方法所需的资源
警告该应用程序在没有额外安全层的情况下使用 MPI。如本步骤中所述,导出的数据(用于同步事件、RDMA 和 MMAP)应在生产部署中通过安全通道传递。
初始化 DOCA DPA 上下文
打开 DOCA DPA 设备(支持 DPA 的 DOCA 设备)。
open_dpa_devices();
使用打开的设备初始化 DOCA DPA 上下文。
extern struct doca_dpa_app *dpa_all2all_app; doca_dpa_create(pf_doca_device, &pf_doca_dpa); doca_dpa_set_app(pf_doca_dpa, dpa_all2all_app); doca_dpa_start(pf_doca_dpa);
从目标 BlueField 运行时:使用打开的 RDMA 设备初始化扩展 DOCA DPA 上下文。
#ifdef DOCA_ARCH_DPU doca_dpa_device_extend(pf_doca_dpa, rdma_doca_device, &rdma_doca_dpa); #
else
*rdma_doca_device = *pf_doca_device; #endif
为全互联初始化所需的 DOCA 同步事件
内核启动的一个完成事件,其中订阅者是 CPU,发布者是 DPA。
内核事件,由远程对等方发布并由 DPA 订阅,数量与进程数相同。
create_dpa_a2a_events() {
// initialize completion event
doca_sync_event_create(&comp_event); doca_sync_event_add_publisher_location_dpa(comp_event); doca_sync_event_add_subscriber_location_cpu(comp_event); doca_sync_event_start(comp_event);// initialize kernels events
for
(i =0
; i < resources->num_ranks; i++) { doca_sync_event_create(&(kernel_events[i])); doca_sync_event_add_publisher_location_remote_net(kernel_events[i]); doca_sync_event_add_subscriber_location_dpa(kernel_events[i]); doca_sync_event_start(kernel_events[i]); } }
准备 DOCA RDMA 并将其设置为在 DPA 上工作
创建 DOCA RDMA,数量与进程/秩相同。
for
(i =0
; i < resources->num_ranks; i++) { doca_rdma_create(&rdma); rdma_as_doca_ctx = doca_rdma_as_ctx(rdma); doca_rdma_set_permissions(rdma); doca_rdma_set_grh_enabled(rdma); doca_ctx_set_datapath_on_dpa(rdma_as_doca_ctx, rdma_doca_dpa); doca_ctx_start(rdma_as_doca_ctx); }将本地 DOCA RDMA 连接到远程 DOCA RDMA。
connect_dpa_a2a_rdmas();
获取本地 DOCA RDMA 的 DPA 句柄(以便 DPA 内核可以使用它们)并将其复制到 DPA 堆内存。
for
(int
i =0
; i < resources->num_ranks; i++) { doca_rdma_get_dpa_handle(rdmas[i], &(rdma_handles[i])); } doca_dpa_mem_alloc(&dev_ptr_rdma_handles); doca_dpa_h2d_memcpy(dev_ptr_rdma_handles, rdma_handles);
准备使用 DOCA Mmap 执行全互联方法所需的内存。这包括为 sendbuf 和 recvbuf 创建 DPA 内存句柄,获取其他进程的 recvbufs 句柄,以及将这些内存句柄及其远程密钥和事件处理程序复制到 DPA 堆内存。
prepare_dpa_a2a_memory();
使用 DOCA DPA 内核启动和所有必需参数启动
alltoall_kernel
每个 MPI 秩启动一个最多
MAX_NUM_THREADS
的内核。此示例将MAX_NUM_THREADS
定义为 16。使用
kernel_launch
启动alltoall_kernel
。doca_dpa_kernel_launch_update_set();
每个进程应执行
num_ranks
个 RDMA 写入操作,本地和远程缓冲区根据执行 RDMA 写入操作的进程的秩以及要写入的远程进程的秩计算。应用程序遍历远程进程的秩。i每个进程在此内核上运行
num_threads
个线程,因此 RDMA 写入操作的数量(即进程数)除以线程数。每个线程都应等待其本地事件,以确保远程进程已完成 RDMA 写入操作。
for
(i = thread_rank; i < num_ranks; i += num_threads) { doca_dpa_dev_rdma_post_write(); doca_dpa_dev_rdma_signal_set(); }for
(i = thread_rank; i < num_ranks; i += num_threads) { doca_dpa_dev_sync_event_wait_gt(); }警告鉴于协议性质引起的敏感性,RDMA 操作应通过生产部署中的安全通道执行。
等待直到
alltoall_kernel
完成。doca_sync_event_wait_gt();
注意在等待事件后添加 MPI 屏障,以确保所有进程都已完成执行
alltoall_kernel
。MPI_Barrier();
在
alltoall_kernel
完成后,所有进程的 recvbuf 都包含全互联方法的预期输出。
销毁
a2a_resources
释放所有 DOCA DPA 内存。
doca_dpa_mem_free();
销毁所有 DOCA Mmap
doca_mmap_destroy();
销毁所有 DOCA RDMA。
doca_ctx_stop(); doca_rdma_destroy();
销毁所有 DOCA 同步事件。
doca_sync_event_destroy();
销毁 DOCA DPA 上下文。
doca_dpa_destroy();
关闭 DOCA 设备。
doca_dev_close();
/opt/mellanox/doca/applications/dpa_all_to_all/
/opt/mellanox/doca/applications/dpa_all_to_all/dpa_all_to_all_params.json