已合并
feat: add SoC-specific ATT performance model #2490
feat: add SoC-specific ATT performance model #2490
已合并
zhang_shengjie创建于 17 天前
zhang_shengjie成员
17 天前

描述

一、主要解决的问题

1.1 V35 需要同时携带 NpuArch 与完整 SoC

原有 PlatformInfo.soc_ver 承担 NpuArch 语义,V35 无法区分同一架构下的具体 SoC。本次保留旧字段和旧接口布局,新增内部完整 SoC 状态与 SetPlatformTarget/GetPlatformTarget,Python set_platform 增加可选第四个位置参数。

1.2 历史性能模型需要按完整 SoC 做少量差异合成

新增 SoC 性能配置核心,按 (NpuArch, full_soc_version) 精确绑定目标,复用历史 JSON 基线并合成显式差异;校验成功后才发布只读缓存,避免目标间参数串用。

1.3 ASCIR / AscendC 需要稀疏函数替换

包装层读取同一目标副本,先按原工厂注册名创建对象,再按注册名解析 ASCIR / AscendC 覆盖。空覆盖保留原函数;显式覆盖的源项或目的函数不存在时失败,不回退到默认函数,也不叠加成本。

1.4 公开入口需要提前失败并正确传播异常

ATT 建模、公开 codegen 和 Python backend 在进入 PGO / 图处理前校验目标;公式失败不提交节点成本;Python codegen 的 runtime_error 转为 Python 异常,不再返回部分 host 结果。

1.5 既有 V35 测试夹具需要显式完整 SoC

为进入新路径的旧夹具统一安装 V35 测试平台,保留原基线成本语义,避免只设置 3510 后因缺少完整 SoC 而误报。

1.6 配置缓存需要避免临时对象地址复用并降低重复解析成本

临时配置不持久缓存,避免地址复用误命中;内置表缓存校验和合成结果,后续函数解析只查当前 API。机制和验证见软件设计 3。

二、修改方案

  1. 平台双维度状态沿用原锁和布局;旧 setter 清理完整名称,新 setter 同步 UB override。
  2. Python 查询 requires_full_soc_version,仅 V35 取完整 SoC,一次设置平台。
  3. soc_perf_config 负责目标校验、JSON 合成、只读缓存和两类覆盖解析。
  4. 旧性能入口使用目标副本;ASCIR 类型名与工厂注册名区分。
  5. ATT/codegen 提前校验,Python 接收状态失败和异常。
  6. UT/ST 扩展原夹具,V35 E2E 使用 InstallV35SocPerfRuntimeStub。
  7. 固定配置缓存校验及合成结果;临时配置不持久缓存,函数解析只查当前 API。

各项数据结构、接口和边界见下文软件设计 1–3。

三、代码修改流程图

graph TD
    A[Python 或 C++ 入口] -->|target| B[读取双维度目标]
    B -->|query| C{是否需要完整 SoC}
    C -->|No| D[原 V2 路径]
    C -->|Yes| E[校验目标与配置]
    E -->|Invalid| X[生成前失败]
    E -->|Valid| F[合成历史 JSON 参数]
    F -->|resolve| G[解析 API 覆盖]
    G -->|generate| H[建模与代码生成]
    H -->|Error| Y[传播错误]
    H -->|Success| Z[返回完整结果]

四、lite 设计:需求 1–3 与软件设计关联

4.1 设计目的、范围及约束

复用历史 JSON 和原工厂/函数注册表,不新增 profile 身份、版本或 variant 注册层。

范围为 JSON 系数、API 函数覆盖和错误接收;VF、头成本、NDDMA / RegBase 沿用基线。真实模型、大量标定、新 schema 和调度差异另评估。不改图/pass 或 SuperKernel 接口,参数变化可能影响 tiling。

完整请求串行执行,期间目标固定。原子设置不等于整链并发安全;旧公式再次进入包装仍重新读取目标,不承诺整批只读一次或跨目标并发建模。

