尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

动手实战:asc-comm CCU样例实现AllGather集合通信算子的完整代码解析

动手实战:asc-comm CCU样例实现AllGather集合通信算子的完整代码解析 动手实战asc-comm CCU样例实现AllGather集合通信算子的完整代码解析【免费下载链接】asc-comm本项目是CANN 推出的昇腾AI处理器面向通算融合场景打造的专属开源仓库屏蔽硬件差异为底层硬件协同与上层通信算法落地提供统一高性能数据面。项目地址: https://gitcode.com/cann/asc-commasc-comm 是 CANN 推出的面向昇腾 AI 处理器通算融合场景的开源仓库屏蔽硬件差异为底层硬件协同与上层通信算法落地提供统一、高性能的数据面。本文带你走进examples/ccu/ccu_allgather这个官方样例完整解析一个AllGather 集合通信算子如何用HCCL 通信域 API CCU 数据面 API从零搭起来主机侧如何分配线程与通道资源CCU 内核如何用Write远程写 GroupCopy本地拷贝完成人人有份的集合通信并给出构建运行步骤与结果验证方法。一、先搞懂 AllGather样例要解决什么问题AllGather全收集是集合通信中最经典的算子之一每个 rank 持有自己的一小块数据目标是每个 rank 最终都拿到所有 rank 数据的完整拼接。样例的验证方式非常直观每个 rank 发送rankSize个 FP32 元素输入初始化为自己的 rank ID2 卡环境下rank 0 发送[0 0]rank 1 发送[1 1]AllGather 完成后两个 rank 的输出都应是[0 0 1 1]。运行结果的示意见 examples/ccu/ccu_allgather/README.md 中的 Result Example 章节。二、样例工程结构一图看懂代码布局整个样例分为**主机侧host**和 **CCU 内核侧kernel**两大块正好对应控制面 数据面的职责划分目录 / 文件职责main.cc入口初始化 ACL、创建 HCCL 通信域、多线程驱动每卡执行op_host/alg_resource.cc分配 CCU 线程与通信通道资源注册 CCU 内核op_host/exec_op.cc执行算子切分大数据、循环发射 CCU 内核op_kernel_ccu/ccu_kernel.ccCCU 内核远程写 本地拷贝 事件同步op_kernel_ccu/ccu_kernel.h内核参数结构体与 GroupCopy 循环参数计算run.sh一键构建并运行脚本两个运行时依赖也很清晰libhcomm.so提供 HCCL 通信域、CCU 控制面与线程/通道资源 APIlibasccomm_ccu_dataplane.so提供asccomm_ccu_kernel_register*、asccomm_ccu_kernel_launch、asccomm_ccu_get_mem_token等数据面编程 API。三、主机侧三步走初始化 → 资源分配 → 内核发射第 1 步main.cc 完成通信域初始化main.cc 的主流程aclInit初始化运行时aclrtGetDeviceCount探测可用 NPU 数量用HcclGetRootInfoHcclCommInitRootInfo创建 HCCL 通信域多进程间通过 root info 交换握手信息为每块卡开一个线程线程内aclrtMalloc分配发送/接收缓冲大页内存ACL_MEM_MALLOC_HUGE_ONLY把输入数据填成 rank ID 后调用自定义的HcclAllGatherCustom同步流、把结果拷回主机打印最后销毁通信域、释放资源。这里的关键点是AllGather 的自定义实现被封装成了一个普通的 HCCL 算子入口——HcclAllGatherCustom拿到sendBuf / recvBuf / comm后内部走的是 CCU 数据面而不是 HCCL 内置的集合通信路径。这正是 asc-comm 想让开发者体验的自己落地通信算法的模式。第 2 步alg_resource.cc 分配线程与通道资源资源分配是 AllocAlgResource 的两段式流程1申请线程 通道AllocThreadAndChannelResource通过HcclThreadAcquireWithStream申请一个绑定到流上的 CCU 线程对每一个远端 rank共rankSize - 1个用HcclRankGraphGetLinks查询拓扑中本 rank 到对端的最优链路选出COMM_PROTOCOL_UBC_CTP协议的链路再用HcclChannelAcquire申请一条CCU 通道Channel通道数 rank 数 − 1这是 1D Mesh 全互联模型的直接体现每个 rank 与每个对端直连一条通道。2注册 CCU 内核RegisterAllGatherKernel组装ccu_kernel_info内核函数指针 内核参数包含所有通道句柄、rankSize、rankId按register_start → register → register_end三步完成内核注册拿到ccu_kernel_handle供后续发射使用。 单卡rankSize 1时跳过通道申请与内核注册直接退化为本地拷贝逻辑上更简洁。第 3 步exec_op.cc 切分数据并循环发射内核ExecOp 体现了工程化的数据切分策略超大切分单片数据上限UB_MAX_DATA_SIZE 256MB超过则按 256MB 循环切分多次发射内核token 机制先对输入缓冲调用asccomm_ccu_get_mem_token拿到内存 token——这是 CCU 数据面访问受保护内存的钥匙内核侧所有地址读写都携带它每片发射LaunchCcuKernelSlice 组装 10 个任务参数输入/输出地址、token、本片在整块数据中的偏移、片长、GroupCopy 预计算参数通过asccomm_ccu_kernel_launch发射到 CCU。值得注意的是偏移量的算法本 rank 的数据在输出缓冲中的位置是dataSize * myRank——所有 rank 的 AllGather 输出布局天然一致每个 rank 独立计算出相同的写入位置无需任何协调这是 1D Mesh 模型优雅的地方。四、CCU 内核侧解析Write 远程写 GroupCopy 本地拷贝内核入口是 CcuAllGatherMesh1DMem2MemKernel执行顺序如下4.1 装载参数与交换地址从注册时绑定的通道资源中取出每通道的output/token交换变量GetResByChannel用ccu::load_arg把主机侧发射的 10 个参数逐个载入 CCU 变量地址广播向每条通道执行write_variable_with_notify把我要写入的远端输出地址 token推给对端再notify_wait确认对端已收到——这一步保证所有 rank 对彼此缓冲区地址的认知一致。4.2 核心传输ExecuteAllGatherTransfer这是 AllGather 数据面的心脏分三路并行本 rank 数据 ──┬── ccu::Write(通道0, 远端rank输出) ┐ ├── ccu::Write(通道1, 远端rank输出) ├── 三路并行 └── GroupCopy(本地输出) ┘ │ ▼ event_record / event_wait 全员同步远程路径遍历所有对端 rank用ccu::Write(channel, 远端地址, 本地源, 片长, event, mask)通过对应通道把本 rank 数据直接写入对端的输出缓冲一次 Write 完成跨卡传输本地路径自己的数据走GroupCopy本地拷贝避免绕道网络同步屏障event_record标记本 rank 数据已就绪再event_wait(totalMask)等待所有 rank 的写全部完成此时本卡输出缓冲才完整可用。4.3 GroupCopy把大块本地拷贝变成流水线GroupCopy 不是一把梭的 memcpy而是把拷贝拆成循环组配置常量ccu_kernel.h内存切片ccu_ms_size 4KB、交错数ccu_ms_interleave 8、每轮循环8 片、循环组数8——多片在途交错执行掩盖访存延迟主机侧的 CalGoSize 预先算好循环参数addr_offset整组偏移、parallel_param尾段并行参数、residual不足一片的尾巴长度内核侧按addr_offset ! 0/parallel_param ! 0两个条件分支发射loop_group每个循环体内部是LocalCopy → event_wait → LocalCopy → event_wait的中转缓冲模式通过ccu::buffer双缓冲保持拷贝流水线不空转。这种主机算参数、内核发循环的设计把位域打包的硬件循环描述符get_loop_param/get_parallel_param/get_offset_param封装成简单语义是 CCU 编程模型的典型范式。4.4 收尾双向同步防悬空内核退出前对所有通道执行notify_record(POST_SYNC_ID)notify_wait(POST_SYNC_ID)形成跨 rank 的后置屏障确保没有任何 rank 在远端数据真正落盘前提前释放/复用缓冲区。五、构建与运行3 条命令跑通 AllGather 样例环境准备需要已安装 CANN 并设置环境source ${ASCEND_HOME_PATH}/set_env.sh export HCCL_OP_EXPANSION_MODECCU_SCHED进入样例目录一键构建运行cd examples/ccu/ccu_allgather bash run.shrun.sh 内部就是标准的 CMake 两步构建cmake -S ... -B build -DASCEND_HOME_PATH...配置 cmake --build build -j$(nproc)编译最后直接执行产物。预期输出2 卡环境Found 2 NPU device(s) available rankId: 0, input: [ 0 0 ] rankId: 1, input: [ 1 1 ] rankId: 0, output: [ 0 0 1 1 ] rankId: 1, output: [ 0 0 1 1 ]两个 rank 的输出完全一致且等于所有输入按 rank 顺序拼接——AllGather 验证通过 ✅。六、总结与延伸阅读这个样例麻雀虽小五脏俱全展示了用 asc-comm 自定义集合通信算子的完整套路控制面HCCL 通信域 API 负责拓扑查询HcclRankGraphGetLinks、线程与通道资源申请、内核注册数据面CCU API 负责远程写ccu::Write、本地拷贝GroupCopy、事件/通知同步event/notify工程化大数据切分、内存 token 权限管理、循环流水线、前后双屏障缺一不可。如果你想继续深挖仓库中还有这些值得一看的材料更多 CCU 集合通信样例examples/ccu/ 下的ccu_allreduce带规约、ccu_all_to_all、ccu_broadcast、ccu_reduce_scatterCCU 内置算子与 Direct 模式样例examples/ccu/ccu_builtin/、examples/ccu/ccu_direct/通信编程模型文档执行模型、内存模型、通信模式选择docs/zh/programming_model/构建与测试指南docs/zh/guide/build_and_test.md。建议按 builtin → direct → allgather → allreduce 的顺序读样例从最简形态逐步过渡到完整控制面 数据面编程即可快速上手在昇腾通算融合场景下开发高性能集合通信算子。【免费下载链接】asc-comm本项目是CANN 推出的昇腾AI处理器面向通算融合场景打造的专属开源仓库屏蔽硬件差异为底层硬件协同与上层通信算法落地提供统一高性能数据面。项目地址: https://gitcode.com/cann/asc-comm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表