HCCL 2 :薄绑定

举报
黄生 发表于 2026/10/18 21:43:27 2026/10/18
【摘要】 无中间封装层。 Python 接口与 C 接口一一对应,参数原样转发,无内存拷贝、无数据组装。每个算子模块只做一件事:把 Python 参数传给 C 函数,检查返回码。 用户 Python 应用 │ import hccl4py ▼ hccl4py ├─ ops...

无中间封装层。 Python 接口与 C 接口一一对应,参数原样转发,无内存拷贝、无数据组装。每个算子模块只做一件事:把 Python 参数传给 C 函数,检查返回码。

                用户 Python 应用
                        │  import hccl4py
                        ▼
   hccl4py
   ├─ ops/         14 个通信算子   ← hccl 仓
   ├─ comm.py      通信域 5 接口   ← hcomm 仓
   ├─ types.py     公开常量层
   └─ _binding.py  私有声明层
                        │  ctypes
                        ▼
                    libhccl.so

_binding.py — 私有声明层

职责:动态库加载 + 全部 C 声明。ops/ 和 comm.py 共用,不对外暴露。

_LIB_PATH = os.environ.get("HCCL4PY_LIB_PATH", "libhccl.so")
hccl = ctypes.CDLL(_LIB_PATH)          # 模块级单例

# 模块加载时即声明 argtypes/restype,避开 ctypes 默认慢路径
hccl.HcclBroadcast.argtypes = [ctypes.c_void_p, ctypes.c_uint64, ctypes.c_int,
                               ctypes.c_uint32, ctypes.c_void_p, ctypes.c_void_p]
hccl.HcclBroadcast.restype = ctypes.c_int

关键点:

  • CDLL 模块级单例,库路径支持 HCCL4PY_LIB_PATH 环境变量覆盖;
  • 19 个函数逐一设置 argtypes/restype,指针统一 c_void_p,枚举统一 c_int;
  • 三个结构体(HcclRootInfo/HcclCommConfig/HcclSendRecvItem)定义于此;
  • HcclError 异常类定义于此,携带 HcclResult 码。

types.py — 公开常量层

HcclDataType(17 项)、HcclReduceOp(4 项)、HcclResult(25 项),取值与 hccl_types.h 逐项一致:

class HcclDataType(enum.IntEnum):
    INT8 = 0; INT16 = 1; INT32 = 2; FP16 = 3; FP32 = 4
    INT64 = 5; UINT64 = 6; UINT8 = 7; UINT16 = 8; UINT32 = 9
    FP64 = 10; BFP16 = 11; INT128 = 12; HIF8 = 14
    FP8E4M3 = 15; FP8E5M2 = 16; FP8E8M0 = 17

_binding.py 只引用 types.py 的枚举,不重复定义——单一来源。

ops/ — 算子接口层

每算子一模块(ops/broadcast.py、ops/all_reduce.py …),ops/__init__.py 扁平再导出。用户视角:

from hccl4py.ops import broadcast, all_reduce, send  # 一个 import 搞定

每个模块极薄,以 broadcast 为例:

def broadcast(hccl_comm, buf, count, data_type, root, stream):
    _check_stream(stream)
    ret = hccl_broadcast(buf, int(count), int(data_type), int(root),
                         hccl_comm, stream)
    if ret != types.HCCL_SUCCESS:
        raise HcclError(ret)
    return ret

没有业务逻辑、类型推导、默认值填充——调用方显式给出所有参数,绑定原样转发。

comm.py — 通信域层

5 个接口:get_root_info、init_rank_config、init_cluster_config、config_init、destroy_comm。比算子层稍厚,因为通信域创建涉及出参改返回值、config 默认值填充、rootInfo 序列化辅助。但仍然没有"业务逻辑",只是把 C 的出参模式翻译成 Python 的返回值模式。

双仓分工

ops/ 属 hccl 仓,comm.py 属 hcomm 仓。两仓各自 PR 合入时均提交完整包目录,声明层(_binding.py/types.py)内容保持一致,最终两仓代码各自独立完整可运行。

这不是两个独立包,是同一个包 hccl4py 的两半,按 C 侧的仓库边界切分。

为什么不分更厚

可以在算子层加 dtype 推导(根据 numpy 数组自动推断 HcclDataType)、加 buffer 自动 device 化、加 stream 自动创建。这些会让用户代码更短,但:

  • 推导逻辑出错时,错误发生在绑定层而非用户代码,调试困难;
  • 隐式行为与 C 接口语义不一致,用户对照 C 文档时产生困惑;

薄绑定的代价是用户多写几个参数,收益是行为完全可预测、与 C 文档一一对照、性能开销透明。

下一篇:ctypes 结构体绑定。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。