ARTICLE DETAIL

资讯详情

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

CANN opbase 算子开发指南:aclTensor::SetStorageFormat 接口详解与 StorageFormat 内存排布设置

CANN opbase 算子开发指南:aclTensor::SetStorageFormat 接口详解与 StorageFormat 内存排布设置 CANN opbase 算子开发指南aclTensor::SetStorageFormat 接口详解与 StorageFormat 内存排布设置【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase导读本文聚焦 CANN/opbase 算子库中aclTensor对象的核心元数据接口之一 ——SetStorageFormat讲解如何显式设置张量在设备内存中的排布格式StorageFormat并深入源码说明该接口与op::Tensor底层存储格式属性之间的调用关系。阅读本文后你将掌握op::Format即ge::Format枚举的取值约定、aclTensor的 storage/origin/view 三层格式视图的区别以及如何在算子开发与单测中正确设置和校验张量存储格式。一、StorageFormat张量在内存中的排布格式在算子开发过程中张量具备逻辑维度如 NCHW 四维语义与物理存储排布数据在内存中的实际存放顺序两层信息。StorageFormat描述的正是后者 ——aclTensor 在内存中的排布格式例如NCHW、ND、NHWC、NC1HWC0、FRACTAL_NZ等。它决定了算子读取输入、写入输出时如何根据多维索引计算物理内存偏移。在 common_types.h 中可以看到op命名空间对底层类型做了别名统一namespace op { using Format ge::Format; using Tensor gert::TensorV2; using StorageFormat gert::StorageFormat; using StorageShape gert::StorageShape; }其中using Format ge::Format;明确说明SetStorageFormat的入参类型op::Format本质就是ge::Format枚举。1.1 aclTensor 的三层格式视图从 common_types.h 的接口声明可以看到aclTensor对格式的管理分为三个维度分别对应三对 Get/Set 接口格式视图Get 接口Set 接口语义StorageFormatGetStorageFormat()SetStorageFormat()张量在内存中的实际排布格式OriginalFormatGetOriginalFormat()SetOriginalFormat()张量原始的逻辑排布格式用户视角ViewFormatGetViewFormat()SetViewFormat()当前视图view下的排布格式StorageFormat是其中最贴近硬件与底层框架的一层。原始格式Origin通常与存储格式一致但当发生格式转换如插入 format transform 算子时二者就会出现差异而视图格式View则用于描述Reshape、切片等视图操作后张量呈现的格式。1.2 op::Format 枚举的常见取值op::Format枚举包含多种格式。结合 format_utils.h 中ToAclFormat的可转换列表常见取值包括枚举值说明FORMAT_NDN 维通用格式无特定排布要求FORMAT_NCHW通道在前C 维按序排布的四维格式FORMAT_NHWC通道在最后C 维不连续的四维格式FORMAT_NC1HWC0Ascend 硬件典型的 5 维分形格式C 维拆分为 C1/C0FORMAT_FRACTAL_Z/FORMAT_FRACTAL_NZ面向特定硬件算子如矩阵运算的分形排布格式FORMAT_HWCN与 NCHW 相反的排布FORMAT_NDHWC/FORMAT_NCDHW5 维数据的 NHWC / NCDHW 排布FORMAT_NC、FORMAT_NCL二维 / 三维的通道格式此外format_utils.h 还提供了GetPrimaryFormat、GetSubFormat、HasSubFormat、GetFormatFromSub等工具函数用于解析带子格式sub format与 C0 信息的复合格式编码说明 Format 枚举值在底层可能是主格式与子格式的位组合。二、函数原型与参数说明2.1 函数原型接口声明位于 common_types.hop::Format GetStorageFormat() const; void SetStorageFormat(op::Format format);2.2 参数说明参数输入/输出说明format输入数据类型为op::Format即ge::Format是一个枚举包含多种不同的 Format例如NCHW、ND、NHWC、NC1HWC0、FRACTAL_NZ等。2.3 返回值说明无返回值void。2.4 约束说明接口本身无额外约束。但从实现看SetStorageFormat只更新元数据中记录的格式信息不会触发实际的数据重排。若将 StorageFormat 设置为与物理内存实际排布不一致的值会导致后续算子按错误的索引计算读取数据因此调用方必须保证设置值与该张量真实的内存排布一致。三、调用示例将 StorageFormat 置为 ND 格式原文档给出的核心用法是将aclTensor的存储格式显式置为ND格式// 将input的Storage Format置为ND格式 void Func(const aclTensor *input) { input-SetStorageFormat(ge::FORMAT_ND); }ge::FORMAT_ND与op::Format::FORMAT_ND指向同一枚举值因op::Format即ge::Format因此在算子实现中也可写作void SetToFractalNz(const aclTensor *input) { input-SetStorageFormat(ge::FORMAT_FRACTAL_NZ); }典型的应用场景包括自定义算子 Tiling 前将输入张量标记为硬件友好的分形格式如FORMAT_FRACTAL_NZ以匹配算子 kernel 的读取方式在Reshape、Transpose等算子中显式修正输出张量的存储格式元数据构造用于单测的张量时模拟指定内存排布验证格式相关逻辑分支。四、源码级实现解析SetStorageFormat 的调用链4.1 接口实现SetStorageFormat的实现位于 common_types.cppvoid aclTensor::SetStorageFormat(op::Format format) { tensor_-SetStorageFormat(format); }可以看到aclTensor内部持有一个op::Tensor即gert::TensorV2指针tensor_SetStorageFormat是薄封装将调用直接转发给底层张量的SetStorageFormat方法写入其StorageFormat属性。与之对应的读取接口在 common_types.cppop::Format aclTensor::GetStorageFormat() const { return tensor_-GetFormat().GetStorageFormat(); }Get/Set一一对应写入通过tensor_-SetStorageFormat()读取通过tensor_-GetFormat().GetStorageFormat()二者操作的是同一个存储格式字段。4.2 构造阶段对 StorageFormat 的初始化从源码看aclTensor在多种构造路径中都会把传入的storageFormat写入底层gert::StorageFormat对象。例如 common_types.cppaclTensor::aclTensor(const op::Shape storageShape, const op::Shape originShape, op::DataType dataType, op::Format storageFormat, op::Format originFormat, void* tensorDataAddr) { ... op::StorageFormat gertFormat; gertFormat.SetStorageFormat(storageFormat); gertFormat.SetOriginFormat(originFormat); ... tensor_ new (base) op::Tensor(gertShape, gertFormat, op::TensorPlacement::kOnDeviceHbm, dataType, tensorDataAddr); }类似的初始化逻辑还出现在其他构造函数中见 common_types.cpp 与 common_types.cpp。这从侧面印证aclTensor创建时即可同时指定存储格式与原始格式SetStorageFormat则用于在张量创建后按需修改存储格式元数据。4.3 私有格式校验在 common_types.cpp 中可以看到aclTensor的视图构造路径会对私有格式private format做警告检查OP_CHECK(!op::IsPrivateFormat(viewFormat_), OP_LOGW(the private format[%s], should not use this constructor., op::ToString(viewFormat_).GetString()), ;);这提示开发者并非所有 Format 枚举值都适合直接用于公开构造或设置路径私有格式如带特定 C0 拆分的内部格式应通过专门的框架机制处理。五、配套接口与格式视图协同使用SetStorageFormat通常与aclTensor的其他格式接口配合使用以完整刻画张量的格式信息声明见 common_types.hop::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.cppop::Format aclTensor::GetStorageFormat() const { return tensor_-GetFormat().GetStorageFormat(); } op::Format aclTensor::GetOriginalFormat() const { return tensor_-GetFormat().GetOriginFormat(); } op::Format aclTensor::GetViewFormat() const { return viewFormat_; } void aclTensor::SetStorageFormat(op::Format format) { tensor_-SetStorageFormat(format); } void aclTensor::SetOriginalFormat(op::Format format) { tensor_-SetOriginFormat(format); } void aclTensor::SetViewFormat(op::Format format) { viewFormat_ format; }从实现差异可以看出设计意图StorageFormat / OriginalFormat存储在底层gert::TensorV2的格式对象中随张量持久化是算子框架真正消费的元数据ViewFormat存储在aclTensor自身的viewFormat_成员中服务于视图层逻辑viewFormat_的初值在构造时取自originFormat见 common_types.cpp。因此如果目标是影响算子调度与内存访问应设置的是SetStorageFormat而仅表达视图语义的格式偏好则使用SetViewFormat。六、测试验证仓库中对该接口的实际使用仓库的测试代码直接印证了SetStorageFormat的典型用法在 composite_op 单测 test_common_types.cpp 中将张量存储格式设置为分形格式a.SetStorageFormat(Format::FORMAT_FRACTAL_NZ);同样用法出现在 composite_op 系统测试 test_common_types.cpp在 individual_op 的 executor 单测中以ge::FORMAT_ND作为入参调用该接口例如 executor_utest.cpp 与 indv_args_utest.cpptensor.rt2Tensor.SetStorageFormat(ge::FORMAT_ND);这些测试一方面验证了op::Formatge::Format与op::Format::FORMAT_*/ge::FORMAT_*两种写法等价另一方面也说明SetStorageFormat被广泛用于构造待测张量是算子级单测中模拟内存排布的标准手段。七、使用注意事项小结只改元数据不重排数据SetStorageFormat仅更新张量格式元数据真实数据需由 format transform 算子或显式拷贝完成重排二者必须保持一致三视图勿混淆物理排布用SetStorageFormat逻辑排布用SetOriginalFormat视图语义用SetViewFormat底层框架真正消费的是前两者枚举取值op::Format即ge::Format常用值包括FORMAT_ND、FORMAT_NCHW、FORMAT_NHWC、FORMAT_NC1HWC0、FORMAT_FRACTAL_NZ等私有格式应避免在普通构造路径中使用配套读取设置后可通过GetStorageFormat()校验结果二者在 common_types.cpp 中操作同一个底层格式字段。关于aclTensor格式接口的完整集合含 Shape 视图的 Get/Set 接口、SetData系列数据写入接口、Numel、IsEmpty、CheckOverflows等可继续阅读 common_types 接口总览其中列出了 GetStorageFormat、SetOriginalFormat、SetViewFormat 等全部配套接口文档。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表