功能需求 软件设计及接口 验证关联
需求 1:双维度目标选择参数 SetPlatformTarget、ReadSocPerfTarget、ValidateSocPerfConfig、GetSocApiParams 同架构 A/B 参数、V2 原路径、缺目标/绑定失败
需求 2:少量 API 覆盖模型 ResolveSocAscIrPerf、ResolveSocAscendCPerf 空覆盖等价、替代只调用一次、注册名/别名、显式缺失失败
需求 3:历史参数同源与基本隔离 原参数 getter、目标缓存、旧 setter / Reset 原表不变、输入字段拒绝、显式目标隔离、串行 A/B/A、地址复用

4.2 软件设计 1:双维度目标选择参数(关联需求 1)

struct SocPerfTarget {
  std::string npu_arch;
  std::string soc_version;
};

using SocPerfKey = std::pair<std::string, std::string>;  // NpuArch、完整 SoC version。

struct SocPerfConfig {
  Json api_param_overrides = Json::object();
  std::map<std::string, std::string> ascir_model_overrides;
  std::map<std::string, std::string> ascendc_model_overrides;
};

using SocPerfConfigs = std::map<SocPerfKey, SocPerfConfig>;

SocPerfKey 是 NpuArch 与完整 SoC 的精确键,不是 profile key。配置随库交付、只读使用,不按前缀推断或解析 ini。架构形态沿用原登记:2201 使用 V2,3510 / 5102 / 9201 / 9202 使用 V35,未登记的 3102 不新增支持。架构登记与正式完整 SoC 绑定是两个独立条件。

Python 从同一 CANN 编译目标取 NpuArch,通过只读 requires_full_soc_version 判定;仅 V35 再取 SOC_VERSION,一次设置平台。C++ 显式设置二者。旧 PlatformInfo.soc_ver 保留 NpuArch 语义和原布局,完整 SoC 存储在 cpp 内部、沿用原锁。

平台接口为 SetPlatformTarget(platform_info, soc_version) / GetPlatformTarget(npu_arch, soc_version);核心接口为 ReadSocPerfTarget、ValidateSocPerfConfig、GetSocApiParams,返回 af::Status。Python setter 的可选第四参数是完整 SoC。

旧 set_platform 三参数顺序不变;旧 setter / Reset 清除完整 SoC,新 setter 同步 UB override。包装经 ReadSocPerfTarget 取得本次副本,核心显式接收目标,不从平台补字段。V35 按副本的 NpuArch 查询 AscirRegistry 和原工厂定位基线,避免目标 A 使用平台 B 的参数。

flowchart TD
    A[同一编译目标的 NpuArch 与完整 SoC] -->|一次设置| B[PlatformContext 双维度目标]
    B -->|包装读取副本| C{查询原架构登记}
    C -->|V2| D[原 V2 路径]
    C -->|V35| E{精确绑定并获取已校验配置}
    C -->|未登记| X[返回失败]
    E -->|缺名称 缺绑定 或非法配置| X
    E -->|成功| F[同架构历史 JSON 与目标差异]
    F -->|参数缓存| G[GetPerf 沿用原公式]

4.3 软件设计 2:少量 API 覆盖模型(关联需求 2)

配置字段 key value 未配置覆盖时
ascir_model_overrides 原工厂规范化 API 注册名,如 AbsV2 EvalCosts 已登记的 Perf key 原 ASCIR 函数
ascendc_model_overrides 原 GetAscendCPerfFunc 注册名,如 LoadV2 EvalCosts 已登记的 AscendCPerf key 原 AscendC 函数

两类映射独立,保留别名和架构 tag,不把 SoC 拼进 API 名称。GetApiPerf 按显式架构创建原对象,以 GetApiName() 选择覆盖;只替换 Perf,原参数表、MicroPerf 和调度表指针不变。

