ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CANN SHMEM 编译运行调试指南:从失败定位到日志、Device 调测与 Profiling

CANN SHMEM 编译运行调试指南:从失败定位到日志、Device 调测与 Profiling CANN SHMEM 编译运行调试指南从失败定位到日志、Device 调测与 Profiling【免费下载链接】shmemCANN SHMEM 是面向昇腾平台的多机多卡内存通信库基于OpenSHMEM 标准协议实现跨设备的高效内存访问与数据同步。项目地址: https://gitcode.com/cann/shmem本指南面向在昇腾平台上开发 CANN SHMEM基于 OpenSHMEM 标准的多机多卡内存通信库算子的开发者系统梳理从编译失败到运行时正确性异常的完整排查方法论。文章以失败定位原则为起点依次覆盖编译、链接、初始化、日志、Device 侧 AscendC 调测 API、通信同步、正确性与 Profiling 辅助定位等环节并结合仓库内docs/debug/、examples/、scripts/与src/中的真实实现给出可复现的排查命令和配置参数。读完本文你将掌握一套先定位首个有效错误、再逐层下钻的 SHMEM 算子调试流程。1. 调试总原则先定位首个有效错误失败后不要从日志末尾盲改。SHMEM 相关问题的典型特征是一个根因引发一串连锁错误因此第一原则是找到第一个能解释后续连锁错误的位置并完整记录以下现场信息后再动手修复compile 阶段定位第一个 compiler error而不是最后一个make失败link 阶段定位第一个undefined reference或cannot find -l...launch/runtime 阶段定位第一个 ACL/SHMEM 返回非 0 的调用点correctness 阶段定位第一个 mismatch 的 PE、case、index、actual、expected。记录内容包括command、workdir、env、返回码和首个有效错误。该原则贯穿本文后续所有章节。2. 编译失败排查2.1 常见信号与可能原因信号可能原因检查要点Cannot find ASCEND_HOME_PATH未 source CANN 环境确认scripts/set_env.sh或 CANN Toolkit 的set_env.sh已生效bisheng: command not foundCANN 编译器不可见which bisheng、确认ASCEND_HOME_PATHpython: command not found/ModuleNotFoundErrorPython 环境或依赖不可见确认python3及仓库requirements.txt依赖已安装找不到shmem.hinclude 路径错误独立工程使用$SHMEM_HOME_PATH/shmem/includeexample 使用${PROJECT_SOURCE_DIR}/includeDevice API 在 Host 编译单元报错Host/Device 边界混淆Device kernel 必须使用 CCE 编译选项Host 只调用 wrapperaclshmem_add_*未定义独立工程误用 examples 宏该宏只在 examples/CMakeLists.txt 中定义独立工程需自行编写 CMake 目标catcoc 头文件缺失3rdparty/catlass不存在SHMEM 构建-examples时会尝试拉取 catlass 依赖无网环境需先准备依赖RDMA target 不存在未开启 RDMA 构建使用bash scripts/build.sh -examples -enable_rdmaAscend950 还需-soc_type Ascend950 -rdma_backend XSCALE|HNS_1825说明3rdparty/catlass依赖由 scripts/build.sh 在-examples等选项下自动git clone拉取见 build.sh 中if [ $BUILD_CATLASS ON ]分支。2.2 调试动作确认构建模式是否选对。常用构建选项见 scripts/build.sh-debugDebug 构建、-examples构建算子样例、-enable_ascendc_dump使能 AscendC dump、-enable_rdma/-rdma_backendRDMA 支持、-soc_type Ascend950等可执行bash scripts/build.sh查看完整 usage。对照相近 example 的CMakeLists.txt补齐 include、compile options 和 link target。各 example 的构建规则统一由 examples/CMakeLists.txt 中的aclshmem_add_fusion_example/aclshmem_add_collective_example函数生成独立工程可参照其写法。只改目标 example 或独立工程的 CMake不要先改全局 SHMEM CMake。3. 链接与加载失败排查信号可能原因处理undefined reference to aclshmem...未链接 shmem 库CMake 中加target_link_libraries(target PRIVATE shmem)cannot find -lshmemlink directory 错误指向$SHMEM_HOME_PATH/shmem/liblibshmem.so: cannot open shared object file运行时库不可见source ${SHMEM_REPO}/install/set_env.sh或设置LD_LIBRARY_PATHbootstrap 插件加载失败插件未与libshmem.so同目录同步部署aclshmem_bootstrap_*.so排查命令ldd bin_or_so | grep -E shmem|not found仓库提供的环境脚本 scripts/set_env.sh 会导出SHMEM_HOME_PATH并将$SHMEM_HOME_PATH/shmem/lib、$SHMEM_HOME_PATH/bin加入LD_LIBRARY_PATH/PATH若安装目录存在torch_binding还会追加 kernels 路径可按需 source。4. 启动与初始化失败排查aclshmemx_init_attr返回非 0 时按以下步骤排查开启日志export SHMEM_LOG_LEVELDEBUG SHMEM_LOG_TO_STDOUT1或直接阅读${HOME}/shmem/log/aclshmem_*.log日志详解见第 5 节与 docs/debug/log_debug.md对照 docs/debug/log_debug.md 中的 bootstrap/init 日志阶段表确认卡在哪一阶段重点核对以下初始化前置条件详见 docs/debug/Troubleshooting_FAQs.md所有 PE 的n_pes、rank、ip_port是否一致同一轮多进程是否使用了同一个SHMEM_UID_SESSION_ID端口是否被旧进程占用含长期运行的torch_test_*.py每个 PE 绑定的 device id 是否合理local_mem_size在所有 PE 是否一致且足够容纳 symmetric heapRDMA/SDMA engine 运行前是否已按要求开启对应构建选项。4.1 高频假 FAIL输出全 0 但进程仍 SUCCESS现象checker 报 FAILED输出.bin全 0nz0而输入/golden 非零Host 仍打印[SUCCESS] ... completed on PE X。首要排查查看 shmem 日志默认${HOME}/shmem/log/aclshmem_*.log日志关键字含义处理address in use for bind listen on 127.0.0.1:xxxxtcp store 端口被占用换IPPORT或结束占用进程Memory Heap Not Initializedshmem init 失败但 Host 未检查返回值修环境不要先改 kernelAccStoreServer startup failedbootstrap 未就绪检查IPPORTSHMEM_UID_SESSION_ID是否冲突修复步骤pkill -f torch_test_.*\.py若有长期 Torch 测试或换独立端口重跑 example 的run.sh确认日志无上述 error 后再对比 golden。反模式看到 FAILED 就删SHMEMI_PROF或改 kernel put 逻辑——在 shmem 未初始化时这些改动无效。常见恢复换一个ip_port/SHMEM_UID_SESSION_ID或清理旧进程后重跑先以小 PE、小 shape、默认 engine 跑通再打开 RDMA/SDMA 或增大 shape。4.2 初始化相关的关键环境变量以下变量详见 docs/api/env_vars_intro.mdSHMEM_UID_SESSION_ID直接指定 PE 0 监听 socket 的 ip 和端口。支持ip:port如127.0.0.1:1234、[ipv6]:port、hostname:port三种格式SHMEM_UID_SOCK_IFNAME指定 PE 0 监听 socket 的网口名和网络层协议。支持ifname:inet4|inet6显式指定地址族或仅ifname自动探测优先 IPv4上述两者同时配置时只读取SHMEM_UID_SESSION_ID均未配置时自动搜索可用网口跳过 lo/docker/veth/br-/virbr/tun/tap 等虚拟接口SHMEM_INSTANCE_PORT_RANGE多实例场景指定可用端口范围如SHMEM_INSTANCE_PORT_RANGE1024:2047。default 模式下每个初始化实例独占端口端口被占用期间不支持再次初始化多实例可将ip_port端口设为 0由框架按instance_id自动分配SHMEM_CYCLE_PROF_PEProfiling 采集目标 PE详见第 9 节。4.3 常见初始化根因仓库 FAQ 佐证aclshmem_malloc非对称分配共享内存若各 rank 分配大小不同如(rank_id1)*1024*1024会出现无 error 日志的精度异常。可用 debug 模式复现定位A2/A3 平台执行bash scripts/build.sh -examples -debugAscend950 平台执行bash scripts/build.sh -soc_type Ascend950 -examples -debug随后报错会明确指出非对称共享内存问题。修正方式是保证每个 rank 分配相同大小的共享内存各 PElocal_mem_size不一致使用aclshmemx_set_attr_uniqueid_args时若各 PE 传入不同的local_mem_size日志会提示local size diffs。注意日志显示的实际分配大小与local_mem_size有约 6MB 差异框架内部使用空间且local_mem_size按 2MB 对齐端口被占用 / IP 不可达用netstat -tuln | grep 端口号检查端口调整SHMEM_UID_SESSION_ID与实际执行文件使用的 ip/port。5. 日志调试SHMEM 日志是 Host 侧最主要的定位手段。完整说明见 docs/debug/log_debug.md。5.1 环境变量变量含义默认值SHMEM_LOG_LEVEL日志等级DEBUG / INFO / WARN / ERROR / FATAL严重程度从低到高ERRORSHMEM_LOG_TO_STDOUT是否输出到控制台0关闭1开启0落盘到文件SHMEM_LOG_PATH日志保存路径需为合法路径${HOME}/shmem/log调试时建议export SHMEM_LOG_LEVELDEBUG export SHMEM_LOG_TO_STDOUT1注意开启SHMEM_LOG_TO_STDOUT1后日志将不再落盘到文件。5.2 日志格式每条 SHMEM 日志包含时间、日志级别、进程号、日志模块、日志文件、日志所在行号、日志信息。仓库日志样例见 docs/debug/images/log/0.png。5.3 关键日志阶段阶段日志标志说明bootstrap 初始化bootstrap flag、SHMEM_UID_SESSION_ID检查 flag 类型如ACLSHMEMX_INIT_WITH_DEFAULT和 UID 设置情况网络检测remote address、netifaddrroot 0 是否为回环地址单机 vs 集群单机可回环集群错误bootstrap 完成bootstrap success PE 号确认 PE 正确注册初始化完成init success PE 号SHMEM 就绪去初始化finalize success PE 号正常退出bootstrap 过程中涉及的 socket 信息也会在日志中体现更详细的 socket 信息可通过 debug 级别查看数量较大。5.4 日志接口源码佐证除环境变量外include/host/utils/shmem_log.h 还提供编程式接口aclshmemx_set_log_level(int level)设置日志级别0-debug, 1-info, 2-warn, 3-erroraclshmemx_set_extern_logger(func)注册自定义日志打印函数aclshmemx_show_prof()已废弃与aclshmemx_get_prof(out_profs, verbose)推荐见第 9 节。注意SHMEM 日志主要提供Host 侧定位能力Device 侧报错需配合 AscendC dump 工具定位见第 6 节。6. Device 侧调测AscendC DumpTensor / printfSHMEM 日志只能覆盖 Host 侧Device kernel 内部的打印与 Tensor 内容查看需要借助 AscendC 提供的算子调测 APIDumpTensor / printf。完整示例见 docs/debug/dump_debug.md。6.1 启用方法在 kernel 函数入口增加#if defined(ENABLE_ASCENDC_DUMP)分支调用AscendC::InitDump(false, dump, ALL_DUMPSIZE)。可参考 examples/sdma/main.cpp 中allgather_sdma_tensor的写法在需要调试的位置插入调测 API// 打印变量 AscendC::printf(my_pe%d block%d offset%d\n, my_pe, block_idx, offset); // Dump Tensor 内容 AscendC::GlobalTensorhalf gmT; gmT.SetGlobalBuffer((__gm__ half*)ptr, size); AscendC::DumpTensor(gmT, size, 16); // 每行 16 个元素ALL_DUMPSIZE、aclCheck等宏与接口定义在 examples/utils/debug.h 中ALL_DUMPSIZE默认为75 * 1024 * 102475MB来源于 AscendC host stub 的单核 1MB 上限用户可自定义修改。6.2 编译与运行A2/A3 平台bash scripts/build.sh -examples -enable_ascendc_dump cd examples/sdma bash run.sh -pes 2 -type intAscend950 平台bash scripts/build.sh -soc_type Ascend950 -examples -enable_ascendc_dump从 examples/CMakeLists.txt 可以看到-enable_ascendc_dump会展开为ENABLE_ASCENDC_DUMP、ASCENDC_DUMP1、ASCENDC_DEBUG三个编译宏并链接ascend_dump库各 example 目标还会通过target_compile_definitions单独继承该宏定义。实际运行参数以目标 example 目录下run.sh的支持项为准如-ranks、-pes、-type、-ipport、-gnpus、-fnpu、-frank等可参考 examples/allgather/run.sh 对应的参数解析逻辑。6.3 注意事项dump/printf 代码必须用#if defined(ENABLE_ASCENDC_DUMP)宏保护否则默认构建未开 dump会编译失败性能采集前必须关闭 dump去掉-enable_ascendc_dump重新编译否则 dump 开销会污染性能数据Device 侧 dump 输出配合 Host 侧 log 才能完整定位跨 Host/Device 的问题。7. 通信与同步问题排查多核多 PE 场景下以下高频问题需要优先检查问题现象检查NBI 后无完成路径偶发读旧值或不同 PE 结果不一致是否有 event、quiet、barrier 等完成机制signal 旧值误唤醒repeats 后才失败signal 是否带 epoch/magic复用前是否清零signal slot 冲突多 core 多 peer 偶发错位slot 是否按 rank/core/phase 隔离symmetric allocation 不对称silent data corruption所有 PE 分配顺序和 size 是否一致offset 单位混用tail 或大 shape 错offset_bytes和offset_elems是否混用barrier 完成域误用Host 等不到 Device 内通信完成Host/Device barrier、stream sync 语义是否匹配8. 正确性失败定位正确性失败遵循以下定位顺序修复实现通常回到代码生成环节本指南只做定位与分类确认 checker 本身输入、golden、dtype、shape、PE 数一致用 rank pattern exact case 排除通信错位判断首个 mismatch 属于哪一类错 PE、错 chunk、错 tail、错 dtype cast 还是错同步dump local compute 和通信 buffer用第 6 节的 DumpTensor 手段若 final output 错但中间通信正确定位 compute/finalize 阶段若通信 buffer 已错定位 RMA/sync/schedule 阶段。9. Profiling 辅助定位正确性通过后Profiling 才作为性能依据正确性失败时Profiling 仅用于辅助观察等待或未完成现象。9.1 设置采集目标 PEexport SHMEM_CYCLE_PROF_PE0SHMEM_CYCLE_PROF_PE取值范围[0, PEs-1]取消采集执行unset SHMEM_CYCLE_PROF_PE。9.2 Kernel 内打点在 kernel 中需要测量的位置前后插入SHMEMI_PROF_START(frame_id); // transport / wait / compute SHMEMI_PROF_END(frame_id);宏定义位于 src/device/utils/prof/shmemi_prof.hSHMEMI_PROF_START在pipe_barrier(PIPE_ALL)后通过AscendC::GetSystemCycle()记录起始 cycle 并从累计值中减去SHMEMI_PROF_END在结束 barrier 后累加 cycle 并自增 count。只有采集 PE 匹配device_state-profs-pe_id shmem_my_pe()时才会计数因此不会影响其他 PE。打点示例可参考 examples/allgather/allgather_kernel.cpp。9.3 Host 侧输出在 Host 应用中调用aclshmemx_get_prof(nullptr, true)打印统计结果可参考 examples/allgather/main.cpp。该接口实现在 src/host/init/shmem_init.cpp 中verbosetrue时打印报告out_profs非空时还可编程获取aclshmem_prof_pe_t*数据aclshmemx_show_prof()为已废弃的零参版本。输出样式如下 BlockID FrameID Cycles Count AvgTime(us) ------------------------------------------------------------ 0 0 7506966 34050 4.409 1 0 7485800 34050 4.397 ... 字段含义BlockID为 Device 核 indexFrameID为埋点 IDCycles为系统 cycle 总数Count为执行总次数AvgTime(us)为平均耗时自动由 cycle 换算为微秒精确到三位小数。完整说明见 docs/debug/profiling.md。10. 调试停止条件满足任一条件时应停止本轮调试并上报而非继续盲目修改失败源于 design contract 不可执行需要修改 SHMEM 核心库但 gap analysis 未授权环境阻塞CANN/Python 缺失已询问用户但无法补齐或设备/权限/网络不可用需要用户确认 PE 拓扑、端口、硬件或目标 SOC。附录常用调试命令速查# 1) 开启 SHMEM 详细日志控制台直接输出 export SHMEM_LOG_LEVELDEBUG export SHMEM_LOG_TO_STDOUT1 # 2) 检查动态库依赖 ldd bin_or_so | grep -E shmem|not found # 3) 检查端口占用 netstat -tuln | grep 端口号 # 4) debug 构建 使能 AscendC dumpA2/A3 bash scripts/build.sh -examples -debug -enable_ascendc_dump # 5) Ascend950 平台含 RDMA bash scripts/build.sh -soc_type Ascend950 -examples -enable_rdma -rdma_backend XSCALE -enable_ascendc_dump # 6) 运行 example 并指定 Profiling 采集 PE export SHMEM_CYCLE_PROF_PE0 cd examples/op_name bash run.sh -ranks 2相关文档速查docs/debug/log_debug.md日志、docs/debug/dump_debug.mdDevice 调测 API、docs/debug/profiling.mdProfiling、docs/debug/Troubleshooting_FAQs.md常见问题、docs/api/env_vars_intro.md环境变量全集。【免费下载链接】shmemCANN SHMEM 是面向昇腾平台的多机多卡内存通信库基于OpenSHMEM 标准协议实现跨设备的高效内存访问与数据同步。项目地址: https://gitcode.com/cann/shmem创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表