Skip to content

fix(topo): fill closestNicId for every GPU so the NIC-GPU map is printed - #36

Merged
hwlong66 merged 2 commits into
HYGON-AI:developfrom
bleech243:develop
Sep 30, 2026
Merged

hwlong66 merged 2 commits into
HYGON-AI:developfrom
bleech243:develop

Conversation

@bleech243

Copy link
Copy Markdown
Contributor

背景

rocshmem_info 的 Closest GPU(s) 列在两条路径下都会显示为空:

  • 默认的 OAM 自动拓扑(Mode 2):整列空白
  • ROCSHMEM_TOPO_FILE_FORCE(Mode 1):只有 mlx5_2 -> 0 一格

(ROCSHMEM_DISABLE_AUTOTOPO=1 的 legacy 路径是正常的,可作为对照。)

根因

GetClosestNicToGpu() 是"带缓存的查表函数":第一次调用时构建整张
closestNicId[],之后所有调用都只读该数组并返回 closestNicId[gpuIndex]。

但 Mode 1 / Mode 2 命中后会在 if (!isInitialized) 块内直接 return:

  • Mode 1(forced topo):只写了 closestNicId[gpuIndex] 一格;
  • Mode 2(OAM):结果存在自己的局部静态 OamclosestNicId 里,closestNicId[]
    一格都不写。

于是 isInitialized 置真后,同进程内从第 2 张卡起全部返回 -1。而
PrintNicToGPUTopo() 是"外层遍历网卡、内层遍历 GPU"的反向查询,只比较返回值,
所以整列变空。

说明:库的真实用法是"一个 rank 一块卡、只查一次",第一次返回值本来就是对的,
所以生产路径不受影响;受影响的只有同进程内遍历多卡的自省场景
(rocshmem_info)。

改动

仅 src/gda/topology.cpp,3 处(+38/−30):

  1. GetClosestNicToGpuFromForcedTopo():签名改为
    (closestNicId, gpuIndex, dev_name),去掉 outNicIdx;遍历所有 GPU 从
    topo 文件填整张表(被查询的 GPU 缺失时仍 LOG_ERROR_EXIT,其余仅告警跳过)。
  2. GetClosestNicToGpuFromOam():返回值 int -> void,首参改为
    closestNicId,末尾把主选半段写回该数组;2*numGpus 工作缓冲由 static
    改为局部(顺带消除备选槽可能残留上次调用的值)。
  3. GetClosestNicToGpu():Mode 1 / Mode 2 命中后
    isInitialized = true; return closestNicId[gpuIndex];;Mode 3 跳过已解析的
    GPU(closestNicId[i] != -1 时 continue),只补空缺,避免覆盖 OAM 结果。

原有的注释未做改动。

验证

环境:bw22 / yuji-test-vllm,DTK /opt/dtk,scripts/build_configs/gda_mlx5
构建 build/tools/rocshmem_info。

8 卡,默认(OAM auto-topo)

修改前 修改后
Closest GPU(s) 整列空白 mlx5_2→0, mlx5_3→1, mlx5_5→2, mlx5_4→3, mlx5_6→4, mlx5_7→5, mlx5_9→6, mlx5_8→7

8 卡,ROCSHMEM_TOPO_FILE_FORCE=topo-8gpu.config

修改前 修改后
只有 mlx5_2→0 mlx5_2..mlx5_9 → 0..7

8 卡,ROCSHMEM_DISABLE_AUTOTOPO=1:修改前后逐项一致
(mlx5_0→1, mlx5_2→0, mlx5_3→2, mlx5_4→3, mlx5_6→4, mlx5_7→7, mlx5_8→5, mlx5_9→6),无回归。

调用方式对比:同一进程内遍历 8 张卡,由"仅第 1 张有值"变为 8/8 全部正确;
"一进程一卡"(真实 rank 用法)结果与修改前一致。

4 卡子集:HIP_VISIBLE_DEVICES=0,1,2,3 与 4,5,6,7 输出与 8 卡时对应
GPU 的映射一致。(注:非连续子集如 0,2,4,6 仍会配错,那是
GetOamToGpuMap() 用 KFD 物理序配对、不识别 HIP_VISIBLE_DEVICES 重排的另一个
问题,不在本 PR 范围内。)

风险

  • 不改变解析逻辑,只改变"结果是否写回缓存":单 rank 路径的返回值与修改前相同。
  • Mode 3 增加 continue 后,OAM 已解析的结果不会被 legacy 覆盖;当 OAM 只解析
    出一部分且被查询的卡未解析时,该卡仍会由 legacy 兜底(不会出现"无网卡可用")。

背景:rocshmem_info 的 "Closest GPU(s)" 列在 OAM 自动拓扑和
ROCSHMEM_TOPO_FILE_FORCE 两条路径下都显示为空。GetClosestNicToGpu() 在
Mode 1 / Mode 2 命中后直接 return,只写了被查询 GPU 的那一格(OAM 路径连
一格都不写),而 isInitialized 置真之后所有后续查询都只读 closestNicId[],
于是同一个进程里从第 2 张卡起全部返回 -1。

