ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

CANN opbase 图模式未知秩检测:IsUnknownRank 接口原理与 shape 推导实战

CANN opbase 图模式未知秩检测:IsUnknownRank 接口原理与 shape 推导实战 CANN opbase 图模式未知秩检测IsUnknownRank 接口原理与 shape 推导实战【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase导读IsUnknownRank是 CANN opbase 框架为算子 Host 侧 shape 推导InferShape提供的基础工具接口用于在图模式Graph Mode场景下判断某个gert::Shape是否为「未知秩」unknown rank。本文以 IsUnknownRank 官方文档 为骨架结合仓库中 shape_util.h 与 shape_util.cpp 的源码实现深入讲解未知秩的判定规则、与未知 shape 的区别、在 InferShape 推导流程中的典型用法以及配套的SetUnknownRank、SetUnknownShape、IsUnknownShape接口族。读完本文你将能够在自定义算子开发中正确识别未知秩输入、并按规范向输出 shape 传播「未知」语义。背景为什么图模式下需要「未知秩」概念在 CANN 的图编译模式中算子图往往不是一次性拿到所有输入的真实形状。以下两类情况非常常见动态 shape 输入同一张计算图需要适配不同的输入维度编译期只能拿到占位信息上游算子尚未完成推导shape 推导InferShape按拓扑序逐算子执行当某个算子被访问时其输入 shape 可能仍处于「未确定」状态。为了统一表达这种不确定性gert::Shape引入了两类特殊的维度标记值定义于 shape_util.cpp标记常量数值语义UNKNOWN_RANK_DIM_VALUE-2LL表示整个 shape 的秩rank即维数未知UNKNOWN_DIM_VALUE-1LL表示某一维的长度未知但秩已知其中IsUnknownRank专门针对第一类情况秩未知即连 shape 有几个维度都不确定此时 shape 被统一规范化为单维[-2]。接口定义函数原型与参数IsUnknownRank属于Ops::Base命名空间声明位于 shape_util.h对外通过OPBASE_API导出定义见 opbase_export.h。namespace Ops { namespace Base { OPBASE_API bool IsUnknownRank(const gert::Shape shape); } // namespace Base } // namespace Ops参数说明参数输入/输出类型说明shape输入const gert::Shape待检查的输入 shape通常来自InferShapeContext::GetInputShape()解引用后的对象返回值说明返回类型为booltrue输入 shape 为未知秩false输入 shape 不为未知秩可能是常规确定 shape也可能是秩已知但含未知维度的 shape详见下文「判定规则」。约束说明官方文档标注「无」约束。从源码看该接口为纯查询函数不做空指针校验、不修改传入对象因此线程安全、无副作用可在 shape 推导路径中任意位置调用。实现原理未知秩的判定规则IsUnknownRank的实现非常简洁见 shape_util.cppbool IsUnknownRank(const gert::Shape shape) { return shape.GetDimNum() 1 shape.GetDim(0) UNKNOWN_RANK_DIM_VALUE; }判定规则拆解判定由两个条件「与」而成GetDimNum() 1shape 的维数必须恰好为 1GetDim(0) -2该唯一维度上的值必须等于-2UNKNOWN_RANK_DIM_VALUE。也就是说仓库将「未知秩」规范化为一个唯一表示形式[-2]。这与SetUnknownRank的写入逻辑完全对称见 shape_util.cppvoid SetUnknownRank(gert::Shape shape) { shape.SetDimNum(0); shape.AppendDim(UNKNOWN_RANK_DIM_VALUE); }即先清空维数再追加一个值为-2的维度。写方用[-2]编码未知秩读方用维数1 唯一维-2识别未知秩二者严格匹配避免出现歧义表示。与未知 shapeunknown shape的关键区别需要特别区分IsUnknownRank与IsUnknownShape它们解决的是两种不同的不确定性接口判定的语义典型表示实现要点shape_util.cppIsUnknownRank秩维数本身未知[-2]维数为 1 且唯一维为-2IsUnknownShape秩已知但至少一个维度长度未知如[1, -1, 3]遍历所有维任一维等于-1即返回 true从实现上看IsUnknownShape是遍历GetDimNum()个维度、逐个检查是否存在-1标记而IsUnknownRank只检查唯一维是否为-2。二者覆盖的场景互补配套文档见 IsUnknownShape.md。官方调用示例在 InferShape 中使用 IsUnknownRank官方文档给出的参考代码IsUnknownRank.md展示了一个典型的「检测—传播」模式若输入为未知秩则把输出 shape 也置为未知秩从而让不确定性沿计算图正确传播。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); }示例要点解析context-GetInputShape(0)/context-GetOutputShape(0)返回const gert::Shape*指针0表示第一个输入/输出参数OP_CHECK_NULL_WITH_CONTEXT(context, ptr)是 opbase 提供的空指针校验宏形参非空时才继续执行详见 op_log.hOps::Base::IsUnknownRank(*in_shape)解引用后传入 shape 对象命中未知秩后调用Ops::Base::SetUnknownRank(*out_shape)将输出 shape 编码为[-2]供下游算子继续识别。官方提示文档注明「以下代码仅供参考不支持直接拷贝运行」——因为实际使用时还需要补全算子注册、InferShape 上下文构造等工程上下文示例只强调核心逻辑片段。仓库源码印证框架内置推导工具中的真实调用IsUnknownRank并非孤立 API它被 opbase 内置的通用 shape 推导工具直接使用是推导流程中处理未知秩的第一道防线。逐元素Elewise推导InferShape4Elewise在 infershape_elewise_util.cpp 中InferShape4Elewise先取出输入输出 shape 并做空指针校验随后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;即输入为未知秩时直接令输出为未知秩并提前返回否则才执行*outShape *inShape的常规拷贝推导。这正印证了文档示例「检测—传播」模式在框架内置工具中的实际落地。对应头文件声明见 infershape_elewise_util.h。广播Broadcast推导InferShape4Broadcast在 infershape_broadcast_util.cpp 中广播推导对两个输入均做未知秩检查任一为未知秩即把输出置为未知秩if (IsUnknownRank(*shape) || IsUnknownRank(*shapeOutput)) { SetUnknownRank(*shapeOutput); // ... 提前返回 }这种双端检测体现了未知秩的「一票否决」特性只要参与运算的某个张量秩未知输出秩就不可能被确定必须原样传播[-2]。Reduce 推导工具中的配套使用除 Elewise/Broadcast 外include/op_common/op_host/infershape_reduce_util.h也引用了IsUnknownRank等 shape 工具接口说明未知秩处理是 opbase 各通用推导工具Elewise、Broadcast、Reduce统一遵循的公共约定。配套接口族完整的 shape 未知性处理工具箱IsUnknownRank隶属于Ops::Base的 shape 工具接口族四个接口共同覆盖「秩未知 / 维度未知」两种不确定性的读与写接口原型作用文档IsUnknownRankbool IsUnknownRank(const gert::Shape)判断 shape 是否为未知秩IsUnknownRank.mdSetUnknownRankvoid SetUnknownRank(gert::Shape)将 shape 置为未知秩编码为[-2]SetUnknownRank.mdIsUnknownShapebool IsUnknownShape(const gert::Shape)判断是否存在未知维度-1IsUnknownShape.mdSetUnknownShapevoid SetUnknownShape(int64_t rank, gert::Shape)设置已知秩并将所有维长标记为未知SetUnknownShape.md与其他接口组合的典型场景输入为未知秩 → 输出也为未知秩文档示例与 Elewise/Broadcast 内置推导中的标准用法输入为未知 shape秩已知→ 输出保持同秩未知参考 SetUnknownShape.md 的示例对输入调用IsUnknownShape命中后以已知秩构造SetUnknownShape(rank, *out_shape)秩已确定但个别维未知SetUnknownShape内部实现见 shape_util.cpp会先校验rank 0非法值打印OP_LOGE并直接返回再将所有维设为-1。使用建议与注意事项先判空再解引用GetInputShape/GetOutputShape返回指针务必配合OP_CHECK_NULL_WITH_CONTEXT校验避免对空指针解引用框架内置工具也遵循这一惯例不要手工构造[-2]表示读写未知秩请统一使用SetUnknownRank/IsUnknownRank这对接口以保证与框架内部约定唯一表示形式[-2]保持一致区分两类未知秩未知-2与维度长度未知-1语义不同、传播策略不同切勿混用秩未知时只能调SetUnknownRank秩已知时才能用SetUnknownShape放置位置IsUnknownRank为纯查询、无副作用可安全放在 shape 推导流程的开头作为早退分支避免后续执行无意义的维度运算适用范围本接口族面向图模式下的 Host 侧 shape 推导若算子不使用图模式推导流程则无需也不应依赖该未知性传播机制。小结IsUnknownRank是 CANN opbase 为图模式 shape 推导提供的「未知秩检测」基础能力实现上以「维数为 1 且唯一维为-2」作为未知秩的唯一编码配套SetUnknownRank完成对称写入在工程上它被 opbase 内置的 Elewise、Broadcast、Reduce 通用推导工具作为未知秩传播的前置分支广泛使用。对自定义算子开发者而言掌握IsUnknownRank及其接口族是写出能正确应对动态 shape 图编译场景的 InferShape 逻辑的关键一步。延伸阅读中文版接口文档IsUnknownRank.md同主题接口SetUnknownRank.md、IsUnknownShape.md、SetUnknownShape.md通用推导工具Elewiseinfershape_elewise_util.h、Broadcastinfershape_broadcast_util.h、Reduceinfershape_reduce_util.h核心实现shape_util.h、shape_util.cpp接口总览op_common_api_introduction.md【免费下载链接】opbase本项目是CANN算子库的基础框架库为算子提供公共依赖文件和基础调度能力。项目地址: https://gitcode.com/cann/opbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表