CAM cam_feature 分支深度分析:ZB 共享工具、构建系统演进与 HFA 新模块

分析分支:remotes/origin/cam_feature vs remotes/origin/master 分析日期:2026-07-21 分析范围:共享工具(op_host / op_kernel utils)、构建系统、HFA 内存分配模块、pybind 层、operator_registry.json


目录

  1. ZB 共享工具变化
  2. 构建系统演进
  3. HFA (HBM Fast Alloc) 新模块
  4. pybind 层变化
  5. operator_registry.json 解读
  6. 从 master 到 cam_feature 的整体架构演进

1. ZB 共享工具变化

1.1 comm_args.h — 新增 memLen 字段与常量清理

文件路径: src/cam/comm_operator/ascend_kernels/utils/op_kernel/comm_args.h

1.1.1 新增字段

// cam_feature 新增
int64_t memLen;

CommArgs 结构体新增 memLen 字段(位于 dfx[DFX_COUNT] 之后),用于传递内存长度参数。这是 ZB(Zero-Buffer)系列算子的关键参数——在 SHMEM 共享内存方案中,memLen 指定了预分配的共享内存窗口大小,算子通过该长度计算 flag 区域和数据区域的偏移。

1.1.2 删除的常量

删除的常量 原值 说明
NOTIFY_DISPATCH_BUFF_OFFSET 204UL * 1024UL * 1024UL 通知分发缓冲区偏移,已迁移到 tiling_args.h 的 Moe 命名空间

该常量在 master 中定义在 comm_args.h,cam_feature 中已删除(迁移到 tiling_args.h 的 NOTIFY_DISPATCH_WIN_OFFSET)。

1.1.3 关键常量保留

cam_feature 保留了以下核心常量:

constexpr int CAM_MAX_RANK_SIZE = 384;              // 最大 NPU 卡数
constexpr int64_t IPC_BUFF_MAX_SIZE = 100 * 1024 * 1024;  // IPC 缓冲区 100MB
constexpr int64_t IPC_DATA_OFFSET = 2 * 1024 * 1024;      // 前 2MB 为 flag,后 100MB 为数据
constexpr int64_t UB_SINGLE_DMA_SIZE_MAX = 190 * 1024;    // UB 单次 DMA 最大 190KB
constexpr int64_t UB_SINGLE_PING_PONG_ADD_SIZE_MAX = UB_SINGLE_DMA_SIZE_MAX / 2;  // Ping-Pong 半区
constexpr int UB_ALIGN_SIZE = 32;                         // UB 对齐 32B
constexpr uint8_t COMM_NUM = 2;   // 通信域数量(EP + TP)
constexpr uint8_t COMM_EP_IDX = 0;
constexpr uint8_t COMM_TP_IDX = 1;
constexpr int64_t STATE_WIN_OFFSET = 900 * 1024;  // 状态窗口偏移
constexpr int64_t UB_SINGLE_TOTAL_SIZE_MAX = 192 * 1024;  // UB 总大小 192KB
constexpr int64_t START_OFFSET_FOR_SHARE = 512;    // 共享区域起始偏移

1.1.4 Op 枚举

enum Op : int {
    COPYONLY = -1,
    ADD = 0,
    MUL = 1,
    MAX = 2,
    MIN = 3
};

该枚举定义了 CpGM2GMPingPong 的原子操作类型,用于 GM→GM 拷贝时的原子归约。

1.2 sync_collectives.h — Detour 原语与 Offset 重载

文件路径: src/cam/comm_operator/ascend_kernels/utils/op_kernel/sync_collectives.h

这是 cam_feature 中变化最大的共享工具文件。SyncCollectives 类是 Ascend C kernel 间同步的核心原语库,管理两套 flag 区域(Memory A 卡内同步 / Memory B 卡间同步)。

1.2.1 新增 InitDetour — 共享内存偏移初始化

__aicore__ inline void InitDetour(int rank, int rankSize, GM_ADDR *shareAddrs,
                                  int64_t shareMemOffset, TBuf<QuePosition::VECCALC> &tBuf)
{
    // ...
    localSyncAddr = (__gm__ int64_t*)(shareAddrs[rank] + shareMemOffset);
    basicSyncAddr = (__gm__ int64_t*)(shareAddrs[rank] + shareMemOffset) + GetBlockIdx() * FLAG_UNIT_INT_NUM;
    blockOuterSyncAddr = (__gm__ int64_t*)(shareAddrs[rank] + shareMemOffset) + segmentCount + GetBlockIdx() * FLAG_UNIT_INT_NUM;
    // ...
}

设计意图: 在 ZB 系列中,共享内存窗口被划分为多个逻辑区域(combine 区域、notify-dispatch 区域等)。shareMemOffset 允许同一算子内的不同 kernel 使用同一块共享内存的不同偏移段,避免 flag 区域冲突。这是 Detour 算子的核心需求——detour 算子需要在同一共享内存窗口内复用同步原语。

1.2.2 新增 WaitSyncFlag 6 参数重载

__aicore__ inline void WaitSyncFlag(int32_t magic, int32_t value, int32_t eventID,
                                     int32_t rank, int64_t flagNum, int64_t offset)
{
    int64_t v = MergeMagicWithValue(magic, value);
    WaitOneRankPartFlag((__gm__ int64_t*)(shareAddrs[rank] + offset) + eventID * FLAG_UNIT_INT_NUM, flagNum, v);
}

相比 5 参数版本,新增 offset 参数,支持在共享内存中指定偏移后等待 flag。

1.2.3 新增 SetOuterFlagDetour / WaitOuterFlagDetour

__aicore__ inline void SetOuterFlagDetour(int32_t magic, int32_t eventID,
    int64_t setRank, int64_t setBlock, int64_t shareMemOffset)
{
    __gm__ int64_t* flagAddr = GetOuterFlagAddrDetour(setRank, setBlock, shareMemOffset);
    int64_t value = MergeMagicWithValue(magic, eventID);
    SetFlag(flagAddr, value);
}

__aicore__ inline void WaitOuterFlagDetour(int32_t magic, int32_t eventID,
    int64_t waitRank, int64_t waitBlock, int64_t shareMemOffset)
{
    int64_t value = MergeMagicWithValue(magic, eventID);
    __gm__ int64_t* flagAddr = GetOuterFlagAddrDetour(waitRank, waitBlock, shareMemOffset);
    WaitOneRankPartFlag(flagAddr, 1, value);
}

