ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

CANN opbase 未知秩判断接口 IsUnknownRank 使用指南:图模式动态 Shape 推导实战

CANN opbase 未知秩判断接口 IsUnknownRank 使用指南:图模式动态 Shape 推导实战 CANN opbase 未知秩判断接口 IsUnknownRank 使用指南图模式动态 Shape 推导实战【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase导读在 CANN opbase算子库基础框架库的图模式Graph 模式推理与训练场景中算子输入 Shape 可能处于**未知秩Unknown Rank**状态此时形状推导逻辑必须能够识别这种状态并正确向下游传播。Ops::Base::IsUnknownRank正是 opbase 在 infershape 工具集 中提供的用于检测 Shape 是否为未知秩的基础接口。阅读本文后你将掌握该接口的函数原型、判定规则与底层实现原理并能在算子 InferShape 函数中配合SetUnknownRank正确完成未知秩状态的传递。功能说明IsUnknownRank用于图模式场景下检查输入 Shape 是否为未知秩。在动态 Shape 支持的图执行流程中算子 Shape 推导InferShape可能在编译期无法确定张量的维度个数。此时该 Shape 被称为未知秩其内部以特殊标记值表示。opbase 将这类 Shape 的判定与设置封装成独立工具接口供各算子的 InferShape 实现复用避免各算子重复实现相同的判读逻辑。从命名空间看该接口位于Ops::Base命名空间即 opbase 的公共基础工具层同族接口还包括Ops::Base::SetUnknownRank将 Shape 置为未知秩与IsUnknownRank配对使用Ops::Base::IsUnknownShape/SetUnknownShape处理已知秩、但某些维度未知-1的 Shape与未知秩-2是两种不同的动态形态。函数原型bool IsUnknownRank(const gert::Shape shape)其中gert::Shape是图引擎运行时Graph Engine Runtime提供的 Shape 类型opbase 侧在 shape_util.h 中通过#include exe_graph/runtime/shape.h引入该类型定义。参数说明参数名输入/输出说明shape输入待检查的输入 Shape。参数以const引用方式传入函数不会修改入参 Shape 内容仅执行只读判定。返回值说明返回类型为booltrue输入 shape 为未知秩false输入 shape 不为未知秩即维度个数已确定。判定规则与底层实现该接口的判定规则直接体现在源码中位于 shape_util.cppnamespace Ops { namespace Base { constexpr int64_t UNKNOWN_RANK_DIM_VALUE -2LL; constexpr int64_t UNKNOWN_DIM_VALUE -1LL; void SetUnknownRank(gert::Shape shape) { shape.SetDimNum(0); shape.AppendDim(UNKNOWN_RANK_DIM_VALUE); } bool IsUnknownRank(const gert::Shape shape) { return shape.GetDimNum() 1 shape.GetDim(0) UNKNOWN_RANK_DIM_VALUE; } } // namespace Base } // namespace Ops从实现可以提炼出两条关键事实未知秩的编码约定opbase 使用常量UNKNOWN_RANK_DIM_VALUE -2即-2LL作为未知秩的标记值与之相对UNKNOWN_DIM_VALUE -1表示秩已知但某一维未知。二者含义不同切勿混用。判定条件IsUnknownRank要求 Shape 满足维度个数为 1 且唯一维度取值为 -2即内部表示形如(-2,)。之所以要求1 维 值 -2是为了与正常的一维 Shape如(5,)以及未知维 Shape在数值表示上严格区分避免误判。同时可以看到未知秩 Shape 由配套的SetUnknownRank构造先将维度数清零再追加一个值为-2的维度最终得到(-2,)的形态与IsUnknownRank的判定条件一一对应。头文件中的对外声明位于 shape_util.h并使用OPBASE_API导出宏保证跨库符号可见。调用示例官方文档给出的关键代码如下仅供参考不支持直接拷贝运行需结合具体算子的 InferShape 上下文auto in_shape context-GetInputShape(0); // 0表示第一个输入参数 OP_CHECK_NULL_WITH_CONTEXT(context, in_shape); auto out_shape context-GetOutputShape(0); OP_CHECK_NULL_WITH_CONTEXT(context, out_shape); // 判断输入张量shape是否为未知秩若是将输出张量shape置为未知秩 if (Ops::Base::IsUnknownRank(*in_shape)) { Ops::Base::SetUnknownRank(*out_shape); }代码要点GetInputShape(0)/GetOutputShape(0)取自gert::InferShapeContext分别表示第一个输入与第一个输出的 ShapeOP_CHECK_NULL_WITH_CONTEXT是 opbase 提供的空指针校验宏失败时携带算子上下文信息打印日志并终止推导判定通过后必须调用Ops::Base::SetUnknownRank(*out_shape)将输出 Shape 也置为未知秩否则输出形状信息会与实际推导状态不一致。源码级应用佐证未知秩在公共推导流程中的传播IsUnknownRank并非孤立接口opbase 内置的多个公共 InferShape 工具在实现中都直接复用了该判定可作为真实调用链的参考。逐元素算子推导 InferShape4Elewise在 infershape_elewise_util.cpp 中InferShape4Elewise的处理逻辑是ge::graphStatus InferShape4Elewise(gert::InferShapeContext* context) { auto inShape context-GetInputShape(0); OP_CHECK_NULL_WITH_CONTEXT(context, inShape); auto outShape context-GetOutputShape(0); OP_CHECK_NULL_WITH_CONTEXT(context, outShape); if (IsUnknownRank(*inShape)) { OP_LOGD(context-GetNodeName(), input shape is UnknownRank, set output shape to (-2, )); SetUnknownRank(*outShape); return ge::GRAPH_SUCCESS; } *outShape *inShape; return ge::GRAPH_SUCCESS; }可见逐元素类算子的通用策略是输入为未知秩时直接将输出置为未知秩并提前返回否则输出等于输入 Shape。广播推导 BroadcastShapeToOutShape在 infershape_broadcast_util.cpp 的BroadcastShapeToOutShape中只要参与广播的两个 Shape 任一为未知秩输出即被置为未知秩if (IsUnknownRank(*shape) || IsUnknownRank(*shapeOutput)) { OP_LOGD(BroadcastShapeToOutShape, the input shape is [-2], set output shape is [-2]!); SetUnknownRank(*shapeOutput); return true; }这两个示例说明未知秩具有传染性——只要上游输入处于未知秩状态任何依赖其形状的推导结果都无法在编译期确定必须向下游持续传递(-2,)标记直至运行时 Shape 信息恢复。与未知维 Shape 的区分使用opbase 在 shape_util.h 中还提供了一对针对未知维的接口OPBASE_API void SetUnknownShape(int64_t rank, gert::Shape shape); OPBASE_API bool IsUnknownShape(const gert::Shape shape);两者适用场景存在本质区别使用时请务必区分接口标记值含义典型场景IsUnknownRank/SetUnknownRank-2维度个数秩未知图模式下连 Rank 都无法静态确定IsUnknownShape/SetUnknownShape-1秩已知但部分维度大小未知动态 Batch、动态序列长度等仅个别维未知在 shape_util.cpp 的实现中SetUnknownShape要求入参rank 0否则记录错误日志并直接返回随后将指定个数的维度全部置为-1IsUnknownShape则遍历所有维度只要存在任一-1即返回true。可以看到这两套接口内部使用完全不同的标记值判读逻辑也因此截然不同。约束与注意事项官方文档声明本接口无额外约束可安全用于图模式 InferShape 流程该接口仅做 Shape 状态判定本身不触发错误、不分配资源可在推导路径中高频调用调用前应确保传入的gert::Shape有效如已通过OP_CHECK_NULL_WITH_CONTEXT校验指针非空判定的前提是 Shape 采用 opbase 约定的-2编码约定UNKNOWN_RANK_DIM_VALUE若 Shape 来源于其他框架或自定义构造请先确认其编码方式一致在需要同时处理未知秩与未知维的场景例如融合算子推导建议分别调用IsUnknownRank与IsUnknownShape组合判断避免把-2与-1两种状态混为一谈。延伸阅读SetUnknownRank 接口文档与本文接口配对的写入接口用于将输出 Shape 置为未知秩infershape 工具集索引查看更多 Shape 推导基础接口如IsUnknownShape、InferShape4Broadcast、InferShape4Elewise等shape_util.h全部 Shape 工具接口的声明与导出shape_util.cpp-2/-1标记常量及全部工具接口的实现infershape_elewise_util.cpp逐元素推导中未知秩传播的完整调用示例infershape_broadcast_util.cpp广播推导中未知秩传播的完整调用示例。【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表