CANN opbase 中 aclTensor 的 SetOriginalFormat 接口:原始 Format 设置原理与实战解析
2026/9/19 17:26:11 网站建设 项目流程

CANN opbase 中 aclTensor 的 SetOriginalFormat 接口:原始 Format 设置原理与实战解析

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

SetOriginalFormat是 CANN opbase 基础框架库中aclTensor公共类型的一个成员接口,用于设置张量在经历transdata节点之前的原始 Format(OriginFormat)。本文将以 SetOriginalFormat.md 为骨架,结合仓库源码与测试用例,讲解该接口的原型、参数、底层实现链路、Format 枚举体系及在算子开发与框架调度中的实际应用,帮助算子开发者准确理解并正确使用原始格式设置能力。

OriginFormat:先弄清"原始格式"到底是什么

在昇腾计算图的算子链路中,张量的数据排布格式(Format)并非一成不变。为满足昇腾 AI Core 对特定算子的高效计算要求,框架可能会在算子之间插入transdata节点,将张量从一种格式转换为另一种格式。例如,把 NCHW 布局的张量转换为适合昇腾硬件计算的 FRACTAL_NZ 分形格式。

OriginFormat描述的就是aclTensor 在经历 transdata 节点之前(如果存在该节点)的原始 Format 信息。它记录的是"这份数据最初以什么格式排布",而与之相对的StorageFormat则描述数据在当前存储中的实际排布。二者解耦的意义在于:即使张量在底层已经以某种硬件友好的格式存储,上层语义(如 shape 推导、算子语义判断、dump 信息还原)依然可以追溯到其原始格式。

SetOriginalFormat正是用于显式设置这一原始格式信息的接口,原型如下:

void SetOriginalFormat(op::Format format)

参数说明

参数输入/输出说明
format输入数据类型为op::Format(即ge::Format),是一个枚举类型,定义了多种不同的数据排布格式,例如 NCHW、ND、NC1HWC0、FRACTAL_NZ 等。
  • 返回值:无(void)。
  • 约束:无。接口为普通成员函数,直接写入张量的 Format 元信息,不涉及内存分配或设备侧操作。

源码级解析:接口的底层实现链路

SetOriginalFormat声明于公共类型头文件 common_types.h,位于aclTensor类中,与GetOriginalFormatSetStorageFormatSetViewFormat等接口并列,共同构成 aclTensor 的 Format 三视图管理能力:

op::Format GetStorageFormat() const; void SetStorageFormat(op::Format format); op::Format GetOriginalFormat() const; void SetOriginalFormat(op::Format format); op::Format GetViewFormat() const; void SetViewFormat(op::Format format);

其实际实现位于 common_types.cpp,实现非常简洁——委托给内部的op::Tensor对象:

void aclTensor::SetOriginalFormat(op::Format format) { tensor_->SetOriginFormat(format); }

对应的读取接口实现为(common_types.cpp):

op::Format aclTensor::GetOriginalFormat() const { return tensor_->GetFormat().GetOriginFormat(); }

由此可见,aclTensor是对内部op::Tensor元数据的薄封装:Format 信息被聚合存储在 Tensor 的 Format 描述对象中,SetOriginalFormat/GetOriginalFormat只是把OriginFormat的读写能力暴露给算子开发者。从代码结构看,SetOriginalFormatSetStorageFormat(common_types.cpp)、SetViewFormat(common_types.cpp)三者分别维护原始格式、存储格式与视图格式,对应 common_types.h 中GetStorageShape/GetOriginalShape/GetViewShape的"存储-原始-视图"三视图设计思想。

常用 Format 枚举值

op::Formatge::Format,完整枚举定义可参考 AICPU 侧公共类型头文件 cpu_types.h,常用取值包括:

枚举值含义
FORMAT_NCHW经典四维布局,通道维 C 在第二位(值为 0)
FORMAT_NHWC通道维 C 在最后一位
FORMAT_ND通用多维张量布局,不限定维度数
FORMAT_NC1HWC0昇腾特有的 5 维布局,C 维按 C0(通常为 16)切分
FORMAT_FRACTAL_NZ分形 NZ 格式,AI Core 计算友好的权重/激活布局
FORMAT_NDC1HWC0/FORMAT_FRACTAL_Z5D/3D 场景及更多专用布局

此外,format_utils.h 提供了一组格式辅助工具,可用于判断私有格式、字符串与枚举互转以及提取主格式/子格式/C0 信息,例如op::ToFormat(const std::string&)op::ToString(Format)op::GetPrimaryFormatop::GetSubFormatop::GetC0Format,实际排布还可能通过主格式+子格式组合编码的方式表达,设置原始格式时传入基础枚举值即可。

调用示例

将输入张量的 OriginFormat 显式设置为 ND 格式(即原文档示例):

// 将 input 的 OriginFormat 置为 ND 格式 void Func(const aclTensor *input) { input->SetOriginalFormat(ge::FORMAT_ND); }