1.2.4 新增 GetOuterFlagAddrDetour

__aicore__ inline __gm__ int64_t* GetOuterFlagAddrDetour(int64_t flagRank, int64_t flagBlock, int64_t shareMemOffset)
{
    return (__gm__ int64_t*)(shareAddrs[flagRank] + shareMemOffset) + segmentCount + flagBlock * FLAG_UNIT_INT_NUM;
}

总结: 所有 Detour 变体都在原始地址计算基础上增加了 shareMemOffset,使得同步原语可以在共享内存窗口的任意偏移处工作。这是 ZB 系列算子(moe_combine_*_zb、moe_dispatch_*_zb、moe_notify_dispatch_zb)的核心基础设施。

1.2.5 同步原语内存布局

共享内存窗口 (peerMems[rank])
├── [0, segmentCount * FLAG_UNIT_INT_NUM * 8)     ← Memory A: 卡内同步 flag
│   ├── block 0: [flag0, flag1, flag2, flag3]       (FLAG_UNIT_INT_NUM = 4)
│   ├── block 1: [flag0, flag1, flag2, flag3]
│   └── ...
├── [segmentCount * 4 * 8, ...)                    ← Memory B: 卡间同步 flag
│   ├── block 0: [flag0, flag1, flag2, flag3]
│   └── ...
└── [IPC_CHUNK_FLAG, ...)                          ← Chunk Flag 区域 (IPC 用)
  • segmentCount = blockNum * FLAG_UNIT_INT_NUM
  • FLAG_UNIT_INT_NUM = 4(每个同步单元 4 个 int64_t = 32 Bytes)
  • MAGIC_OFFSET = 32(magic 占高 32 bits,value 占低 32 bits)

1.3 moe_distribute_base.h — 结构体无变化

文件路径: src/cam/comm_operator/ascend_kernels/utils/op_kernel/moe_distribute_base.h

git diff 显示 master 与 cam_feature 之间无差异。该文件定义了 HCCL 通信库的核心资源描述结构:

结构体 用途
HcclSignalInfo 信号资源(resId、addr、devId、tsId、rankId、flag)
HcclStreamInfo 流信息(streamId、sqId、cqId、logicCqId)
LocalResInfoV2 本地资源 V2(64 个 signal、19 个 stream、2 个 AICPU notify)
AlgoTopoInfo 拓扑信息(rank、rankSize、superPod、RDMA、NIC 等)
HcclOpConfig 算子配置(deterministic、retry、highPerf、floatOverflowMode)
HcclOpResParam 算子资源参数(workspace、window、config、zero-copy ring buffer 等)
HDCommunicateParams HD 通信参数(host/device addr、cache、flag)

关键常量:

constexpr uint32_t LOCAL_NOTIFY_MAX_NUM = 64;     // 最大本地 notify 数
constexpr uint32_t LOCAL_STREAM_MAX_NUM = 19;     // 最大本地 stream 数
constexpr uint32_t AICPU_OP_NOTIFY_MAX_NUM = 2;   // AICPU notify 数
constexpr uint32_t AICPU_MAX_RANK_NUM = 128 * 1024;  // AICPU 最大 rank 数

1.4 tiling_args.h — 窗口偏移常量

文件路径: src/cam/comm_operator/ascend_kernels/utils/op_host/tiling_args.h

namespace Moe {
constexpr uint64_t COMBINE_STATE_WIN_OFFSET = 4U * 1024UL * 1024UL;       // 4MB
constexpr uint64_t NOTIFY_DISPATCH_WIN_OFFSET = 204U * 1024UL * 1024UL;   // 204MB
} // namespace Moe

该文件定义了 ZB 系列算子的共享内存窗口偏移常量: - COMBINE_STATE_WIN_OFFSET (4MB):combine 算子的状态窗口偏移 - NOTIFY_DISPATCH_WIN_OFFSET (204MB):notify-dispatch 算子的窗口偏移

这些常量在 master 中已存在,cam_feature 保持不变。

1.5 mc2_tiling_utils.h — HCCL_BUFFSIZE 解析

文件路径: src/cam/comm_operator/ascend_kernels/utils/op_host/mc2_tiling_utils.h

class Mc2TilingUtils {
public:
    static uint64_t GetMaxWindowSize() {
        uint16_t defaultWindowSize = 200;  // 默认 200MB
        if (getenv("HCCL_BUFFSIZE") != nullptr) {
            try {
                std::string envStr(getenv("HCCL_BUFFSIZE"));
                defaultWindowSize = std::stoi(envStr);
            } catch (...) { /* 异常处理 */ }
        }
        return static_cast<uint64_t>(defaultWindowSize) * 1024UL * 1024UL;
    }
};

通过环境变量 HCCL_BUFFSIZE 动态获取 HCCL 缓冲区大小(单位 MB),用于计算最大窗口尺寸。默认 200MB。

1.6 DFX 工具链(dfx_base.h / ops_log.h / ops_error.h / error_log.h)

1.6.1 dfx_base.h — 统一日志基础设施

class DfxBase {
public:
    static constexpr const int MAX_LOG_LEN = 16000;
    static constexpr const int MSG_HDR_LEN = 200;
    static inline uint64_t GetTid();                          // 获取线程 ID
    static inline std::string GetOpInfo(const gert::TilingContext *context);  // 获取算子信息
    // ... 支持 TilingContext / TilingParseContext / InferShapeContext / InferDataTypeContext
};

核心宏:

#define OPS_LOG_STUB(MOD_ID, LOG_LEVEL, OPS_DESC, FMT, ...)
// 统一日志记录,包含文件名、行号、函数名、TID、算子名

#define OPS_INNER_ERR_STUB(ERR_CODE_STR, OPS_DESC, FMT, ...)
// 内部错误报告 + 日志

#define OPS_CALL_ERR_STUB(ERR_CODE_STR, OPS_DESC, FMT, ...)
// 调用错误报告 + 日志

1.6.2 ops_log.h — 分级日志宏

#define OPS_LOG_D(OPS_DESC, ...) OPS_LOG_STUB_D(OPS_DESC, __VA_ARGS__)    // Debug
#define OPS_LOG_I(OPS_DESC, ...) OPS_LOG_STUB_I(OPS_DESC, __VA_ARGS__)    // Info
#define OPS_LOG_W(OPS_DESC, ...) OPS_LOG_STUB_W(OPS_DESC, __VA_ARGS__)    // Warn
#define OPS_LOG_E(OPS_DESC, ...) OPS_INNER_ERR_STUB("EZ9999", OPS_DESC, __VA_ARGS__)  // Error + Report
#define OPS_LOG_EVENT(OPS_DESC, ...) OPS_LOG_STUB_EVENT(OPS_DESC, __VA_ARGS__)  // Event

