尧图精选

CANN opbase aclTensor::GetStorageShape 接口解析:StorageShape 内存排布语义与算子开发实践

🕒 发布时间:2026/9/18 3:26:49 📁 来源:尧图网络
CANN opbase aclTensor::GetStorageShape 接口解析StorageShape 内存排布语义与算子开发实践【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase导读GetStorageShape是 CANN opbase 开源仓库中aclTensor的核心只读属性接口用于获取张量在设备内存上的实际物理排布形状StorageShape。本文围绕 docs/zh/api/nnopbase/opdev/common_types/GetStorageShape.md 展开结合仓库内头文件、实现源码与单元测试讲清 StorageShape 与 OriginShape、ViewShape 的关系以及该接口在算子开发尤其是 format 转换与视图场景中的典型用法。读完你将掌握GetStorageShape的函数原型、返回值语义、底层实现调用链、与 C 语言侧aclGetStorageShape的对应关系以及何时必须使用它而非逻辑 shape。功能说明StorageShape 是什么GetStorageShape用于获取aclTensor的StorageShape 属性。按原文档的定义StorageShape 表示 aclTensor 在内存上的实际排布即 OriginShape 实际运行时的 shape 格式。也就是说StorageShape 描述的是张量数据真正落在设备内存上的维度组织方式。例如一个逻辑上为[10, 20]的张量在内存中可能按[10, 20]连续排布也可能因为 format 转换如 NCHW → NHWC或视图View操作而被重新组织StorageShape 记录的就是这个“落盘”后的形态。与之相对的 OriginShape 表示张量在经历 transdata 节点如果存在之前的原始 shape 数学描述参见 GetOriginalShape.mdViewShape 则是算子逻辑视角下可使用的 shape参见 GetViewShape.md。三者是aclTensor描述元数据的“三套 shape 视图”shape 属性语义典型来源OriginalShapetransdata 之前的原始 shape 数学描述算子图定义的逻辑 shapeStorageShape内存中实际排布的 shape物理形态实际分配 / format 转换后的形态ViewShape算子使用时将其视为的数据形状逻辑视图Reshape / 切片等视图操作在仓库的公开头文件 include/nnopbase/opdev/common_types.h 中aclTensor同时声明了三套属性的 Get/Set 接口common_types.h 第 152-173 行const op::Shape GetStorageShape() const; void SetStorageShape(const op::Shape shape) const; const op::Shape GetOriginalShape() const; void SetOriginalShape(const op::Shape shape) const; const op::Shape GetViewShape() const; void SetViewShape(const op::Shape shape);从源码结构看aclTensor内部持有op::Tensor* tensor_gert::TensorV2而op::StorageShape、op::Shape等类型别名也集中定义在同一头文件中common_types.h 第 47-55 行using ShapeVector FVectorint64_t, MAX_DIM_NUM; using Shape gert::Shape; using StorageShape gert::StorageShape; using StorageFormat gert::StorageFormat;其中MAX_DIM_NUM定义为 25即张量维度数上限。Shape别名指向gert::Shape这正是返回值类型StorageShape本身也是gert运行时的一个独立数据结构。函数原型与返回值说明原文档给出的函数原型为gert::Shape GetStorageShape()需要指出的是仓库实际声明为 const 成员函数见上文头文件更准确的签名是const op::Shape GetStorageShape() const;两者在用法上一致调用方通过aclTensor对象即可获得 StorageShape无需传入任何参数参数说明为“无”。返回值类型为gert::Shape即op::Shape记录一组 shape 信息。例如一个三维 shape[10, 20, 30]表示该张量在内存中按 3 维、各维大小依次为 10、20、30 排布。gert::Shape支持通过GetDim、GetDimNum、GetShapeSize等方法访问具体维度仓库中 common_types.cpp 第 424 行 的aclTensor::Size()正是基于GetStorageShape().GetShapeSize()计算元素个数可佐证其接口形态。关于gert命名空间下Shape的完整介绍原文档指向《基础数据结构和接口参考》“gert 命名空间 Shape”本文不再展开。约束说明为“无”即该接口不依赖任何前置条件只要持有合法的aclTensor对象即可安全调用。调用示例算子内获取 StorageShape原文档给出最小调用示例在算子或 host 侧代码中直接调用成员函数void Func(const aclTensor *input) { auto shape input-GetStorageShape(); }实际使用中GetStorageShape通常作为完整元数据获取流程的一部分出现。仓库单元测试 tests/nnopbase/ut/composite_op/test_common_types.cpp 中展示了对 StorageShape 的读取与回写验证第 744-748 行a.SetStorageShape(shape1); EXPECT_EQ(a.GetStorageShape(), shape1); EXPECT_EQ(a.GetStorageShape(), shape1);以及创建后立即校验 StorageShape 是否符合预期的模式第 816 行附近EXPECT_EQ(tensorName.GetStorageShape(), shape)说明该接口常用于张量创建后校验物理排布、算子执行前后对比 shape 是否变化、以及驱动后续基于 shape 的 tiling 计算。与 aclGetStorageShape 的关系C 语言侧对应接口除了aclTensor的 C 成员函数本仓库还提供 C 语言风格的全局接口aclGetStorageShape两者语义完全一致、服务不同场景成员函数GetStorageShape面向自定义算子开发opdev 侧直接在算子实现中获取属性全局接口aclGetStorageShape面向 aclnn 接口调用方aclnn 侧通过裸指针输出维度数据。aclGetStorageShape的声明位于 include/nnopbase/aclnn/acl_meta.h 第 56-57 行ACL_FUNC_VISIBILITY aclnnStatus aclGetStorageShape(const aclTensor* tensor, int64_t** storageDims, uint64_t* storageDimsNum);其详细说明见 aclGetStorageShape.md输出参数storageDims指向维度值数组、storageDimsNum表示维度数二者内存由接口内部申请使用后必须delete[]手动释放。该文档还给出了完整的“属性读取 重建 tensor”示例// 1.创建xTensor int64_t xViewDims[] {2, 4}; int64_t xStridesValue[] {4, 1}; // 第1维步长4第2维步长1 int64_t xStorageDims[] {2, 4}; aclTensor *xTensor aclCreateTensor(xViewDims, 2, ACL_FLOAT16, xStridesValue, 0, ACL_FORMAT_ND, xStorageDims, 2, nullptr); // 2. 获取xTensor的实际物理排布shapestorageDims为{2, 4}, storageDimsNum为2 int64_t *storageDims nullptr; uint64_t storageDimsNum 0; auto ret aclGetStorageShape(xTensor, storageDims, storageDimsNum); // 3.根据xTensor的属性创建新的tensor aclTensor *yTensor aclCreateTensor(viewDims, viewDimsNum, dataType, stridesValue, offset, format, storageDims, storageDimsNum, deviceAddr); // 4.手动释放内存 delete[] viewDims; delete[] stridesValue; delete[] storageDims;这个示例同时揭示了 StorageShape 与 ViewShape 在实践中的典型差异xViewDims与xStorageDims可以不同前者是逻辑视图、后者是物理排布而aclCreateTensor的签名见 acl_meta.h 第 37-39 行正是把 viewDims 与 storageDims 作为独立参数传入佐证了两套 shape 是独立维护的元数据。底层实现从 aclTensor 到 gert::TensorV2 的调用链GetStorageShape的实现非常轻量本质是对内部gert::TensorV2的一层转发。见 src/nnopbase/common/utils/common_types.cpp 第 397 行const op::Shape aclTensor::GetStorageShape() const { return tensor_-GetShape().GetStorageShape(); }调用链为aclTensor::GetStorageShape() └─ gert::TensorV2::GetShape() // 返回 gert::TensorShape含多套 shape 视图 └─ gert::TensorShape::GetStorageShape() // 取出 StorageShape 视图从该实现可以推断aclTensor不直接存储 StorageShape 副本而是统一把元数据托管在gert::TensorV2中GetStorageShape返回的是对内部数据的const引用避免了拷贝开销。这也解释了为何头文件中返回类型是const op::Shape。仓库中大量模块依赖这一语义例如算子框架映射与执行z_framework_op.cpp、op_executor.cpp等src/nnopbase/composite_op/aclnn_engineDump 与调试输出indv_dump.cpp在导出张量信息时拼接storage_shape ...src/nnopbase/individual_op/executor/indv_dump.cpp缓存键构建indv_cache_key_builder.cpp以 StorageShape 参与算子缓存 key 计算src/nnopbase/individual_op/executor/indv_cache_key_builder.cpp缓存查询与命中op_cache.cppsrc/nnopbase/common/utils/op_cache.cpp与op_dfx_cache.cppTiling 计算reduce_tiling.cpp等 tiling 逻辑中读取 StorageShape 计算分片src/op_common/atvoss/reduce/reduce_tiling.cpp。典型场景何时必须使用 StorageShape结合上述源码证据以下场景中GetStorageShape是关键信息源format 转换场景当张量经历了 transdata如 NCHW 转 NHWC或采用非 ND 排布时GetOriginalShape返回的仍是数学上的 shape而真正决定内存占用、tiling 分块、DMA 搬运长度的必须是 StorageShape。原文档明确指出 StorageShape 是“OriginShape 实际运行时的 shape 格式”两者在 format 转换后通常不一致。视图View场景GetViewShape表示逻辑视图同一段内存可能被多个不同 ViewShape 引用而 StorageShape 始终是物理排布的唯一真值。仓库 acl_meta.h 第 90-97 行 注释中描述了 ViewCopy/Reshape 这类不产生内核节点的特殊算子其输入输出的 storage 指针共享此时读写物理信息均以 StorageShape 为准。tiling 与内存分配从源码结构看aclTensor::Size()元素个数直接由GetStorageShape().GetShapeSize()计算因此基于元素数做循环、tiling 切分的逻辑都间接依赖 StorageShape 的准确性。小结GetStorageShape是理解 CANN opbaseaclTensor元数据模型的关键入口它以const op::Shape返回张量在内存中的实际物理排布实现上通过gert::TensorV2的GetShape().GetStorageShape()完成一次零拷贝转发common_types.cpp 第 397 行。在自定义算子开发中凡是涉及 format 转换、视图复用、tiling 切分或内存大小计算的地方都应优先读取 StorageShape 而非逻辑 shape。若要进一步掌握相关接口可继续阅读 GetStorageFormat.md物理排布格式、GetOriginalShape.md原始 shape与 GetViewShape.md逻辑 shape并参考 common_types.md 中完整的 common_types 接口清单。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →