ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

CANN opbase 算子格式解析指南:GetPrimaryFormat 接口详解

CANN opbase 算子格式解析指南:GetPrimaryFormat 接口详解 CANN opbase 算子格式解析指南GetPrimaryFormat 接口详解【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase导读GetPrimaryFormat是 CANN opbase 算子基础框架库include/nnopbase/opdev/format_utils.h提供的格式归一化接口用于从携带 C0 扩展信息的完整存储格式如FORMAT_FRACTAL_Z_C04中提取根 format如FORMAT_FRACTAL_Z。本文基于 docs/zh/api/nnopbase/opdev/format_utils/GetPrimaryFormat.md 的接口说明结合仓库内实现与调用点讲解其函数原型、位级实现原理、参数返回值语义以及它在算子缓存 key 生成、调试信息输出、tiling 上下文序列化等场景中的典型用法。功能说明GetPrimaryFormat用于获取根 formatprimary format即去除与 C0 相关的扩展信息后只保留单纯 format 信息的格式。例如将FORMAT_FRACTAL_Z_C04转换为FORMAT_FRACTAL_Z输入 format输出primary formatFORMAT_FRACTAL_Z_C04FORMAT_FRACTAL_Z这种归一化在算子开发中非常常见同一算子的二进制bin通常按主 format 编译而运行时张量的存储格式可能携带 C0 变体信息因此在匹配算子实现、生成缓存 key 或输出诊断信息前需要先把完整格式归一到根格式上。函数原型GetPrimaryFormat提供两个重载版本分别接受int32_t与Format类型的入参int32_t GetPrimaryFormat(int32_t format)Format GetPrimaryFormat(Format format)两个重载位于命名空间op中均为内联函数实现在 include/nnopbase/opdev/format_utils.hinline int32_t GetPrimaryFormat(int32_t format) { return static_castint32_t(static_castuint32_t(format) 0xffU); } inline Format GetPrimaryFormat(Format format) { return static_castFormat(static_castuint32_t(format) 0xffU); }从源码可以看出两种重载的核心逻辑完全相同将 format 视为无符号 32 位整数与0xffU做按位与取低 8 位作为根 format再按入参类型转换回int32_t或Format。区别仅在于返回类型便于调用方在需要Format枚举值如直接与FORMAT_FRACTAL_Z比较与需要整型值如写入序列化数据两种场景下灵活选用。参数说明参数输入/输出说明format输入原始目标数据格式即可能携带 C0 等扩展信息的完整存储格式。format支持两种类型int32_t整型值通常来自GetStorageFormat()等接口返回的原始编码或Format枚举值ge::Format语义。两种类型在调用点可互换使用框架内部均按同一套位布局解析。返回值说明返回去除 C0 信息后的根格式int32_t重载返回去除扩展位后的整型格式值Format重载返回对应的Format枚举值。如果入参本身就不含 C0 扩展信息即高 24 位全为 0则返回值与入参一致即该接口对普通格式是幂等的。约束说明无。该接口为纯位运算的轻量内联函数不涉及资源申请、格式合法性校验或运行环境依赖可在任意上下文中安全调用代价可忽略不计。调用示例以下示例来自 docs/zh/api/nnopbase/opdev/format_utils/GetPrimaryFormat.md演示判断某个张量的 storage format 是否为 fractal z 格式// 判断当input的storage format是fractal z时返回 void Func(const aclTensor *input) { if (GetPrimaryFormat(input-GetStorageFormat()) FORMAT_FRACTAL_Z){ return; } }这里的关键点在于input-GetStorageFormat()返回的是张量实际的完整存储格式可能包含_C04等 C0 变体后缀直接与FORMAT_FRACTAL_Z比较可能不相等。先经过GetPrimaryFormat归一化后再比较才能正确识别底层数据布局属于 fractal z 家族的张量。源码级原理解析format 的位布局要理解GetPrimaryFormat为什么取低 8 位需要看format的整体编码。从 include/nnopbase/opdev/format_utils.h 中与之配套的一系列内联函数可以还原出完整的位布局约定// 根 format低 8 位bit0 ~ bit7 inline Format GetPrimaryFormat(Format format) { return static_castFormat(static_castuint32_t(format) 0xffU); } // 子 format中间 16 位bit8 ~ bit23 inline int32_t GetSubFormat(int32_t format) { return static_castint32_t((static_castuint32_t(format) 0xffff00U) BIT_NUM_OF_ONE_BYTE); } // 是否存在子 format 信息 inline bool HasSubFormat(int32_t format) { return GetSubFormat(format) 0; } // C0 指数高 4 位bit24 ~ bit271 左移该指数即得到 C0 数值 inline int64_t GetC0Format(int32_t format) { return static_castint64_t( 1 (static_castint32_t((static_castuint32_t(format) 0xf000000U) BIT_THREE_BYTES) - 1)); } // 是否存在 C0 信息 inline bool HasC0Format(int32_t format) { return ((static_castuint32_t(format) 0xf000000U) BIT_THREE_BYTES) 0; } // 由根 format 与子 format 反向合成完整格式 inline Format GetFormatFromSub(int32_t primaryFormat, int32_t subFormat) { return static_castFormat((static_castuint32_t(primaryFormat) 0xffU) | ((static_castuint32_t(subFormat) 0xffffU) 8U)); }可以推断仓库采用的 format 编码布局为bit0 ~ bit7低 8 位根 formatprimary format即GetPrimaryFormat提取的部分如FORMAT_FRACTAL_Zbit8 ~ bit23中间 16 位子 formatsub format由GetSubFormat提取用于表达更细粒度的格式变体bit24 ~ bit27高 4 位C0 指数C0 信息由GetC0Format/HasC0Format提取对应FORMAT_FRACTAL_Z_C04这类带 C0 的格式——C04即表示 C0 值为 4编码时以1 左移指数 - 1的方式存取。因此GetPrimaryFormat的 0xffU掩码本质上就是只保留格式编码中的根 format 字段屏蔽掉子 format 与 C0 两类扩展信息。需要说明的是该接口只做位截取不执行格式合法性校验即使入参并非合法编码接口也会按位运算返回结果。调用方应在业务逻辑层面保证入参来自框架提供的存储格式或另行配合格式合法性判断。典型使用场景仓库内的真实调用GetPrimaryFormat在仓库中被多处使用以下是几个有代表性的调用点可用于理解它的实际业务价值。1. 算子缓存 key 生成时的格式匹配在 src/nnopbase/composite_op/aclnn_engine/kernel_arg.cpp 的GenKeyByArgImpl中框架为算子执行生成缓存 key 时会用GetPrimaryFormat归一化张量的存储格式再与算子注册信息中声明支持的格式集合进行匹配auto primaryFormat static_castge::Format(GetPrimaryFormat(tensor-GetStorageFormat())); if (tensorInfo.fmtInfo.supportFormats.count(primaryFormat) ! 0) { AssignAndIncrement(key, primaryFormat); } else { ... }此处若不归一化带有_C04等后缀的存储格式将无法命中按根 format 注册的算子实现导致缓存 miss 甚至匹配失败失败时打印的错误信息同样使用GetPrimaryFormat输出见 kernel_arg.cpp。2. 调试与日志信息的可读化输出在 include/op_common/op_host/tiling_base_class.h 的GetTensorDebugStr中tiling 基类打印张量调试信息时先用GetPrimaryFormat归一化存储格式再调用ge::TypeUtils::FormatToSerialString转成可读字符串oss (format: ge::TypeUtils::FormatToSerialString( static_castge::Format(ge::GetPrimaryFormat(tensor-GetStorageFormat()))) ),;同样的模式也出现在 aicpu_common/context/utils/kernel_util.cc 的FormatToSerialString中先用GetPrimaryFormat在kFormatToStringMap中查找根格式的字符串名若存在子 format 再追加:子格式值后缀。3. tiling 上下文 JSON 序列化在 src/nnopbase/common/op_info_record/tiling_context_to_json.cpp 中tiling 上下文转 JSON 时分别处理三个字段形成完整的格式信息输出j[format] ge::TypeUtils::FormatToSerialString( static_castge::Format(ge::GetPrimaryFormat(cpTdInfo-GetStorageFormat()))); if (ge::HasSubFormat(cpTdInfo-GetStorageFormat())) { j[sub_format] ge::GetSubFormat(cpTdInfo-GetStorageFormat()); } if (ge::HasC0Format(cpTdInfo-GetStorageFormat())) { j[c0_format] ge::GetC0Format(cpTdInfo-GetStorageFormat()); }这里可以清晰地看到三者的分工GetPrimaryFormat负责根格式GetSubFormat/HasSubFormat负责子格式GetC0Format/HasC0Format负责 C0 信息共同保证 dump 出的 JSON 中格式信息完整且不丢失任何扩展细节。与配套接口的配合使用GetPrimaryFormat通常与 format_utils.h 中的其他格式解析接口搭配使用形成完整的格式处理能力接口作用提取位段GetPrimaryFormat获取根 format去除 C0 与子格式信息bit0 ~ bit7GetSubFormat获取子 formatbit8 ~ bit23HasSubFormat判断是否携带子 format 信息bit8 ~ bit23 非零GetC0Format获取 C0 数值bit24 ~ bit27指数换算HasC0Format判断是否携带 C0 信息bit24 ~ bit27 非零GetFormatFromSub由根 format 与子 format 合成完整格式低 8 位 bit8 起 16 位在 docs/zh/api/nnopbase/opdev/format_utils/format_utils.md 中可以看到format_utils 目录下还包含IsPrivateFormat、ToOpFormat、ToAclFormat等接口用于私有格式判断、aclFormat与Format之间的互转见 format_utils.h它们与GetPrimaryFormat一起构成 CANN opbase 面向算子开发者的完整格式工具集。英文版接口说明见 docs/en/api/nnopbase/opdev/format_utils/GetPrimaryFormat.md。总结GetPrimaryFormat是 CANN opbase 算子开发中最常用的格式归一化接口之一接口语义去除 format 编码中的 C0 扩展信息只保留根 format实现原理format 0xffU取低 8 位为纯位运算内联实现零开销典型场景算子缓存 key 的格式匹配kernel_arg.cpp、tiling 调试信息输出tiling_base_class.h、tiling 上下文 JSON 序列化tiling_context_to_json.cpp与 format 字符串化kernel_util.cc。在算子开发与调试中凡是需要将携带扩展信息的存储格式与按根格式组织的数据算子 bin、支持格式集合、日志标签等对齐的场景都应优先考虑使用GetPrimaryFormat进行归一化避免因_C04等后缀导致格式比较失败或缓存无法命中。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表