CANN SHMEM 算子代码生成参考体系:从 GUIDE.md 索引到 API 边界与代码模式
【免费下载链接】shmemCANN SHMEM 是面向昇腾平台的多机多卡内存通信库,基于OpenSHMEM 标准协议,实现跨设备的高效内存访问与数据同步。项目地址: https://gitcode.com/cann/shmem
本文以 SHMEM 仓库中shmem-ops-code-genskill 的参考资料入口 GUIDE.md 为主线,梳理该代码生成工作流的六份核心参考资料(API 边界、API 分类、代码模式、AtomicAdd 累加、代码规范、README 规范)与两份跨 skill 辅助索引各自的职责、读取时机和关键技术内容。读完本文,你可以掌握在生成 SHMEM 通信算子或通算融合算子时,如何在正确阶段查阅正确资料,并理解其中沉淀的 API 使用边界、同步模式、累加决策表与交付规范。
一、参考体系定位:一个"按需读取"的资料索引
GUIDE.md 本身并不直接讲解某项技术,而是shmem-ops-code-gen(根据设计文档生成基于 SHMEM 的算子代码、CMake、README 和目录结构)所需的参考资料索引。它用一张"文件 | 用途 | 何时读取"的矩阵规定了每份资料的作用与阅读时机,避免一次性加载全部文档:
| 文件 | 用途 | 何时读取 |
|---|---|---|
| internal-api-boundary.md | 禁止aclshmemi_*、deprecated barrier、quiet 误用 | 代码生成与走读前 |
| api.md | SHMEM API 分类和选择参考 | 选择 lifecycle/memory/transport/sync API 时 |
| code-patterns.md | Host/Device 代码组织模式 | 步骤 4 代码生成时 |
| atomic-add-pattern.md | SetAtomicAdd<T>()累加:安全顺序、边界、风险 | 实现 reduce/累加时 |
| code-style.md | C/C++ 代码规范和审查清单 | 代码生成后审查时 |
| readme-spec.md | 算子 README.md 格式要求 | 生成 README 时 |
| shmem-repo-resolution.md | 定位SHMEM_REPO | 读取仓内 examples/API 前 |
| shmem-repo-docs-index.md | 仓内docs/、include/索引 | API 路径不确定时 |
此外,模板资料独立放在 templates 目录,按生成分支按需读取:纯通信模板见 templates/communication/GUIDE.md(分步读取),通算融合模板见 templates/fused-compute/GUIDE.md(op_kind=fused_compute_comm时使用)。这种"索引 + 分步加载"的设计与 SKILL.md 中的工作流是配套的:skill 明确规定NEVER 一次读完全部模板,每个生成子步骤只读当前分支对应的模板文件。
二、参考体系与五步代码生成工作流的对应关系
SKILL.md 定义了五步工作流:提取设计契约 → 选择模板和参考 example → 制定实现计划 → 渐进式代码生成 → 调用shmem-ops-compile-debug编译验证。GUIDE.md 中各资料的"何时读取"列正是围绕这五步展开的:
- 进入 skill 之前:先按 shmem-repo-resolution.md 定位
SHMEM_REPO(当前工作目录同时存在include/与src/即为仓根,或通过SHMEM_REPO环境变量探测),因为 skill 不一定安装在 SHMEM 仓库内,不能假定用相对路径链到仓内文档。 - 代码生成与走读前:读 internal-api-boundary.md 建立 API 边界意识——哪些接口能用、哪些是 deprecated、quiet 该怎么选。
- 选择 API 时:查 api.md 的接口层次与使用边界速查表。
- 步骤 4 渐进式代码生成:读 code-patterns.md 对齐
main.cpp结构与 kernel 拆分习惯;实现 reduce/累加时加读 atomic-add-pattern.md。 - 代码生成后:用 code-style.md 第 12 节的约 32 项审查清单逐项核对;生成 README 时按 readme-spec.md 的结构填写。
- API 路径不确定时:回查 shmem-repo-docs-index.md 中
${SHMEM_REPO}/docs/、install/shmem/include/、examples/的索引表。
三、API 边界参考:internal-api-boundary.md 的核心约束
internal-api-boundary.md 是新算子(custom-ops)开发的第一道门禁,它把 SHMEM 接口划分为三个层次:
aclshmem_*:标准公开 API;aclshmemx_*:扩展公开 API(MTE/SDMA/RDMA 数据面、mte_quiet等,允许且常用);aclshmemi_*/shmemi_*实现符号:internal,新算子禁止直接调用。
文档明确列出了禁止直接调用的 internal 符号及其替代方案:aclshmemi_barrier_core_soft/aclshmemi_barrier_core应改用AscendC::SyncAll;aclshmemi_copy_ub2gm等 internal 数据面应改用公开的aclshmemx_mte_*/aclshmem_*;aclshmemi_get_state等状态查询不应在算子 kernel 中直接访问。值得注意的是 legacyexamples/中可能仍调用 internal 接口,但禁止照抄到 custom-ops。文档还给出了自动化检测手段:对custom-ops/执行rg 'aclshmemi_'/rg 'shmemi_'(排除注释与 profiling 宏头文件)。
三个高频易错点值得展开:
1. deprecated 接口。aclshmemx_barrier_all_vec和aclshmemx_barrier_vec已标记 deprecated,新代码MUST写aclshmem_barrier_all/aclshmem_barrier;仅对齐既有 legacy example 时可原样保留未改动行。
2. quiet 选型(勿混用):
| API | 范围 |
|---|---|
aclshmem_quiet | 全引擎(MTE + SDMA + UDMA + RDMA) |
aclshmemx_mte_quiet | 仅 MTE |
aclshmemx_sdma_quiet | 仅 SDMA |
aclshmemx_udma_quiet(pe) | 仅 UDMA |
aclshmemx_roce_quiet | 仅 RDMA/RoCE |
纯 MTE put/get 路径MUST NOT用全局aclshmem_quiet代替aclshmemx_mte_quiet。
3. 例外清单。utils/prof/shmemi_prof.h是唯一允许出现的shmemi_*头文件,它提供 Device 侧 cycle profiling 宏(SHMEMI_PROF_*),仅限性能调试使用,默认性能路径禁止常驻 include;宏内部调用的aclshmemi_get_state属 SDK 实现,算子禁止手写等价逻辑。
四、API 分类参考:api.md 的能力地图
api.md 按使用场景梳理 SHMEM 对外接口的能力族,重点说明接口族在系统中的职责、组合方式和边界(不展开逐 API 参数)。它的核心是一张接口层次表:
| 层次 | 标识 / 前缀 | 职责 |
|---|---|---|
| Host 侧 | ACLSHMEM_HOST_API | bootstrap、资源初始化、team 管理、symmetric heap 分配、Host RMA/同步、日志 |
| Device 侧 | ACLSHMEM_DEVICE | PE 查询、RMA 搬运、signal/wait、barrier、quiet/fence、atomic |
| 标准能力 | aclshmem_* | 标准 SHMEM 接口 |
| 扩展能力 | aclshmemx_* | 指定 bootstrap、stream 版本、MTE/SDMA/RDMA engine、profiling/debug |
整个 API 体系的核心前提是各 PE 拥有一致的 symmetric memory 视图:跨 PE 访问、aclshmem_ptr、RMA 目标地址、signal 地址、team 同步数据都依赖该前提。文档将能力划分为六类场景:
- Lifecycle:三种 bootstrap 模式——
ACLSHMEMX_INIT_WITH_DEFAULT(SHMEM 默认控制面)、ACLSHMEMX_INIT_WITH_MPI(借助 MPI 进程组)、ACLSHMEMX_INIT_WITH_UNIQUEID(rank 0 生成aclshmemx_uniqueid_t后经外部机制广播);辅助能力含aclshmemx_init_status、aclshmem_info_get_version/name、aclshmem_finalize、aclshmem_global_exit。PE/Team 查询包括aclshmem_my_pe、aclshmem_n_pes、aclshmem_team_my_pe/n_pes、aclshmem_team_translate_pe,Host 侧另有aclshmem_team_split_strided、aclshmem_team_split_2d、aclshmem_team_destroy。 - Memory:
aclshmem_malloc/calloc/align/free分配 device-side 对称内存;aclshmemx_*变体可指定aclshmem_mem_type_t区分DEVICE_SIDE与HOST_SIDE。关键约束是所有 PE 必须按相同顺序、相同大小分配和释放;非对称分配不会在访问点立刻报错,而是导致远端地址映射错位。aclshmem_ptr(ptr, pe)把本 PE 对称地址转换为远端 PE 的对应地址,但它不是传输原语——拿到远端地址后仍须用 SHMEM put/get/engine API 搬运,禁止裸DataCopy。 - Transport:Device GM2GM 是 kernel 内 GM 到远端 GM 的主要路径,NBI 接口返回后不代表数据完成,需要配套 engine-specific quiet、全局 quiet、barrier、event/flag 或 Host stream 同步;UB2GM(
aclshmem_<type>_get_nbi(__ubuf__ T *dst, __gm__ T *src, ...)等)主要服务通信与计算融合;低层 engine 接口aclshmemx_mte_put_nbi/get_nbi、aclshmemx_sdma_put_nbi/get_nbi(需预留至少 64B UB buffer)、aclshmemx_roce_put_nbi/get_nbi(需大于 128B UB buffer,底层不支持同一 PE 目标上的 RMA/AMO 并发乱序写)用于明确选择数据通路。文档还专门警告:跨 PE 搬运禁用裸DataCopy——即使机内 HCCS/HBM 可达,语义上仍必须使用aclshmem_*或公开aclshmemx_*数据面接口,这样 SHMEM runtime 才能管理拓扑、engine、同步和可见性。 - Sync:
aclshmem_put_signal/put_signal_nbi将数据搬运与 signal 更新合并;aclshmem_signal_wait_until按ACLSHMEM_CMP_EQ/NE/GT/GE/LT/LE等待;aclshmem_barrier(team)对 team/world 集合同步,而aclshmem_sync只保证本地 memory stores 完成,不保证远端 RMA 更新完成。Device barrier 要求 MIX kernel;Host 与 Device 的 barrier 完成域不同(CPU 发起只完成 CPU 通信,NPU 发起只完成 NPU 通信)。 - Atomic:公开 Device atomic 目前集中在六种 atomic add(
aclshmem_int8/16/32_atomic_add、aclshmem_half_atomic_add、aclshmem_bfloat16_atomic_add、aclshmem_float_atomic_add),均为异步接口,读取结果前需 quiet/barrier 等同步。 - Profiling 与 Debug:
SHMEM_LOG_LEVEL、SHMEM_LOG_TO_STDOUT、SHMEM_LOG_PATH环境变量控制日志;Device profiling 以GetSystemCycle为基础,通过SHMEMI_PROF_START/END(frame_id)埋点,Host 侧aclshmemx_get_prof(nullptr, true)打印;Ascend C 调试依赖-enable_ascendc_dump编译开关、AscendC::InitDump、AscendC::DumpTensor与AscendC::printf。
文档末尾的"使用边界速查表"把每个场景按 Host/Device 可用性、symmetric allocation 要求、完成/同步要求四个维度做成一表,是生成代码时最实用的对照工具。
五、代码组织模式:code-patterns.md 的骨架
code-patterns.md 从仓内examples/(如 examples/allgather/allgather_kernel.cpp)中抽取可复用的代码组织与通信骨架。要点包括:
main.cpp固定结构(11 阶段):解析 rank 参数 → ACL 初始化(aclInit、aclrtSetDevice、按需创建aclrtStream)→ 构造aclshmemx_init_attr_t(my_pe、n_pes、ip_port、local_mem_size、option_attr.data_op_engine_type)→aclshmemx_init_attr初始化 → 准备 kernel 辅助参数(Device barrier 需要util_get_ffts_config())→ 分配输入/输出/symmetric buffer(普通 GM 用aclrtMalloc,跨 PE 共享状态、staging、signal flags 用aclshmem_malloc)→ 读取输入 → kernel launch → 完成等待 → 结果写出 → 逆序释放资源。核心原则是:SHMEM 初始化早于 symmetric allocation,所有 kernel 完成后再释放 symmetric buffer,aclshmem_finalize最后。两条硬约束:单进程单 PE(多 PE 由scripts/run.sh启动多个独立进程);复杂 tiling/route/packing 逻辑拆到独立.cpp/.h,main.cpp只做BuildPlan → PrepareInputs → LaunchOp → WriteOutputs编排。禁止main.cppfork/spawn 多 PE 子进程。
put + signal + wait 模式(生产者推数据、消费者按 signal 消费):生产者计算数据范围 → 用 engine put_nbi 或 typed put 写入目标 PE symmetric buffer → 用 event/quiet 保证写入完成 →aclshmemx_signal_op或put_signal更新远端 signal word → 消费者aclshmem_signal_wait_until等待 → 读取数据。signal 值建议带 epoch/magic,多 core 场景按 lane id 隔离 flag offset。
get + local compute 模式(reduce、scatter、KV shuffle 等"本地掌握调度"场景):按 PE/phase/chunk 计算远端地址 →get_nbi拉到本地 GM 或 UB → event/quiet 等待 tile 到达 → 本地做累加/cast/重排 → 写回。其优点是写冲突容易控制:所有累加都在本 PE 本地完成;对 RDMA/SDMA 这类搬运本身不做 reduce 的通路,先 get 到tmp_recv再本地累加回state_symm。
集合通信通用骨架:AllGather 采用"生产阶段只写本 PE staging,消费阶段按 PE 拉取"的读写分离结构,大数据按 chunk 循环并用一半 core 做 staging、另一半轮询 signal 拉取;ReduceScatter 按 phase 调度,远端数据先进tmp_recv或 UB tile,本地累加后只保留本 PE 的 scatter 分片,非 ring 或跨机非均匀调度建议 Host 预生成 per-phase/per-peer range list;AllReduce 由 ReduceScatter + AllGather 组成,关键规范是明确"谁拥有某个 chunk 的写权"。文档同时规定默认 unified single path:禁止未证明收益就维护*_small_data/*_big_data并行实现,size 分支须附 profiling,只有 ≥5% bus_bandwidth 或时延收益才保留。
对称 buffer 生命周期分三类:数据 staging、状态/结果、同步区(signal flags、barrier counters、per-core ready flags)。生命周期建议在aclshmemx_init_attr成功后分配,所有 PE 保持相同分配顺序和大小(即使某 PE 当前 case 不使用某段 buffer),固定 layout 管理 flag 区与数据区,kernel 和 Host 校验全部完成后再aclshmem_free。
六、AtomicAdd 累加决策:atomic-add-pattern.md 的优先级表
atomic-add-pattern.md 是 GUIDE.md 中标注"实现 reduce/累加时"必读的资料。它首先区分 SHMEM Device 侧的两类 atomic add 机制:
| 类型 | 机制 | 操作对象 | 数据规模 |
|---|---|---|---|
| 标量 atomic | aclshmemx_mte_atomic_add等引擎 API 对远端对称地址做标量加法 | 远端 PE 的__gm__地址 | 单个元素 |
| 批量 atomic | SetAtomicAdd<T>()切换当前 core 的 GM 写入模式,后续 MTE3 写入(如mte_get_nbi目的端)自动变为D += src | 本地GM 地址 | tile 级别 |
SetAtomicAdd<T>()不是"执行一次加法",而是把当前 core 后续的所有 GM 写入切换为 atomic add 模式,真正发生加法的是后续 MTE3 写入;SetAtomicNone()恢复普通覆盖写。三引擎对标情况为:MTE 同时具备标量(aclshmemx_mte_atomic_add,910B/910C 走 MTE2,Ascend950 走 UB + MTE3)与批量两条路径;UDMA 只有标量aclshmemx_udma_atomic_add(dtype 限 int32/uint32/int64/uint64/float,读结果前必须aclshmemx_udma_quiet(pe));RDMA 只有aclshmemx_roce_atomic_add(仅整数 dtype);SDMA 没有 device 侧 atomic add API,必须走 fallback。
SDMA fallback 策略(§4)是"chunk 分拆 + 核间并行 + 核内串行":把本地输出按 offset 切分为互不重叠的 chunk(chunk 数 = 参与的 AIV core 数),不同 core 写不同 chunk 从而核间无冲突可并行;每个 core 内部对 R-1 个 peer 串行执行sdma_get_nbi → UB → AscendC::Add → DataCopy 写回。对比 MTE bulk atomicAdd(peer 维度全部 in-flight、MTE3 硬件累加),SDMA 路径的并发来源退化为 chunk 维度。
最关键的交付级结论是 §12 的决策优先级表(编号小的优先):
| 优先级 | 场景 | 推荐方法 | 并发方式 |
|---|---|---|---|
| 1(首选) | 多 remote source → 同 destination:reduce-scatter / allreduce RS 阶段 | SetAtomicAdd<T>()(MTE 批量)+mte_get_nbi+ 双 barrier | peer 维度全部 in-flight,MTE3 硬件累加 |
| 2 | 单元素远端累加(signal/flag/counter) | shmem_*_atomic_add(标量,自动按 topo 分发 MTE/UDMA) | 逐元素调用,各自独立 |
| 3 | 跨 PCIE/SIO 单元素远端累加 | aclshmemx_udma_atomic_add+aclshmemx_udma_quiet | 逐元素,需 quiet 同步 |
| 4 | MTE 不可用时多 PE reduce | SDMA fallback:chunk 分拆,核间并行/核内串行 | chunk 维度并行,peer 维度串行 |
| 5 | 单 remote source 或无远端传输 | UB get →AscendC::Add→ DataCopy 写回 | 无并发需求 |
SKILL.md 的 P0 阻断级检查将此表落实为硬性要求:reduce-scatter/allreduce 的 RS 阶段MUST使用SetAtomicAdd<T>()+mte_get_nbi,禁止以串行 UB 累加作为交付路径。即使没有跨 PE 写冲突,多 source 聚合也 SHOULD 优先 MTE 批量 AtomicAdd——UB 累加路径会把 R-1 个远端 source 的 get 强制串行化(每轮必须先 get 到 UB、AscendC::Add、再释放 UB 给下一轮),而批量模式下所有 peer 的 get 可全部 in-flight。
安全调用顺序(§6.1)同样不可省略任何一步:aclshmem_barrier_all()(workspace 就绪)→SetAtomicAdd<T>()→PipeBarrier<PIPE_ALL>()→ 遍历 remote rank 发mte_get_nbi(跳过 self rank)→FinalizeBlockLoop()等 copy event →SetFlag<MTE3_S>/WaitFlag<MTE3_S>drain MTE3(必选)→SetAtomicNone()→PipeBarrier<PIPE_ALL>()→ 第二个aclshmem_barrier_all()。若在还有 in-flight MTE3 写时提前SetAtomicNone(),后续完成的写入会退化为覆盖写而丢失累加。§10 的风险表还列出一条容易忽略的反模式:atomic 区间内混入普通 DataCopy 写 GM,该次写入也会变成 atomic add,破坏预期值。
七、交付质量约束:code-style.md 与 readme-spec.md
code-style.md 定义代码规范,GUIDE.md 将其定位在"代码生成后审查时"读取。其要点可归纳为五组:
错误处理(§1):必须用宏做错误检查(ACL_CHECK、ACL_CHECK_WITH_RET、CHECK_SHMEM),禁止裸写if (status != ACL_ERROR_NONE);带return的检查宏只能用于不持有局部资源的代码段,已分配资源后失败必须走统一 cleanup(goto cleanup+ 逆序释放);cleanup 阶段的aclshmem_finalize、aclrtResetDevice、aclFinalize等调用也要检查返回值,推荐用cleanup_ok累计后与主流程ok合并返回。
SHMEM 生命周期(§3.2/§3.4):固定顺序为aclInit → aclrtSetDevice → aclshmemx_init_attr → 业务 → aclshmem_free(逆序)→ aclshmem_finalize → aclrtResetDevice → aclFinalize;释放 symmetric memory 前相关 kernel/RMA/barrier 必须已完成,aclshmem_free必须早于aclshmem_finalize,finalize 后禁止再访问 symmetric pointer。
Device 同步(§6.2):NBI 操作后必须有明确完成路径;单引擎 MTE 用aclshmemx_mte_quiet(),多引擎混用或收尾阶段才用aclshmem_quiet();新代码 phase 同步MUST用aclshmem_barrier_all()/aclshmem_barrier(team)。
格式与命名(§0.1/§4):4 空格缩进、单行不超过 120 列、指针左对齐int *ptr;变量名必须体现单位(*_bytes、*_elems);常量统一kPascalCase,全大写只留给宏;所有.cpp/.h/.py/.sh交付文件必须带 CANN Open Software License 头。
CMake 与脚本(§10):优先 target-scoped 的target_include_directories/target_compile_options/target_link_libraries,禁止全局link_libraries()污染其他 target;依赖通过ASCEND_HOME_PATH/SHMEM_HOME_PATH发现,缺失时message(FATAL_ERROR ...)fail fast;run script 用SCRIPT_DIR/PROJECT_ROOT定位工程,多 PE 启动必须在脚本层完成(后台启动 +wait),禁止main.cppfork/spawn。第 12 节的约 32 项审查清单(License 头、include guard、FFTS 设置、UB/event 命名常量、main.cpp边界、target 与设计一致性等)是交付前的逐项核对表。
readme-spec.md 则约束生成算子的README.md:必须包含算子介绍、环境要求、目录结构、参数说明(PE_SIZE、FIRST_NPU、IP_PORT、shape、dtype、engine 等表格)、编译项目、运行算子、生成数据、验证结果、性能采集、注意事项九个 section;命令必须能与实际CMakeLists.txt、scripts/run.sh、gen_data.py、check_result.py对上,禁止只写"按需修改参数"而不给可执行示例;README 不得写未测量的性能结论,没有采集时只写明采集入口和当前状态;必须说明scripts/run.sh启动多个独立进程、main.cpp单进程单 PE 不负责启动多 PE。
八、两份跨 skill 辅助索引
GUIDE.md 最后两行链接的辅助资料来自其他 skill 的 references 目录,解决"从哪里读真源"的问题:
shmem-repo-resolution.md规定读取仓内 examples/API 前必须定位SHMEM_REPO,因为 skill 工具链可能安装在~/.cursor/skills/、独立 git 仓等与 SHMEM 仓库不同的位置,禁止用../../../docs/之类的相对路径假定 skill 与仓同根。定位顺序为:已记录的phase0_intake.shmem_repo→ 当前工作目录同时存在include/与src/→ 当前目录下的shmem/子目录 →SHMEM_REPO环境变量,均失败则询问用户;验证命令是test -d "${SHMEM_REPO}/include" && test -d "${SHMEM_REPO}/src"。该文档还要求区分SHMEM 仓原生路径(docs/、examples/、include/、install/set_env.sh,Read 真源文件)与custom-ops 交付树(${SHMEM_REPO}/custom-ops/<op>/,本工作流生成、非 upstream 自带,以 skill 模板为准);docs/为只读官方文档,Agent 不得修改。
shmem-repo-docs-index.md给出仓内文档与 API 的索引:调试文档(docs/debug/log_debug.md、docs/debug/Troubleshooting_FAQs.md、docs/debug/dump_debug.md、docs/debug/profiling.md);API 与原理(docs/api/env_vars_intro.md、docs/api/atomic_api_sync_async_comparison.md、docs/quickstart.md);构建后install/shmem/include/头文件是 API 参考真源;以及 examples/ 下各示例的用途(如examples/allgather/allgather_kernel.cpp展示 sender/receiver 分核与 per-chunk signal)。文档还内置了aclshmemx_init_attr失败的排障路径:export SHMEM_LOG_LEVEL=DEBUG、SHMEM_LOG_TO_STDOUT=1重跑,然后 grep 日志中的fail|error|address in use|bootstrap,按"端口被占 → 清理进程/动态SHMEM_UID_SESSION_ID"、"local size diffs → 各 PElocal_mem_size一致"等映射定位根因。
九、按 GUIDE 工作的一次典型资料读取路径
综合以上各份资料,一次典型的算子代码生成遵循的资料读取路径是:
- 定位仓库:按 shmem-repo-resolution.md 确认
SHMEM_REPO,此后所有仓内路径都写为${SHMEM_REPO}/<路径>; - 建立边界:读 internal-api-boundary.md,明确只用
aclshmem_*/aclshmemx_*,quiet 按引擎选型,barrier 不用 deprecated 的_vec变体; - 选 API:对照 api.md 的边界速查表确定 lifecycle/memory/transport/sync 的具体接口与完成路径;
- 写代码:按 code-patterns.md 组织
main.cpp与 kernel 文件,选择 put+signal+wait 或 get+local compute 骨架;涉及跨 PE 累加时按 atomic-add-pattern.md §12 优先级表选型,并严格执行 §6 安全顺序(含 MTE3 drain 与双 barrier); - 自检:用 code-style.md §12 审查清单逐项核对,再按 readme-spec.md 的结构生成 README;
- 编译验证:将代码交给
shmem-ops-compile-debug构建,遇到初始化/日志问题回查 shmem-repo-docs-index.md 的排障表。
这套"索引优先、分步读取、每份资料绑定明确读取时机"的组织方式,配合 SKILL.md 中 P0/P1/P2 三级 MUST 检查(目录结构、CMake target-scoped、跨 PE 传输接口、返回值检查、License 头等),共同保证了生成代码在 API 边界、同步语义、累加正确性和交付完整性上可逐项审计。对需要在此仓库基础上开发 SHMEM 通信算子的读者而言,直接从这份 GUIDE.md 索引切入各参考文档,是比通读全仓源码更高效的路径。
【免费下载链接】shmemCANN SHMEM 是面向昇腾平台的多机多卡内存通信库,基于OpenSHMEM 标准协议,实现跨设备的高效内存访问与数据同步。项目地址: https://gitcode.com/cann/shmem
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考