ResolveSocAscIrPerf / ResolveSocAscendCPerf 以 target、API 注册名和默认函数为输入,输出所选函数,返回 af::Status。

default_func 来自同一目标,输出沿用 Perf / AscendCPerf。覆盖只选择一个已登记函数,不累计默认成本;显式关联不存在则失败。AscendC 覆盖只作用于经过 GetAscendCPerfFunc 的调用。原 GetPerfFunc 保持静态查询,注册阶段不读取平台。

flowchart TD
    A[显式目标与规范化 API 注册名] -->|读取| B[已校验的内置配置]
    B -->|仅查当前 API| C{是否配置覆盖}
    C -->|否| D[同目标原函数]
    C -->|是| E{原始 EvalCosts 查询替代函数}
    E -->|缺失| X[返回失败 禁止默认兜底]
    E -->|成功| F[替代函数]
    D -->|执行| G[只调用所选函数一次]
    F -->|执行| G

4.4 软件设计 3:历史参数同源与基本隔离(关联需求 3)

历史 JSON 是参数基线层:原 perf_param 中的 kParamV2Info 原位保留,原 getter 仍返回历史表;本方案没有替代它或复制一份新参数源码。

原 perf_param / kParamV2Info(历史基线)
  + SocPerfConfig.api_param_overrides(SoC 稀疏差异)
  -> 校验及合成 -> 共享 const JSON -> 原 GetPerf / 公式
新增 MCXXXX 的 API 系数适配规则
  1. 先确认 MCXXXX 的真实 NpuArch,并确认该架构已登记为 V35;不能按型号前缀推断。未知架构需要先接入架构实现,只有 SoC 参数绑定不够。
  2. 在 soc_perf_config.cpp 的 GetBuiltinSocPerfConfigs 生产分支,构造 SocPerfConfig 并以 (NpuArch, MCXXXX) 登记。参数结构为 API -> model_params -> dtype pair -> 完整系数记录;参数 key 使用历史 JSON 名称 Abs,不是函数覆盖注册名 AbsV2。
  3. 每条 dtype 记录提供完整系数;即使只调整 k,仍需提供 b。API、dtype 和字段必须存在于基线;不得改 model_type,拒绝 data_type_size / block_count_idx。实际 float 范围及必要除数非零校验沿用现有逻辑,负系数按公式语义处理。
  4. 未覆盖 API/dtype 沿用历史参数,原 dtype fallback 和 EnrichParamMapForModel 不变。仅系数变化时两类模型覆盖映射保持为空,原公式和 kParamV2Info 不修改。

假设已确认 MCXXXX 属于 5102,生产配置构造阶段的登记示例如下;数值仅演示,需替换为真实标定值:

SocPerfConfigs result;
SocPerfConfig mc_config;
mc_config.api_param_overrides["Abs"]["model_params"]["float16tofloat16"] =
    {{"k", 0.01F}, {"b", 22.0F}};
result.emplace(SocPerfKey{"5102", "MCXXXX"}, std::move(mc_config));

正常 Python 编译自动读取完整目标;手动调用时设置二者:

ascir.utils.set_platform("5102", vector_core_num, ub_size, "MCXXXX")

配置随库交付,修改后重新构建。UT/ST 验证新系数生效、未覆盖参数保持基线、默认函数不变及非法记录拒绝。测试宏使用独立配置表,公共入口测试需同步测试绑定;核心可显式注入配置。新增 SoC 的真实系数精度另做标定/RDV,不属于下文已有测试结果。

内置配置按 SocPerfKey 缓存成功校验、配置副本、历史 JSON 与合成参数;首次校验与合成复用解析结果,后续入口直接命中。空差异共享解析基线,非空差异生成独立只读参数;失败不发布目标缓存。临时显式测试配置不持久缓存,避免对象地址复用。

