
分析对象OpenUCX tagv1.19.0分析日期2026-08-041. UCX v1.19.0 CUDA 依赖1.1. CUDA 编译/运行依赖1.1.1 启用开关配置选项说明--with-cuda[DIR]启用 CUDA 支持并指定 CUDA Toolkit 路径默认guess自动探测--without-cuda显式禁用 CUDA--with-gdrcopy[DIR]启用 GDR COPYGPUDirect RDMA 低延迟拷贝支持--with-iodemo-cuda为io_demo测试程序添加 CUDA 支持1.1.2 configure 检查项config/m4/cuda.m4中的UCX_CHECK_CUDA会依次检查组件头文件库符号检查是否必须CUDA Drivercuda.hlibcudacuDeviceGetUuid是CUDA Runtimecuda_runtime.hlibcudartcudaGetDeviceCount是NVMLnvml.hlibnvidia-mlnvmlInit是NVCC—nvcc可执行文件否仅影响部分测试/示例编译CUDA Static Runtime—libcudart_static否注意NVML 是硬性要求。若显式使用--with-cuda但找不到nvml.h或libnvidia-mlconfigure会直接报错。1.1.3 构建产物模块产物路径UCT CUDAlibuct_cuda.sosrc/uct/cuda/UCM CUDAlibucm_cuda.sosrc/ucm/cuda/perftest CUDAlibucx_perftest_cuda.sosrc/tools/perf/cuda/GDR COPYlibuct_cuda_gdrcopy.sosrc/uct/cuda/gdr_copy/CUDA 传输组件包括cuda_copyHost↔Device、Device↔Device 数据拷贝cuda_ipc同一节点 GPU 间通过 CUDA IPC 共享内存gdr_copyGPUDirect RDMA 低延迟拷贝需单独安装 gdrcopy1.1.4 最低 CUDA 版本推断源码中多处使用CUDA_VERSION/CUDART_VERSION做条件编译特性宏检查所需 CUDA 版本cudaMallocAsync/cuMemAllocAsync钩子CUDA_VERSION 11020/CUDART_VERSION 11020CUDA 11.2cudaTypedefs.h、部分 fabric handle 类型CUDA_VERSION 11070CUDA 11.7cuCtxGetId上下文有效性检查CUDA_VERSION 12000CUDA 12.0nvmlDeviceGetGpuFabricInfo新 API测试CUDA_VERSION 12050CUDA 12.5结论UCX v1.19.0 的核心 CUDA 代码可在较老版本 CUDA 上编译但新特性CUDA Fabric Handle / MNNVL / Grace 主机内存需要CUDA 11.7部分功能需CUDA 12.0 / 12.5。官方 CI 脚本buildlib/az-helpers.sh显示当前使用CUDA 12.8进行验证。1.1.5 包依赖RPMucx.spec.in中ucx-cuda子包包含libuct_cuda.so.*、libucm_cuda.so.*、libucx_perftest_cuda.so.*ucx-gdrcopy依赖ucx-cuda。DEBdebian/ucx-cuda.install、debian/ucx-gdrcopy.install包含对应模块。1.1.6 常用构建命令# 自动探测 CUDA默认./contrib/configure-release--prefix/opt/ucx# 显式启用并指定 CUDA 路径./contrib/configure-release--prefix/opt/ucx\--with-cuda/usr/local/cuda\--with-gdrcopy/usr/local/gdrcopy# 完全禁用 CUDA./contrib/configure-release--prefix/opt/ucx --without-cuda1.2. UCX v1.19.0 是否仍会 Hook CUDA 库结论是的UCX v1.19.0 仍然会通过 UCMUnified Communication Memory对 CUDA Driver API 和 CUDA Runtime API 进行 Hook。1.2.1 Hook 实现位置核心实现文件src/ucm/cuda/cudamem.csrc/ucm/cuda/cudamem.h1.2.2 被 Hook 的 CUDA 函数CUDA Driver API分配类释放类cuMemAlloccuMemFreecuMemAlloc_v2cuMemFree_v2cuMemAllocManagedcuMemFreeHostcuMemAllocPitchcuMemFreeHost_v2cuMemAllocPitch_v2cuMemUnmapcuMemMapcuMemFreeAsyncCUDA 11.2cuMemAllocAsyncCUDA 11.2cuMemAllocFromPoolAsyncCUDA 11.2cuModuleGetGlobal_v2CUDA Runtime API分配类释放类cudaMalloccudaFreecudaMallocManagedcudaFreeHostcudaMallocPitchcudaFreeAsyncCUDA 11.2cudaMallocAsyncCUDA 11.2cudaMallocFromPoolAsyncCUDA 11.2cudaGetSymbolAddress1.2.3 Hook 机制ucm_cudamem_install()会依次尝试两种 Hook 方式Bistro二进制指令级插桩用于 CUDA Driver API通过ucm_bistro_patch()修改目标函数入口指令即使 CUDA Runtime 被静态链接到应用中也能拦截 Runtime 对 Driver API 的调用RelocELF 重定位表修改用于 CUDA Driver API 和 CUDA Runtime API通过ucm_reloc_modify()修改动态链接重定位表如果应用静态链接了 CUDA Runtime可能会漏掉部分内存事件默认启用策略src/ucm/util/sys.c.cuda_hook_modes#ifUCM_BISTRO_HOOKSUCS_BIT(UCM_MMAP_HOOK_BISTRO)|#endifUCS_BIT(UCM_MMAP_HOOK_RELOC),即如果平台支持 Bistro则同时启用 Bistro Reloc否则只启用 Reloc。1.2.4 运行时配置通过环境变量UCX_MEM_CUDA_HOOK_MODE可以控制 Hook 模式src/ucs/config/ucm_opts.c模式说明none不设置 CUDA Hookreloc通过 ELF 重定位表设置 Hook对静态链接 CUDA Runtime 的应用可能漏事件bistro通过二进制指令级插桩设置 Hook可拦截静态链接应用对 Driver API 的调用UCX_MEM_CUDA_HOOK_MODE是位图类型可同时指定多个模式例如UCX_MEM_CUDA_HOOK_MODEbistro,reloc。1.2.5 Hook 触发的事件CUDA 内存 Hook 会向上层派发两类 UCM 事件UCM_EVENT_MEM_TYPE_ALLOCCUDA 内存分配事件UCM_EVENT_MEM_TYPE_FREECUDA 内存释放事件这些事件被 UCS 内存类型缓存memtype cache等模块消费用于自动识别指针是否为 GPU 内存避免重复的内存属性查询支持 RMA / Rendezvous 协议正确选择传输路径1.2.6 历史背景与兼容性UCX 早期版本曾因 CUDA Hook 导致部分 NVIDIA GPU 应用出现兼容性问题尤其是应用静态链接 CUDA Runtime 时。从后续版本开始UCX 引入了Bistro Reloc 双模式以及UCX_MEM_CUDA_HOOK_MODE配置项允许用户按需关闭或调整 Hook 行为。在 v1.19.0 中相关代码仍然完整保留并默认启用说明 CUDA Hook 仍是 UCX GPU 内存感知的核心机制。1.3. 综合结论UCX v1.19.0 构建 CUDA 支持需要CUDA Toolkitcuda.h、cuda_runtime.h、-lcuda、-lcudart以及 NVIDIA 驱动的 NVMLnvml.h、-lnvidia-ml。UCX v1.19.0 仍然 Hook CUDA 库通过src/ucm/cuda/cudamem.c对 CUDA Driver API 和 CUDA Runtime API 的内存分配/释放函数进行 Hook默认启用 Bistro Reloc 双模式。Hook 可被关闭或调整通过环境变量UCX_MEM_CUDA_HOOK_MODEnone可完全禁用使用reloc或bistro可单独选择模式。2. UCX v1.19.0 x86 平台下 Bistro 与 Reloc CUDA Hook 对比分析分析对象OpenUCX tagv1.19.0分析日期2026-08-04问题在 x86 平台上UCX v1.19.0 默认对 CUDA 内存分配/释放同时使用Bistro和Reloc两种 Hook 模式。问题是否可以只启用Reloc关闭Bistro如果关闭 Bistro仅使用 Reloc能否达到与两者同时启用相同的目的简短结论问题结论能否只启用 Reloc可以。通过环境变量UCX_MEM_CUDA_HOOK_MODEreloc即可。是否能达到相同目的不能 100% 等价。对动态链接 CUDA Runtime 的应用基本等价但对静态链接 CUDA Runtime的应用Reloc 可能漏掉部分 CUDA 内存事件。2.1. 两种 Hook 模式的实现机制2.1.1 Bistro二进制指令级插桩实现文件src/ucm/bistro/bistro_x86_64.c原理直接修改目标函数入口处的机器指令插入一条跳转到 Hook 函数的指令。特点不依赖 ELF 重定位表。只要调用者执行到被 Hook 函数的入口地址就会被拦截。即使 CUDA Runtime 被静态链接进应用只要它调用的是动态库libcuda.so中的 Driver API 函数入口就能被拦截。x86_64 补丁形式优先使用 5 字节的相对跳转JMP rel32。若 Hook 函数距离超过 32 位范围则使用 12 字节的movabs %rax, addr; jmp *%rax。2.1.2 RelocELF 重定位表修改实现文件src/ucm/util/reloc.c原理修改动态库的.got/.plt等重定位表将对外部符号如cuMemAlloc的解析结果指向 Hook 函数。特点只影响通过动态链接解析的符号引用。对动态链接的libcudart.so和libcuda.so有效。若 CUDA Runtime 被静态链接到应用中且应用绕过动态重定位直接调用 Driver API例如通过dlsym或链接时解析的地址则可能无法被拦截。2.2. 默认行为与配置方式2.2.1 默认启用策略src/ucm/util/sys.cucm_global_config_tucm_global_opts{....cuda_hook_modes#ifUCM_BISTRO_HOOKSUCS_BIT(UCM_MMAP_HOOK_BISTRO)|#endifUCS_BIT(UCM_MMAP_HOOK_RELOC),...};在 x86 Linux 上config/m4/ucm.m4会检查SYS_mmap等系统调用号。只要这些宏存在就会定义UCM_BISTRO_HOOKS1。因此x86 平台默认同时启用 Bistro Reloc。2.2.2 运行时关闭 Bistro 的方法通过环境变量UCX_MEM_CUDA_HOOK_MODE控制src/ucs/config/ucm_opts.c# 仅使用 Reloc关闭 BistroUCX_MEM_CUDA_HOOK_MODEreloc# 仅使用 BistroUCX_MEM_CUDA_HOOK_MODEbistro# 两者都启用默认UCX_MEM_CUDA_HOOK_MODEbistro,reloc# 完全关闭 CUDA HookUCX_MEM_CUDA_HOOK_MODEnone2.2.3 编译时彻底禁用 Bistro如果希望编译出的 UCX 根本不包含 Bistro 代码可以在不支持 Bistro 的平台上编译或手动修改config/m4/ucm.m4的判定逻辑。但在普通 x86 Linux 上无法通过 configure 选项直接关闭因为UCM_BISTRO_HOOKS是自动根据系统调用是否存在来决定的。2.3. 关闭 Bistro 后的影响2.3.1 CUDA Driver API 的 Hooksrc/ucm/cuda/cudamem.c中安装 Driver API Hook 的逻辑statusucm_cuda_install_hooks(ucm_cuda_driver_funcs,driver,UCM_MMAP_HOOK_BISTRO,driver_api_hooks);...statusucm_cuda_install_hooks(ucm_cuda_driver_funcs,driver,UCM_MMAP_HOOK_RELOC,driver_api_hooks);默认先尝试 Bistro再尝试 Reloc。若设置UCX_MEM_CUDA_HOOK_MODEreloc则 Bistro 步骤会被跳过仅执行 Reloc。结果对动态链接 CUDA Runtime 的应用通常仍然可以正常工作因为libcudart.so调用libcuda.so时会经过重定位表。对静态链接 CUDA Runtime 的应用可能漏掉部分内存分配/释放事件。2.3.2 CUDA Runtime API 的 Hooksrc/ucm/cuda/cudamem.cstatusucm_cuda_install_hooks(ucm_cuda_runtime_funcs,runtime,UCM_MMAP_HOOK_RELOC,runtime_api_hooks);Runtime API只使用 Reloc从不用 Bistro。因此关闭 Bistro 对 Runtime API 的 Hook 没有影响。2.3.3 文档中的明确说明src/ucs/config/ucm_opts.c中对两种模式的描述reloc - Use ELF relocation table to set hooks. In this mode, if any part of the application is linked with Cuda runtime statically, some memory events may be missed and not reported. bistro - Use binary instrumentation to set hooks. In this mode, its possible to intercept calls from the Cuda runtime library to Cuda driver APIs, so memory events are reported properly even for statically-linked applications.这已经明确说明Reloc 无法完全替代 Bistro 在静态链接场景下的能力。2.4. 实际使用建议2.4.1 何时可以安全地只使用 Reloc如果你的应用满足以下条件可以只启用 Reloc应用使用动态链接的 CUDA Runtimelibcudart.so。没有通过dlsym(RTLD_NEXT, cuMemAlloc)等方式绕过 PLT/GOT 直接调用 Driver API。对 CUDA 内存事件的完整性要求不极端允许偶发漏报。2.4.2 何时必须保留 Bistro以下情况建议保留 Bistro默认应用静态链接了 CUDA Runtime。应用或某些第三方库通过dlsym动态获取 CUDA Driver API 地址。需要确保所有 CUDA 内存分配/释放事件都被 UCX 感知以支持 GPU 内存的 RMA/Rendezvous 协议。2.4.3 如果 Bistro 导致兼容性问题在某些环境中Bistro 可能因为以下原因失败目标函数前几条指令无法被ucm_bistro_relocate_one()识别。多线程竞争导致补丁应用失败。某些安全机制如 SELinux、PaX、某些容器环境禁止修改只读代码页。此时可以尝试UCX_MEM_CUDA_HOOK_MODEreloc如果 Reloc 也不能满足需求可以完全关闭UCX_MEM_CUDA_HOOK_MODEnone但关闭后 UCX 将无法自动追踪 CUDA 内存可能影响 GPU 内存的传输优化。2.5. 总结对比项BistroReloc拦截层级函数入口机器指令ELF 重定位表是否需要动态链接否是静态链接 CUDA Runtime可有效拦截 Driver API 调用可能漏事件x86 默认是否启用是是单独使用是否可行是是能否完全替代两者—不能完全替代 Bistro最终答案在 x86 平台上可以通过UCX_MEM_CUDA_HOOK_MODEreloc只启用 Reloc、关闭 Bistro。但这不等价于默认的 Bistro Reloc对动态链接 CUDA Runtime 的应用基本足够对静态链接 CUDA Runtime 的应用可能丢失部分 CUDA 内存事件。如果应用没有静态链接 CUDA Runtime 且没有绕过 PLT/GOT 调用 Driver API则只使用 Reloc 通常可以达到相同目的。