CANN Graph-Autofusion 设备验证(Device Validation)指南:用例契约、SoC Profile 与真机验证全流程
发布时间:2026/9/18 18:39:20来源:尧图网络
CANN Graph-Autofusion 设备验证Device Validation指南用例契约、SoC Profile 与真机验证全流程【免费下载链接】graph-autofusionGraph-autofusion 是一个面向昇腾Ascend芯片的轻量级、解耦式组件集合旨在通过自动融合技术加速模型执行。 目前已开源 SuperKernel 组件和 Autofuse 组件未来将持续开放更多自动融合相关模块。项目地址: https://gitcode.com/cann/graph-autofusionGraph-Autofusion 的device_validation是面向真机Ascend 硬件的端到端验证框架用于验证自动融合用例在真实设备上的编译、运行、精度与性能表现。本文围绕 autofuse/tests/st/device_validation/README_en.md 展开完整讲解其核心模型、环境搭建、从零编写新用例的五步流程、case.json 与 SoC Profile 编写规则、性能采集及故障诊断方法读者学完后可以独立新增或迁移一个设备验证用例并看懂其与 codegen/JIT/ACL 运行链路的对应关系。1. 核心模型三份契约设备验证框架由三个组成部分构成它们共同定义了在什么设备上、以什么方式、验证什么cases/case_id/case.json声明该用例支持的backend、SoC、dtype、shape以及编译/功能/精度/性能等能力矩阵profiles/soc.json声明某个设备型号的soc_version、ASCIR 平台信息platform/core_type/ub_size、资源上限、ABI 与工具链Runner/JIT消费 case 与 profile依次执行 codegen、设备编译、ACL 启动、D2H 回读与报告生成。框架的核心约束是可扩展不加分支新增用例或 SoC 时不允许在框架代码中为芯片型号添加分支逻辑。SoC 必须在 case 的support_matrix与 profile 中完全一致字符串精确相等任何不匹配都必须在设备任务启动前停止执行。从仓库结构看这三份契约分别对应 autofuse/tests/st/device_validation/cases/、autofuse/tests/st/device_validation/profiles/ 以及 autofuse/tests/st/device_validation/runner/ 与 autofuse/tests/st/device_validation/tools/ 下的执行编排代码。2. 环境搭建2.1 基础环境变量source CANN installation directory/set_env.sh export PYTHONPATHautofuse/tests/st:$PYTHONPATH export DEVICE_VALIDATION_RUNNER$PWD/build/autofuse/tests/st/device_validation/device_validation_runner export AUTOFUSE_DEVICE_JIT$PWD/autofuse/tests/st/device_validation/tools/jit_adapter.py说明CANN installation directory是占位符需替换为实际安装目录例如/usr/local/Ascend/ascend-toolkit/set_env.sh。本仓库不绑定任何固定路径。set_env.sh会导出ASCEND_HOME_PATH后续 CANN 包路径探测与运行时探测都依赖它。若未导出可用echo $ASCEND_HOME_PATH确认或手动设置为实际安装目录。2.2 确认设备与精确运行型号npu-smi info python3 - PY import ctypes import os lib ctypes.CDLL(os.path.join(os.environ[ASCEND_HOME_PATH], lib64, libacl_rt.so)) lib.aclrtGetSocName.restype ctypes.c_char_p print(lib.aclrtGetSocName().decode()) PY不要把显示的Ascend910泛化成Ascend910B、Ascend910B1/B2/B3/B4或Ascend910_93。必须使用aclrtGetSocName()的精确返回值例如仓库 profile 中出现的Ascend910_9362、Ascend950PR_9579。2.3 限制构建并行度cmake --build build --target pyautofuse device_validation_ut device_validation_runner -j 82.4 使用本仓库最新 autofuse 源码默认方式用于开发自验证codegen/ATT 流水线通过autofuse.pyautofuse加载自动融合实现。开发期自验证的目标是跑通本仓库最新源码因此默认应使用仓库构建的pyautofuse并将其置于PYTHONPATH最前# 构建 pyautofuse 需要本地 .dev_env第三方依赖配置未提交到仓库 # 没有 .dev_env 时无法构建 pyautofuse见下方回退到 CANN 包 cmake --build build --target pyautofuse -j 8 # 将仓库构建产物置于 PYTHONPATH 最前 export PYTHONPATH$PWD/build/autofuse/compiler/py_module:$PWD/autofuse/tests/st:$PYTHONPATH验证模块来源确认运行的是最新仓库代码而非 CANN 捆绑版本python3 -c import autofuse.pyautofuse; print(autofuse.pyautofuse.__file__) # 期望输出以 $PWD/build/autofuse/compiler/py_module 开头仓库构建产物 # 若打印的是 $ASCEND_HOME_PATH/python/site-packages 下的路径 # 说明模块未构建或 PYTHONPATH 顺序不对注意只有修改了仓库autofuse/目录下的源码optimize/codegen 等后构建产物才包含最新变更改码后重跑用例前必须重新构建 pyautofuse。2.5 回退到 CANN 捆绑 autofuse仅回退非最新源码在没有.dev_env或 pyautofuse 未构建时codegen 会报No module named autofuse。此时需要加入完整的 CANN Python 包而不只是包含裸pyautofuse.so的目录export PYTHONPATH$PWD/autofuse/compiler/python:$PWD/autofuse/tests/st:$ASCEND_HOME_PATH/python/site-packages:$PYTHONPATH注意此路径下验证的是CANN 捆绑的 autofuse而非仓库最新源码因此不能作为本仓库 autofuse 变更的自验证证据用上面的自检命令区分两者。在 CI 或无法构建 pyautofuse 的环境中回退到 CANN 包是可接受的基础验证基线。$ASCEND_HOME_PATH/python/site-packages依赖set_env.sh导出的环境变量若未导出用echo $ASCEND_HOME_PATH确认或替换为实际的 CANN Python 包目录。3. 新用例目录布局cases/case_id/ ├── case.json ├── input_ascir.py ├── gen_input.py ├── reference.py └── steps/ ├── op_a.py └── op_b.pycase.json输入、输出、支持矩阵与变体variantsinput_ascir.py融合 ASCIR/codegen 入口gen_input.py使用固定种子fixed seed与相关边界值进行确定性输入生成reference.py独立 golden 实现不得调用被测 AscendC APIsteps/*.py未融合分解每个 step 有自己的输入/输出与 ABI 契约。4. 从零构建用例五步实战教程本章以最小用例演示完整五步开发流程。真实样例可对照阅读 autofuse/tests/st/device_validation/cases/isinf_maskedfill_fusion/一个融合 ASCIR 入口 三个未融合 stepisinf、logical_or、masked_fill。第 5–8 章是各阶段的参考说明写用例时可结合使用。4.1 第一步创建目录与 case.json目录布局同第 3 章cases/my_case/ ├── case.json ├── input_ascir.py ├── gen_input.py ├── reference.py └── steps/ ├── step_codegen.py # 可选多个 step 共用的 codegen 骨架 ├── op_a.py └── op_b.py最小可运行case.json模板{ schema_version: 1, case_id: my_case, graph_name: my_case, inputs: [{shape: [1], dtype: float16, dynamic: true}], outputs: [{shape: [1], dtype: float16, dynamic: true}], verification: {functional: true, precision: true, atol: 0.001, rtol: 0.001}, performance: {required: false, profiler: true, metric: runner_wall_clock}, support_matrix: [{ case_id: my_case, backend: ascendc_real_device, soc: ascend910_9362, compile: required, functional: required, precision: required, performance: optional, dtypes: [float16], input_dtypes: [float16], output_dtypes: [float16], shapes: [[128, 128]] }], variants: {fused: {codegen_entry: input_ascir.py, graph: my_case}} }字段逐项说明schema_version固定为1。case_id必须与目录名一致。graph_namecodegen/JIT 使用的融合图名。inputs/outputs占位 shape 与 dtype 声明dynamic: true表示实际 shape 来自运行时的--shape参数。verificationfunctional/precision开关与容差atol/rtol。performance性能是否required、是否运行profiler、默认metric。support_matrix[].soc必须与profiles/soc.json的profile字段精确相等字符串相等。support_matrix[].input_dtypes/output_dtypes必须覆盖真实输入、输出以及未融合的中间输出。support_matrix[].shapes显式列出对齐、非对齐与尾部tailshape未声明的 shape 不会运行。variants.fusedcodegen_entry指向入口脚本名graph与graph_name对应未融合变体见 4.6。验证python3 -c import json; json.load(open(autofuse/tests/st/device_validation/cases/my_case/case.json)) pytest autofuse/tests/st/device_validation -q主机测试通过即说明用例可加载、支持矩阵/契约校验通过。仓库中真实样例 isinf_maskedfill_fusion/case.json 展示了三个输入float16、uint8、float16、一个输出、支持矩阵ascend950 与 ascend910_9362 两个 SoC、以及 fused/unfused/unfused_aclnn 三种变体。4.2 第二步编写融合入口 input_ascir.py骨架完整可读的构图代码见 cases/isinf_maskedfill_fusion/input_ascir.pyimport argparse import json from pathlib import Path from autofuse.pyautofuse import ascir, Autofuser, AutofuserOptions def build_graph(shape): # 用 ascir.ops/SizeExpr/Axis 描述融合图参见样例 input_ascir.py # 中的 _create_* / _compute_and_output 辅助函数 ... def generate_codegen(shape, output_dir, profile): platform json.loads(Path(profile).read_text(encodingutf-8))[ascir] ascir.utils.set_platform( platform[platform], platform[core_type], platform[ub_size] ) fuser Autofuser(AutofuserOptions()) fused fuser.schedule(build_graph(shape)) tiling, host, device fuser.codegen(fused) output Path(output_dir) output.mkdir(parentsTrue, exist_okTrue) (output / tiling.h).write_text(tiling) (output / host_impl.cpp).write_text(host) (output / device_impl.cpp).write_text(device) if __name__ __main__: parser argparse.ArgumentParser() parser.add_argument(--rows, typeint, requiredTrue) parser.add_argument(--cols, typeint, requiredTrue) parser.add_argument(--profile, requiredTrue) parser.add_argument(--output-dir, requiredTrue) options parser.parse_args() generate_codegen((options.rows, options.cols), options.output_dir, options.profile)要点四个参数名--rows/--cols/--profile/--output-dir是 runner 的调用契约不要改名。产物为tiling.h、host_impl.cpp、device_impl.cppabi_metadata.json可由 codegen 显式写出未融合的steps/step_codegen.py就是这么做的也可省略——省略时 runner 从device_impl.cpp中的启动签名推导并校验 ABI。不要硬编码 shape/SoCshape 来自--rows/--cols平台信息来自--profile的ascir字段。仓库中 isinf_maskedfill_fusion/input_ascir.py 展示了真实的融合构图方式用ascir.HintGraph建图ascir.SizeExpr表达行/列尺寸ascir.ops.Data声明三个输入数据节点ascir.ops.Load建立轴axis与步长stridesascir.ops.IsInf、LogicalOr、MaskedFill串联计算最后ascir.ops.Storeascir.ops.Output输出——这印证了文档所述描述融合图的完整 DSL 用法。手动执行一次 codegen 验证python3 autofuse/tests/st/device_validation/cases/my_case/input_ascir.py \ --rows 128 --cols 128 \ --profile autofuse/tests/st/device_validation/profiles/ascend910_9362.json \ --output-dir /tmp/my_case_codegen ls /tmp/my_case_codegen确认三个.h/.cpp产物存在且host_impl.cpp中包含AutofuseLaunch启动签名。4.3 第三步编写 gen_input.py 与 reference.pygen_input.py骨架固定种子、注入边界值import numpy as np def generate_inputs(shape, seed0): rng np.random.default_rng(seed) x rng.uniform(-4, 4, sizeshape).astype(np.float16) # 按需注入 NaN/Inf/0/边界值参见样例 gen_input.py x.reshape(-1)[0] np.inf return xreference.py骨架独立实现golden 不得依赖被测 kernelimport numpy as np def compute_reference(x): return np.where(np.isinf(x), 1.0, x).astype(np.float16)要点gen_input.py必须使用固定种子保证生成可复现reference.py只能使用独立的数学/框架实现禁止调用被测 AscendC API 或被测融合算子。仓库样例 isinf_maskedfill_fusion/gen_input.py 展示了边界注入的实战写法rng.uniform(-4, 4)生成 float16 数据后在位置 0/1/3 注入±inf在位置 2/3 注入 mask1——既覆盖isinf路径又覆盖 mask 置位路径对应的 reference.py 用np.where(np.isinf(x) | (mask ! 0), value, x)独立实现 golden。验证相同种子运行两次产生完全一致的输入字节reference 输出的 dtype/shape 与case.json中outputs声明一致。4.4 第四步声明 Profile 关联support_matrix[].soc与profiles/soc.json的profile字段必须精确字符串相等不做模糊或前缀匹配大小写或分隔符差异都会导致匹配失败。上真机前用aclrtGetSocName()确认精确芯片型号见第 2 章校验片段python3 - PY import ctypes import os lib ctypes.CDLL(os.path.join(os.environ[ASCEND_HOME_PATH], lib64, libacl_rt.so)) lib.aclrtGetSocName.restype ctypes.c_char_p print(lib.aclrtGetSocName().decode()) PY用返回值作为 profilesoc_version的证据ascir.platform/core_type/ub_size等参数必须来自该芯片真实的编译/设备事实绝不能从别的 SoC 的 profile 拷贝见第 6 章。验证--mode prepare生成 manifest 且无 SoC 不匹配命令见 4.5。4.5 第五步按验证顺序跑通顺序与命令见第 8 章各阶段验收标准1. Host tests: pytest autofuse/tests/st/device_validation -q 标准无失败用例加载与支持矩阵/契约校验通过 2. --mode prepare --shape 128 128 --warmup 0 标准生成输入/golden 与 manifest.json 成功prepare 的正常结果是 prepare_onlystage_statusnot_applicable, reasonprepare_only 此处不会出现 stage_statuspassed 3. --variant fused --mode functional --warmup 0 标准stage_statuspassed, precision.passedtrue, mismatch_count0, soc_profile 正确 4. --variant unfused --mode functional --warmup 0 标准每个 step 通过自身 ABI 校验最终 golden 与 fused 一致 需先在 case.json 声明 unfused steps见 4.6否则报 unfused variant must declare steps 5. --variant all --mode functional --warmup 0 标准fused 与 unfused 均通过 6. --mode performance --metric runner_wall_clock --warmup 2 --repeat 5 标准报告包含带真实 unit/timing_source 的 repeat 样本 7. --mode performance --profiler --metric device_kernel_duration --warmup 1 --repeat 3 标准profiler 导出成功失败时报告 profiler_export_failed 绝不用主机时间冒充设备时长prepare_only、skipped或not_applicable出现在 functional/performance 阶段不算功能通过stage_statuspassed仅适用于 functional/performance 阶段。4.6 编写未融合 steps每个steps/*.py是独立 CLI遵循steps/step_codegen.py中的run_step_codegen契约接收--rows/--cols/--profile/--output-dirop 名称与输入/输出 dtype 在脚本内固定。例如from step_codegen import run_step_codegen if __name__ __main__: run_step_codegen(isinf_graph, IsInf, (float16,), uint8)仓库样例 steps/isinf.py 正是这个形态而 steps/step_codegen.py 实现了run_step_codegen的完整逻辑解析参数 → 按 dtype 映射创建ascir.ops.Data/Load→ 按 op 名IsInf/LogicalOr/其他二元/三元 op挂接输入 →StoreOutput收尾 →Autofuser.schedule/codegen生成产物并用_write_artifacts写出abi_metadata.json。在case.json中variants.unfused.steps[i]声明每个 stepscript指向上面的脚本inputs中$previous表示上一个 step 的输出文件其余条目形如{file: input_N.bin, dtype: ..., shape: ...}outputs声明本 step 的产物。每个 step 有自己的输入、输出与 ABIsteps/step_codegen.py的_write_artifacts为每个 step 写独立的abi_metadata.jsonrunner 逐个校验不要复用 fused ABI。case.json的input_dtypes/output_dtypes必须覆盖未融合中间输出例如 uint8 mask否则矩阵校验失败。真实样例 isinf_maskedfill_fusion/case.json 的 unfused 变体展示了三步串联isinffloat16→uint8→ logical_or$previous uint8 输入→ masked_fillfloat16 $previous float16。4.6.1 可选 aclnn 模式直接调用 CANN 原生 aclnn op除了 ASCIR stepsteps/*.py codegen JITsteps 条目还可声明aclnn: OpName直接使用 CANN 原生 aclnn op例如IsInf/LogicalOr/MaskedFillScalar/MaskedFillTensor此时不需要scriptvariants: { unfused: { steps: [ {name: isinf, aclnn: IsInf, inputs: [{file: input_0.bin, dtype: float16, shape: [1]}], outputs: [{file: step_0_output_0.bin, dtype: uint8, shape: [1]}]} ] } }流程差异跳过 codegen/JIT不生成tiling.h/host_impl.cpp/device_impl.cpp不调用jit_adapter.py也不需要abi_metadata.json扁平请求携带aclnn_oprunner 分派到 aclnn step 执行器backend/aclnn_executor.cpp直接调用 CANN aclnn API未知 op 报unknown_aclnn_op。JIT 环境要求当所有 steps 都是 aclnn 时AUTOFUSE_DEVICE_JIT非必需fused 运行或含 ASCIR 入口的 step 仍需要它。4.6.2 aclnn step 的调用方式runner 执行序列aclnn step 在设备上遵循统一的 CANN query-allocate-create-bind-execute-sync-free 调用序列在 backend/aclnn_executor.cpp 中实现为 op 分发表支持IsInf/LogicalOr/MaskedFillScalar/MaskedFillTensor新增 op 沿用同一模式// 1) 查询 workspace 需求op 相关 aclnnXxxGetWorkspaceSize(desc, workspace_size); // 2) 分配 workspace设备内存 aclrtMalloc(workspace, workspace_size, ACL_MEM_MALLOC_NORMAL_ONLY); // 3) 将输入/输出张量描述为设备内存视图shape/dtype/formatACL_FORMAT_ND aclCreateTensor(shape, dims, dtype, 0, nullptr, 0, ACL_FORMAT_ND, addr, tensor); // 4) 创建 op 执行器并绑定输入/输出 aclnnCreateXxx(executor); aclnnSetXxxInputTensor(executor, input_tensor); // 每个输入 aclnnSetXxxOutputTensor(executor, output_tensor); // 输出 // 5) 异步执行任务入队到 stream aclnnXxx(executor, stream, workspace, workspace_size, ...); // 6) 同步到完成安全释放前必须 aclrtSynchronizeStream(stream); // 7) 释放同步后——workspace 与张量描述符 aclDestroyTensor(tensor); aclrtFree(workspace);关键语义Execute是异步入队aclnnXxx(...)返回后 kernel 可能尚未运行必须在释放 workspace/张量前aclrtSynchronizeStream与 AscendC 的异步拷贝内存生命周期约束一致输入数据先由 runner 按扁平请求tensor_specs从.bin文件 H2D 拷贝输出在 sync 后 D2H随后走与 ASCIR step 相同的 decode/精度/采样流水线warmup/repeat采样与 msprof 设备时长采集对 aclnn 与 ASCIR step 完全一致kernel 名过滤使用 aclnn op 名例如IsInf匹配IsInf_xxxx任务记录。isinf_maskedfill_fusion示例用例提供--variant unfused_aclnn直接复现 aclnn 单 op 链无需AUTOFUSE_DEVICE_JIT。维度ASCIR stepaclnn step执行栈Autofuse 栈steps/*.py codegen JITCANN 原生 aclnn op支持 op任意可分解的 Autofuse opCANN 在目标 SoC 上注册的 op产物tiling.h/host_impl/device_implabi_metadata.json无未知 op不适用在 codegen/JIT 阶段失败unknown_aclnn_op$previous串联与输入/输出文件契约不变精度与报告流程与 ASCIR step 相同msprof kernel 名过滤使用 aclnn op 名。aclnn step 与 ASCIR step 可在同一steps列表中混用。FAQ两种未融合 step 模式如何选择—— 需要验证 Autofuse op 自身的 codegen/JIT 产物时用 ASCIR stepop 不在 Autofuse 支持范围内、或只想对 CANN 原生 op 验证数据流与精度框架时用 aclnn step。4.7 常见陷阱SoC 名不精确匹配写成Ascend910、ascend910或ascend910_9362大小写/分隔符不一致都无法匹配 profileascend910_9362运行会在任何设备任务前以 SoC mismatch 失败。动态 shape 缺失inputs/outputs缺少dynamic: true或shapes未覆盖非对齐/尾部 shape会失败于 shape 校验或静默漏掉尾部路径。golden 使用被测 kernelreference.py若调用被测 AscendC/融合算子mismatch_count0是被保证的证明不了任何事。warmup 不影响样本数墙钟采样总是恰好返回repeat个样本与 warmup 无关--warmup --repeat不会导致样本不匹配warmup 只排除前 N 个样本。只有 profiler 记录缺失被 msprof 丢弃导致samples少于repeat且该阶段 performance 声明为required时报告才报performance samples do not match repeat。用主机时间冒充设备时间runner_wall_clock是毫秒级粗略参考融合增益对比必须用device_kernel_duration微秒profiler 导出失败时绝不伪造设备 kernel 时长。从别的 SoC 拷贝 profile 参数platform/core_type/ub_size必须来自真实芯片的事实从别的 SoC 拷贝会产生不可信的设备结果。5. 编写 case.json最小结构同 4.1 模板此处省略重复 JSON。规则soc必须与 profile 的profile字段精确匹配input_dtypes/output_dtypes必须覆盖实际输入、输出与未融合中间输出对齐、非对齐、尾部与边界 shape 必须显式列出required 能力失败会阻塞该阶段optional 能力不可用则跳过或 not applicable未融合 steps 用$previous传递输出fused 与 unfused 使用同一个最终 golden 输出。6. 编写 Profile平台字段必须来自 CANN/运行时/设备编译事实不要从别的 SoC 拷贝参数{ profile: ascend910_9362, soc_version: Ascend910_9362, allowed_abi: AutofuseLaunchV2,AutofuseLaunch, dtypes: [float16, uint8], simulator_backend: ascendc_simulator, real_device_backend: ascendc_real_device, profiler: optional, tools: {toolkit: ASCEND_HOME_PATH, profiler: msprof}, ascir: {platform: 2201, core_type: 40, ub_size: 196608}, resources: {max_block_dimension: 40} }若max_tiling_bytes或max_workspace_bytes没有可靠的芯片级事实就省略它们不要用默认值或 ABI 类型范围充当硬件上限。仓库已提供两份真实 profile 可供对照ascend910_9362.jsoncore_type40、ub_size196608、max_block_dimension40与 ascend950.jsonsoc_versionAscend950PR_9579dtype 覆盖 float16/bfloat16/float32/int32/int64/uint8core_type1、ub_size245760并声明了max_tiling_bytes67108864、max_workspace_bytes4294967296、max_block_dimension4096与max_shape_elements——可以看出不同 SoC 的资源上限差异显著这正是参数必须来自真实芯片事实的原因。7. Codegen、输入与 Golden 输出input_ascir.py应接收--rows、--cols、--profile与--output-dir从 profile 读取平台信息生成tiling.h host_impl.cpp device_impl.cpp abi_metadata.jsoncodegen 中不要硬编码 shape 或 SoC。gen_input.py使用固定种子。reference.py保持独立于被测 kernel并显式定义 dtype、shape、容差、NaN 与 Inf 行为。8. 推荐的验证顺序1. host JSON/schema/support-matrix 测试 2. --mode prepare 3. real-codegen 预检 4. codegen/JIT/设备编译 5. fused functional/precision 6. unfused functional/precision 7. --variant all 8. runner_wall_clock 性能 9. device_kernel_duration profiler 10. 完整 pytest/gtest/CTestPreparePYTHONPATHautofuse/tests/st:$PYTHONPATH \ python3 -m device_validation.tools.run_device_validation \ --case autofuse/tests/st/device_validation/cases/my_case \ --soc-profile ascend910_9362 \ --profile autofuse/tests/st/device_validation/profiles/ascend910_9362.json \ --backend ascendc_real_device --device 0 \ --mode prepare --shape 128 128 --warmup 0prepare生成输入、golden 与 manifest不启动任何设备 kernel。Functional/precisionPYTHONPATHautofuse/tests/st:$PYTHONPATH \ python3 -m device_validation.tools.run_device_validation \ --case autofuse/tests/st/device_validation/cases/isinf_maskedfill_fusion \ --soc-profile ascend910_9362 \ --profile autofuse/tests/st/device_validation/profiles/ascend910_9362.json \ --backend ascendc_real_device --device 0 \ --variant fused --mode functional --shape 128 128 --warmup 0用[128,130]与[127,129]重复运行用--variant unfused与--variant all做对比。验收要求stage_statuspassed precision.passedtrue precision.mismatch_count0 soc_profileexpected profile run_parameters.selected_shaperequested shapeprepare_only、skipped、not_applicable以及mismatch_count0但precision.passedfalse都不算功能通过。命令行编排入口是 autofuse/tests/st/device_validation/tools/run_device_validation.pyHost orchestrator for real-device validation cases它负责参数解析、case 加载、支持矩阵解析support_matrix.resolve_support、unfused step 上下文管理UnfusedContext与报告构建report.build_report——即文档核心模型中的 Runner/JIT 层的 Python 侧实现。9. 性能指标与 SQLite Profiler 依赖指标runner_wall_clock主机 launchsync 墙钟单位ms仅作粗略参考device_kernel_durationprofiler 导出的设备 AI Core 时长单位us用于正式的融合增益对比。使用多样本--mode performance --metric runner_wall_clock --warmup 2 --repeat 5 --mode performance --profiler --metric device_kernel_duration --warmup 1 --repeat 3CANN 的msprof_analysis.so可能依赖名为libsqlite3.so的确切库而发行版通常只提供libsqlite3.so.0或libsqlite3.so.0.x.y。缺少无版本号名称仅影响profiler 离线导出task_time_*.csv生成device_kernel_durationfused/unfused 设备时长对比。不影响case/profile 校验、codegen/JIT、AscendC 设备编译、ACL functional/precision 与runner_wall_clock。使用真实、与架构兼容的库路径/path/to/...仅为示意请替换为实际兼容库目录export DEVICE_VALIDATION_SQLITE_LIB_PATH/path/to/sqlite/libsqlite3.so验证路径为示意请使用实际库文件file /path/to/libsqlite3.so readelf -d /path/to/libsqlite3.so | grep SONAME LD_LIBRARY_PATH$(dirname /path/to/libsqlite3.so):$LD_LIBRARY_PATH \ python3 -c import ctypes; ctypes.CDLL(libsqlite3.so); print(sqlite load passed)不要提交SQLite 二进制、私有兼容目录或系统符号链接。导出失败时报告必须标记profiler_export_failed/profiler_export_unavailable主机时间绝不能被当作设备时长展示。10. CMake/CTest 分层Host pytest 直接运行pytest autofuse/tests/st/device_validation -q。配置包含 device-validation 子目录时注册 Host CTest。Runner 契约、real-codegen 与硬件通过 CMake 选项独立 opt-in。Runner 契约不得携带real_codegen标签。CMake 只能引用已存在的 Python 测试文件。cmake --build build --target device_validation_ut device_validation_runner -j 8 ./build/autofuse/tests/ut/device_validation/device_validation_ut ctest --test-dir build/autofuse/tests/st --output-on-failure -L ^device_validation$ -j 8 ctest --test-dir build/autofuse/tests/st --output-on-failure -L ^device_validation_runner$ -j 811. 故障排查阶段典型错误首先检查ProfileSoC mismatchaclrtGetSocName()、case 的soc、profile 的profileCodegenNo module named autofuse完整 CANN Python 包、PYTHONPATH、LD_LIBRARY_PATHJIT生成产物缺失Codegen stdout/stderr、ABI metadataMatrixinvalid_artifact_path父/嵌套产物、遍历、符号链接ABIabi_mismatchFused 顶层 ABI、unfused step ABIRuntimeACL failure设备、缓冲区、stream、共享库PrecisionMismatchGolden、dtype、shape、容差Profilerlibsqlite3.so/导出失败SQLite ELF 架构、SONAME、分析根目录CTest未找到测试CMake 选项、标签、工作目录先修复日志中第一个有效错误再排查级联错误。12. 提交检查清单[ ] case.json 契约完整SoC 与 profile 精确匹配 [ ] Profile 平台/资源字段有 CANN 或设备证据 [ ] 未在框架核心新增 SoC 分支 [ ] 对齐、非对齐与尾部 shape 全部通过 [ ] Fused/unfused/all 精度通过 [ ] Profiler 结果有真实 metric、unit 与 timing_source [ ] Host pytest、device_validation_ut 与 CTest 通过 [ ] README 命令从仓库根目录执行 [ ] 不提交构建产物、artifact 与 SQLite 兼容文件13. Ascend910_9362 参考运行结果针对本文示例用例isinf_maskedfill_fusion在 CANN 9.2、Ascend910_9362、device 0 环境下预先声明的 shape128x128、128x130、127x129的 fused/unfused functional 与 precision 验证均以mismatch_count0通过。512x512在 Ascend950PR 上测量通过fused/unfused含 aclnn 模式Ascend910_9362的512x512条目目前仅是声明扩展等待设备验证。Profiler 导出成功fused p50 约4.72 usunfused p50 约15.52 us。这些仅是本环境与用例下的测量值不代表对其他 SoC、CANN 版本或用例的通用承诺。【免费下载链接】graph-autofusionGraph-autofusion 是一个面向昇腾Ascend芯片的轻量级、解耦式组件集合旨在通过自动融合技术加速模型执行。 目前已开源 SuperKernel 组件和 Autofuse 组件未来将持续开放更多自动融合相关模块。项目地址: https://gitcode.com/cann/graph-autofusion创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网