改动(src/gda/topology.cpp):
- GetClosestNicToGpuFromForcedTopo():签名改为
  (closestNicId, gpuIndex, dev_name),去掉 outNicIdx;遍历所有 GPU 从 topo
  文件填整张表,被查询的 GPU 缺失时仍 LOG_ERROR_EXIT,其余仅告警跳过。
- GetClosestNicToGpuFromOam():返回值 int -> void,首参改为 closestNicId;
  2*numGpus 工作缓冲由 static 改为局部(顺带消除备选槽残留),末尾把主选
  半段写回 closestNicId。
- GetClosestNicToGpu():Mode 1 / Mode 2 命中后
  isInitialized = true; return closestNicId[gpuIndex];Mode 3 跳过已解析的
  GPU(closestNicId[i] != -1 时 continue),只补空缺。

验证(bw22 / yuji-test-vllm,DTK /opt/dtk,gda_mlx5 构建):
- 修改前:默认(OAM auto-topo)整列为空;ROCSHMEM_TOPO_FILE_FORCE 只有
  mlx5_2 -> 0。
- 修改后:默认输出完整的 8 行
  mlx5_2->0, mlx5_3->1, mlx5_5->2, mlx5_4->3,
  mlx5_6->4, mlx5_7->5, mlx5_9->6, mlx5_8->7;
  ROCSHMEM_TOPO_FILE_FORCE 输出 mlx5_2..mlx5_9 -> 0..7;
  ROCSHMEM_DISABLE_AUTOTOPO=1 与修改前逐项一致(无回归)。
- 同进程遍历 8 卡:由"仅第 1 张有值"变为 8/8 全部正确;一进程一卡(真实
  rank 用法)的结果不变。

@hygon-ai-reviewer hygon-ai-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Review

🟢 未发现有明确证据的问题

在已提供并完成审查的 diff 范围内未形成可确认问题。

变更概览

本次变更主要包含:

  • GetClosestNicToGpuFromForcedTopo 由只查询单个 GPU 改为遍历全部 GPU 从强制拓扑文件填充整张 closestNicId 缓存,被查询 GPU 缺失时仍 LOG_ERROR_EXIT,其余缺失仅告警跳过。
  • GetClosestNicToGpuFromOam 返回类型由 int 改为 void,首参改为 closestNicId 数组,以支持将 OAM 解析结果写回缓存。
  • 修复 GetClosestNicToGpu 缓存机制:OAM 与强制拓扑命中路径改为把整张 NIC-GPU 映射写回 closestNicId 数组,使同进程遍历多卡时每张卡都能返回正确网卡而非 -1;OAM 工作缓冲由 static 改为局部消除残留值。
文件审查摘要
文件 变更 审查结果
src/gda/topology.cpp 修改 · +38/-30 —
审查信息
  • 变更统计:1 个文件,+38/-30。
  • 覆盖情况:共 1 个文件,已完整审查 1 个。
  • 候选问题:0 项;证据复核过滤:0 项;发布前敏感信息保护:0 项。
  • 本服务以 GitHub 提供的 PR diff 为审查主体,PR 描述与按相关性选取的仓库片段仅用于核验;未执行代码或重跑测试,结论仍需维护者核验。

@hygon-ai-reviewer hygon-ai-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI Review

🟢 未发现有明确证据的问题

在已提供并完成审查的 diff 范围内未形成可确认问题。

变更概览

本次变更主要包含:

  • 重构 topology.cpp 中强制拓扑与 OAM 两条最近 NIC 解析函数:改为将结果写回整张 closestNicId 缓存表(移除 outNicIdx 参数、OAM 函数改为 void 返回),使同进程遍历多 GPU 时 NIC-GPU 拓扑可完整打印
  • topology.cpp 中 OAM 自动拓扑路径改为把整张最近网卡表写回 closestNicId 缓存,Mode 1/2 命中后置位 isInitialized 并直接返回缓存值,使同进程内后续其他 GPU 的查询不再返回 -1;同时 OAM 工作缓冲由 static 改为局部,避免备选槽残留上次调用的值。
文件审查摘要
文件 变更 审查结果
src/gda/topology.cpp 修改 · +38/-30 —
审查信息
  • 变更统计:1 个文件,+38/-30。
  • 覆盖情况:共 1 个文件,已完整审查 1 个。
  • 候选问题:0 项;证据复核过滤:0 项;发布前敏感信息保护:0 项。
  • 本服务以 GitHub 提供的 PR diff 为审查主体,PR 描述与按相关性选取的仓库片段仅用于核验;未执行代码或重跑测试,结论仍需维护者核验。

@hwlong66
hwlong66 merged commit adce20c into HYGON-AI:develop Sep 30, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants