
人工智能算子库CANNAscend【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址https://gitcode.com/cann/opbase点击查看免费下载本篇技术指南围绕 CANN/opbase 算子库中 infershapeShape 推导工具集的核心接口Ops::Base::SetUnknownShape展开系统讲解其函数原型、参数语义、底层实现原理与图模式动态 Shape 场景下的典型用法。读者将掌握如何将输出 Tensor 的 Shape 设置为已知维度rank但各轴长度未知的动态形态并结合配套的IsUnknownShape、SetUnknownRank、IsUnknownRank接口在算子 Shape 推导函数中正确处理动态输入。一、接口定位infershape 工具集与图模式动态 Shape在 CANN/opbase 算子开发中Host 侧 Shape 推导infershape阶段负责根据输入 Tensor 的 Shape 推导输出 Tensor 的 Shape。当算子运行于**图模式graph mode**且输入为动态 Shape 时输入张量的维度长度甚至维度数量在构图阶段可能未知此时推导函数必须显式地标记这些未知信息供后端图编译与运行时解析。SetUnknownShape正是这一机制下的核心写操作接口与同目录下的SetUnknownRank、IsUnknownShape、IsUnknownRank共同构成一组动态 Shape 处理工具。四个接口的官方定义分别位于SetUnknownShape.md本文主体SetUnknownRank.mdIsUnknownShape.mdIsUnknownRank.md这组接口均声明于头文件 shape_util.h实现在 shape_util.cpp统一位于Ops::Base命名空间并通过OPBASE_API导出宏对外暴露。二、函数原型与参数说明void SetUnknownShape(int64_t rank, gert::Shape shape)参数输入/输出说明rank输入设定 Shape 的维度数即维数/rank必须是大于等于 0 的整数。shape输出目标 Shape 对象调用后其维度数被设置为rank且每一根轴dimension的长度都被标记为不确定值。返回值无void。约束说明官方文档声明无特殊约束但结合源码实现rank为负数时接口会拒绝执行详见下文底层实现小节调用方应保证传入合法的非负 rank。关键语义已知 rank、未知维度长度SetUnknownShape表达的 Shape 状态是维度数量确定、各维长度不确定。这与维度数量也不确定的**未知 rankUnknown Rank**状态是两种不同的动态 Shape 形态Unknown Rank连维度数量都未知由SetUnknownRank产生Shape 被编码为仅含一个特殊值-2的 1 维结构Unknown Shape本接口产物rank 已知如SetUnknownShape(2, shape)表示一个 2 维张量但每一维的长度均为不确定值由特殊值-1编码。区分这两种状态对推导逻辑至关重要例如一个任意 batch、任意长度的序列数据若只需 batch 维未知可构造已知 rank 的 Unknown Shape若连输入是几维都不确定则必须走 Unknown Rank 分支。三、底层实现原理源码级解析SetUnknownShape的实现位于 shape_util.cppconstexpr int64_t UNKNOWN_RANK_DIM_VALUE -2LL; constexpr int64_t UNKNOWN_DIM_VALUE -1LL; void SetUnknownShape(int64_t rank, gert::Shape shape) { OP_CHECK_IF(rank 0, OP_LOGE(SetUnknownShape, the rank value is invalid, return unsuccessful), return); const size_t dimNum static_castsize_t(rank); shape.SetDimNum(dimNum); for (size_t i 0; i dimNum; i) { shape.SetDim(i, UNKNOWN_DIM_VALUE); } }从实现中可以提炼出以下关键事实编码约定仓库用-2LL表示未知 rank用-1LL表示未知维度长度。SetUnknownShape将每一维都设置为UNKNOWN_DIM_VALUE-1从而在gert::Shape上刻画出已知 rank、未知各轴长度的语义。非法参数防御当rank 0时接口通过OP_CHECK_IF宏记录错误日志the rank value is invalid, return unsuccessful并直接返回不会对shape做任何修改。因此调用方传入负 rank 不会产生脏数据但也不会得到预期结果。零维特例rank 0时循环不执行仅将shape的维度数设为 0等价于标量 Shape。与之配套的读操作IsUnknownShape同样位于 shape_util.cpp用于判断某个 Shape 是否含未知维度bool IsUnknownShape(const gert::Shape shape) { size_t dimNum shape.GetDimNum(); for (size_t i 0; i dimNum; i) { if (shape.GetDim(i) UNKNOWN_DIM_VALUE) { return true; } } return false; }注意IsUnknownShape的判定语义是只要存在任一维度长度为-1即返回 true而非要求所有维度均未知。这与 IsUnknownShape.md 中Checks if each dimension length of an input shape is unknown的字面表述略有差异从源码看其实际行为是检测是否含有未知维。调用方在编写推导逻辑时应以实际行为为准。四、典型调用示例继承自官方文档以下代码摘自官方文档仅供理解接口用法不支持直接拷贝运行auto in_shape context-GetInputShape(0); OP_CHECK_NULL_WITH_CONTEXT(context, in_shape); auto out_shape context-GetOutputShape(0); OP_CHECK_NULL_WITH_CONTEXT(context, out_shape); if (Ops::Base::IsUnknownShape(*in_shape)) { Ops::Base::SetUnknownShape(0, *out_shape); }示例解读通过context-GetInputShape(0)/context-GetOutputShape(0)分别取第 0 号输入与第 0 号输出的 Shape 指针OP_CHECK_NULL_WITH_CONTEXT在指针为空时结合 context 上报错误属于 opbase 推导代码中的标准空指针防护先调用IsUnknownShape(*in_shape)判断输入是否含有未知维度若输入为动态 Shape则调用SetUnknownShape(0, *out_shape)将输出 Shape 置为0 维标量且无未知长度——这是动态场景下一种常见的保守推导策略输入不确定时将输出退化为标量/固定形态避免形状冲突。配套接口对照示例当输入为 Unknown Rank维度数未知时则应使用SetUnknownRank将输出标记为未知 rankauto in_shape context-GetInputShape(0); // 0 indicates the first input parameter. OP_CHECK_NULL_WITH_CONTEXT(context, in_shape); auto out_shape context-GetOutputShape(0); // 0 indicates the first output parameter. OP_CHECK_NULL_WITH_CONTEXT(context, out_shape); // Check if the shape of the input tensor is of unknown rank. If yes, the shape of the output tensor is set to unknown rank. if (Ops::Base::IsUnknownRank(*in_shape)) { Ops::Base::SetUnknownRank(*out_shape); }SetUnknownRank的实现将 Shape 重置为仅含一个-2的 1 维结构见 shape_util.cppIsUnknownRank则通过维度数为 1 且第 0 维为-2来判定未知 rankshape_util.cpp。五、仓库内的真实应用场景在 opbase 仓库中这组接口已被内建推导工具实际调用可作为理解其用法的参照广播推导infershape_broadcast_util.cpp当输入 Shape 或输出 Shape 为 Unknown Rank 时直接调用SetUnknownRank将输出置为未知 rank跳过常规的广播维度对齐逻辑逐元素推导infershape_elewise_util.cpp输入为 Unknown Rank 时同样以SetUnknownRank(*outShape)快速传递动态状态。这些内建工具InferShape4Broadcast、InferShape4Elewise、InferShape4Reduce等的完整接口文档见 infershape 索引页中文版本可参考 infershape 目录。同时op_common 接口总览 与 op_common 列表 提供了整个 op_common 工具集的索引便于按需查阅其他 Shape 与广播工具。六、使用建议与注意事项明确两种动态形态写推导逻辑前先判断输入属于已知 rank、未知长度用IsUnknownShapeSetUnknownShape还是未知 rank用IsUnknownRankSetUnknownRank二者编码不同-1vs-2混用会导致后续图编译阶段解析错误。IsUnknownShape的判定语义其实际行为是任一维为-1即返回 true当需要精确判断全部维度未知时应自行遍历所有维逐一核对。rank 合法性SetUnknownShape对负 rank 仅记录日志并返回不会抛异常也不会修改 Shape请确保传入非负值并在调试时留意 opbase 日志OP_LOGE输出。空指针防护从context获取的 Shape 指针在使用前务必经过OP_CHECK_NULL_WITH_CONTEXT校验这是 opbase 推导代码的通用规范。示例代码仅供理解官方示例属于片段式参考代码实际编写算子推导函数时需结合算子自身的输入输出契约输入输出个数、索引、约束补全完整上下文。七、总结Ops::Base::SetUnknownShape是 CANN/opbase 图模式动态 Shape 推导中已知 rank、未知各轴长度的标准写接口与IsUnknownShape、SetUnknownRank、IsUnknownRank配套构成完整的动态 Shape 处理闭环。理解其-1/-2编码约定、gert::Shape操作方式以及空指针与非法 rank 的防护模式是编写健壮、可编译通过的算子 infershape 函数的基础。开发者可结合 shape_util.cpp 的实现与 infershape_broadcast_util.cpp、infershape_elewise_util.cpp 的实际调用快速在自己的算子推导逻辑中落地这套动态 Shape 处理方案。赞分享人工智能算子库CANNAscend【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址https://gitcode.com/cann/opbase点击查看免费下载相关推荐CANN opbase 图模式 Shape 推导SetUnknownShape 接口解析与实战用法CANN opbase 图模式 Shape 推导SetUnknownShape 接口解析与实战用法 导读 Ops::Base::SetUnknownShape人工智能算子库CANNAscendCANN opbase 动态 Shape 推理实战SetUnknownRank 接口解析与源码级实现CANN opbase 动态 Shape 推理实战SetUnknownRank 接口解析与源码级实现 本文基于 CANN 算子库基础框架库 opbase 的官人工智能算子库CANNAscendCANN opbase 未知秩判断接口 IsUnknownRank 使用指南图模式动态 Shape 推导实战CANN opbase 未知秩判断接口 IsUnknownRank 使用指南图模式动态 Shape 推导实战 导读 在 CANN opbase算子库基础框架人工智能算子库CANNAscend上一篇如何用 Magisk 的 magisk --denylist 命令行添加、移除并查询 DenyList 条目下一篇探索未来科技 SciPhi-AI 的 R2R 项目详解创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考