条件日志宏:

#define OPS_LOG_D_IF(COND, OP_DESC, EXPR, ...)
#define OPS_LOG_E_IF_NULL(OPS_DESC, PTR, EXPR)  // 空指针检查 + 错误报告

1.6.3 ops_error.h — 错误报告宏

#define OPS_REPORT_VECTOR_INNER_ERR(OPS_DESC, ...) OPS_INNER_ERR_STUB("E89999", OPS_DESC, __VA_ARGS__)
#define OPS_REPORT_CUBE_INNER_ERR(OPS_DESC, ...) OPS_INNER_ERR_STUB("E69999", OPS_DESC, __VA_ARGS__)
#define OPS_ERR_IF(COND, LOG_FUNC, EXPR) OPS_LOG_STUB_IF(COND, LOG_FUNC, EXPR)

错误码体系: - EZ9999:通用错误 - E89999:Vector 内核内部错误 - E69999:Cube 内核内部错误

1.6.4 error_log.h — 轻量级 printf 日志

#define OP_LOGI(opname, ...)          // Info 级别(空实现)
#define OP_LOGW(opname, ...)          // Warn 级别(printf)
#define OP_LOGE_WITHOUT_REPORT(opname, ...)  // Error 不报告
#define OP_LOGE(opname, ...)          // Error 级别(printf)
#define OP_LOGD(opname, ...)          // Debug 级别(空实现)

这是 tiling 侧的轻量级日志,使用 printf 而非 Alog。

1.7 data_copy.h — GM↔GM Ping-Pong 拷贝

文件路径: src/cam/comm_operator/ascend_kernels/utils/op_kernel/data_copy.h

核心函数 CpGM2GMPingPong:

template <typename K, typename U = K>
FORCE_INLINE_AICORE void CpGM2GMPingPong(int64_t dataSizeRemain,
    const GlobalTensor<U> &sendDataInputGt,
    const GlobalTensor<K> &recvDataOutputGT, int op)

设计要点: 1. Ping-Pong 双缓冲:UB 分为两个区域(UB_HEAD_OFFSET 和 UB_MID_OFFSET),MTE2(GM→UB)和 MTE3(UB→GM)流水线化 2. 类型转换支持:当 K != U 时(如 half→float),UB 按 sizeof(U):sizeof(K) 比例分割 3. 原子操作:通过 SetAtomic<K>(op) 支持 ADD/MUL/MAX/MIN 归约 4. 事件同步:使用 MTE3_MTE2、MTE2_MTE3、MTE2_V、V_MTE3 等硬事件

辅助函数:

template <typename T> void CpUB2GM(__gm__ T *gmAddr, __ubuf__ T *ubAddr, uint32_t size);
template <typename T> void CpGM2UB(__ubuf__ T *ubAddr, __gm__ T *gmAddr, uint32_t size);
template<typename T> void CopyUB2UB(__ubuf__ T *dst, __ubuf__ T *src, const uint32_t calCount);
template<typename T> void copyGmToGmWithBlocks(...);  // 多核分块 GM→GM

2. 构建系统演进

2.1 operator_registry.json — 从 5 个算子到 13 个算子

2.1.1 master 版本(5 个算子)

{
  "soc_versions": {
    "ascend910_93": [
      "dispatch_layout",
      "fused_deep_moe",
      "moe_combine_normal",
      "moe_dispatch_normal",
      "notify_dispatch"
    ]
  },
  "operator_meta": {
    "dispatch_layout": { "requires_shmem": false },
    "fused_deep_moe": { "requires_shmem": false, "family": "fused_deep_moe", "variant": "base" },
    "moe_combine_normal": { "requires_shmem": false },
    "moe_dispatch_normal": { "requires_shmem": false },
    "notify_dispatch": { "requires_shmem": false }
  }
}

2.1.2 cam_feature 版本(13 个算子)

{
  "soc_versions": {
    "ascend910_93": [
      "a2e",
      "all_to_all_detour",
      "e2a",
      "fused_deep_moe",
      "fused_deep_moe_fwk",
      "fused_deep_moe_w4a8",
      "moe_combine_lowlatency_zb",
      "moe_combine_normal_zb",
      "moe_dispatch_layout_zb",
      "moe_dispatch_lowlatency_zb",
      "moe_dispatch_normal_zb",
      "moe_notify_dispatch_zb",
      "reduce_scatter_detour"
    ]
  }
}

2.1.3 新增算子清单

算子名 requires_shmem family variant 说明
a2e - - - Attention→Expert 数据搬运
e2a - - - Expert→Attention 数据搬运
all_to_all_detour - - - All-to-All Detour 通信
reduce_scatter_detour - - - Reduce-Scatter Detour 通信
fused_deep_moe_fwk false fused_deep_moe fwk 独立 FWK 变体
fused_deep_moe_w4a8 false fused_deep_moe w4a8 W4A8 量化变体
moe_combine_lowlatency_zb true - - ZB 低延迟 Combine
moe_combine_normal_zb true - - ZB 标准 Combine
moe_dispatch_layout_zb true - - ZB Dispatch 布局
moe_dispatch_lowlatency_zb true - - ZB 低延迟 Dispatch
moe_dispatch_normal_zb true - - ZB 标准 Dispatch
moe_notify_dispatch_zb true - - ZB Notify-Dispatch

2.1.4 SHMEM 依赖分析

requires_shmem = true(7 个): 全部为 ZB 系列算子 - moe_combine_lowlatency_zb - moe_combine_normal_zb - moe_dispatch_layout_zb - moe_dispatch_lowlatency_zb - moe_dispatch_normal_zb - moe_notify_dispatch_zb

requires_shmem = false(2 个): - fused_deep_moe_fwk - fused_deep_moe_w4a8

未标记 requires_shmem(4 个): 默认为 false - a2e, e2a, all_to_all_detour, reduce_scatter_detour

2.1.5 fused_deep_moe 家族互斥规则

fused_deep_moe (base) ──┐
                         ├── 互斥(共享 fused_deep_moe.* 文件名)
fused_deep_moe_w4a8 ────┘

fused_deep_moe_fwk ───── 独立(fused_deep_moe_fwk.* 文件名),可与 base/w4a8 共存
  • base 和 w4a8 共享 fused_deep_moe.h / fused_deep_moe.cpp,互斥
  • fwk 使用独立文件名 fused_deep_moe_fwk.*,可与任意变体共存
  • --quant 标志选择 w4a8 变体

2.2 select_ops.py — 算子选择逻辑

文件路径: build/cam/comm_operator/select_ops.py

2.2.1 核心 resolve 函数流程

输入: registry, soc_list, shmem, quant, user_ops
  │
  ├─ 1. 确定候选集: user_ops 或全量 soc_list
  │
  ├─ 2. fused_deep_moe 互斥规则
  │   ├─ quant=true: 强制 w4a8,移除 base
  │   ├─ quant=false + 两者都在: 保留 base,移除 w4a8
  │   └─ fwk 不受影响
  │
  ├─ 3. SHMEM 过滤
  │   └─ shmem=false: 移除所有 requires_shmem=true 的算子
  │
  └─ 4. 按注册表顺序排序输出

2.2.2 命令行参数

python3 select_ops.py \
    --registry operator_registry.json \
    --soc ascend910_93 \
    --shmem 1 \
    --quant \
    --ops "a2e;e2a;fused_deep_moe"

2.2.3 master vs cam_feature 差异

select_ops.py 在 master 和 cam_feature 之间逻辑完全一致,仅注释语言不同(master 英文,cam_feature 中文)。变化的是 operator_registry.json 的内容。

2.3 compile_ascend_proj.sh — SHMEM 注入与中文注释

文件路径: build/cam/comm_operator/compile_ascend_proj.sh

2.3.1 SHMEM 检测逻辑

shmem_installed=1
if [ -z "${SHMEM_HOME_PATH}" ]; then
    shmem_installed=0
fi

通过 SHMEM_HOME_PATH 环境变量判断 SHMEM 是否安装。

2.3.2 SHMEM 编译选项注入(关键 patch)

# Patch kernel compile .make files to pass custom include paths to OPC tool.
KERNEL_COMPILE_OPTS=""
if [ -n "${SHMEM_HOME_PATH}" ]; then
    KERNEL_COMPILE_OPTS="-I${SHMEM_HOME_PATH}/shmem/include -I${SHMEM_HOME_PATH}/shmem/src/device"
fi
if [ -n "${CATLASS_HOME_PATH}" ]; then
    KERNEL_COMPILE_OPTS="${KERNEL_COMPILE_OPTS}-I${CATLASS_HOME_PATH}/include"
fi
if [ -n "${KERNEL_COMPILE_OPTS}" ]; then
    find build_out/op_kernel/CMakeFiles -name "build.make" \
        -exec sed -i "s|--compile-options=\"\"|--compile-options=\\\"${KERNEL_COMPILE_OPTS}\\\"|g" {} +
fi

设计意图: npu_op_* 构建系统的 simple_kernel_compile 不读取 custom_compile_options.ini,导致 --compile-options 为空。该 patch 通过 sed 直接修改 .make 文件,将 SHMEM 和 Catlass 的 include 路径注入到编译选项中。

2.3.3 Include-List 构建模式

copy_ops_include() {
    # 始终复制 utils 公共头目录
    cp -rf "$src_dir/utils/op_host/"* "$dst_dir/op_host/"
    cp -rf "$src_dir/utils/op_kernel/"* "$dst_dir/op_kernel/"

    # 仅复制选中算子的 op_host/op_kernel/op_api
    for name in "${ops[@]}"; do
        cp -rf "$subdir/op_host/"* "$dst_dir/op_host/"
        cp -rf "$subdir/op_kernel/"* "$dst_dir/op_kernel/"
        cp -rf "$subdir/op_api/"* "$dst_dir/pregen/build_out/autogen/"
    done
}

相比旧版全量拷贝 + exclude-list,新版只复制 select_ops.py 求解出的算子,从根本上避免同名算子文件覆盖。

2.3.4 master vs cam_feature 差异

compile_ascend_proj.sh 在 master 和 cam_feature 之间逻辑完全一致,仅注释语言不同(master 英文,cam_feature 中文)。

2.4 ascendc_impl_build.py — SHMEM 路径修复

文件路径: src/cam/comm_operator/ascend_kernels/cmake_files/cmake/util/ascendc_impl_build.py

2.4.1 关键 Bug Fix

# master(有 bug)
options.append("-I" + SHMEM_HOME_PATH + "shmem/include/device")  # 缺少 / 分隔符

# cam_feature(修复)
options.append("-I" + SHMEM_HOME_PATH + "/shmem/include/device")  # 正确路径

影响: 在 master 中,如果 SHMEM_HOME_PATH 以 / 结尾则正常,否则路径拼接错误。cam_feature 修复了此问题。

2.4.2 SHMEM Include 路径列表

options.append("-I" + SHMEM_HOME_PATH + "/shmem/include")
options.append("-I" + SHMEM_HOME_PATH + "/shmem/include/device")
options.append("-I" + SHMEM_HOME_PATH + "/shmem/include/host_device")
options.append("-I" + SHMEM_HOME_PATH + "/shmem/include/internal")
options.append("-I" + SHMEM_HOME_PATH + "/shmem/src")
options.append("-I" + SHMEM_HOME_PATH + "/shmem/src/device")
options.append("-I" + SHMEM_HOME_PATH + "/memfabric_hybrid/include/smem/device")

2.5 CMakeLists.txt 演进

2.5.1 op_kernel/CMakeLists.txt — Catlass 架构宏

# cam_feature 新增
list(APPEND KERNEL_COMPILE_OPTS -I${CMAKE_CURRENT_SOURCE_DIR} -DASCENDC_DUMP=0 --cce-auto-sync=off -DCATLASS_ARCH=2201)

变化: 1. 新增 -I${CMAKE_CURRENT_SOURCE_DIR}:将当前源码目录加入全局头搜索路径 2. 新增 -DCATLASS_ARCH=2201:Catlass 架构版本宏(2201 对应 Ascend 910B)

2.5.2 op_host/CMakeLists.txt — CANN 版本检测

set(CANN83_PATH "${CANN_ROOT}/include/platform/platform_infos_def.h")
set(CANN82_PATH "${CANN_ROOT}/include/experiment/platform/platform/platform_infos_def.h")

if(EXISTS "${CANN83_PATH}")
    add_definitions(-DUSE_CANN83_PATH)
