perf(vpto): non-negative ranges for SIMT hardware ID ops + range-driven arith opts (floordivsi/remsi by pow2) - #1497
Draft
jimmychou0 wants to merge 1 commit into
Conversation
jimmychou0
force-pushed
the
zjm/issue1493-tid-pow2-range
branch
from
September 9, 2026 07:35
c75288f to
ad1ad05
Compare
Contributor
Author
|
Review 意见已全部修复(ad1ad0551):
验证:238b 全量重建 0 error;lit 两个用例(tid + block_idx)FileCheck 实跑 PASS;真实 kernel 端到端 .text 仍与手改 and/lshr 版逐字节相同(md5 6e851189,P2 修复未改变 tid 路径产出);真机数值 AMAX+FP8 PASS,延迟 0.4919ms。 |
jimmychou0
force-pushed
the
zjm/issue1493-tid-pow2-range
branch
4 times, most recently
from
September 10, 2026 08:48
58a0c3c to
e20e481
Compare
Contributor
Author
|
新增:block query 的 AIC 编排路径(非 SIMT entry)现在也走 32 位 tpe intrinsic + zext,与 SIMT 路径和 CCE 前端语义一致( |
jimmychou0
force-pushed
the
zjm/issue1493-tid-pow2-range
branch
6 times, most recently
from
September 11, 2026 07:06
55af82a to
9dec823
Compare
Contributor
|
Resolved: ci-sim runtime is back within its soft budget.
The previous duration warning is resolved. This status is advisory only. |
jimmychou0
force-pushed
the
zjm/issue1493-tid-pow2-range
branch
2 times, most recently
from
September 13, 2026 10:39
9b001be to
316068e
Compare
…en arith opts Implement InferIntRangeInterface on the provably non-negative hardware ID queries and run the upstream arith integer-range optimizations early in the VPTO backend pipeline, so floordivsi/remsi by a power of two on thread/block indices reach the LLVM backend as udiv/urem instead of the signed-division guard chain. Covers both dialects: the VPTO SIMT queries (get_tid_x/y/z with [0, dim-1] from section.simt launch dims, get_block_idx_x/y/z, get_block_dim_*, get_grid_dim_*, get_veccoreid, get_laneid) and the PTO-level i64 runtime queries (get_block_idx, get_subblock_idx [0,1], get_block_num, get_subblock_num) used by cube-side orchestrators. Block queries are rounded through i32 on all paths (both emitters), matching the CCE frontend where __builtin_cce_get_block_idx/get_block_num are int32_t: inside simt_entry functions the query calls the 32-bit tpe intrinsic and zero-extends to the i64 PTO result; the AIC orchestrator path must keep the 64-bit intrinsic (the tpe form is only legal in simt_entry), so it truncates the result to i32 and zero-extends back. Both forms pin the value to [0, 2^32) for downstream folding. Building on those range facts, a second step narrows the element-offset chains feeding pto.load/pto.store/pto.addptr to i32 whenever a local recursive range evaluation proves the chain stays in [0, 2^32). The default lowering widens these chains to index/i64 because loop induction variables are index-typed, so each mul/add lowers as a 64-bit operation although A5 scalar units compute in 32 bits. Two rewrites fall out of one traversal: a fully provable chain replaces the offset operand outright (converted back with index_castui), and a provable operand under an unprovable parent -- e.g. `w * 2048` beneath `+ block_idx`, where the runtime block count blocks the proof -- is still swapped for its i32 mirror widened back with a zero-extend. The evaluator is local rather than a dataflow-framework analysis on purpose: the rewrite needs operand-level subchain decisions (narrow only the provable operand of an unprovable parent, e.g. `w * 2048` beneath `+ block_idx`) that a global sparse range analysis does not drive on its own, and the chain grammar is closed, so local evaluation is both sound and precise for it; anything unprovable keeps the wide form. Mirrored div/rem ops are emitted unsigned so the shift-friendly udiv/urem forms established by the int-range phase are preserved. andi is deliberately excluded from the grammar: the chains it feeds (e.g. the ping-pong UB buffer address `(w & 1) * 4096`) sit on the MTE address path, where the extra trunc/zext pair costs more than the i64 mul and measurably regresses the kernel. On the SIMT-VF per-token cast-to-fp8 example (8192x8192) the narrowed kernel measures level with the AscendC-backend build of the same program on a quiet A5 board (0.291 ms vs 0.288 ms, both within the run-to-run noise band), with numerics unchanged; the narrowing makes the PTO addressing arithmetic match AscendC's all-int32 forms, removing the 64-bit address-math divergence previously visible in trace comparisons. Three existing lit tests are updated for the new canonical forms (extsi->extui on tid, floordivsi->divui on block queries, cmpi sge->uge on non-negative operands, tpe i32 callees on AIC queries); one tautological guard whose loop bound equals the guard bound is decoupled so the guard stays dynamic; the guarded-LICM pipeline test now expects the narrowed IV chain. A new test covers both narrowing outcomes. Closes hw-native-sys#1493.
jimmychou0
force-pushed
the
zjm/issue1493-tid-pow2-range
branch
from
September 13, 2026 16:20
316068e to
9d19881
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #1493.
Range-driven arith optimizations for SIMT scalar index math, following the
approach agreed in the issue discussion:
InferIntRangeInterface—get_tid_x/y/z,get_block_idx_x/y/z,get_block_dim_x/y/z,get_grid_dim_x/y/z,get_veccoreid,get_laneidreport non-negativeresult ranges. Thread indices are tightened to
[0, dim-1]when theenclosing
pto.section.simt<<<...>>>carries static launch dims.Deliberately excluded (not provably non-negative):
get_clock32/64(wraps) and
get_lanemask_*(sign bit can be set).pto-arith-range-optimizepass wired into the VPTO backendpipeline (before
VPTOSplitCVModulePass, where the SIMT queries are stillpresent). It runs the upstream
arith::createIntRangeOptimizationsPass()+createArithUnsignedWhenEquivalentPass()+ canonicalize — no customrewrite rules, so ops whose range cannot be proven are left unchanged
(the "keep as-is when analysis fails" expectation from the issue).
With the non-negative ranges, the upstream passes rewrite
arith.floordivsi/remsi <tid>, 2^kintoudiv/urem, and the LLVM backendfolds those into shifts/masks — eliminating the 9-instruction
signed-division guard chain that currently reaches every SIMT warp.
Validation
test/lit/pto/issue1493_tid_pow2_range.pto: the issue's repro pattern(
tid % 32 == 0guard +(tid // 32) * 64addressing insidepto.section.simt) asserts the emitted VPTO LLVM IR containsudiv/uremand nosdiv/srem.issue, 8192x8192):
.ptoinput now emitsurem/udiv(guard chain gone);.textis byte-identical to the hand-verifiedand/lshrrewrite from the issue (1112 vs 1192 bytes, −20 instructionwords);
0.4936 ms baseline on the same box, consistent with the 0.3–0.5%
measured on three CANN versions).
ninjabuild of ptoas with the change on x86 CANN 9.1.0.