CANN opbase aclTensor::SetStorageFormat 详解:为张量设置存储格式(StorageFormat)
2026/9/19 3:49:25 网站建设 项目流程

CANN opbase aclTensor::SetStorageFormat 详解:为张量设置存储格式(StorageFormat)

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

SetStorageFormat是 CANN opbase 框架库中aclTensor类的核心属性设置接口,用于指定张量在设备内存中的实际排布格式(如 NCHW、ND 等)。本文以 docs/en/api/nnopbase/opdev/common_types/SetStorageFormat.md 为骨架,结合仓库内头文件声明、实现源码与算子执行链路中的真实调用,完整讲解该接口的原型、参数语义、可用格式取值、底层实现机制与在算子开发中的典型用法,帮助算子开发者正确读写张量的存储格式元数据。

1. 功能概述:什么是 StorageFormat

在 CANN opbase 中,aclTensor是算子开发过程中传递张量数据的核心对象。一个aclTensor在内存中的实际排布方式由StorageFormat(存储格式)描述,常见的取值包括NCHWND等。

从仓库源码结构看,aclTensor对张量格式的管理分为三个相互独立的维度(对应三组 Get/Set 接口):

维度语义对应接口
StorageFormat张量在物理内存中的实际排布格式GetStorageFormat、SetStorageFormat
OriginalFormat张量的原始逻辑格式(数据来源时携带的格式)GetOriginalFormat、SetOriginalFormat
ViewFormat当前视图(view)视角下张量的格式GetViewFormat、SetViewFormat

SetStorageFormat专门负责设置其中的StorageFormat维度,即声明该aclTensor在内存中"实际是怎么排的"。

2. 接口原型与参数说明

2.1 原型

SetStorageFormataclTensor的公有成员函数,原型如下:

void SetStorageFormat(op::Format format)

该声明位于 include/nnopbase/opdev/common_types.h#L162-L163:

op::Format GetStorageFormat() const; void SetStorageFormat(op::Format format);

2.2 参数

参数Input/Output说明
formatInput数据类型为op::Format(即ge::Format),是定义不同格式的枚举类型,例如 NCHW、ND 等

关于op::Format的类型来源,include/nnopbase/opdev/common_types.h#L44-L55 中给出了明确的类型别名定义:

