
CANN opbase 算子格式解析指南GetPrimaryFormat 接口詳解【免費(fèi)下載鏈接】opbase本項(xiàng)目是CANN算子庫(kù)的基礎(chǔ)框架庫(kù)為算子提供公共依賴文件和基礎(chǔ)調(diào)度能力。項(xiàng)目地址: https://gitcode.com/cann/opbase導(dǎo)讀GetPrimaryFormat是 CANN opbase 算子基礎(chǔ)框架庫(kù)include/nnopbase/opdev/format_utils.h提供的格式歸一化接口用于從攜帶 C0 擴(kuò)展信息的完整存儲(chǔ)格式如FORMAT_FRACTAL_Z_C04中提取根 format如FORMAT_FRACTAL_Z。本文基于 docs/zh/api/nnopbase/opdev/format_utils/GetPrimaryFormat.md 的接口說明結(jié)合倉(cāng)庫(kù)內(nèi)實(shí)現(xiàn)與調(diào)用點(diǎn)講解其函數(shù)原型、位級(jí)實(shí)現(xiàn)原理、參數(shù)返回值語(yǔ)義以及它在算子緩存 key 生成、調(diào)試信息輸出、tiling 上下文序列化等場(chǎng)景中的典型用法。功能說明GetPrimaryFormat用于獲取根 formatprimary format即去除與 C0 相關(guān)的擴(kuò)展信息后只保留單純 format 信息的格式。例如將FORMAT_FRACTAL_Z_C04轉(zhuǎn)換為FORMAT_FRACTAL_Z輸入 format輸出primary formatFORMAT_FRACTAL_Z_C04FORMAT_FRACTAL_Z這種歸一化在算子開發(fā)中非常常見同一算子的二進(jìn)制bin通常按主 format 編譯而運(yùn)行時(shí)張量的存儲(chǔ)格式可能攜帶 C0 變體信息因此在匹配算子實(shí)現(xiàn)、生成緩存 key 或輸出診斷信息前需要先把完整格式歸一到根格式上。函數(shù)原型GetPrimaryFormat提供兩個(gè)重載版本分別接受int32_t與Format類型的入?yún)nt32_t GetPrimaryFormat(int32_t format)Format GetPrimaryFormat(Format format)兩個(gè)重載位于命名空間op中均為內(nèi)聯(lián)函數(shù)實(shí)現(xiàn)在 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 視為無符號(hào) 32 位整數(shù)與0xffU做按位與取低 8 位作為根 format再按入?yún)㈩愋娃D(zhuǎn)換回int32_t或Format。區(qū)別僅在于返回類型便于調(diào)用方在需要Format枚舉值如直接與FORMAT_FRACTAL_Z比較與需要整型值如寫入序列化數(shù)據(jù)兩種場(chǎng)景下靈活選用。參數(shù)說明參數(shù)輸入/輸出說明format輸入原始目標(biāo)數(shù)據(jù)格式即可能攜帶 C0 等擴(kuò)展信息的完整存儲(chǔ)格式。format支持兩種類型int32_t整型值通常來自GetStorageFormat()等接口返回的原始編碼或Format枚舉值ge::Format語(yǔ)義。兩種類型在調(diào)用點(diǎn)可互換使用框架內(nèi)部均按同一套位布局解析。返回值說明返回去除 C0 信息后的根格式int32_t重載返回去除擴(kuò)展位后的整型格式值Format重載返回對(duì)應(yīng)的Format枚舉值。如果入?yún)⒈旧砭筒缓?C0 擴(kuò)展信息即高 24 位全為 0則返回值與入?yún)⒁恢录丛摻涌趯?duì)普通格式是冪等的。約束說明無。該接口為純位運(yùn)算的輕量?jī)?nèi)聯(lián)函數(shù)不涉及資源申請(qǐng)、格式合法性校驗(yàn)或運(yùn)行環(huán)境依賴可在任意上下文中安全調(diào)用代價(jià)可忽略不計(jì)。調(diào)用示例以下示例來自 docs/zh/api/nnopbase/opdev/format_utils/GetPrimaryFormat.md演示判斷某個(gè)張量的 storage format 是否為 fractal z 格式// 判斷當(dāng)input的storage format是fractal z時(shí)返回 void Func(const aclTensor *input) { if (GetPrimaryFormat(input-GetStorageFormat()) FORMAT_FRACTAL_Z){ return; } }這里的關(guān)鍵點(diǎn)在于input-GetStorageFormat()返回的是張量實(shí)際的完整存儲(chǔ)格式可能包含_C04等 C0 變體后綴直接與FORMAT_FRACTAL_Z比較可能不相等。先經(jīng)過GetPrimaryFormat歸一化后再比較才能正確識(shí)別底層數(shù)據(jù)布局屬于 fractal z 家族的張量。源碼級(jí)原理解析format 的位布局要理解GetPrimaryFormat為什么取低 8 位需要看format的整體編碼。從 include/nnopbase/opdev/format_utils.h 中與之配套的一系列內(nèi)聯(lián)函數(shù)可以還原出完整的位布局約定// 根 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 指數(shù)高 4 位bit24 ~ bit271 左移該指數(shù)即得到 C0 數(shù)值 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)); }可以推斷倉(cāng)庫(kù)采用的 format 編碼布局為bit0 ~ bit7低 8 位根 formatprimary format即GetPrimaryFormat提取的部分如FORMAT_FRACTAL_Zbit8 ~ bit23中間 16 位子 formatsub format由GetSubFormat提取用于表達(dá)更細(xì)粒度的格式變體bit24 ~ bit27高 4 位C0 指數(shù)C0 信息由GetC0Format/HasC0Format提取對(duì)應(yīng)FORMAT_FRACTAL_Z_C04這類帶 C0 的格式——C04即表示 C0 值為 4編碼時(shí)以1 左移指數(shù) - 1的方式存取。因此GetPrimaryFormat的 0xffU掩碼本質(zhì)上就是只保留格式編碼中的根 format 字段屏蔽掉子 format 與 C0 兩類擴(kuò)展信息。需要說明的是該接口只做位截取不執(zhí)行格式合法性校驗(yàn)即使入?yún)⒉⒎呛戏ň幋a接口也會(huì)按位運(yùn)算返回結(jié)果。調(diào)用方應(yīng)在業(yè)務(wù)邏輯層面保證入?yún)碜钥蚣芴峁┑拇鎯?chǔ)格式或另行配合格式合法性判斷。典型使用場(chǎng)景倉(cāng)庫(kù)內(nèi)的真實(shí)調(diào)用GetPrimaryFormat在倉(cāng)庫(kù)中被多處使用以下是幾個(gè)有代表性的調(diào)用點(diǎn)可用于理解它的實(shí)際業(yè)務(wù)價(jià)值。1. 算子緩存 key 生成時(shí)的格式匹配在 src/nnopbase/composite_op/aclnn_engine/kernel_arg.cpp 的GenKeyByArgImpl中框架為算子執(zhí)行生成緩存 key 時(shí)會(huì)用GetPrimaryFormat歸一化張量的存儲(chǔ)格式再與算子注冊(cè)信息中聲明支持的格式集合進(jìn)行匹配auto primaryFormat static_castge::Format(GetPrimaryFormat(tensor-GetStorageFormat())); if (tensorInfo.fmtInfo.supportFormats.count(primaryFormat) ! 0) { AssignAndIncrement(key, primaryFormat); } else { ... }此處若不歸一化帶有_C04等后綴的存儲(chǔ)格式將無法命中按根 format 注冊(cè)的算子實(shí)現(xiàn)導(dǎo)致緩存 miss 甚至匹配失敗失敗時(shí)打印的錯(cuò)誤信息同樣使用GetPrimaryFormat輸出見 kernel_arg.cpp。2. 調(diào)試與日志信息的可讀化輸出在 include/op_common/op_host/tiling_base_class.h 的GetTensorDebugStr中tiling 基類打印張量調(diào)試信息時(shí)先用GetPrimaryFormat歸一化存儲(chǔ)格式再調(diào)用ge::TypeUtils::FormatToSerialString轉(zhuǎn)成可讀字符串oss (format: ge::TypeUtils::FormatToSerialString( static_castge::Format(ge::GetPrimaryFormat(tensor-GetStorageFormat()))) ),;同樣的模式也出現(xiàn)在 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 上下文轉(zhuǎn) JSON 時(shí)分別處理三個(gè)字段形成完整的格式信息輸出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負(fù)責(zé)根格式GetSubFormat/HasSubFormat負(fù)責(zé)子格式GetC0Format/HasC0Format負(fù)責(zé) C0 信息共同保證 dump 出的 JSON 中格式信息完整且不丟失任何擴(kuò)展細(xì)節(jié)。與配套接口的配合使用GetPrimaryFormat通常與 format_utils.h 中的其他格式解析接口搭配使用形成完整的格式處理能力接口作用提取位段GetPrimaryFormat獲取根 format去除 C0 與子格式信息bit0 ~ bit7GetSubFormat獲取子 formatbit8 ~ bit23HasSubFormat判斷是否攜帶子 format 信息bit8 ~ bit23 非零GetC0Format獲取 C0 數(shù)值bit24 ~ bit27指數(shù)換算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之間的互轉(zhuǎn)見 format_utils.h它們與GetPrimaryFormat一起構(gòu)成 CANN opbase 面向算子開發(fā)者的完整格式工具集。英文版接口說明見 docs/en/api/nnopbase/opdev/format_utils/GetPrimaryFormat.md。總結(jié)GetPrimaryFormat是 CANN opbase 算子開發(fā)中最常用的格式歸一化接口之一接口語(yǔ)義去除 format 編碼中的 C0 擴(kuò)展信息只保留根 format實(shí)現(xiàn)原理format 0xffU取低 8 位為純位運(yùn)算內(nèi)聯(lián)實(shí)現(xiàn)零開銷典型場(chǎng)景算子緩存 key 的格式匹配kernel_arg.cpp、tiling 調(diào)試信息輸出tiling_base_class.h、tiling 上下文 JSON 序列化tiling_context_to_json.cpp與 format 字符串化kernel_util.cc。在算子開發(fā)與調(diào)試中凡是需要將攜帶擴(kuò)展信息的存儲(chǔ)格式與按根格式組織的數(shù)據(jù)算子 bin、支持格式集合、日志標(biāo)簽等對(duì)齊的場(chǎng)景都應(yīng)優(yōu)先考慮使用GetPrimaryFormat進(jìn)行歸一化避免因_C04等后綴導(dǎo)致格式比較失敗或緩存無法命中?!久赓M(fèi)下載鏈接】opbase本項(xiàng)目是CANN算子庫(kù)的基礎(chǔ)框架庫(kù)為算子提供公共依賴文件和基礎(chǔ)調(diào)度能力。項(xiàng)目地址: https://gitcode.com/cann/opbase創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考