news 2026/9/19 21:02:53

CANN opbase 格式工具 GetPrimaryFormat:获取根 Format 的实现原理与调用指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CANN opbase 格式工具 GetPrimaryFormat:获取根 Format 的实现原理与调用指南

CANN opbase 格式工具 GetPrimaryFormat:获取根 Format 的实现原理与调用指南

【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase

导读

GetPrimaryFormat是 CANN opbase 算子库(cann/opbase)中format_utils工具集的核心接口之一,用于从携带 C0 扩展信息的格式编码中提取"根格式",例如将FORMAT_FRACTAL_Z_C04归一化为FORMAT_FRACTAL_Z。在算子开发中,当需要基于张量实际存储格式做分支判断(如判断是否 fractal Z 数据)时,该接口可以屏蔽 C0 子格式差异,让判断逻辑更简洁可靠。读完本文你将掌握GetPrimaryFormat的两种重载形式、位域编码原理、实际调用场景,以及与format_utils家族其他接口(IsPrivateFormatGetSubFormatToOpFormat等)的配合方式。

功能说明

GetPrimaryFormat获取张量数据的根 format,即去除关于 C0 的信息,只保留单纯的 format 信息

在昇腾算子的数据布局体系中,部分格式会在基础格式之上叠加 C0 维度信息,形成"带子格式的扩展格式"。例如:

  • FORMAT_FRACTAL_Z_C04FORMAT_FRACTAL_Z
  • FORMAT_NC1HWC0_C04FORMAT_NC1HWC0

这类 C0 扩展格式在语义上仍属于其根格式,因此在做格式判断、格式映射、日志打印等操作时,往往需要先剥离 C0 信息、还原根格式,这正是GetPrimaryFormat的职责所在。

函数原型

GetPrimaryFormat提供两个重载版本,分别面向底层整数编码与Format枚举类型:

int32_t GetPrimaryFormat(int32_t format)
Format GetPrimaryFormat(Format format)

其中Formatop::Format(等同于ge::Format),是算子侧使用的格式枚举类型;而int32_t版本适用于需要在整数层面直接处理格式编码的场景,例如在日志序列化、tiling 信息落盘等模块中传入原始整型格式值。

参数说明

参数输入/输出说明
format输入原始目标数据格式,可为int32_t格式编码或Format枚举值。

返回值说明

返回去除 C0 信息后的格式:

  • int32_t重载返回剥离 C0 信息后的整型格式编码;
  • Format重载返回剥离 C0 信息后的Format枚举值。

传入的格式本身不携带 C0 信息时,返回值与传入值保持一致(对格式无副作用,可安全用于任意格式的归一化处理)。

约束说明

无。该接口为纯位运算实现,不依赖运行环境、不申请内存、不抛异常,可在算子 Shape 推导、tiling 计算、日志输出等任意阶段安全调用。

底层实现原理:Format 的位域编码

GetPrimaryFormat的实现位于 include/nnopbase/opdev/format_utils.h,是一个内联函数,核心逻辑只有一行位掩码运算:

inline int32_t GetPrimaryFormat(int32_t format) { return static_cast<int32_t>(static_cast<uint32_t>(format) & 0xffU); } inline Format GetPrimaryFormat(Format format) { return static_cast<Format>(static_cast<uint32_t>(format) & 0xffU); }

从源码结构可以推断出Format枚举值是一个 32 位整数,其位域布局如下:

  • 低 8 位(bit 0–7):根格式(primary format),即GetPrimaryFormat通过& 0xffU保留的部分;
  • bit 8–23:子格式(sub format),由 GetSubFormat 通过& 0xffff00U再右移 8 位提取;
  • bit 24–27:C0 格式(C0 format),由 GetC0Format / HasC0Format 通过& 0xf000000U提取,用于标记 C0 通道数(如 C04 表示 C0=4)。