namespace op { using Format = ge::Format; using StorageFormat = gert::StorageFormat; // ... } // namespace op

也就是说,op::Formatge::Format是同一枚举类型,二者可以互换使用,文档示例中也直接以ge::FORMAT_ND作为参数传入。

2.3 返回值

该接口无返回值(void),调用失败时也不会抛出异常——它只是纯元数据写入操作(详见第 5 节的源码实现分析)。

2.4 限制

无。

3. 支持的格式取值(op::Format / ge::Format 枚举)

SetStorageFormat的入参是ge::Format枚举。结合 src/nnopbase/common/utils/format_utils.cpp 中ToString(Format)支持的格式映射表,仓库实际识别并支持的格式包括但不限于:

格式枚举字符串典型用途
FORMAT_NCHWNCHW4 维图像数据默认逻辑排布
FORMAT_NHWCNHWC通道在最后的图像数据排布
FORMAT_NDND通用 N 维数据排布,未指定特殊排布时使用
FORMAT_NC1HWC0NC1HWC0昇腾 5D 格式(私有格式)
FORMAT_FRACTAL_ZFRACTAL_Z分形 Z 格式(私有格式)
FORMAT_FRACTAL_NZFRACTAL_NZ分形 NZ 格式(私有格式)
FORMAT_NCNC2 维矩阵数据排布
FORMAT_NCLNCL3 维数据排布
FORMAT_NDHWC/FORMAT_NCDHWNDHWC / NCDHW5 维数据排布
FORMAT_NDC1HWC0NDC1HWC05D 变体格式
FORMAT_FRACTAL_Z_3DFRACTAL_Z_3D3 维分形格式
FORMAT_FRACTAL_NZ_C0_16等系列FRACTAL_NZ_C0_16/32/2/4/8面向不同 C0 对齐宽度的分形格式

说明:上表仅摘录了常用格式;完整的枚举映射可查看 src/nnopbase/common/utils/format_utils.cpp#L103-L171 中的kFormatToStringMap,它覆盖了 50 余种格式。

3.1 私有格式的注意事项

仓库将部分格式标记为"私有格式"(private format)。src/nnopbase/common/utils/format_utils.cpp#L21-L31 中的op::IsPrivateFormat()会判定FORMAT_NC1HWC0FORMAT_FRACTAL_ZFORMAT_NDC1HWC0FORMAT_FRACTAL_Z_3DFORMAT_FRACTAL_NZFORMAT_FRACTAL_NZ_C0_*等为私有格式。在使用特定构造路径创建aclTensor时,若视图格式为私有格式,框架会打印告警日志(见 src/nnopbase/common/utils/common_types.cpp#L212-L214),提示此类格式不应通过某些普通构造接口创建。因此,在调用SetStorageFormat之前,建议结合算子实际支持的格式合理取值。

4. 使用示例

文档给出的最简示例是将输入张量的存储格式设置为 ND:

// Set the storage format of the input to ND. void Func(const aclTensor *input) { input->SetStorageFormat(ge::FORMAT_ND); }

在实际算子开发中,SetStorageFormat常与读取接口配合使用,例如将算子输出张量的存储格式与输入保持一致:

void SetOutputSameAsInput(const aclTensor *input, aclTensor *output) { // 先读取输入张量当前的存储格式 op::Format inputFormat = input->GetStorageFormat(); // 将输出张量的存储格式设置为与输入一致 output->SetStorageFormat(inputFormat); // 同时可配合设置原始格式 output->SetOriginalFormat(input->GetOriginalFormat()); }

读取侧对应的实现是 src/nnopbase/common/utils/common_types.cpp#L404 的GetStorageFormat(),它返回底层op::Tensorgert::TensorV2)中保存的存储格式:

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

5. 源码级实现:SetStorageFormat 做了什么

5.1 实现位置

SetStorageFormat的实现位于 src/nnopbase/common/utils/common_types.cpp#L475:

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

5.2 工作原理

从实现看,aclTensor::SetStorageFormat是一个纯元数据写入操作

  • aclTensor内部维护一个op::Tensor* tensor_指针(即gert::TensorV2),所有格式、形状、数据类型信息都保存在该底层张量对象中(见 include/nnopbase/opdev/common_types.h#L258-L267 的成员声明);
  • SetStorageFormat将入参透传给底层tensor_->SetStorageFormat(format),更新TensorV2内部Format描述中的 storage 部分;
  • 该操作不会对张量数据做任何搬运、转置或重排,也不重新分配内存——它只改变"这段内存该如何被解释"的描述信息。如果存储格式与实际内存排布不一致,可能引发算子侧对数据解释错误,因此调用前需要确保值与真实排布相符。

这一点与aclTensor的多种构造函数的行为一致:构造函数内部通过op::StorageFormat format; format.SetStorageFormat(storageFormat);完成初始存储格式的写入(见 src/nnopbase/common/utils/common_types.cpp#L130-L136),SetStorageFormat只是把这一写入能力开放为运行时可调用的公有接口。

6. 在算子执行链路中的实际应用

SetStorageFormat不仅用于算子开发侧的显式调用,也被框架内部多个执行模块使用:

6.1 复合算子(composite op)编译描述构建

在 src/nnopbase/composite_op/aclnn_engine/kernel_context_holder.cpp#L240 与 第 298 行 中,框架在构建算子编译描述时会把输入/输出张量的存储格式直接透传到compileDesc

compileDesc_[inputNum_].storage_format_.SetStorageFormat(tensor->GetStorageFormat()); // ... compileDesc_[inputNum_ + outputNum_].storage_format_.SetStorageFormat(tensor->GetStorageFormat());

可见:aclTensor上设置的 StorageFormat 会作为算子编译(tiling/编译描述)阶段的输入信息,直接影响算子的编译与调度决策。

6.2 独立算子(individual op)运行时张量同步

在 src/nnopbase/individual_op/executor/indv_executor_tensor.cpp#L305-L308 中,框架在构造运行时(runtime)张量时也会调用SetStorageFormat

rt2Tensor->SetStorageFormat(ge::FORMAT_ND); // ... rt2Tensor->SetStorageFormat(format);

这说明在执行器把算子输入转换为 runtime 张量时,会通过SetStorageFormat显式声明张量的存储格式(默认场景使用FORMAT_ND,特殊场景透传原格式),保证下游 kernel 拿到正确的排布信息。

6.3 调试与序列化输出

此外,aclTensor::ToString()(见 src/nnopbase/common/utils/common_types.cpp#L744-L759)在打印张量信息时会同时输出storage_formatori_format等字段,方便开发者在 dump 调试时核对SetStorageFormat是否生效。

7. 相关辅助工具与配套接口

7.1 格式工具函数

include/nnopbase/opdev/format_utils.h 提供了与op::Format配套的工具函数,在设置存储格式前后可用于格式校验与转换:

函数作用
op::IsPrivateFormat(Format)判断是否为私有格式(NC1HWC0、FRACTAL_Z 等)
op::ToFormat(const std::string&)将字符串(如"ND")转换为Format枚举
op::ToString(Format)Format枚举转换为可读字符串
op::GetPrimaryFormat(Format)提取主格式(低 8 位)
op::GetSubFormat(Format)提取子格式信息
op::HasSubFormat(Format)判断是否携带子格式
op::ToOpFormat(aclFormat)aclFormat转换为op::Format
op::ToAclFormat(Format)op::Format转换回aclFormat,不支持时返回ACL_FORMAT_UNDEFINED

其中op::ToFormatop::ToString的完整字符串-枚举映射见 src/nnopbase/common/utils/format_utils.cpp,可作为设置存储格式时取值范围的权威参考。

7.2 配套接口

SetStorageFormat属于 common_types 接口族 的一员,常用配套接口包括:

  • GetStorageFormat:读取存储格式,与SetStorageFormat互为读写对;
  • SetOriginalFormat / GetOriginalFormat:设置/读取原始格式;
  • SetViewFormat / GetViewFormat:设置/读取视图格式;
  • SetStorageShape / GetStorageShape:设置/读取存储形状(存储格式与存储形状共同决定内存布局的完整描述)。

8. 总结

  • aclTensor::SetStorageFormat(op::Format format)用于设置张量的存储格式元数据,参数类型为op::Format(即ge::Format),无返回值、无限制;
  • 实现上仅为对底层gert::TensorV2的元数据写入(src/nnopbase/common/utils/common_types.cpp#L475),不会触发数据搬运或内存重排,调用前需确保与实际排布一致;
  • 存储格式会沿算子执行链路向下透传:复合算子的编译描述构建(kernel_context_holder.cpp)与独立算子的 runtime 张量构造(indv_executor_tensor.cpp)都会消费该信息,是算子正确编译与执行的关键属性之一。

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

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

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

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

立即咨询