flowchart TD
    A[显式目标与同架构历史 JSON] -->|查内置目标| B{成功资源缓存命中}
    B -->|是| C[共享只读参数]
    B -->|否| D[校验绑定 系数及模型覆盖]
    D -->|失败| X[返回失败 不发布目标缓存]
    D -->|成功| E[复用基线解析结果并合成差异]
    E -->|成功后发布| C
    C -->|求值| F[原 dtype fallback 输入增强及公式]

缓存有界,不持有 Expr、设备句柄或跨 SO 回调;核心不读取平台。

4.5 错误、兼容性与后续迁移

缺完整名称、未知架构、未登记 SoC、非法系数或显式模型缺失,在公开 codegen / ATT 入口提前失败,不跨 V2 / V35 回退。V35 公式失败不提交节点成本,Python 转为异常;历史 PGO 重试规则保留,重试目标与模型不变。

V2 原路径、历史 JSON、ApiPerf / ModelInfo / Codegen / TilingLib 旧布局和签名保持;有效 V35 空差异绑定默认成本等价,仅架构 V35 调用需补齐目标。沿用既有打包规则,测试资源不进入正式包。测试及交付证据见下文;合成测试不代表芯片精度,真实差异需 source/codegen 对照与 RDV。

完整方案复用目标、绑定、稀疏映射、显式核心和 UT/ST,再扩展 context、typed 参数、全成本域、平台快照与完整错误协议。原完整版设计和计划保留,不声明 lite 已实现完整方案。

变更类型

关联的Issue

无

如何测试

一、测试用例说明

1.1 单元测试

  • C1 common UT:通过。
  • C2 ATT UT:通过,1340 个用例运行、1 个禁用;新增 SocPerfConfigTest 36/36 通过。
  • C3 codegen / py_module UT:通过;Python 汇总 275 passed / 5 skipped。
  • C4 test_asc_codegen_compile_soc_target.py:5/5 通过。
  • 平台上下文、入口校验、公式失败、异常路径、float 溢出 / 零除数、注册名与别名场景均有定向用例。

1.2 系统测试

  • C5 ATT ST:1/1 通过,包含 115 个 gTest 用例。
  • C6 autofuse_framework:通过,test_main 与 Python 276 passed / 5 skipped。
  • C7 autofuse_e2e:通过,四阶段分别为 49/49、82/82、49/49、82/82。
  • C8 正常打包:通过,生成 cann-graph-autofusion_9.2.0_linux-x86_64.run。
  • C9 no-autofuse 打包:通过;包内仅含 SuperKernel 产物,不含 Autofuse 后端与测试资源。

二、性能验证

默认目标建模耗时约 13–14 ms/次,重复执行结果稳定;成功参数由共享只读缓存复用,核心接口不读取当前平台,默认路径无节点级 runtime 查询。内置目标校验与合成结果按目标缓存,后续函数解析仅查询当前 API 覆盖项。

核对清单

其他信息

验证方法

使用本地 CANN 与 third_party 依赖执行计划中的 C1–C9,全部通过。交付包内容已核对:正常包包含 aihac_codegen、pyautofuse 与 Python 脚本;no-autofuse 包不包含 Autofuse 后端;两种包均不包含测试宏、测试配置或测试 tiling 库。

注意事项

  • 正式完整 SoC 绑定清单尚未确认。本地仅有 MC62CM12AA -> 5102 证据,生产内置绑定表目前为空;生产 V35 请求会因缺少绑定提前失败,需确认首期清单并登记后才能正式启用。本地证据不自动视为交付授权。
  • 测试宏只切换测试资源来源,不改变校验、公式或错误行为;正式 aihac_codegen 不包含 ATT_SOC_PERF_CONFIG_TEST。
  • pyautofuse_runtime_error_tiling 仅用于测试构建,不进入正式交付包。

提交记录

Commit 描述 修改文件数
bf6c6cab0 feat: add SoC-specific ATT performance model 214
6038ef6a5 fix: harden SoC perf config cache 2

修改文件清单

