CANN/cannbot-skills:算子规范L0校验规则详解 9-stage L0 校验规则详解【免费下载链接】cannbot-skillsCANNBot 是面向 CANN 开发的用于提升开发效率的系列智能体本仓库为其提供可复用的 Skills 模块。项目地址: https://gitcode.com/cann/cannbot-skills本文件是SKILL.md §4的详细参考。SKILL.md 只保留 stage 概述表完整子规则、numpy 子集 API、代码示例在此处。stage 1 — schema_static按schemas/op-spec.jsonDraft 2020-12逐字段校验必填、类型、enum、pattern、additionalProperties。stage 2 — category_paradigm_consistency校验 category↔paradigm 必含映射 4 套白名单 paradigm 内部约束子规则检查内容required_paradigm_missingcategory → 必含 paradigm 是否齐全fused_composite_basicscategoryFusedComposite ⇒ ≥ 2 条基础 paradigmElementwise 被其他范式吸收不计入基础范式计数mutually_exclusiveScatterUpdate 与 AtomicUpdate 不得共存paradigm_constraint.numerical_stableNumericalStable ⇒numerical_stability.required: trueparadigm_constraint.fused_composite_*FusedComposite ⇒ composition 必填、primitives ≥ 2、op 在白名单、中间不泄漏、dataflow 闭合paradigm_constraint.reduction_axis_missingReduction无 Recurrence⇒ 必有 axis/dim/axes 输入或属性或reduction.axis_source: fixed或reduction.axis_source: implicit_allparadigm_constraint.argreduce_dtypeArgReduce ⇒ 输出dtype_rule经 numpy_expr 求值得到int32或int64典型y.dtype np.int64paradigm_constraint.stateful_state_or_inplaceStateful ⇒ 至少一项 input.rolestate 或 output.aliasinginplace_with(...)paradigm_constraint.quantization_attrsQuantization ⇒ scale zero_pointparadigm_constraint.variable_output_flagVariableOutput ⇒ outputs[].data_dependent_shape: trueparadigm_constraint.random_sampling_seedRandomSampling ⇒ seed 属性paradigm_constraint.collective_hcclCollectiveCommunication ⇒ op.platform_constraints.requires_hccl: trueinvariant_kind_resolved.*invariants[].kind 在白名单 required_fields tolerance_inherit 约束structural 必为 falsemachine_check_kind_unknownboundary/extreme 的 machine_check.kind 在白名单error_type_unknownraises_error.error_type 在错误语义类别枚举内synthesize_pattern_unknownextreme_inputs.synthesize.patterns[].pattern 在白名单synthesize_legacy_format旧顶层pattern:写法 ⇒ WARNcomposition_without_fused_compositecomposition 存在但 paradigms 不含 FusedComposite ⇒ WARNparadigm_groups.fusion_min_basicfusion 组必须含 ≥ 2 条基础范式Elementwise 不计入paradigm_groups.combination_missing_switchcombination 组必须有 switch 字段paradigm_groups.combination_missing_whencombination 组必须有 when 字段paradigm_groups.mismatchparadigm_groups 中的 paradigms 必须都在 op.paradigms 中paradigm_groups.combination_should_existop.paradigms 含 ≥ 2 个基础范式排除 NumericalStable / FusedComposite 等修饰符范式但 paradigm_groups 缺失时 ⇒ WARN若同时存在string_in/enum_in/int_in_range(lower0)属性消息会额外指出强烈暗示横向组合paradigm_groups.mode_switch_may_need_combination仅 1 个基础范式但存在模式切换属性且其值包含直通语义 ⇒ WARN提示该值可能使算子退化为 Elementwise建议补范式 paradigm_groups。模式切换属性检测范围string_in/enum_in值含none/identity/passthrough或int_in_range且lower_inclusive0值 0 通常对应 none/identity 模式format_variants.reduction_axes_negativeformat_variants[].reduction_axes 含负值 ⇒ ERRformat_variants.reduction_axes_out_of_rankformat_variants[].reduction_axes 中某值 ≥ variant.rank ⇒ ERRformat_variants.oracle_kwargs_dim_mismatchformat_variants[].oracle_kwargs.dim 与 reduction_axes 不一致 ⇒ WARNparadigm_groups 字段说明op.paradigm_groups声明 paradigms 之间的组合关系区分纵向融合与横向组合kind语义示例fusion纵向融合多范式按顺序串联执行softmax:[Reduction, Broadcast]combination横向组合多范式择一由属性值决定mse_loss:[Reduction]或[Elementwise]取决于reduction属性规则所有组的 paradigms 并集必须是op.paradigms的子集未分组的视为修饰符范式如 NumericalStable、Quantization、FusedCompositefusion组内 ≥ 2 基础范式Elementwise 被其他范式吸收不计入combination组必须有switch属性名when属性值示例# softmax: 纯纵向融合 paradigms: [Reduction, Broadcast, NumericalStable, FusedComposite] paradigm_groups: - kind: fusion paradigms: [Reduction, Broadcast] # mse_loss: 横向组合 paradigms: [Reduction, Elementwise] paradigm_groups: - kind: combination paradigms: [Elementwise] switch: reduction when: none - kind: combination paradigms: [Reduction] switch: reduction when: *stage 3 — shape_closurenumpy_expr 求值按outputs[].shape_rule_kind分流numpy_expr默认— 在受限 AST 沙箱中执行outputs[].shape_rulenumpy 子集表达式求出每个输出的 SymbolicShape若math_semantics.formula_kindnumpy_expr还会在正常边界样例上用具体 shape/attr 校验 formula 输出 shape防止shape_rule写成简化/占位版本。data_dependent— 用于输出 shape 由输入数据值决定的算子nonzero / unique / masked_select 等通常含 VariableOutput 范式不求解但强制校验data_dependent_shape: trueshape_bounds.max_elements 建议配shape_rule_description。只依赖 input shape / attribute 的输出必须写numpy_expr。textual_only— 用于输出 shape 因数据排布格式而异的算子如 NCHW/NHWC 的 Channel 轴位置不同不求解但要求math_semantics.format_variants存在且配shape_rule_description。shape_rule 可含${format_variants[].channel_axis}等占位符。确定性 shape 规则必须完整写在shape_rule当输出 shape 同时依赖 input rank 和 attribute 时不能只写默认分支再把完整语义放进 notes 或测试约束。纯Reduction算子不能把输出 shape 写成input.shape应按dim/keep_dims描述归约轴变化。shape_rule 示例numpy_exprmatmuloutputs: - name: c shape_rule_kind: numpy_expr shape_rule: | c.shape ( np.broadcast_shapes(a.shape[:-2], b.shape[:-2]) ((a.shape[-1] if transpose_a else a.shape[-2]),) ((b.shape[-2] if transpose_b else b.shape[-1]),) )data_dependentnonzerooutputs: - name: indices shape_rule_kind: data_dependent data_dependent_shape: true shape_rule_description: | indices.shape (K, rank(x))K count(x ! 0)仅运行时已知 shape_bounds: max_elements: prod(x.shape) * rank(x) output_rank: 2 static_dims: [{axis: 1, value: rank(x)}] dynamic_dims: [{axis: 0, name: K, depends_on_value_of: x}]子规则表子规则检查内容shape_closure.shape_rule_kind_missingoutputs[].shape_rule_kind 未声明shape_closure.shape_rule_kind_unknown非 numpy_expr / data_dependentshape_closure.shape_rule_placeholdershape_rule 含 TODO / 占位 / 简化说明shape_closure.reduction_shape_identity_suspicious纯 Reduction 的 shape_rule 直接写成 input.shapeshape_closure.synthesize_parse_errorWARN — boundary synthesize 中 shape / attr 字面量无法解析不能用于 shape oracleshape_closure.numpy_expr_shape_mismatch正常边界样例下 shape_rule 形状与 formula 实际输出形状不一致shape_closure.numpy_expr_formula_eval_error正常边界样例下 formula 不能作为 shape oracle 执行shape_closure.dsl_parse_errornumpy_expr 语法错shape_closure.dsl_eval_error求值时 AttributeError / TypeError / 沙箱拒绝shape_closure.unresolved_symbol引用了未声明的 input / attribute 名shape_closure.incompatible_dims显式维冲突如 matmul K 维同名约束失败shape_closure.folded_dim_misuse折叠维...x重复或不在首位shape_closure.unregistered_symbolWARN — 显式维未在shape_constraints.symbols登记shape_closure.rank_overflow输出 rank 超过inputs[].rank_range上限shape_closure.data_dependent_flag_missingdata_dependent但未配data_dependent_shape: trueshape_closure.data_dependent_missing_boundsdata_dependent但未配shape_bounds.max_elementsshape_closure.data_dependent_missing_descriptionWARN — 建议补shape_rule_descriptionshape_closure.textual_only_requires_format_variantstextual_only但math_semantics.format_variants不存在 ⇒ ERRshape_closure.textual_only_requires_descriptiontextual_only但缺shape_rule_description⇒ ERRnumpy_expr 支持的子集按需可扩展见scripts/evaluators/shape_eval.pyx.shape/x.shape[-1]/x.shape[:-2]切片 负索引tuple拼接(a.shape[-1],) (b.shape[-1],)np.broadcast_shapes(*shapes)numpy 标准 API 签名np.reduce_shape(shape, axisdim, keepdimskeep_dims)归约输出 shape折叠前缀形状需用负 axis 指向显式后缀维IfExpa if cond else b符号求解用 attribute 默认值具体样例校验用边界样例 attr沙箱规则同 stage 8禁 import / def / class / for / while / lambda / dunder attribute5 秒超时。stage 4 — dtype_closure对dtype_policy.supported_combinations的每一行执行outputs[].dtype_rulenumpy 子集表达式推导输出 dtype与显式表交叉比对。dtype_rule 常见形式# 同 dtype 直传 dtype_rule: y.dtype x.dtype # 类型提升 dtype_rule: c.dtype np.promote_types(a.dtype, b.dtype) # 固定 dtype如 ArgReduce 输出索引 dtype_rule: y.dtype np.int64 # 条件分支如 complex_of dtype_rule: | out.dtype np.complex64 if real.dtype np.float32 else np.complex128子规则表子规则检查内容dtype_closure.combination_mismatchdtype_rule 推得 X 但显式表写 Y典型锁定意图机制当 numpy promote 表升级时spec 不会被静默改语义dtype_closure.combination_missing_output组合行未声明某 output 的 dtypedtype_closure.dsl_parse_error/dsl_eval_error表达式语法错 / 求值错dtype_closure.unresolved_symboldtype_rule 引用的 input 不在该组合内dtype_closure.dtype_rule_kind_unknown非 numpy_expr 的 dtype_rule_kindnumpy 子集支持x.dtypeinput 的 dtype 字符串np.promote_types(a, b)/np.result_type(*xs)— 复用 promote 表np.int8 / int16 / int32 / int64 / uint8 / uint16 / uint32 / uint64 / float16 / float32 / float64 / bfloat16 / complex64 / complex128 / bool_dtype 常量比较与 IfExpa.dtype np.float32、x if cond else yPromotion 表覆盖 fp16 / fp32 / fp64 / bf16 / int8 / int16 / int32 / int64 / uint* / bool / complex64 / complex128 窄浮点 fp4_e2m1 / fp8_e4m3fn / fp8_e5m2 / hifloat8见scripts/evaluators/promote.py。stage 5 — broadcast_legality校验算子计算中的 broadcast 语义是否合法。broadcast字段描述的是算子计算是否需要对数据进行 broadcast数据复制/扩展而非仅描述多输入 shape 是否需要对齐。kind语义适用场景numpy计算涉及数据广播多输入 elementwiseadd/mulnone计算不涉及任何 broadcast输入 shape 严格一致、无需数据扩展的算子explicit部分维度 broadcast 部分维度不 broadcastmatmulbatch dims broadcastM/K/N 不 broadcast子规则表子规则检查内容broadcast_legality.numpy_violationkind: none但算子计算实际需要 broadcast 数据broadcast_legality.incompatible_dimskind: numpy下显式维冲突不可右对齐broadcast_legality.explicit_rules_uncoveredkind: explicit的 rules 未覆盖输入全部维度v1 已实现numpy含折叠维/none/explicitbroadcast.rules必须恰好一条scope: trailing 一条scope: leadingpolicy 各支持numpy/no_broadcast覆盖 matmul 形式。explicit 的高阶组合多于 2 个 input、scope: axis留待扩展。stage 6 — boundary_min_set按op.paradigms检查boundary_conditions[]/extreme_inputs[]是否覆盖该范式必含的最低 case 集。数据源registries/boundary_min_cases.yaml。子规则检查内容boundary_min_set.missing_required_case例如 Reduction ⇒ 必含reduce 轴长1 / rank0 / 空 TensorNumericalStable ⇒ 必含 fp16 上溢 extreme case匹配方式每条 requirement 用match_any关键词列表与 case 描述做子串包含任一命中即算覆盖。结构性约束走special_check直接检查。覆盖的 paradigms 见registries/boundary_min_cases.yaml当前覆盖 Reduction / NumericalStable / SlidingWindow / Padding / IndexGather / ScatterUpdate / AtomicUpdate / MaskPredicate / SortSelect / ArgReduce / Histogram / Spectral / DynamicShape / RandomSampling / Quantization / Stateful / VariableOutput / Sparse / Contraction / Elementwise / Broadcast。stage 7 — tolerance_coverage子规则检查内容tolerance_coverage.uncovered_output_dtypedtype_policy.supported_combinations中所有出现的输出 dtype 必须在numerical_tolerance.per_dtype中声明容差FAILtolerance_coverage.tolerance_too_tightrtol 显著低于 dtype 单步舍入量级fp32 1e-7、fp16 1e-4、bf16 1e-3⇒ WARNstage 8 — formula_smoke_eval把math_semantics.formula在小 shape默认[2,3]上用 numpy 跑一遍确认能跑通且产出预期 dtype。子规则表子规则检查内容formula_smoke_eval.syntax_errorformula 字符串语法错formula_smoke_eval.formula_ast_disallowedAST 含禁止节点import / def / class / for / while / try / lambdaformula_smoke_eval.formula_banned_name用了__import__/exec/getattr等绕沙箱标识符formula_smoke_eval.numpy_eval_error运行时 numpy 报错API 拼错 / 参数错 / shape 不对formula_smoke_eval.formula_timeout5 秒超时不应发生formula 应是纯向量化操作formula_smoke_eval.missing_outputformula 未给某个声明的 output 变量赋值formula_smoke_eval.dtype_mismatch_at_runtimeWARN — 运行时 dtype 与 supported_combinations 声明不一致formula_smoke_eval.produces_unexpected_nanWARN — 中性输入下产出全 NaNformula_smoke_eval.empty_formulaformula_kindnumpy_expr 但 formula 字符串为空设计要点AST 白名单沙箱—— 只允许表达式、赋值、numpy 调用禁止 import / def / class / 循环 / lambda受限 globals—— 只暴露np/math 安全 builtins 子集5 秒超时—— SIGALRM-based防止意外死循环小 shape—— 折叠维...d丢弃显式符号维默认3常量维原样使用dtype 选择—— 取supported_combinations[0]的输入 dtypebfloat16没有 numpy 原生类型用float32替代formula_kind取值的影响numpy_expr→ 跑 stage 8python_block/textual_only→ SKIP写在 formula 里的 LaTeX / 自然语言无法 evalstage 9 — oracle_reachable真 importmath_semantics.reference_oracle.framework并走getattr链找到api确认它存在且 callable同时校验kwargs中的${...}占位符引用真实存在的 attribute / input / output。子规则表子规则检查内容oracle_reachable.absentINFO — absenttrue ⇒ stage 9 SKIP语义由 invariants boundary 覆盖oracle_reachable.incompleteframework 或 api 字段缺失且 absentfalseoracle_reachable.api_framework_mismatchapi 字符串首段与 framework 字段不一致oracle_reachable.framework_not_installedINFO — framework 未装stage 9 走 SKIP不算 FAIL但仍校验占位符oracle_reachable.api_not_foundframework 已装但 api 字符串中某段getattr失败拼写错oracle_reachable.api_not_callableapi 找到了但不是 callableoracle_reachable.placeholder_unresolved${attr.X}/${input.X}/${output.X}引用 spec 中不存在的名字oracle_reachable.unknown_frameworkWARN — framework 不在已知列表见registries/framework_oracle_registry.yamloracle_reachable.dtype_unsupportedWARN — supported_combinations 输入 dtype 不在 oracle.available_for_dtype 中降级策略framework 未装⇒ SKIP不算失败这是环境问题不是 spec 缺陷api 拼错⇒ FAIL前提是 framework 装了没装则跳过占位符校验与是否装框架无关永远跑性能torch 冷启动 1-3 秒同进程内多次调用因 import 缓存而即时返回。pre-commit 用户若没装 torchstage 9 走 SKIP 不影响 1s 体验。【免费下载链接】cannbot-skillsCANNBot 是面向 CANN 开发的用于提升开发效率的系列智能体本仓库为其提供可复用的 Skills 模块。项目地址: https://gitcode.com/cann/cannbot-skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考