elseif(EXISTS "${CANN82_PATH}")
    add_definitions(-DUSE_CANN82_PATH)
endif()

自动检测 CANN 8.2 vs 8.3+ 版本,定义对应的宏。

2.5.3 顶层 CMakeLists.txt

cmake_minimum_required(VERSION 3.16.0)
project(opp)
find_package(ASC REQUIRED)
set(package_name ${vendor_name})

npu_op_package(${package_name} TYPE RUN CONFIG INSTALL_PATH ${CMAKE_BINARY_DIR}/)

add_subdirectory(op_host)
add_subdirectory(op_kernel)

使用 npu_op_package 宏定义算子包,类型为 RUN(run 包)。


3. HFA (HBM Fast Alloc) 新模块

文件路径: src/cam/utilities/hfa/

HFA 是 cam_feature 中全新引入的模块,master 中不存在。

3.1 模块概览

hfa/
├── .gitignore
├── CMakeLists.txt
├── README.md
├── doc/
│   └── HFA.pdf
├── include/
│   └── hbm_fast_alloc.h        ← 对外头文件
├── src/
│   ├── CMakeLists.txt
│   ├── acl_free_chunks.cpp     ← 空闲块管理
│   ├── acl_virtual_memory.cpp  ← 虚拟内存管理
│   ├── acl_virtual_memory.h    ← 虚拟内存头文件
│   ├── flex_alloc.cpp          ← 弹性分配器
│   ├── flex_alloc.h            ← 弹性分配器头文件
│   ├── hbm_fast_alloc.cpp      ← HBM 快速分配器
│   └── hfa_log.h               ← 日志工具
└── test/

3.2 FlexAlloc — 双索引弹性分配器

文件路径: src/cam/utilities/hfa/src/flex_alloc.h / flex_alloc.cpp

3.2.1 数据结构

class FlexAlloc {
private:
    struct Range { length_t size; };

    // 主索引:按起始偏移排序
    using StartMap = std::map<offset_t, Range>;
    // 辅助索引:按大小排序,值为 StartMap 的迭代器
    using SizeMap = std::multimap<length_t, typename StartMap::iterator>;

    StartMap m_free_ranges_by_offset;   // 按偏移索引的空闲区间
    SizeMap  m_free_ranges_by_size;     // 按大小索引的空闲区间
    size_t m_mem_size { 0 };
    size_t m_total_alloc_bytes { 0 };
    size_t m_total_free_bytes { 0 };
    size_t m_total_alloc_objs { 0 };
};

设计亮点: 双索引结构——StartMap 支持 O(log n) 的邻居合并,SizeMap 支持 O(log n) 的最佳适配查找。SizeMap 存储的是 StartMap 的迭代器,避免数据冗余。

3.2.2 分配算法

FlexAlloc::FlexRetCode FlexAlloc::alloc(length_t req_size, size_t &offset, size_t &alloc_size)
{
    alloc_size = round_up_bits(req_size, OBJ_SIZE_BITS);  // 64 字节对齐

    // 1. 在 SizeMap 中查找第一个 >= alloc_size 的区间
    auto sizeIt = m_free_ranges_by_size.lower_bound(alloc_size);

    // 2. 如果没找到,区分"内存不足"和"碎片化"
    if (sizeIt == m_free_ranges_by_size.end()) {
        if (get_total_free_mem() >= alloc_size)
            return FLEX_RC_ERR_FRAGMENTATION;  // 总空闲够但无连续块
        else
            return FLEX_RC_ERR_NO_MEM;         // 总空闲不够
    }

    // 3. 分配并分割剩余
    offset = rangeIt->first;
    blkSz = rangeIt->second.size;
    // 从两个索引中删除
    // 如果有剩余,将新区间插回两个索引
}

时间复杂度: O(log n)(红黑树操作)

3.2.3 释放与合并

bool FlexAlloc::free(offset_t offset, length_t size)
{
    // 1. 查找第一个起始位置 >= offset 的区间
    auto next = m_free_ranges_by_offset.lower_bound(offset);

    // 2. 尝试与前一个区间合并
    if (prevEnd == offset) { /* 合并 */ }

    // 3. 尝试与后一个区间合并
    while (newStart + newSize == rangeStart) { /* 合并 */ }

    // 4. 插入合并后的区间
}

3.2.4 对齐策略

static size_t const OBJ_SIZE_BITS = 6;           // 2^6 = 64 字节对齐
static size_t const MIN_OBJ_SIZE = (1UL << OBJ_SIZE_BITS);  // 最小 64 字节

template <typename T>
T round_up_bits(T num, uint32_t nbits) {
    T shift = ((static_cast<T>(1)) << nbits) - 1;
    return (num + shift) & ~(shift);
}

3.2.5 返回码

enum FlexRetCode {
    FLEX_RC_SUCCESS,            // 成功
    FLEX_RC_ERROR,              // 通用错误
    FLEX_RC_ERR_INVAL_ARG,      // 无效参数
    FLEX_RC_ERR_NO_MEM,         // 内存不足
    FLEX_RC_ERR_FRAGMENTATION   // 碎片化(总空闲够但无连续块)
};

3.3 AclVirtualMemory — ACL 虚拟内存管理

文件路径: src/cam/utilities/hfa/src/acl_virtual_memory.h / acl_virtual_memory.cpp

3.3.1 核心能力

class AclVirtualMemory {
public:
    // 分配 HBM 内存:虚拟内存最大 128GB,物理内存最大 32GB
    std::pair<VmRet, void*> alloc(int32_t device_id, size_t vr_mem_size,
                                   size_t ph_mem_size, size_t ph_page_size);

    // 碎片整理:将分散的物理页重新映射为连续块
    VmRet defrag(AclFreeChunks* p_free_chunks);

    void* get_base_addr() { return mp_vr_base_addr; }
    void free();
};

3.3.2 关键常量

const size_t MAX_VIRTUAL_MEM_SIZE = 128UL * 1024 * 1024 * 1024;  // 128GB
const size_t PH_PAGE_ALIGN_SIZE = 2 * 1024 * 1024;               // 2MB 页对齐
const size_t DEF_INITIAL_FREE_PAGES = 1024;
const size_t DEF_INITIAL_FREE_CHUNKS = 1024;

3.3.3 碎片整理算法(defrag)

