From 92f1dbc2c9b9544b870b247cbdd18096aad51c68 Mon Sep 17 00:00:00 2001 From: Oseltamivir <58582368+Oseltamivir@users.noreply.github.com> Date: Wed, 28 Oct 2026 16:32:33 +0800 Subject: [PATCH 1/2] CollectiveX: keep hwloc's PCI discovery in the bundled aws-ofi-nccl build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bundled hwloc was configured without I/O discovery, so aws-ofi-nccl found no NIC beside any GPU, its RDMA protocol failed to start (topo group size 0), and GIN, which runs only on that protocol, was unavailable: every nccl-ep EP16 case on H100 failed. hwloc now reads the PCI tree through a static libpciaccess (0.16, hash-pinned) linked into the plugin, and a plugin built on the bundled hwloc keys its own cache so the broken build is replaced. 内置 hwloc 曾在关闭 I/O 发现的情况下配置,导致 aws-ofi-nccl 找不到任何 GPU 旁的网卡,其 RDMA 协议无法启动 (拓扑组大小为 0),而 GIN 只能运行在该协议上,因此不可用:H100 上所有 nccl-ep EP16 用例均失败。现在 hwloc 通过静态链接进插件的 libpciaccess(0.16,固定哈希)读取 PCI 树;基于内置 hwloc 构建的插件使用独立缓存键, 以替换此前损坏的构建。 --- collectivex/runtime/common.sh | 2 ++ collectivex/runtime/prepare_backend.sh | 34 +++++++++++++++++++++----- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/collectivex/runtime/common.sh b/collectivex/runtime/common.sh index aff266d5a2..551ce8b46e 100644 --- a/collectivex/runtime/common.sh +++ b/collectivex/runtime/common.sh @@ -57,6 +57,8 @@ COLLX_OFI_NCCL_SHA256="2533d1ec179a86dcf0470fc39800b06cd9169cd854c0c913cc4782a42 # has no runtime hwloc dependency. 2.10.0 is the h100-dgxc hosts' distro version. COLLX_HWLOC_VERSION="2.10.0" COLLX_HWLOC_SHA256="c7fd8a1404a9719c76aadc642864b9f77aed1dc1fc8882d6af861a9260ba240d" +COLLX_PCIACCESS_VERSION="0.16" +COLLX_PCIACCESS_SHA256="84413553994aef0070cf420050aa5c0a51b1956b404920e21b81e96db6a61a27" collx_log_tail() { local log_path="$1" diff --git a/collectivex/runtime/prepare_backend.sh b/collectivex/runtime/prepare_backend.sh index a6c19cf89a..01909dfc7b 100644 --- a/collectivex/runtime/prepare_backend.sh +++ b/collectivex/runtime/prepare_backend.sh @@ -605,18 +605,37 @@ ofi_nccl_ready() { [ -f "$1/.ready" ] && [ -r "$1/lib/libnccl-net-ofi.so" ]; } # Static hwloc for images without its headers (see COLLX_HWLOC_VERSION). ofi_nccl_build_hwloc() { - local root="$1" version="$COLLX_HWLOC_VERSION" tarball + local root="$1" version="$COLLX_HWLOC_VERSION" tarball pciaccess + pciaccess="libpciaccess-$COLLX_PCIACCESS_VERSION" + curl -sSfL --connect-timeout 30 --max-time 300 --retry 3 -o "$root/$pciaccess.tar.gz" \ + "https://www.x.org/releases/individual/lib/$pciaccess.tar.gz" \ + && printf '%s %s\n' "$COLLX_PCIACCESS_SHA256" "$root/$pciaccess.tar.gz" | sha256sum -c --quiet \ + && tar -xzf "$root/$pciaccess.tar.gz" -C "$root" \ + || { collx_log "ERROR: libpciaccess source fetch failed"; return 1; } + ( + cd "$root/$pciaccess" \ + && ./configure -q --prefix="$root/pciaccess" --enable-static --disable-shared --with-pic \ + && make -s -j"$(nproc)" && make -s install + ) >&2 2>&1 || { collx_log "ERROR: libpciaccess build failed"; return 1; } + rm -rf "${root:?}/$pciaccess" "${root:?}/$pciaccess.tar.gz" tarball="hwloc-$version.tar.gz" curl -sSfL --connect-timeout 30 --max-time 300 --retry 3 -o "$root/$tarball" \ "https://download.open-mpi.org/release/hwloc/v${version%.*}/$tarball" \ && printf '%s %s\n' "$COLLX_HWLOC_SHA256" "$root/$tarball" | sha256sum -c --quiet \ && tar -xzf "$root/$tarball" -C "$root" \ || { collx_log "ERROR: hwloc source fetch failed"; return 1; } + # The plugin groups each GPU with its nearest EFA NICs from hwloc's PCI tree, so I/O discovery + # must stay on (without it every group is empty and the RDMA protocol, the only one GIN supports, + # fails to start). hwloc reads the PCI tree through libpciaccess, built static alongside it; the + # GPU-vendor components would only link vendor libraries into the static archive. collx_log "aws-ofi-nccl: building hwloc $version (the image has no hwloc headers)" ( cd "$root/hwloc-$version" \ - && ./configure -q --prefix="$root/hwloc" --enable-static --disable-shared --with-pic \ - --disable-libxml2 --disable-cairo --disable-io --disable-plugins \ + && HWLOC_PCIACCESS_CFLAGS="-I$root/pciaccess/include" \ + HWLOC_PCIACCESS_LIBS="$root/pciaccess/lib/libpciaccess.a" \ + ./configure -q --prefix="$root/hwloc" --enable-static --disable-shared --with-pic \ + --disable-libxml2 --disable-cairo --disable-plugins --disable-libudev \ + --disable-cuda --disable-nvml --disable-opencl --disable-rsmi --disable-levelzero \ && make -s -j"$(nproc)" && make -s install ) >&2 2>&1 || { collx_log "ERROR: hwloc build failed"; return 1; } rm -rf "${root:?}/hwloc-$version" "${root:?}/$tarball" @@ -637,7 +656,7 @@ ofi_nccl_install() { local -a hwloc=() if [ ! -r /usr/include/hwloc.h ]; then ofi_nccl_build_hwloc "$root" || return 1 - hwloc=(--with-hwloc="$root/hwloc") + hwloc=(--with-hwloc="$root/hwloc" LIBS="$root/pciaccess/lib/libpciaccess.a") fi collx_log "aws-ofi-nccl: building $version" ( @@ -660,8 +679,11 @@ ofi_nccl_prepare() { collx_log "aws-ofi-nccl: using the host plugin" return 0 fi - root="$(backend_cache_root ofi-nccl efa "$COLLX_OFI_NCCL_VERSION")" \ - || root="/tmp/collectivex-ofi-nccl-$COLLX_OFI_NCCL_VERSION" + # A plugin built on the bundled hwloc keys its own cache, so a change to that build replaces it. + local variant="$COLLX_OFI_NCCL_VERSION" + [ -r /usr/include/hwloc.h ] || variant+="-hwloc$COLLX_HWLOC_VERSION-pciaccess$COLLX_PCIACCESS_VERSION" + root="$(backend_cache_root ofi-nccl efa "$variant")" \ + || root="/tmp/collectivex-ofi-nccl-$variant" with_cache_lock "aws-ofi-nccl" "$root" ofi_nccl_ready ofi_nccl_install || return 1 export COLLX_OFI_NCCL_LIB_DIR="$root/lib" collx_log "aws-ofi-nccl $COLLX_OFI_NCCL_VERSION ready" From 157db21dc656fdf95faad54b9dfa788b6b407e1f Mon Sep 17 00:00:00 2001 From: Oseltamivir <58582368+Oseltamivir@users.noreply.github.com> Date: Wed, 28 Oct 2026 16:48:27 +0800 Subject: [PATCH 2/2] CollectiveX: carry libpciaccess inside the bundled static hwloc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libtool packed libpciaccess.a into the plugin's convenience archive as an unreadable member, so the aws-ofi-nccl link failed. Its objects now join libhwloc.a, and hwloc's .la is dropped so libtool links the archive as is. libtool 曾把 libpciaccess.a 作为无法读取的成员打包进插件的便利库,导致 aws-ofi-nccl 链接失败。现在其目标文件 并入 libhwloc.a,并删除 hwloc 的 .la,使 libtool 直接链接该静态库。 --- collectivex/runtime/prepare_backend.sh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/collectivex/runtime/prepare_backend.sh b/collectivex/runtime/prepare_backend.sh index 01909dfc7b..8fde1ec655 100644 --- a/collectivex/runtime/prepare_backend.sh +++ b/collectivex/runtime/prepare_backend.sh @@ -638,7 +638,14 @@ ofi_nccl_build_hwloc() { --disable-cuda --disable-nvml --disable-opencl --disable-rsmi --disable-levelzero \ && make -s -j"$(nproc)" && make -s install ) >&2 2>&1 || { collx_log "ERROR: hwloc build failed"; return 1; } - rm -rf "${root:?}/hwloc-$version" "${root:?}/$tarball" + # libtool cannot pass a bare static archive through to a shared plugin, so libpciaccess's objects + # join libhwloc.a and -lhwloc carries both; without hwloc's .la, libtool takes the archive as is. + ( + mkdir "$root/pciaccess/objects" && cd "$root/pciaccess/objects" \ + && ar x ../lib/libpciaccess.a && ar rs "$root/hwloc/lib/libhwloc.a" ./*.o + ) >&2 2>&1 || { collx_log "ERROR: hwloc archive merge failed"; return 1; } + rm -f "$root/hwloc/lib/libhwloc.la" + rm -rf "${root:?}/hwloc-$version" "${root:?}/$tarball" "${root:?}/pciaccess/objects" } ofi_nccl_install() { @@ -656,7 +663,7 @@ ofi_nccl_install() { local -a hwloc=() if [ ! -r /usr/include/hwloc.h ]; then ofi_nccl_build_hwloc "$root" || return 1 - hwloc=(--with-hwloc="$root/hwloc" LIBS="$root/pciaccess/lib/libpciaccess.a") + hwloc=(--with-hwloc="$root/hwloc") fi collx_log "aws-ofi-nccl: building $version" ( @@ -681,7 +688,7 @@ ofi_nccl_prepare() { fi # A plugin built on the bundled hwloc keys its own cache, so a change to that build replaces it. local variant="$COLLX_OFI_NCCL_VERSION" - [ -r /usr/include/hwloc.h ] || variant+="-hwloc$COLLX_HWLOC_VERSION-pciaccess$COLLX_PCIACCESS_VERSION" + [ -r /usr/include/hwloc.h ] || variant+="-hwloc$COLLX_HWLOC_VERSION-pciaccess$COLLX_PCIACCESS_VERSION-merged" root="$(backend_cache_root ofi-nccl efa "$variant")" \ || root="/tmp/collectivex-ofi-nccl-$variant" with_cache_lock "aws-ofi-nccl" "$root" ofi_nccl_ready ofi_nccl_install || return 1