因此,当格式编码为FORMAT_FRACTAL_Z_C04时,其高 28 位携带了子格式/C0 信息,而低 8 位仍是FORMAT_FRACTAL_ZGetPrimaryFormat通过按位与直接命中根格式,计算开销极小(单个位运算指令)。

GetPrimaryFormat配套的还有位域反向组合接口:

inline Format GetFormatFromSub(int32_t primaryFormat, int32_t subFormat)

GetFormatFromSub(include/nnopbase/opdev/format_utils.h)将根格式置于低 8 位、子格式左移 8 位后做按位或,完成与GetPrimaryFormat相反的操作,可用于构造带子格式的完整格式值。

调用示例

原文档给出的典型用法是:当输入张量的存储格式为 fractal Z 时提前返回,配合GetStorageFormat()读取存储格式:

// 判断当 input 的 storage format 是 fractal z 时,返回 void Func(const aclTensor *input) { if (GetPrimaryFormat(input->GetStorageFormat()) == FORMAT_FRACTAL_Z) { return; } }

需要注意的是,示例中传入的是input->GetStorageFormat()的结果,存储格式可能是FORMAT_FRACTAL_Z_C04这类携带 C0 信息的扩展格式;若不调用GetPrimaryFormat归一化,直接用== FORMAT_FRACTAL_Z比较会漏掉 C04 等变体。这正是该接口的实战价值所在。

场景一:格式分支判断(算子执行路径选择)

在 src/nnopbase/composite_op/aclnn_engine/kernel_arg.h 中,GetPrimaryFormat被用于判断张量存储格式是否为 fractal Z,从而决定不同的 kernel 参数装配路径:

static_cast<ge::Format>(GetPrimaryFormat(tensor->GetStorageFormat())) == ge::FORMAT_FRACTAL_Z

同一文件的 kernel_arg.cpp 中,也先通过GetPrimaryFormat(tensor->GetStorageFormat())取得根格式,再基于根格式做后续参数构造与地址计算,确保 C04 等变体格式能复用统一的 fractal Z 处理逻辑。

场景二:tiling 上下文序列化

在算子信息记录模块 src/nnopbase/common/op_info_record/tiling_context_to_json.cpp 中,tiling 信息导出 JSON 前会先调用ge::GetPrimaryFormat(cpTdInfo->GetStorageFormat())对存储格式做归一化,保证不同 C0 变体格式在序列化结果中呈现为统一的根格式,避免导出数据出现格式枚举不一致。

场景三:格式名打印与 ToString

在 src/nnopbase/common/utils/format_utils.cpp 的ToString实现中,先调用GetPrimaryFormat拿到根格式后去kFormatToStringMap查找格式名,再通过HasSubFormat(format)判断是否需要追加:子格式号后缀:

const auto it = kFormatToStringMap.find(static_cast<Format>(GetPrimaryFormat(static_cast<int32_t>(format)))); if (it != kFormatToStringMap.end()) { if (op::HasSubFormat(format)) { return ge::AscendString((it->second + ":" + std::to_string(op::GetSubFormat(format))).c_str()); } return ge::AscendString((it->second).c_str()); }

可见GetPrimaryFormatformat_utils内部被ToString复用的基础能力,也是整个格式工具链的基石。

与 format_utils 家族其他接口的配合

GetPrimaryFormat隶属于op命名空间下的format_utils工具集,文档入口见 docs/zh/api/nnopbase/opdev/format_utils/format_utils.md(英文版见 docs/en/api/nnopbase/opdev/format_utils/format_utils.md),同族接口包括:

  • IsPrivateFormat:判断格式是否为私有格式(如FORMAT_NC1HWC0FORMAT_FRACTAL_ZFORMAT_FRACTAL_NZ及其 C0 变体等),实现在 src/nnopbase/common/utils/format_utils.cpp;
  • ToOpFormat:将aclFormat转为op::Format
  • ToAclFormat:将op::Format转为aclFormat,仅支持白名单内的格式(见 include/nnopbase/opdev/format_utils.h),不支持时返回ACL_FORMAT_UNDEFINED
  • GetSubFormat/GetC0Format/HasSubFormat/HasC0Format:子格式与 C0 信息的提取与判定;
  • ToFormat/ToString:格式字符串与枚举的双向转换,ToFormat维护了从"FRACTAL_Z_C04""FRACTAL_NZ_C0_16"等字符串到枚举的映射(src/nnopbase/common/utils/format_utils.cpp)。

实际开发中的常见组合模式是:先用IsPrivateFormat判断是否为私有格式,再用GetPrimaryFormat归一化后与根格式常量比较,最后用ToString输出可读的格式名用于日志。这些接口共同构成了算子侧格式处理的标准工具箱。

总结

GetPrimaryFormat是 CANN opbase 中处理格式归一化的基础工具接口:

  • 职责单一:剥离 C0 信息、还原根格式,对不携带 C0 信息的格式原样返回;
  • 实现极简:基于 32 位格式编码的位域设计,一条& 0xffU位运算完成,零开销、无副作用;
  • 应用广泛:在格式分支判断(kernel_arg.h、kernel_arg.cpp)、tiling 序列化(tiling_context_to_json.cpp)、格式名打印(format_utils.cpp)等核心链路上均有实际调用。

在编写算子代码时,凡是涉及存储格式与根格式常量的比较、格式映射或格式日志输出,建议优先通过GetPrimaryFormat归一化,避免因 C0 子格式差异引入判断遗漏。

【免费下载链接】opbase本项目是CANN算子库的基础框架库,为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 21:00:50

智慧军营管理平台:国产化架构落地与验证实践

简介&#xff1a;本资源是一份面向军队信息化建设管理者、安防系统集成工程师及智慧营区项目实施人员的专业级PPT课件&#xff0c;系统阐述智慧军营综合管理平台的整体架构与12大核心子系统。内容覆盖物联网接入、电子地图可视化防控、一卡通身份认证、应急指挥调度、大数据分析…

作者头像 李华
网站建设 2026/9/19 20:57:59

庖丁解牛式个人成长:普通人精进方法论

1. 项目背景与核心价值"庖丁解牛"这个成语出自《庄子养生主》&#xff0c;原本讲述的是厨师庖丁宰牛时游刃有余的境界。在现代语境下&#xff0c;这个词组常被用来比喻对事物本质的透彻理解和娴熟掌握。而"普通人无条件前程似锦"这个前缀&#xff0c;则给传…

作者头像 李华
网站建设 2026/9/19 20:55:48

Lightning Fabric 安装指南:从 pip/Conda 到源码构建与验证

Lightning Fabric 安装指南&#xff1a;从 pip/Conda 到源码构建与验证 【免费下载链接】pytorch-lightning Pretrain, finetune ANY AI model of ANY size on 1 or 10,000 GPUs with zero code changes. 项目地址: https://gitcode.com/gh_mirrors/py/pytorch-lightning …

作者头像 李华
网站建设 2026/9/19 20:53:34

Delta Lake 与 Iceberg/Hudi 深度对比:表格式选型、性能基准与生态兼容

Delta Lake 与 Iceberg/Hudi 深度对比&#xff1a;表格式选型、性能基准与生态兼容 1. 数据湖表格式概述与核心架构差异 Delta Lake、Apache Iceberg 和 Apache Hudi 是当前数据湖存储格式的三大主流解决方案&#xff0c;它们各自解决了数据湖中事务支持、模式演进和数据治理等…

作者头像 李华
网站建设 2026/9/19 20:51:35

Ryujinx Switch模拟器完整教程:从硬件体检到流畅开玩的5步流程

Ryujinx Switch模拟器完整教程&#xff1a;从硬件体检到流畅开玩的5步流程 【免费下载链接】Ryujinx 用 C# 编写的实验性 Nintendo Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/ry/Ryujinx Ryujinx是一款用 C# 编写的开源 Nintendo Switch 模拟器&…

作者头像 李华