输入: 空闲块列表 (AclFreeChunks)
  │
  ├─ 1. 遍历每个空闲块,提取完整物理页
  │   ├─ 对齐的首页 → 加入 free_pages
  │   ├─ 对齐的尾页 → 加入 free_pages
  │   └─ 中间完整页 → 加入 free_pages
  │
  ├─ 2. 重新映射完整页到虚拟内存末尾
  │   for each page in free_pages:
  │     if 完整页: aclrtMapMem 到末尾
  │     else: 作为不完整块保留
  │
  └─ 3. 输出: 一个连续大块 + 若干不完整边块

关键 API: - aclrtMapMem:将物理页映射到指定虚拟地址 - aclrtUnmapMem:解除映射 - aclrtFreePhysical:释放物理内存 - aclrtReleaseMemAddress:释放虚拟地址空间

3.3.4 错误码体系

enum class VmRet {
    SUCCESS = 0,
    E_OUT_OF_MEMORY = 0x100,
    E_INSTANCE_NOT_INITIALIZED = 0x101,
    E_INSUFFICIENT_MEM = 0x102,
    E_INVALID_PARAMETER = 0x103,
    // ...
    E_ACL_MAP_MEM_FAILED = ACL_BASE_ERROR + 5,
    E_ACL_UNMAP_MEM_FAILED = ACL_BASE_ERROR + 6,
};

3.4 HbmFastAlloc — 统一分配器

文件路径: src/cam/utilities/hfa/include/hbm_fast_alloc.h / src/cam/utilities/hfa/src/hbm_fast_alloc.cpp

3.4.1 类定义

class HbmFastAlloc {
public:
    bool init(int32_t device_id, size_t vr_mem_size, size_t ph_mem_size,
              size_t ph_page_size, size_t initial_free_pages);
    void deinit();
    void *alloc(size_t req_size);
    bool free(void *ptr);
    void free_all();

    size_t get_last_defrag_elem_size() { return m_last_defrag_elem_size; }
    static void set_log_level(int lvl);
    static int get_log_level();

private:
    bool try_defrag();
    bool handle_defrag(size_t size, size_t &alloc_offset, size_t &alloc_size);

    AclVirtualMemory *mp_avm { nullptr };
    FlexAlloc        *mp_fa  { nullptr };
    std::mutex        m_alloc_map_lock;
    AllocMap          m_alloc_map;           // ptr → (offset, size)
    size_t            m_last_defrag_elem_size { 0 };
    size_t            m_defrag_ctr { 0 };
    size_t            m_defrag_failed { 0 };
};

3.4.2 分配流程

alloc(size)
  │
  ├─ 1. mp_fa->alloc(size, offset, alloc_size)
  │   ├─ 成功 → 返回对象地址
  │   └─ 失败且为 FRAGMENTATION → 进入 defrag 流程
  │
  ├─ 2. handle_defrag(size, offset, alloc_size)
  │   ├─ try_defrag()
  │   │   ├─ 获取所有空闲区间
  │   │   ├─ 调用 mp_avm->defrag() 重新映射物理页
  │   │   └─ 将新区间插回 FlexAlloc
  │   └─ 再次尝试 mp_fa->alloc()
  │
  └─ 3. 记录到 m_alloc_map,返回地址

3.4.3 释放流程

bool HbmFastAlloc::free(void *ptr)
{
    std::lock_guard<std::mutex> lock(m_alloc_map_lock);
    auto iter = m_alloc_map.find(static_cast<uint8_t*>(ptr));
    if (iter == m_alloc_map.end()) return false;

    // 通过 FlexAlloc 释放
    mp_fa->free(iter->second.first, iter->second.second);
    m_alloc_map.erase(iter);
    return true;
}

3.5 hfa_log.h — 分级日志

enum HfaLogLevel {
    HFA_LOG_DEBUG = 0,
    HFA_LOG_INFO = 1,
    HFA_LOG_WARNING = 2,
    HFA_LOG_ERROR = 3
};

#define DEBUG_PRINT(...)   HFA_LOG_PRINT_IF(HFA_LOG_DEBUG, stdout, __VA_ARGS__)
#define INFO_PRINT(...)    HFA_LOG_PRINT_IF(HFA_LOG_INFO, stdout, __VA_ARGS__)
#define WARNING_PRINT(...) HFA_LOG_PRINT_IF(HFA_LOG_WARNING, stdout, __VA_ARGS__)
#define ERROR_PRINT(...)   HFA_LOG_PRINT_IF(HFA_LOG_ERROR, stderr, __VA_ARGS__)

默认日志级别:HFA_LOG_WARNING。

3.6 HFA 与 Zero-Buffer 的关系

HFA 虽然位于 src/cam/utilities/hfa/ 公共目录,但其设计目标是为 ZB 系列算子提供共享内存窗口的动态分配能力:

  1. ZB 算子的内存需求: ZB 系列(moe_combine_*_zb、moe_dispatch_*_zb、moe_notify_dispatch_zb)需要在 HBM 上预分配大块共享内存窗口,用于卡间 flag 同步和数据交换
  2. HFA 的角色: 提供高效的 HBM 分配/释放/碎片整理,使 ZB 算子能动态管理共享内存窗口
  3. 碎片整理: ZB 算子的内存分配模式(频繁 alloc/free 不同大小块)容易产生碎片,HFA 的 defrag 通过 ACL API 重新映射物理页解决

性能指标(README 描述): - ~99.7% HBM 利用率(所有对象大小) - ~0.5 µs 分配/释放延迟(超低且稳定)


4. pybind 层变化

文件路径: src/cam/comm_operator/pybind/pybind.cpp / functions.h

4.1 master 版本(4 个算子)

PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
    m.def("fused_deep_moe", &FusedDeepMoeImplAutograd);
    m.def("get_dispatch_layout", &GetDispatchLayoutImplAutograd);
    m.def("moe_dispatch_prefill", &MoeDispatchPrefillImplAutograd);
    m.def("moe_combine_prefill", &MoeCombinePrefillImplAutograd);
}

4.2 cam_feature 版本(10 个算子 + 1 个类)

PYBIND11_MODULE(TORCH_EXTENSION_NAME, m) {
    m.def("fused_deep_moe", &FusedDeepMoeImplAutograd);
    m.def("all2_all_detour", &all2_all_detour_impl_autograd);
    m.def("reduce_scatter_detour", &reduce_scatter_detour_impl_autograd);
    m.def("cam_get_comm", &cam_get_comm);
    m.def("cam_free_comm", &cam_free_comm);
    m.def("cam_get_rank_size", &cam_get_rank_size);
    m.def("cam_get_and_increase_magic", &cam_get_and_increase_magic);
    m.def("cam_get_magic", &cam_get_magic);
    m.def("a2e", &A2eImplAutograd);
    m.def("e2a", &E2aImplAutograd);

    // ZB Fused Deep MOE Buffer 类
    pybind11::class_<fused_deep_moe::Buffer>(m, "FusedDeepMoeBuffer")
        .def(pybind11::init<>())
        .def("init", &fused_deep_moe::Buffer::init)
        .def("zb_fused_deep_moe", &fused_deep_moe::Buffer::zb_fused_deep_moe)
        .def("is_initialized", &fused_deep_moe::Buffer::is_initialized)
        .def("get_ext_info", &fused_deep_moe::Buffer::get_ext_info)
        .def("get_shmem_workspace", &fused_deep_moe::Buffer::get_shmem_workspace);
}

4.3 新增算子详解

算子 功能 参数
all2_all_detour All-to-All Detour 通信 sendData, commRankIds, commArgs, commId
reduce_scatter_detour Reduce-Scatter Detour sendData, commRankIds, commArgs, commId, op
cam_get_comm 获取通信资源 comm_id, rank, group_size, server_ip_port
cam_free_comm 释放通信资源 comm_id
cam_get_rank_size 获取 rank 数量 comm_id
cam_get_and_increase_magic 原子获取并递增 magic comm_id
cam_get_magic 获取当前 magic comm_id
a2e Attention→Expert 数据搬运 x, expert_ids, scales, batch_size, hidden_size, topk, ...
e2a Expert→Attention 数据搬运 expand_x, atten_batch_size, batch_size, hidden_size, topk, ...

4.4 FusedDeepMoeBuffer 类

namespace fused_deep_moe {
class Buffer {
    void init(int rank, int num_ranks, uint64_t memsize, const std::string &ip_port);
    std::vector<at::Tensor> zb_fused_deep_moe(
        const at::Tensor &x,
        const at::Tensor &expert_ids,
        const TensorVector &gmm1_weight,
        // ... 完整参数列表
    );
    bool is_initialized() const;
    int64_t get_ext_info() const;
    int64_t get_shmem_workspace() const;
};
}

设计意图: FusedDeepMoeBuffer 封装了 ZB Fused Deep MOE 算子的状态管理: - init:初始化共享内存工作区(通过 HCCL 通信) - zb_fused_deep_moe:执行 ZB 融合 MOE 前向计算 - get_shmem_workspace:返回共享内存工作区指针(供其他算子使用)

4.5 TORCH_LIBRARY 注册

TORCH_LIBRARY(umdk_cam_op_lib, m) {
    m.def("fused_deep_moe(...) -> Tensor[]");
    m.def("all2_all_detour(Tensor sendData, Tensor commRankIds, Tensor commArgs, int commId) -> Tensor");
    m.def("reduce_scatter_detour(Tensor sendData, Tensor commRankIds, Tensor commArgs, int commId, int op) -> Tensor");
    m.def("cam_get_comm(int comm_id, int rank, int group_size, str server_ip_port) -> Tensor");
    m.def("cam_free_comm(int comm_id) -> Tensor");
    m.def("a2e(...) -> Tensor[]");
    m.def("e2a(...) -> Tensor");
}

通过 TORCH_LIBRARY 注册为 PyTorch 自定义算子,支持 torch.compile 和 AOTInductor。

4.6 functions.h 签名变化

master cam_feature
GetDispatchLayoutImplAutograd 移除
MoeDispatchPrefillImplAutograd 移除
MoeCombinePrefillImplAutograd 移除
- all2_all_detour_impl_autograd (新增)
- reduce_scatter_detour_impl_autograd (新增)
- A2eImplAutograd (新增)
- E2aImplAutograd (新增)

5. operator_registry.json 解读

5.1 架构设计

operator_registry.json
├── _comment: 元数据说明
├── soc_versions: 代际 → 算子目录名列表
│   └── ascend910_93: [13 个算子]
└── operator_meta: 算子元数据
    ├── requires_shmem: 是否需要 SHMEM
    ├── family: 家族(用于互斥)
    └── variant: 变体(base/w4a8/fwk)

5.2 算子分类

5.2.1 按功能分类

类别 算子 说明
ZB MOE 核心 moe_combine_*_zb, moe_dispatch_*_zb, moe_notify_dispatch_zb 7 个,全部 requires_shmem=true
Fused MOE fused_deep_moe, fused_deep_moe_w4a8, fused_deep_moe_fwk 3 个变体
数据搬运 a2e, e2a Attention↔Expert
通信 Detour all_to_all_detour, reduce_scatter_detour 通信加速

5.2.2 按 SHMEM 依赖分类

requires_shmem 算子数 算子
true 6 moe_combine_lowlatency_zb, moe_combine_normal_zb, moe_dispatch_layout_zb, moe_dispatch_lowlatency_zb, moe_dispatch_normal_zb, moe_notify_dispatch_zb
false 2 fused_deep_moe_fwk, fused_deep_moe_w4a8
未指定(默认 false) 5 a2e, e2a, all_to_all_detour, reduce_scatter_detour, fused_deep_moe

5.3 family/variant 互斥规则

fused_deep_moe (family=fused_deep_moe, variant=base)
fused_deep_moe_w4a8 (family=fused_deep_moe, variant=w4a8)
  └── 互斥:共享 fused_deep_moe.* 文件名

fused_deep_moe_fwk (family=fused_deep_moe, variant=fwk)
  └── 独立:fused_deep_moe_fwk.* 文件名,可与 base/w4a8 共存

互斥规则代码实现:

if quant:
    # -q 选择 w4a8,移除 base
    candidates = [o for o in candidates if o != BASE]
    if W4A8 not in candidates:
        candidates.append(W4A8)
else:
    # 默认选择 base,移除 w4a8
    if has_base and has_w4a8:
        candidates = [o for o in candidates if o != W4A8]

5.4 构建流程中的算子选择

build.sh
  │
  ├─ CAM_USE_W4A8=1 → --quant
  ├─ CAM_OP_SELECT="a2e;e2a"  --ops
  └─ SHMEM_HOME_PATH → --shmem 1/0
      │
      └─ select_ops.py
          │
          ├─ 1. 确定候选集
          ├─ 2. 应用互斥规则
          ├─ 3. SHMEM 过滤
          └─ 4. 输出最终列表