将张量原始格式设置为 FRACTAL_NZ 的完整读写示例:

#include "nnopbase/opdev/common_types.h" void SetAndQueryOriginalFormat(aclTensor *tensor) { // 设置原始格式为 FRACTAL_NZ tensor->SetOriginalFormat(op::Format::FORMAT_FRACTAL_NZ); // 读取并核对 op::Format fmt = tensor->GetOriginalFormat(); // fmt == op::Format::FORMAT_FRACTAL_NZ }

注意示例中既可以使用ge::FORMAT_NDge命名空间别名),也可以使用op::Format::FORMAT_FRACTAL_NZop命名空间),二者指向同一枚举。

配套接口与三格式协同

aclTensor围绕 Format 提供了一组配套读写接口(common_types.h),实际开发中通常成组使用:

  • GetStorageFormat()/SetStorageFormat(Format):数据在内存中的实际存储格式;
  • GetOriginalFormat()/SetOriginalFormat(Format):数据进入 transdata 之前的原始格式;
  • GetViewFormat()/SetViewFormat(Format):视图(view)语义下的格式,配合SetViewShape使用。

三者的典型关系是:原始格式描述语义排布,存储格式描述物理排布,视图格式描述用户视角的切片排布。当张量经过transdata后,其 StorageFormat 发生变化而 OriginFormat 保持不变,这正是推理与调试场景中还原数据原始语义的关键。

在框架调度中的实际应用

从源码搜索可以看到OriginFormat被框架多个模块读取使用,这些调用点印证了该接口的实战价值:

  • Tiling 上下文构建:在单算子执行器中,indv_tilingcontext_builder.cpp 等多处通过storageFormat.GetOriginFormat()将原始格式写入 TilingData,供 AI Core 侧 Tiling 解析使用;
  • 编译描述生成:复合算子引擎在 kernel_context_holder.cpp 中通过tensor->GetOriginalFormat()把原始格式写入编译描述(compileDesc)的 storage_format,参与算子二进制选择与缓存 key 构建;
  • Tiling 信息落盘:算子信息记录模块在 tiling_context_to_json.cpp 中将origin_format序列化进 JSON,供离线分析工具还原 Tiling 现场;
  • 执行器张量维护:indv_executor_tensor.cpp 在运行期按实际存储格式对运行时张量调用SetOriginFormat,保证运行时上下文与编译期描述一致。

测试验证

仓库测试用例对SetOriginalFormatGetOriginalFormat的读写一致性做了直接验证,见 test_common_types.cpp(UT 用例,ST 侧用例见 test_common_types.cpp):

a.SetStorageFormat(Format::FORMAT_FRACTAL_NZ); EXPECT_EQ(a.GetStorageFormat(), Format::FORMAT_FRACTAL_NZ); a.SetOriginalFormat(Format::FORMAT_FRACTAL_NZ); EXPECT_EQ(a.GetOriginalFormat(), Format::FORMAT_FRACTAL_NZ); a.SetViewFormat(Format::FORMAT_FRACTAL_NZ); EXPECT_EQ(a.GetViewFormat(), Format::FORMAT_FRACTAL_NZ);

该用例将 Storage/Original/View 三种格式分别设置并断言读取结果,直接验证了SetOriginalFormat的写入-读取闭环,也佐证了三格式互不干扰、独立存取的设计。

使用建议与注意事项

  1. 设置时机:建议在创建/构造 aclTensor 语义信息时同步设置原始格式,或在张量经过格式转换(transdata)之前记录下转换前的格式,避免语义信息丢失;
  2. 与 StorageFormat 的关系SetOriginalFormat只影响语义层面的原始格式记录,不会触发数据重排或内存搬运,真正的数据转换由transdata算子完成,本接口只是元数据标注;
  3. 与视图语义配合:当通过aclCreateTensor等接口创建带 view 语义的张量时,建议同时明确 Storage/Original/View 三套格式,保证 shape 推导、tiling 计算与 dump 信息完整一致;
  4. 格式化调试:如需将 Format 转为可读字符串,可使用 format_utils.h 中的op::ToString(Format),与 Tiling 落盘 JSON 中的origin_format字段对应,便于排查格式链路问题。

小结

SetOriginalFormat虽然是一个仅有几行实现的小接口,却是 aclTensor 三视图 Format 体系中承上启下的一环:它把"数据在 transdata 之前的原始格式"显式记录进张量元数据,并被 tiling 上下文构建、编译描述生成与信息落盘等框架模块广泛读取。掌握该接口及配套的GetOriginalFormat/SetStorageFormat/SetViewFormat,有助于在自定义算子开发中正确维护张量格式语义,确保 shape 推导、tiling 与 dump 全链路的信息一致性。相关接口的完整清单可参阅 common_types.md 与 opdev API 总览。

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

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询