整体规模:214 个文件,2488 行新增,407 行删除。其中生产代码 14 个文件约 839 行新增 / 38 行删除,测试与构建 200 个文件约 1649 行新增 / 369 行删除。

lite 原预算为生产与测试合计 760–1000 行,文档不计入;实际新增/删除合计 2895 行,已超原预算。生产代码约 877 行不代表整体达成 1000 行目标,预算验收仍需范围复核。

文件路径 修改类型 说明
autofuse/common/platform_context.cpp 修改 双维度平台状态与 UB override 语义
autofuse/inc/common/platform_context.h 修改 新增目标 setter/getter 声明
autofuse/att/gen_model_info/api_perf_register/soc_perf_config.h 新增 SoC 目标、配置与解析接口
autofuse/att/gen_model_info/api_perf_register/soc_perf_config.cpp 新增 校验、合成、缓存加固与稀疏函数解析
autofuse/att/gen_model_info/api_perf_register/utils/api_perf_utils.cpp 修改 旧入口统一读取显式目标
autofuse/att/gen_model_info/api_perf_register/ascendc_api_perf.cpp 修改 AscendC 运行期覆盖包装
autofuse/att/gen_model_info/gen_model_info.cpp 修改 建模入口预校验
autofuse/att/gen_model_info/expr_gen/pipe_perf_expr.cpp 修改 V35 公式失败返回
autofuse/codegen/codegen.cpp 修改 公开 codegen 入口预校验
autofuse/compiler/py_module/pyautofuse.cpp 修改 runtime_error 转 Python 异常
autofuse/compiler/python/asc_codegen_compile.py 修改 Python 同源目标输入
autofuse/tests/common/att/soc_perf_test_config.h 新增 只读测试 SoC 配置
autofuse/tests/ut/att/testcase/gen_model_info/api_perf_register/test_soc_perf_config.cpp 新增 核心配置与覆盖 UT
autofuse/tests/ut/python/test_asc_codegen_compile_soc_target.py 新增 目标输入 pytest
autofuse/tests/v35/st 修改 180 个 V35 ST 夹具统一安装测试目标
likedislike
Pull Request已成功合入, 合并人@CANN-robot
(感谢 zhang_shengjie 的贡献)
Zzhang_shengjie成员
17 天前 创建了 pull request,commit 0ef8b905
atomgit-bot
atomgit-bot
17 天前 评论:

🤖 正在生成合并请求摘要,请稍候…

likedislike
不准确?
atomgit-bot
atomgit-bot
17 天前 评论:

🤖 AI 代码检视正在进行中,请稍候…

likedislike
不准确?
CANN-robotCANN-robot成员
17 天前 添加了label:cann-cla/yes
CANN-robot
CANN-robot成员
17 天前 评论:

Thanks for your pull-request.
The full list of commands accepted by me can be found at here.
You can get sig-info at here.
You can self-configure the PR merge rules for this repository. For more details, please refer to Here.
For more, you also can visit HICANN.


PR Approval Progress

✅ Congratulations! All modules have met the lgtm and approve requirements.

Module Approval Details

module lgtm status approve status
repo-cann/graph-autofusion ✅ yangyongqiang0606, xchu42, wangxiaotian995, liyuewei (4/2) ✅ yangyongqiang0606 (1/1)

💡 Tip:

  • Committer can comment /approve or /lgtm
  • Commenting /approve implies both code review (lgtm) and intent to merge (approve)

CLA Signature Pass

zhang_shengjie, thanks for your pull request. All authors of the commits have signed the CLA. 👍

likedislike
此处折叠了98条消息 查看更多
CANN-robotCANN-robot成员
13 天前 添加了label:lgtm
liyuewei
liyuewei成员
13 天前 评论:

/lgtm

likedislike
yangyongqiang
yangyongqiang成员
12 天前 评论:

/approve

likedislike
CANN-robotCANN-robot成员
12 天前 添加了label:approved
CANN-robotCANN-robot成员
12 天前 合入了pull request