6. 从 master 到 cam_feature 的整体架构演进

6.1 算子体系演进

master (5 个算子)                          cam_feature (13 个算子)
─────────────────                          ──────────────────────
dispatch_layout                    →        (移除,替换为 ZB 版本)
fused_deep_moe                     →        fused_deep_moe (保留)
moe_combine_normal                 →        moe_combine_normal_zb (SHMEM 化)
moe_dispatch_normal                →        moe_dispatch_normal_zb (SHMEM 化)
notify_dispatch                    →        moe_notify_dispatch_zb (SHMEM 化)
                                       +    moe_combine_lowlatency_zb (新增)
                                       +    moe_dispatch_lowlatency_zb (新增)
                                       +    moe_dispatch_layout_zb (新增)
                                       +    fused_deep_moe_w4a8 (新增量化变体)
                                       +    fused_deep_moe_fwk (新增 FWK 变体)
                                       +    a2e (新增)
                                       +    e2a (新增)
                                       +    all_to_all_detour (新增)
                                       +    reduce_scatter_detour (新增)

6.2 共享内存架构演进

master: 使用 HCCL 标准通信,无自定义共享内存

cam_feature: 引入 SHMEM 共享内存窗口

共享内存窗口布局 (HBM)
├── [0, 4MB)                    ← COMBINE_STATE_WIN_OFFSET
│   └── combine 算子 flag 区域
├── [204MB, ...)                 ← NOTIFY_DISPATCH_WIN_OFFSET
│   └── notify-dispatch 算子 flag 区域
├── [IPC_CHUNK_FLAG, ...)        ← IPC Chunk 标志区域
└── [peerMems[rank], ...)        ← 每个 rank 的 flag 区域
    ├── Memory A: 卡内同步 flag
    └── Memory B: 卡间同步 flag

6.3 同步原语演进

特性 master cam_feature
基础 Init ✓ ✓
Detour Init(偏移初始化) ✗ ✓
WaitSyncFlag 5 参数 ✓ ✓
WaitSyncFlag 6 参数(+offset) ✗ ✓
SetOuterFlagDetour ✗ ✓
WaitOuterFlagDetour ✗ ✓
GetOuterFlagAddrDetour ✗ ✓

6.4 构建系统演进

特性 master cam_feature
构建系统 npu_op_* npu_op_*
算子选择 select_ops.py select_ops.py
构建模式 include-list include-list
SHMEM 检测 SHMEM_HOME_PATH SHMEM_HOME_PATH
SHMEM 编译注入 sed patch .make sed patch .make
SHMEM 路径修复 有 bug(缺 /) 已修复
Catlass 架构宏 无 CATLASS_ARCH=2201
全局头搜索路径 无 -I${CMAKE_CURRENT_SOURCE_DIR}

6.5 新增模块

模块 master cam_feature
HFA (HBM Fast Alloc) ✗ ✓
FusedDeepMoeBuffer (pybind) ✗ ✓
a2e / e2a 算子 ✗ ✓
all_to_all_detour / reduce_scatter_detour ✗ ✓
cam_get_comm / cam_free_comm 等通信 API ✗ ✓

6.6 架构演进总结

cam_feature 分支代表了 CAM 库从标准 HCCL 通信向SHMEM 共享内存加速的架构转型:

  1. ZB 系列算子: 7 个新的 ZB 算子(全部 requires_shmem=true)使用自定义共享内存窗口替代部分 HCCL 通信,降低延迟
  2. Detour 同步原语: SyncCollectives 新增 Detour 变体,支持在共享内存窗口任意偏移处工作
  3. HFA 内存管理: 全新的 HBM 快速分配器,提供 O(log n) 分配/释放 + 碎片整理能力
  4. pybind 扩展: 新增 6 个通信管理 API + 1 个 ZB Fused MOE Buffer 类
  5. 构建系统: 修复 SHMEM 路径 bug,新增 Catlass 架构宏,支持更灵活的算子选择

附录:关键文件路径索引

文件 路径
tiling_args.h src/cam/comm_operator/ascend_kernels/utils/op_host/tiling_args.h
mc2_tiling_utils.h src/cam/comm_operator/ascend_kernels/utils/op_host/mc2_tiling_utils.h
dfx_base.h src/cam/comm_operator/ascend_kernels/utils/op_host/dfx_base.h
ops_log.h src/cam/comm_operator/ascend_kernels/utils/op_host/ops_log.h
error_log.h src/cam/comm_operator/ascend_kernels/utils/op_host/error_log.h
ops_error.h src/cam/comm_operator/ascend_kernels/utils/op_host/ops_error.h
comm_args.h src/cam/comm_operator/ascend_kernels/utils/op_kernel/comm_args.h
sync_collectives.h src/cam/comm_operator/ascend_kernels/utils/op_kernel/sync_collectives.h
data_copy.h src/cam/comm_operator/ascend_kernels/utils/op_kernel/data_copy.h
moe_distribute_base.h src/cam/comm_operator/ascend_kernels/utils/op_kernel/moe_distribute_base.h
operator_registry.json src/cam/comm_operator/ascend_kernels/operator_registry.json
select_ops.py build/cam/comm_operator/select_ops.py
compile_ascend_proj.sh build/cam/comm_operator/compile_ascend_proj.sh
ascendc_impl_build.py src/cam/comm_operator/ascend_kernels/cmake_files/cmake/util/ascendc_impl_build.py
flex_alloc.h src/cam/utilities/hfa/src/flex_alloc.h
flex_alloc.cpp src/cam/utilities/hfa/src/flex_alloc.cpp
hbm_fast_alloc.h src/cam/utilities/hfa/include/hbm_fast_alloc.h
hbm_fast_alloc.cpp src/cam/utilities/hfa/src/hbm_fast_alloc.cpp
acl_virtual_memory.h src/cam/utilities/hfa/src/acl_virtual_memory.h
acl_virtual_memory.cpp src/cam/utilities/hfa/src/acl_virtual_memory.cpp
hfa_log.h src/cam/utilities/hfa/src/hfa_log.h
pybind.cpp src/cam/comm_operator/pybind/pybind.cpp
functions.h src/cam/comm_operator/pybind/functions.h
buffer.h src/cam/comm_operator/pybind/buffer.h
ext_utils.h src/cam/comm_operator/pybind/ext_utils.h
← 新通信算子 — A2E/E2A/Detour 📑 索引 Pybind + Examples + Docker →