已开启
[Requirement|需求建议]: 支持 IndexExpr 和 Arange Autofusion #302
Jett_Woo创建于  25 天前
Jett_Woo成员
25 天前 创建

简介

目的

本文档描述 IndexExpr 与 Arange Autofusion 的完整需求设计(Issue #302:支持
IndexExpr 和 Arange Autofusion),覆盖两个算子的端到端能力与两期合入:

  • PR 1961(feat: support IndexExpr and Arange autofusion,已合入 develop,2026-09-05):建立 IndexExpr/Arange 的 ASCIR 注册、Python 接口、IndexExpr 标量消费链路、VF Arange codegen 与调度准入等基础能力。
  • PR 1980(fix: complete Arange fallback path,关联 Issue #302):补齐退化轴 Arange 广播透传、根图 Arange codegen 回退路径与 VF 准入门控,扩展 IndexExpr 标量块物化,并修复 VF 混合 dtype 掩码错位、Store DMA 方向错误与 Python 绑定引用计数缺陷。

需求是双主体的:IndexExpr 负责符号标量(尺寸/索引表达式的整型物化与标量消费),Arange 负责等差序列(向量生产与广播扩维);两者经 Broadcast 汇入同一 elementwise 融合链。

目标读者:Autofuse 前端接入(TorchInductor lowering)、图优化与 codegen 维护者、测试开发者。期望输出:合入 develop 的完整能力 + 正式 UT/ST + 真机验证闭环。

范围

包含(两期合并):

  • ASCIR 注册(autofuse/ascir/generator、autofuse/v35/ascir/generator)
  • Autofuse 图优化(autofuse/v35/optimize、autofuse/optimize)
  • Autofuse codegen(autofuse/v35/codegen、autofuse/codegen):MicroAPI/VF 双路径 + 根图 ArangeApiCall 回退
  • Python 前端 API(autofuse/compiler/python/ascir_api.py)
  • Python/C++ 绑定(autofuse/compiler/py_module)
  • 测试:v35 UT/ST、py module UT、真机 device validation 用例

不包含:

  • SuperKernel 组件(两期均零改动)
  • CI workflow / 构建打包 / run 包布局(零改动)
  • 验证框架、device validation runner 业务化、tool/、temp/(本地资产,不入库)

总体概述

软件概述

项目介绍

Autofuse 前端(TorchInductor 接入层)把符号计算拆解为 **IndexExpr(标量表达式)

  • Arange(等差序列)+ Broadcast + elementwise** 图形:
  • IndexExpr:ops.index_expr(expr, dtype) 语义——把符号尺寸/索引表达式
    (如 s27*s77、s0 + 2*k)物化为一个整型标量值,参与标量算术
    (Add/Minimum/Maximum)、比较(Lt/Le/Gt/Ge/Eq/Ne)或经 Broadcast 扩为向量。
  • Arange:等差序列生产(base + k*step),组合索引数学(如行主序线性
    索引 cols*p0 + p1、triu 掩码的 p2 - p1)拆解为退化轴 Arange +
    Broadcast + Add。

两者在 VF(VectorFunc)融合链中分别承担"值参数"与"向量生产"角色:IndexExpr
值经 VF 函数参数传入 MicroAPI 标量变体(如 Adds),Arange 在 VF 内经
Reg::Arange 生成序列后作为张量输入参与计算。

需求按两期演进:

PR 1961(基础,已合入)                    PR 1980(补全,Issue #302)
├─ IndexExpr.expr Expression 化            ├─ 退化轴 Arange 广播透传
├─ Arange v2 注册(int32/int64)           ├─ 根图 ArangeApiCall 物化
├─ Python arange/IndexExpr API             ├─ VF 准入门控(4 类拒绝)
├─ VF Arange codegen(逻辑 offset、         ├─ VF 混合 dtype 掩码统一
│   outer-for、多 Arange 参数隔离)        ├─ Store DMA 方向 / 常量 Cast 修复
├─ IndexExpr scalar 参数(VF 值传递)       ├─ IndexExpr 标量块 / blk tensor
└─ Arange VF 准入与对齐策略                ├─ 前端协议收紧(非退化零 stride 拒绝)
                                          └─ 绑定引用计数修复(py≤3.10 崩溃)

PR 1980 之前存在三个真机复现缺陷:① Pattern B(尾退化 [4,1]/[1,0]) 在旧"展开方案"下 codegen 必然失败;② VF 嵌套循环掩码 dtype 未统一,混合 dtype 子图真机上每 4 个元素损坏 1 个;③ 根图 Arange 无 codegen 注册(ApiCall 名为空串),三类回退场景全部无法出码。

产品环境介绍

  • 依赖 CANN Toolkit(AscendC 头文件、bisheng 编译链),SoC:ascend950_v2。
  • 产物为 tiling.h / host_impl.cpp / device_impl.cpp,经 JIT 编译为 kernel_module.so 后由 AutofuseLaunch ABI 加载执行。
  • 前端接口:autofuse Python 包(pyautofuse.so + ascir_api.py),Python 3.10+(CI 为 3.10.2)。

软件功能

IndexExpr 能力:

  1. Expression 物化:expr 承载完整 Expression(动态 SizeExpr 及 FloorDiv/Mod/Min/Max 组合),v1/v2 注册输出 dtype 限定 DT_INT32/DT_INT64;根图物化为 kernel 内具名符号标量(tiling 参数引用),非普通 UB tensor。
  2. scalar-like 消费协议:IndexExpr 与 Scalar/ScalarData 同类调度;消费边按位置分类——Add/Minimum/Maximum 单标量输入(可交换)、六种比较的第二输入可直连 Micro scalar 变体(Add→Adds),其余位置经显式 Broadcast 扩为向量后消费。
  3. VF 值参数:IndexExpr 值经 VF 函数标量参数传入,随调用点 tiling 变化。
  4. 标量块物化:纳入 blk tensor(32B 对齐标量块)物化链,符号常量回退 tiler.Size 表达式(1980)。
  5. 浮点消费协议(前端契约):浮点 dtype 消费拆解为 IndexExpr(int64) → Broadcast → Cast(目标浮点),Cast 必须在向量域;运行时 dtype 不确定走 guard fallback(规划项 float_indexexpr_cast_mul RDV 用例)。

Arange 能力:

  1. v2 注册:base/step 均为 Expression(支持动态 base、动态 step、非 1/0/负 step),输出 int32/int64。
  2. Python 前端 API:ascir_api.arange(...) 提供 axis/size/stride 逻辑 view 构图入口(与 IndexExpr 入口对称)。
  3. VF Arange codegen:Arange 作为零输入向量生产节点融合进 VF,MicroAPI Reg::Arange 生成数值序列;支持跨 vector block、外层调度 offset(outer-for 逻辑偏移)、高维(最多 4 个 vectorized_axis)。
  4. 多 Arange 参数隔离:同一 VF 内多个 Arange 各自 base/step 独立传参。
  5. 退化视图透传:多轴退化 Arange 视图原样透传,扩维由 Broadcast 通用路径承担;仅 1D Arange 补齐退化轴(1980)。
  6. 根图 Arange 物化:新增 ArangeApiCall,显式循环物化等差序列,物理写偏移与逻辑取值偏移分离(1980)。
  7. VF 准入门控:烘焙广播 Arange(任意位置非退化零 stride)、带控制边 Arange、UBFuse 上下文 Arange、8↔4 字节 Cast 拒绝进 VF(1980)。

链路修复(PR 1980,双主体共用):

  1. VF 掩码 dtype 统一:循环/掩码 dtype 统一为子图最宽计算 dtype;单合并轴无条件折叠;Arange 块偏移参数化。
  2. DMA/常量修复:Store DMA 按真实 UB 侧布局计算;常量 Cast 直接 Duplicate。
  3. 前端协议收紧:arange 任意位置非退化零 stride 构图期拒绝。
  4. 绑定引用计数修复:SizeExpr 比较返回新引用(修复 py≤3.10 退出崩溃)。

设计约束

  • CANN Toolkit 9.2.0;AscendC MicroAPI 8↔4 字节转换要求双寄存器语义(RegTraitNumTwo),VF 单寄存器张量无法表达——只能门控拒绝。
  • Arange 物理 vectorized_stride 必须静态等于 1(两期共同约束,1961 确立)。
  • Python 绑定 ABI:SizeExpr richcompare 协议(新引用、NotImplemented);pyautofuse.so 与 Python 3.10/3.12 双版本构建均需通过。
  • 图改写确定性(编码红线 #5):视图改写只读属性向量、无容器遍历顺序依赖。
  • 性能:编译期 pass 不引入 O(n²) 以上遍历;不新增默认开启日志。

假设和依赖关系

  • 退化轴(size=1, stride=0)对物理偏移与逻辑取值均无贡献——透传等价性的数学前提(已由退化轴 Load→Broadcast 已验证路径佐证)。
  • Reg::Arange 只能表达单条连续等差序列——烘焙广播必须留在根图的前提。
  • IndexExpr/Arange 的 expr 恒为整数语义表达式(inductor size/index 语义按 int64 管理)。
  • CI py module UT 在 Python 3.10.2 上运行——引用计数缺陷只在非永生单例的版本暴露。
  • 上游 develop 的 ApplyGraphSchedAxisToNodes(图级 sched 统一提升)为基线行为,一级扩维要求由此推导(已实测验证)。

需求分析与设计

整体介绍

数据流与关键模块边界(两期合并视图):

flowchart LR
    subgraph FE["前端构图 (ascir_api)"]
        A1["IndexExpr API (expr: SizeExpr)"]
        A2["arange API<br/>退化视图校验 (位置无关规则)"]
    end
    subgraph REG["ASCIR 注册 (PR 1961)"]
        R1["v1 IndexExpr<br/>v2 Arange base/step Expression"]
    end
    subgraph OPT["图优化"]
        B1["NormalizeArangeBroadcastViews<br/>(PR 1980, 合轴前)"]
        B2["RefineEnableVFFlag<br/>Arange/Cast VF 门控 (PR 1980)"]
        B3["UnAlignmentStrategy<br/>Arange 消费对齐 (两期演进)"]
    end
    subgraph CG["Codegen"]
        C0["IndexExpr: 符号常量/标量块<br/>+ VF 值参数 (1961+1980)"]
        C1["VF: Reg::Arange + scalar 参数<br/>(PR 1961) + 掩码 dtype 统一 (PR 1980)"]
        C2["ArangeApiCall 根图回退<br/>(PR 1980 新增)"]
        C3["Store DMA / Cast 修复 (PR 1980)"]
    end
    A1 --> B2
    A2 --> B1 --> B2 --> B3 --> C0 & C1 & C2 & C3
    R1 -.注册支撑.-> A1 & A2

两期边界划分:PR 1961 的 VF 内 Arange 能力(逻辑 offset、outer-for、参数隔离)在 PR 1980 中保持不变;PR 1980 的门控把无法安全表达 VF 的 Arange 形态(烘焙广播、控制边、UBFuse)导向新根图路径,两路径互补。

功能需求

功能需求 1:IndexExpr Expression 物化与注册(PR 1961)

  1. 介绍
    IndexExpr.expr 从整数 attr 升级为完整 Expression,可承载动态 SizeExpr 及组合(s27*s77 等);v1/v2 均注册,输出 dtype 限定 DT_INT32/DT_INT64。根图物化为 kernel 内具名符号标量(非 UB tensor),值随 tiling 参数在 host 侧解析。
  2. 输入
    符号表达式(常量、size vars、循环变量线性式、FloorDiv/Mod/Min/Max 组合)。
  3. 处理
    v2 注册表登记 dtype 白名单(ascir_builtin_ops_v2.cpp);infer_dtypes 校验;codegen 侧 TPipe::AddTensor(output, expr, name) 注册 Expression 常量并区分字符串常量路径(值为 0 的 Expression 仍为有效表达式)。
  4. 输出
    根图有命名 const 标量;消费者经 GetScalarValue() 取得生成后的具名变量(const_value 为空时回退 tensor 变量名),或在显式 Broadcast 后取得向量。

功能需求 2:IndexExpr scalar-like 消费边协议(PR 1961)

  1. 介绍
    每条 IndexExpr→消费者的边必须确定走标量还是张量协议,不能因消费者"属于 elementwise"整体放行;多消费者时各边可有不同 Broadcast view,不把单一消费者的 view 复制给所有用途。
  2. 输入
    消费者算子类型、输入位置、其他输入是否 scalar、输出 view、所选普通/VF 实现。
  3. 处理
    按消费边位置分类(协议表见 AL-9):Add/Minimum/Maximum 允许单个 scalar 输入(MicroBinaryScalar 自动交换到第二位、API 加 s 后缀);六种比较仅第二输入可识别 scalar;其余位置(比较第一输入、Store 数据输入等)不支持直连,需上游显式 Broadcast。白名单判定统一为 IsScalarNodeType(Scalar | ScalarData | IndexExpr)。
  4. 输出
    合法 scalar call(Adds/Muls 等 MicroAPI 标量变体)或显式 Broadcast 后的向量消费;不支持位置保留必要 Broadcast 或拒绝,不悄悄交换非交换律操作参数。

功能需求 3:IndexExpr 标量块物化(PR 1980)

  1. 介绍
    根图 IndexExpr 纳入与 Scalar 相同的 blk tensor(32B 对齐标量块)物化链,索引消费链可直接引用对齐标量块。
  2. 输入
    根图 IndexExpr 节点及其输出张量调度/tiling 元数据。
  3. 处理
    ParseScalarNeedGenBlkTensors 判定纳入 IndexExpr;BlkTensorAllocAndInit 常量值回退(const_value 为空时用 tiler.Size(const_value_expr, true) 生成 tiling 参数引用);ParseGraph 的 IndexExpr 分支补 ParseOptimizeInfo(此前只 AddTensor 不解析优化信息,后续 tiling 查不到该张量)。
  4. 输出
    根图 IndexExpr 生成合法的 blk tensor 初始化代码;符号值 Scalar 不再产出空串非法 C++。

功能需求 4:IndexExpr 浮点消费协议(前端契约,规划项)

  1. 介绍
    ops.index_expr(expr, float_dtype) 不能直接物化(dtype 白名单仅整型);前端拆解为 IndexExpr(int64) → Broadcast → Cast(目标浮点),Cast 必须在 Broadcast 之后(向量域)——IndexExpr 输出无 axis/repeats(scalar-like),向量算子的 Cast 需要 view,不存在"Broadcast 前标量域 Cast"的合法形态。
  2. 输入
    整数语义表达式、目标浮点 dtype(float16/bfloat16/float32)。
  3. 处理
    前端构图改写(外部仓);运行时 dtype 无法静态确定时走既有 dtype guard fallback(该融合点不进入 AF)。
  4. 输出
    infer_dtypes() 通过的合法 ASCIR 图;等价 RDV 用例 float_indexexpr_cast_mul(规划,形状 [32,64]/[32,65]/[2,127] 对拍 eager)。

功能需求 5:Arange v2 注册与前端 API(PR 1961 + 1980 收紧)

  1. 介绍
    v2 注册 Arange(零输入),base/step 均为 Expression;Python ascir_api.arange(...) 提供逻辑 view(axis/size/stride)构图入口。PR 1980 收紧:任意位置 stride==0 且 size!=1 构图期拒绝并提示改法(use 1D Arange followed by explicit Broadcast)。
  2. 输入
    dtype(int32/int64)、base/step(SizeExpr)、axis/size/stride(等长三列表)。
  3. 处理
    注册表校验 dtype;前端校验 view 一致性 + 位置无关零 stride 规则。
  4. 输出
    合法 Arange 节点;违规时 ValueError(含改法提示)。

功能需求 6:VF Arange Codegen(PR 1961)

  1. 介绍
    Arange 作为零输入向量生产节点融合进 VF,MicroAPI Reg::Arange 按块生成数值序列。
  2. 输入
    VF 子图内 Arange 节点的 base/step/逻辑 strides/物理 vectorized 布局。
  3. 处理
    逻辑值偏移(logical_offset + 块内偏移)× step 计算取值;物理 UB 地址按 vectorized strides 前进;outer-for 场景外层调度轴偏移并入逻辑 offset;多 Arange 各自参数独立。
  4. 输出
    VFCall... 函数中的 Reg::Arange 指令序列;支持最多 4 个 vectorized_axis,超过 4 轴在任何图改写前明确失败。

功能需求 7:IndexExpr VF 值参数(PR 1961)

  1. 介绍
    IndexExpr 值经 VF 函数标量参数传入消费算子,随调用点 tiling 变化,与 DS-7 的根图具名常量构成"VF 参数 / 根图变量"双形态。
  2. 输入
    VF 子图内消费 IndexExpr 的 Micro 调用(binary/compare scalar 变体)。
  3. 处理
    VF 签名收集 scalar 输入形参;调用点以根图 IndexExpr 变量名实参传入。
  4. 输出
    VFCall...(…, scalar_<name>, …) 标量传参;不含 IndexExpr 的 VF 签名不变。

功能需求 8:退化轴 Arange 广播透传(PR 1980)

  1. 介绍
    显式"Arange→单输入 Broadcast"对,当 Arange 为多轴退化视图(恰好一根变化轴 stride=1,其余退化)且与 Broadcast 输出同轴数时,视图原样保留;Arange 为 1D(轴数更少)时按 Broadcast 输出位置补退化轴。
  2. 输入
    Arange 视图(axis/size/strides 三列表等长)、Broadcast 输出视图(尾轴一致、尾 stride=1)、双方均无控制边。
  3. 处理
    逐对校验(轴数 ≤、变化轴唯一且 stride=1、变化轴存在性、尾轴对齐、无控制边);不满足任一条件整个 pass 失败(fail-closed,不做无法证明安全的改写)。
  4. 输出
    Arange 视图(透传或补齐后)、sched.axis 与 Broadcast 对齐;违规时 Normalize explicit Arange Broadcast views failed 错误。

功能需求 9:根图 Arange 物化(ArangeApiCall,PR 1980)

  1. 介绍
    根图 Arange 由新 ApiCall 生成显式循环:for(arange_i) SetValue(base + (logical_offset + arange_i) * step);非固定广播轴展开为内层 arange_b 帧循环。
  2. 输入
    节点 ir_attr 的 base/step(SizeExpr);输出张量 vectorized 布局。
  3. 处理
    从最内轴向外扫描:退化轴跳过(对物理偏移与逻辑取值均无贡献);固定轴记 has_fixed_axis;广播轴入 broadcast_frames;变化轴做有界连续校验(size==轴尺寸且物理 stride==累积宽度),无法证明安全即报错。
  4. 输出
    device_impl.cpp 中的物化循环;烘焙广播视图先经 MaterializeArangeViewContiguous 连续化物理布局。

功能需求 10:VF 准入门控(PR 1980)

  1. 介绍
    四类节点拒绝进 VF:①烘焙广播 Arange(位置无关检测:非退化零 stride);②带控制边 Arange;③UBFuse 上下文 Arange(graph attr 传递);④8↔4 字节 Cast(含 float↔int64)。
  2. 输入
    节点视图 strides/repeats、控制边计数、graph attr。
  3. 处理
    RefineEnableVFFlag 建簇前判定;UBFuse 标记由 BufQueAllocator 写、PlatformV2 读(不扩展 BasePlatform 公共接口)。
  4. 输出
    enable_vf = false,节点留在根图走对应 ApiCall(ArangeApiCall / CastExtend)。

功能需求 11:VF 混合 dtype 掩码统一(PR 1980)

  1. 介绍
    VF 所有嵌套循环的 UpdateMask/CreateMask 统一使用子图最宽计算 dtype(loop_dtype),各张量 Load/Store 保持自身 dtype。
  2. 输入
    子图各算子 dtype 集合。
  3. 处理
    GenerateFuncDefinition 计算 loop_dtype = max_dtype_size_,root_loop_.SetLoopDtype 递归传播到全部嵌套循环。
  4. 输出
    掩码位与计算寄存器 lane 对齐(修复每 4 个元素坏 1 个)。

功能需求 12:Store DMA 方向与常量 Cast 修复(PR 1980)

  1. 介绍
    BuildDataCopyApiParamInNormal 的 ub_tensor 实参由固定 dst 改为 copy_in ? dst : src;常量 Cast 分支改用 Duplicate 直铺。
  2. 输入
    Load(copy_in=true,src=GM/dst=UB)/ Store(copy_in=false,src=UB/dst=GM);常量输入的 Cast。
  3. 处理
    按 copy 方向显式选择 UB 侧实参;常量值经 GetScalarValue 内嵌生成代码。
  4. 输出
    非连续 Store 的 DMA 块参数正确;常量链少一个中间张量。

功能需求 13:绑定引用计数修复(PR 1980)

  1. 介绍
    SizeExpr::Compare 返回新引用并实现 Py_NE/NotImplemented。
  2. 输入
    Python 比较运算(==/!=/< 等)。
  3. 处理
    richcompare 按 CPython 协议返回 Py_RETURN_TRUE/FALSE,IsConvType/IsCubeType 同步修复。
  4. 输出
    py module UT 在 Python ≤3.10 不再退出崩溃;不支持的比较返回干净 TypeError。

非功能需求

可维护性

  • 门控/校验/跳过三处统一"位置无关"规则,一处语义(非退化+零 stride=广播);
  • mutable loop_dtype_ 已注释说明取舍;logical_strides 收集三处同构(后续可提取 helper);
  • VF 与根图双路径互补而非重叠:VF 保持 1961 语义不变,1980 仅新增门控与回退,路径边界清晰。

可测试性

  • UT 入口:sh build.sh -u --module=autofuse_framework -j 8;
  • 真机入口:tool/index_expr/run_index_expr_regression.sh(计划生成与 runner preflight 零漂移);
  • 探针:auto_arange_fallback 的 ARANGE_GRAPH_PROBE 控制边注入库。

可移植性

  • Python 3.10(CI)/3.12(本地)双版本构建验证;
  • 不依赖芯片型号判断(无硬编码 SoC 字符串)。

可靠性

  • 全部改写 fail-closed:无法证明安全即失败并给出原因;
  • 图改写无容器遍历顺序依赖(编码红线 #5);
  • 绑定层引用计数协议正确(编码红线 #9)。

特性交叉影响

已按 cross_feature_check.md 逐项检查:

场景 适用性 结论
SuperKernel Python/C++ 接口 不适用 两期均零改动,wheel/ABI 不受影响
Autofuse 图优化 适用 normalize 新增 pass 挂载于合轴前,时序依赖已注释;透传为视图级等价改写;1961 的准入/对齐策略被 1980 门控收编为统一规则
Autofuse Codegen/Backend 适用 新 ApiCall 注册、VF 签名扩展(stride 全量传参)、掩码 dtype 传播
AscendC API / Runtime 交互 不适用 无新增 rt/aclrt 调用
Python/C++ 混合绑定 适用 richcompare 协议修复
构建与打包 不适用 CMake/构建脚本零改动
测试与覆盖率 适用 两期新增 UT + 真机用例(55 组合)
性能与日志 适用 见下节,无高频路径新增日志
兼容性 适用 arange API 有意收紧(行为变化,见兼容性检查)

性能

编译时长

  • normalize 为单次线性扫描(Broadcast 节点 × 视图长度),无嵌套遍历;
  • 门控检查 O(视图轴数)。整体新增编译期耗时可忽略。

执行性能

  • 根图 ArangeApiCall 为回退路径(VF 不可用时),本身非高性能路径;
  • VF 签名变长(stride 全量传参):函数参数个数增加,寄存器传参影响可忽略,已列为后续优化项(仅传被引用项)。
  • 真机 triu [128,408,408] 掩码链闭环通过(性能非本 PR 验收项)。

内存和产物大小

  • 无新增常驻结构/缓存;pyautofuse.so 增量约一个 ApiCall 类的代码量;
    无 run 包布局变化。

接口设计

新增/修改接口描述

接口 类型 变化 期次
IndexExpr.expr: Expression ASCIR 属性 整数 attr 升级 Expression;输出 dtype 限定 int32/int64(浮点消费走前端改写协议,见 FR4) 1961
Arange.base/step: Expression ASCIR v2 属性 新增注册(int32/int64) 1961
ascir_api.arange(...) Python 前端 新增构图入口;1980 行为收紧:非退化零 stride 抛 ValueError(带改法提示) 1961+1980
ascir_api.IndexExpr(...) Python 前端 新增构图入口 1961
optimize::NormalizeArangeBroadcastViews(AscGraph&) C++ 内部导出 新增:视图规范化入口 1980
VectorFuncPartitioner(graph, disable_arange_vf=false) C++ 内部 构造函数加默认参数(源码兼容) 1980
kGraphAttrIsUBFuseContext C++ 内部 attr 键 新增:BufQueAllocator 写 / PlatformV2 读 1980
"ArangeApiCall" codegen 工厂注册 新增:根图 Arange 出码 1980
SizeExpr.__eq__/__ne__ Python 绑定 修复:返回新引用、!= 可用、< 等干净 TypeError 1980

接口检查项

检查项 子检查项 是否涉及 说明
接口说明 是否需要接口评审 否 均为内部接口,无对外 API 变化
接口说明 是否需要补充文档 是 前端协议已更新至构图指南 3.2/3.3/4.6.6
接口兼容 行为是否兼容 部分 arange 校验有意收紧(旧放行的烘焙广播现拒绝)
接口兼容 ABI/API 是否兼容 是 默认参数构造、纯新增导出符号
接口约束 约束不满足时是否清晰报错 是 构图期 ValueError;编译期 fail-closed 带原因
接口测试 是否需要独立接口用例 是 UT 覆盖校验分支;真机覆盖合法形态

软件设计

关键数据结构

DS-1 双视图张量模型(全链路数据基座)

Arange 的一切判定都建立在逻辑 view 与物理布局分离的既有张量模型上
(AscTensorAttr / codegen::Tensor,字段见 codegen_kernel.h:97):

字段组 语义 消费方
axis / repeats(size) / strides 逻辑 view:每根轴的尺寸与逻辑取值步长(stride=0 即值重复) ArangeHasBroadcastOuterAxis、Tiler::Offset(逻辑偏移)、前端校验
vectorized_axis / vectorized_axis_pos / vectorized_strides 物理布局:调度器合轴后的 UB 连续布局,vectorized_axis_pos 回指逻辑 view 下标 Tiler::TensorVectorizedOffset(物理偏移)、GetArangeBlockOffset、ArangeApiCall 扫描

生命周期:随图节点输出 attr 由构图写入,normalize/scheduler 依调度结果重写
vectorized_*,codegen 只读;无独立所有权(附属于节点输出)。

设计含义:取值语义永远由逻辑 strides 决定,物理摆放由 vectorized_strides
决定
。透传、门控、双偏移三个算法都只做"从两组字段各自读取正确一侧",
不改写彼此,这是图改写等价性可证明的结构基础。

DS-2 ArangeParam——VF 内 Arange 的参数载体(1980 扩展)

struct ArangeParam {              // vf_loop.h:19
  ascir::TensorId tensor_id;      // 关联 Arange 输出张量(参数命名后缀)
  std::string base;               // base 表达式串
  std::string step;               // step 表达式串
  std::string offset;             // 外层调度逻辑偏移(outer-for 场景)
  std::vector<std::string> logical_strides;  // 1980 新增:各逻辑轴 stride 形参名
};

由 VFLoop::CollectArangeParams 递归收集(值语义,codegen 期临时对象),
logical_strides 从 tensor->axis_strides_ 逐轴填充。直接决定 VF 函数签名:

// vec_func_call.cpp:506 生成的形参(每个 VF 内 Arange 一组)
int64_t arange_offset_<id>, int64_t arange_base_<id>, int64_t arange_step_<id>,
int64_t arange_stride_<id>_0, ..., int64_t arange_stride_<id>_<n-1>

多 Arange 隔离:参数以 tensor_id 为命名空间,同一 VF 内 N 个 Arange
互不串扰。签名兼容性:不含 Arange 的 VF 签名不变(1961 确立的约束)。

DS-3 VFLoop 循环树——VF 代码的结构载体(1980 修复)

struct VFLoopBody { LoopType type_;  // LOOP 或 CALL
                    union { MicroApiCall *call_; VFLoop *loop_; }; };
class VFLoop {
  std::vector<VFLoopBody> bodys_;        // 嵌套循环/调用体
  std::string max_dtype_size_;           // 子图最宽计算 dtype(构造期计算)
  mutable std::string loop_dtype_;       // 1980 新增:掩码 dtype(递归传播)
};
  • 生命周期:ConstructFromNodes 自 VF 子图构建(new 出的子循环由 Destruct() 递归释放),随 VfCall 代码生成期存活。
  • max_dtype_size_ 在遍历子图全部输出时按 GetSizeByDataType 取最大字节宽确定(vec_func_call.cpp:342),随后 SetMaxDtypeSize → SetLoopDtype 递归传播给整棵循环树。
  • mutable 的取舍:Generate 为 const 接口,传播发生在生成前一刻;已注释说明。

DS-4 CallParam——MicroAPI 调用上下文(1980 扩展)

struct ArangeParams { bool valid; std::string base; std::string step; };
struct CallParam { std::string p_reg;      // 掩码寄存器名
                   std::string offset;     // 块偏移(Arange 场景)
                   std::string max_dtype_size;  // 调用侧 dtype
                   ArangeParams arange; };  // Arange 参数直通

VFLoop::GenerateBody 对 MicroApiName()=="Arange" 的调用先算块偏移再经
param.arange 把 VF 形参名(arange_base_<id>/arange_step_<id>)传入
MicroArangeApiCall::Generate,与根图直连场景(用节点自身表达式)区分。

DS-5 ArangeApiCall——根图 Arange 出码器(1980 新增)

class ArangeApiCall final : public ApiCall {
  af::Expression base_;   // ParseAttr 从 ir_attr 解析
  af::Expression step_;
  // Generate 为纯函数:扫描状态(slice/broadcast_frames/has_fixed_axis)
  // 均为栈上局部量,无跨调用状态
};

工厂经 static ApiCallRegister<ArangeApiCall> register_arange_api_call("ArangeApiCall")
注册;注册名 "ArangeApiCall" 由 v2 注册表 GetApiCallName() 提供
(1980 之前为空串导致根图 Arange 无法出码)。持有零输入张量状态。

DS-6 kGraphAttrIsUBFuseContext——上下文标记(1980 新增)

图级 attr 键:BufQueAllocator 在 UBFuse 分配时写入,PlatformV2 分区时读取。
选择 graph attr 而非 BasePlatform 公共接口,避免为单一消费方扩公共 ABI;
生命周期与图一致,一次写一次读。

DS-7 IndexExpr Expression 常量——符号标量的双形态载体(1961 建立、1980 扩展)

IndexExpr 不是普通 UB tensor,值在 codegen 中以两种形态存在:

形态 载体 生成方 消费方
根图具名常量 Tensor::const_value_expr(ascir::SizeExpr,codegen_kernel.h:127)经 TPipe::AddTensor(output, expr, name) 注册 ParseGraph IndexExpr 分支 + BlkTensorAllocAndInit(1980 补 ParseOptimizeInfo 与符号回退) GetScalarValue():const_value 为空时返回生成后的具名 tensor 变量名(codegen_kernel.h:164)
VF 值参数 VfCall 签名中的标量形参 CollectArangeParams 同源的 scalar 输入收集 MicroBinaryScalar/MicroCompare 标量变体

关键不变量:值为 0 的 Expression 仍是有效表达式(1961 修复"零表达式被误判
为空值");符号值 Scalar 的 const_value 字符串为空属正常态,必须回退
tiler.Size(const_value_expr, true) 而非产出空串(1980 修复非法 C++)。

DS-8 IsScalarNodeType——scalar-like 白名单(1961 确立)

bool IsScalarNodeType(const std::string &node_type) {   // micro_binary_scalar_api_call.cpp:17
  return node_type == Scalar::Type || node_type == ScalarData::Type ||
         node_type == IndexExpr::Type;
}

IndexExpr 与 Scalar/ScalarData 同类调度与同路识别,但三者行为不完全等价
(如 ScalarData 的常量直取路径与 IndexExpr 的符号解析路径不同);白名单
同时被 partition(直连准入)与 codegen(s 后缀变体选择、参数交换)消费,
是消费边协议(AL-9)的判定原语。

关键技术/算法

AL-1 退化轴透传等价性(1980,透传正确性证明)

命题:设 Arange 逻辑 view 第 i 轴退化(repeats[i]=1, strides[i]=0),
则从 view 中删除或补入该轴,物化结果与消费语义均不变。

证明分两支(对应 DS-1 双视图):

  1. 物理无关:该轴尺寸为 1,对物理连续布局的贡献是乘 1——删除后
    TensorVectorizedOffset 输出的写地址表达式不变;
  2. 逻辑无关:该轴 stride 为 0,Tiler::Offset 中 stride==0 直接
    输出常数 "0"(codegen_kernel.cpp:665)——删除后取值表达式不变。

因此扩维(值沿该轴重复)可以完整移交 Broadcast 节点的通用
BroadcastExtend 路径处理,Arange 只物化扁平一维序列——与已验证的
退化轴 Load[4,1] → Broadcast[4,8] 路径同构。改动前实现把 Broadcast
输出 repeats 烘焙进 Arange view(repeats=[4,8]),与"保持 Broadcast
扩维职责"的注释自相矛盾,且 Pattern B 物化代价 O(rows×cols) 标量写
;
透传后降为 O(单轴) 标量写 + 向量化 BroadcastExtend,严格占优。

AL-2 1D 补齐算法(1980,normalize 内)

对"Arange 轴数 < Broadcast 输出轴数"的 1D 形态(1961 前端协议),按
Broadcast 输出轴序逐位置补齐:变化轴位置保留自身 size 与 stride=1,
其余位置补 (size 1, stride 0);vectorized_strides 按补齐后 repeats
重建为扁平连续布局(从尾到头累积 flat_stride *= axis_size)。

前置校验(fail-closed,任一不满足整体 Optimize 失败):

  • 三列表(axis/repeats/strides)等长、轴数不超 Broadcast 输出;
  • 恰好一根非退化轴且其 stride==1(IsDegenerateAxis 判定);
  • 变化轴存在于 Broadcast 输出轴中;尾轴一致且 Broadcast 尾 stride==1;
  • Arange/Broadcast 双方均无控制边(等价性证明不覆盖带序约束的图)。

同轴数多轴退化视图直接透传(仅同步 sched.axis)。复杂度:单次线性
扫描 Broadcast 节点 × 视图长度,无嵌套。

AL-3 ArangeApiCall 尾到头扫描状态机(1980,根图物化核心)

对 output.vectorized_axis 从最内轴向外逐轴分类(四个状态):

状态 判定 处理
退化轴 axis_size[pos]==1 && axis_strides[pos]==0 continue 跳过(对两偏移均无贡献,见 AL-1)
固定轴 轴 id ∈ current_axis(外层循环已固定该轴前缀) has_fixed_axis=true;count 改用切片实际尺寸
广播轴 逻辑 axis_strides[pos]==0 且非退化 记入 broadcast_frames(帧尺寸, 物理 stride),物化时展开帧循环
变化轴 其余 有界连续校验:axis_size[pos]==axis.size(值域有界)且 vectorized_strides[index]==累积 stride(物理连续);加入连续切片 slice

伴随的守卫:IsFrom(current, id) 禁止未证实的派生轴局部范围(防止
tiling 分裂后 current_axis 与逻辑 view 的对应关系无法证明);
!GetAxis(slice.front()).IsInner() 禁止多轴内尾压平。

有界连续校验失败即 FAILED——不做无法证明安全的猜测性出码,由
上层 Optimize fail 携带原因退出。这是根图路径的 fail-closed 边界。

AL-4 烘焙广播物化——双偏移分离(1980)

C++ 直连 ASCIR(无前端协议约束)仍可能携带烘焙广播 view(如
size=[4,8], strides=[1,0])。物化分两步:

  1. 物理连续化(MaterializeArangeViewContiguous):把 vectorized_strides
    按 repeats 从尾到头重算为连续布局(每轴 stride=右侧各轴尺寸之积),
    物理侧恢复可连续写入;
  2. 双偏移循环生成:
for (arange_b0 < frame_size) {                      // 广播帧(物理 stride 前进)
  for (arange_i < count)                            // 连续序列
    SetValue(write_addr + arange_i,                 // 物理偏移:连续/帧步长
             base + (logical_offset + arange_i) * step);  // 逻辑偏移:stride 语义
}

write_addr(TensorVectorizedOffset + 帧偏移)决定写在哪里;
logical_offset(Tiler::Offset,逻辑 stride 求值)决定取什么值。
两者解耦是烘焙广播可物化的充分条件——值重复(逻辑 stride=0)与
物理前进(连续布局)互不干扰。

AL-5 VF Arange 块偏移与 outer-for 合成(1961 确立、1980 参数化)

VF 内 Arange 每块取值 = base + (外部逻辑偏移 + 块内偏移) × step:

  1. 块内偏移(GetArangeBlockOffset,vf_loop.cpp:84):找 lane 轴
    (vectorized_strides 尾部最后一个非零轴),lane 轴贡献
    ELEMENT_PER_VECTOR_LENGTH(向量寄存器一次装载的元素数),外层轴
    贡献 axis_var * logical_stride;
  2. 外部偏移(outer-for):调度把外层轴循环放在 VF 调用点外时,
    逻辑偏移经 VF 形参 arange_offset_<id> 传入,与块内偏移相加;
    全量逻辑 strides 亦形参化(arange_stride_<id>_<k>),使同一 VF
    函数可被不同 tiling 的调用点复用;
  3. 块基合成(MicroArangeApiCall::Generate):
    block_base = vf_base + block_offset × vf_step,随后按 step 静态值
    分派:step==1 → 单条 Reg::Arange(block_base);step≠1/动态 →
    Reg::Arange(0) + Reg::Muls(step, p_reg) + Reg::Adds(block_base, p_reg)
    三指令降级(掩码寄存器 p_reg 保证尾块按掩码长度计算)。

正确性来源:Reg::Arange 只能表达单条连续等差序列——这正是 AL-6
把烘焙广播挡在 VF 外的根本原因(MicroAPI 能力边界即算法边界)。

AL-6 位置无关广播检测(1980,门控核心)

ArangeHasBroadcastOuterAxis:遍历逻辑 strides,任一轴满足
stride==0 && repeats!=1 即判定为烘焙广播(值沿该轴重复),拒绝进 VF。

位置无关的含义:旧实现只检查"lane 轴之前"的零 stride(Pattern A 假设),
Pattern B(strides=[1,0],广播在尾轴)漏检。新规则与 normalize
(AL-2 的 IsDegenerateAxis)、前端校验(构图期拒绝)三处共用同一语义
——"非退化 + 零 stride = 广播",不依赖轴位置,三处判定零漂移。

AL-7 掩码 dtype 统一传播(1980,修复混合 dtype 错位)

缺陷机理:UpdateMask<T>(len) 按 dtype T 的每向量元素数生成掩码;
循环与计算 dtype 不一致时(如 int64 掩码配 float32 计算),掩码位与
计算寄存器 lane 错位——每 sizeof(宽)/sizeof(窄) 个元素损坏 1 个。

修复算法:ConstructFromNodes 遍历子图全部输出取最宽 dtype 为
max_dtype_size_;SetLoopDtype 自根循环递归传播到全部嵌套循环;
所有 UpdateMask 统一用 loop_dtype_(vf_loop.cpp:435),各张量的
Load/Store 仍用自身 dtype。不变量:掩码跟随最宽计算 dtype,张量各自
保持 dtype
——掩码是 lane 对齐的全局资源,取值是张量局部行为。

AL-8 逻辑/物理偏移原语(1961 基座,两路径共用)

// codegen_kernel.cpp:640 —— 逻辑偏移:stride 0→"0",1→axis,否则 axis*stride
Tiler::Offset(current_axis, axis, axis_strides);
// codegen_kernel.cpp:682 —— 物理偏移:仅累计 current_axis ∩ vectorized_axis
Tiler::TensorVectorizedOffset(current_axis, tensor);

VF 路径(AL-5 的块偏移合成)与根图路径(AL-3/AL-4 的双偏移)消费同一
对原语,保证两条 codegen 路径对同一视图的偏移语义一致——这是双路径
互补(VF 不变 + 根图回退)在算法层的落点。

AL-9 IndexExpr 消费边分类协议(1961 确立)

逐边协议表(partition 直连准入 + codegen 变体选择):

消费方式 行为 关键边界
IndexExpr → Broadcast scalar-like 调度;VF 中可变为 Scalar 占位和值参数 设备用例的主要方式;Broadcast 需要明确目标 axis/size/stride
IndexExpr → Add/Minimum/Maximum MicroBinaryScalar 识别 IndexExpr;单 scalar 输入自动交换到第二位,API 加 s 后缀(Add→Adds) 双 scalar 输入拒绝(Init 断言)
IndexExpr → Lt/Le/Gt/Ge/Eq/Ne 第二输入 MicroCompare scalar 路径识别 仅第二输入;第一输入需寄存器(VF 准入拒绝 Scalar/IndexExpr 第一输入),不能泛化为两侧
IndexExpr → Compare 第一输入 拒绝 应在上游保持 Broadcast 或做语义正确的前端转换,不是 codegen 自动改比较方向
IndexExpr → 其他 Micro 算子 非白名单且任意输入直连 scalar-like 时禁用该节点 VF MicroBinaryScalar 能识别某类型 ≠ partition 对所有使用它的 op 都放行
IndexExpr → FloorDiv/Sub/Remainder 等 当前组合测试显式 Broadcast 后作为 tensor 消费 不能据测试推导全部直连 scalar 位置已支持
IndexExpr → Store 数据输入 Store IsNodeValid 不支持 scalar 输入 需物化为 tensor(blk tensor,1980 FR3)
IndexExpr 用作 Load/Store offset offset 是独立 Expression attr,不是把 IndexExpr 输出数据边转地址 写值、写地址、间接索引是三种不同协议

重要边界:InsertBroadcastAfterScalarForAscGraph 仅收集 Scalar、不收集
IndexExpr(scalar_broadcast_insert.cpp:124-139),VF 的 Broadcast 消除也只把
根源 Scalar 作为候选(scalar_broadcast_optimization.cpp:45-61)——因此
"optimizer 自动为 IndexExpr 插入 Broadcast"不构成当前契约,前端必须显式
构图 Broadcast(scalar_consumer/composition/compare_mask/window_math
均如此)。

AL-10 IndexExpr 浮点消费改写等价性(前端契约)

改写:index_expr(expr, f32) → IndexExpr(expr, int64) → Broadcast → Cast(f32)。

等价性论证:

  1. expr 值域为整数,int64 物化无截断(inductor size/index 语义按 int64 管理);
  2. int64 → f32 舍入与 inductor 参考实现一致:参考实现同样把整数值转 f32
    参与运算,numel > 2²⁴ 时双方一致舍入,对齐参考即正确;
  3. Broadcast 保持逻辑取值不变(退化轴 stride 0),Cast 仅改 dtype 不改 view。

形态约束:Cast 必须在 Broadcast 之后——IndexExpr 输出无 axis/repeats,
标量域无 Cast 的合法形态;顺序颠倒会因 Cast 无 view 失败。guard 分支:
dtype 依赖运行时信息无法静态确定时走 fallback(不融合),与 eager fallback
一致,不产生半改写图。

AL-11 IndexExpr 标量块物化与符号回退(1980)

根图 IndexExpr 与 Scalar 共享 blk tensor(32B 对齐标量块)物化链,三个环节:

  1. 准入:ParseScalarNeedGenBlkTensors 的类型过滤器从
    Scalar | ScalarData 扩为 Scalar | ScalarData | IndexExpr——决定哪些
    节点生成 blk tensor;
  2. 取值回退:BlkTensorAllocAndInit 中
    const_value.empty() ? tiler.Size(const_value_expr, true) : const_value——
    符号值 Scalar/IndexExpr 的字符串常量为空,直接用会生成空串非法 C++,
    回退用 tiler.Size 把符号表达式转成 tiling 参数引用;
  3. 元数据补全:ParseGraph 的 IndexExpr 分支补 ParseOptimizeInfo,
    与 Scalar 分支对齐——此前只 AddTensor 不解析优化信息,后续 tiling
    查不到该张量。

三处缺一都会导致索引消费链拿到未初始化/未对齐/查不到的标量块。

流程设计

主流程:构图(校验)→ GraphPass(normalize,合轴前)→ 分区(门控)→
调度(对齐策略)→ codegen(VF 或根图)。异常流程:任一校验失败即整体
Optimize 失败并携带原因;无部分改写状态(视图改写原子完成)。

对子模块的修改

  • PR 1961(36 文件,+3156/-121):ASCIR 注册 3、Python 接口 6、公共 codegen 3、VF/MicroAPI 7、optimize 4、测试 12(含新增 test_index_expr_arange_schema.cpp、micro_arange_api_call UT)。逐文件说明见 pr_1961_change_summary.md。
  • PR 1980(17 业务文件):逐文件清单与语义见 pr_1980_code_change_rationale.md 第 4 章。

错误处理

系统错误

  • 内存/属性缺失:GE_ASSERT 系列(含原因);工厂注册失败进程启动期暴露。

接口错误

  • 前端:ValueError(含改法提示);编译期:Optimize fail 携带 pass 名(如 Normalize explicit Arange Broadcast views failed);
  • 绑定:__eq__ 正常返回 bool;不支持的比较返回 NotImplemented(Python 层表现为 TypeError)。

安全检查

已读取并检查 编码红线.md:

  • 敏感信息/公网地址/芯片硬编码:无 ✔
  • 外部输入作索引/长度:视图长度与 vectorized_pos 使用前均有范围断言(pos < axis_size.size() 等)✔
  • 整数溢出/除 0:符号表达式运算由 SymEngine 承载,无裸整数运算 ✔
  • 资源生命周期:无新增动态资源;绑定层引用计数协议修复 ✔
  • ABI/API:构造默认参数、纯新增符号、无结构体布局变化 ✔
  • 图改写等价与确定性:透传为视图级等价改写;无容器遍历顺序依赖 ✔
  • runtime/aclrt:无新增调用 ✔
  • 静态检查:G.CMT.04 空注释行已修复(vector_func_partitioner.cpp:112)✔

兼容性检查

  • Python API 行为变化(有意):ascir_api.arange 拒绝非退化零 stride。
    影响面:直接构图脚本需改用 1D Arange + 显式 Broadcast 或退化视图;
    TorchInductor 前端按新协议生成,不受影响。
  • 脚本参数/配置/安装目录/run 包布局:无变化。
  • 旧产物:VF 函数签名内部变化不影响已加载产物。

测试设计

测试边界

入口:py module UT(构图+schedule+codegen 断言)、v35 UT(分区/codegen
文本断言)、真机 device validation(codegen→JIT→编译→load→launch→
精度)。打桩:ARANGE_GRAPH_PROBE 控制边注入。验证数据:numpy 随机输入

  • 独立 reference(如 np.triu)。IndexExpr 覆盖用例:scalar_consumer、
    composition、compare_mask、window_math(+规划 float_indexexpr_cast_mul);
    Arange 覆盖用例:arange_store、degenerate_arange_add(_3d)、triu_arange_mask、
    broadcast_add、auto_arange_fallback 等。

测试用例设计

测试类别 关键测试项 测试方法 用例类型
功能 IndexExpr Expression 物化与符号常量(1961) codegen 文本断言(具名标量)+ 真机精度(scalar_consumer、composition) UT/ST/RDV
功能 IndexExpr scalar 消费边协议(1961) 真机精度(compare_mask 比较第二输入、window_math FloorDiv 显式 Broadcast 链)+ UT(白名单/双 scalar 拒绝/参数交换) UT/ST/RDV
功能 IndexExpr 标量块物化与符号回退(1980) codegen 文本断言 + 真机(索引消费链 32B 对齐标量块) UT/ST
功能 浮点消费改写 IndexExpr(int64)→Broadcast→Cast(f32)(FR4 规划) RDV 对拍 eager(float_indexexpr_cast_mul,[32,64]/[32,65]/[2,127])+ pytest 构图正向用例 RDV/ST
功能 VF Arange 逻辑 offset/outer-for/多 Arange 隔离(1961) codegen 文本断言 + 真机精度 UT/ST
功能 Pattern A/B 透传、3D 线性组合、batch triu 掩码(1980) 真机精度比对(degenerate_arange_add(_3d)、triu_arange_mask、broadcast_add) ST/RDV
功能 根图回退出码形态(arange_i/SetValue)(1980) 文本断言(auto_arange_fallback + probe) UT/ST
功能 VF 掩码 dtype 统一(1980) 生成代码断言 + 真机精度(掩码链) UT/ST
异常 浮点 dtype 直连 IndexExpr 清晰报错(1980 契约) 既有负向用例回归(Check dtype failed) UT
异常 非退化零 stride 构图拒绝(1980) pytest.raises(值与提示语) UT
异常 normalize 校验失败路径(1980) UT(各违规维度) UT
异常 SizeExpr !=/< 协议(1980) UT(返回值与 TypeError) UT
兼容性 Store DMA 方向(Load 行为不变)(1980) codegen 文本断言 + 真机 UT/ST
兼容性 常量 Cast Duplicate 形态(1980) E2E 断言(scalar_cast_add) ST
特性交叉 UBFuse 禁 Arange、8↔4 Cast 门控(1980) UT(partitioner)+ ST(fusion 期望) UT/ST

测试命令

sh build.sh -u --module=autofuse_framework -j 8   # 预期: 全绿 (py 267+ passed)
bash tool/index_expr/run_index_expr_regression.sh  # 预期: 55 组合 PASS=55 FAIL=0

验收标准

  1. 框架全量 UT 全绿(含 py module 267 passed,CI Python 3.10 无退出崩溃)。
  2. 真机 55 组合全 PASS:2026-09-11 全量重跑 55/55 通过,
    21,329,846 元素 mismatch=0、nan=0;triu [128,408,408] 掩码链
    2130 万元素零误差(max_abs_error=0.0);3D 退化轴组合索引通过。
  3. clang-format 18.1.8 / ruff 0.14.14 / OAT / 静态检查(G.CMT.04 等)全过。
  4. PR diff 仅含语义修改(无 .gitcode、无纯格式 churn)。
  5. CI(GitCode 流水线)全量 COMPLETED,ci-pipeline-passed label 生效。
  6. 文档:构图指南协议章节更新、两期逐文件修改说明、崩溃分析归档完成。

设计文档检查结果

likedislike
JJett_Woo成员
25 天前 关联了pull request:feat: support IndexExpr and Arange autofusion
JJett_Woo成员
25 天前 将 Jett_Woo 设为负责人
JJett_Woo成员
25 天前 修改了issue 的描述
JJett_Woo成员
25 天前 修改了issue 的描述
JJett_Woo成员
25 天前 修改了issue 的描述
JJett_Woo成员
25 天前 修改了issue 的描述
JJett_Woo成员
25 天前 关联了pull request:fix: complete Arange fallback path (#302)
JJett_Woo成员
19 天前 修改了issue 的描述
Jett_Woo成员
19 天前 评论:

需求完善

likedislike
JJett_Woo成员
19 天前 修改了issue 的描述
JJett_Woo成员
16 天前 关联了pull request:fix: skip broadcast backward for scalar-like producers with empty views
JJett_Woo成员
16 天前 关联了pull request:fix: complete Arange fallback path (#302) [backport 9.2.0]
JJett_Woo成员
16 天前 关联了pull request:fix: adapt IndirectLoad SIMT coordinates and CV tiling data access for Arange graphs
xiebangrui2025xiebangrui2025成员
14 天前 关联了pull request:feat: 支持 IndirectLoad Load-Transpose 布局并完善 SIMD/SIMT codegen [backport 9.2.0]
JJett_Woo成员
10 天前 关联了pull request:fix: skip broadcast backward for scalar-like producers with empty views [9.2.0]
JJett_Woo成员
8 天前 关联了pull request:fix: BroadcastBackward Arange门控降粒度并放行退化轴公共轴后移
JJett_Woo成员
8 天前 关联了pull request:fix: BroadcastBackward Arange门控降粒度并放行退化轴公共轴后移 [9.2.0]
JJett_Woo成员
5 天前 关联了pull request:fix: 回合v35 reduce迁移系列并放行BroadcastBackward Arange退化轴公共轴后移 [9.2.0]