Repository navigation
[MLAS] KleidiAI fix igemm regression - #28571
Hariharan Seshadri (hariharans29) merged 7 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR addresses a CPU convolution performance regression on ARM64 when the KleidiAI SME IGEMM path is selected, by introducing a new convolution route-selection heuristic and changing the KleidiAI LHS packing strategy to reduce peak temporary memory and improve cache locality on large workloads.
Changes:
- Added
ArmKleidiAI::SelectConvRoute(withConvRouteoptionsIgemm,GemmFallback,None) to decide whether to run KleidiAI IGEMM, fall back to GEMM, or use the existing path. - Updated KleidiAI convolution to pack the IGEMM LHS in bounded chunks instead of packing the full LHS up front.
- In the generic MLAS convolution implementation, routed certain workloads to
MlasGemm(instead ofMlasSgemmOperation) whenSelectConvRoutechoosesGemmFallback.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| onnxruntime/core/mlas/lib/kleidiai/mlasi_kleidiai.h | Adds ConvRoute + SelectConvRoute heuristic helpers for choosing conv execution route. |
| onnxruntime/core/mlas/lib/kleidiai/convolve_kleidiai.cpp | Reworks KleidiAI SME IGEMM LHS packing into chunked packing and integrates route selection into capability checks. |
| onnxruntime/core/mlas/lib/convolve.cpp | Uses SelectConvRoute to optionally switch im2col+SGEMM slices to MlasGemm for the fallback route. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@microsoft-github-policy-service agree company="Arm" |
|
Can you please address the Copliot comments ? |
|
Hi, thanks for the reminder. The comments Copilot left are sensible, I'm addressing them with a new patch that's currently work in progress. Once it's done and clears internal review, I'll add it to the PR. |
Thank you! |
|
Hi, I pushed a new patch addressing the Copilot comments, and left a reply with further details on one of the comments. |
Review — PR #28571
|
|
Thank you for the thorough review! The comments are sensible and understandable. I will update the PR as soon as we have a patch to address them finished and internally reviewed. |
|
Hi Hariharan Seshadri (@hariharans29), thanks again for the thorough review. I've pushed an updated patch addressing the comments. Summary of the changes with respect to the previous review comment points:
Nits:
Additional verification and notesRe-running the regressing modelI reran the regressing PP-OCR model from #27633 on a macOS Arm64 device based on the original report. Using I didn't include a Snapdragon X run because the original issue reported the regression on macOS Arm64.
|
Re-review — PR #28571
|
|
Thank you for the comments! They are all clear and sensible. Good catch with the NHWC padding symmetry correctness comment. I have a patch completed resolving the comments, I'll push it here once it clears internal review. |
|
Hi Hariharan Seshadri (@hariharans29), thank you for the review! I made changes to address the generated comments. In addition, I found that the pipeline failures were indeed related to the patch, included in the latest commit is a fix moving from |
Third pass — PR #28571Verdict: still approve. Commit New since the last pass1. NHWC padding gate is now strictly uniform — and that's a correctness fix
// The channels-last float convolution path is only implemented by the Arm® KleidiAI™
// SME conv override, which currently uses a single padding value in its LHS indirection table.
// Require uniform padding until separate H/W padding is supported there.
if (Padding[0] != Padding[2] ||
Padding[1] != Padding[3] ||
Padding[0] != Padding[1]) {
return false;
}The previous gate accepted any H-symmetric AND W-symmetric padding (e.g., This isn't just a tightening for the new IGEMM route — Worth a one-line note in the PR description acknowledging this is a behavioral change beyond the IGEMM regression scope — anyone bisecting an NHWC accuracy issue across this PR will appreciate it. 2. Enum and override renaming clarify scope
3. Config-option parsing — contract is now tested
Exactly the missing-test gap I flagged in the prior round. Note: the negative test catches 4.
|
|
Can you please fix the conflict ? |
ebf3f4e to
8571e8f
Compare
|
Hi Hariharan29, thanks for the comment! I rebased the branch which should resolve the conflict. In addition, I added a small change to fix a numeric issue related to NCHW/NHWC correctness that was flagged by failing tests. With the latest commits, all tests are passing locally. |
Every target moves from 1.27.0 to 1.31.1 (6af1a932e2286d5c58166085d24c68783033edee): - Android, Linux, macOS, Windows: Microsoft's archives. The GitHub archives match GitHub's digests; the Android AAR matches Maven's SHA-1 and MD5 (Maven publishes no SHA-256). - iOS: dynamic libraries built by tool/apple/build_ios_native_assets.sh, published as release native-assets-ort-1.31.1. They no longer include libortextensions.dylib, which fonnx stopped using in 65c3603. - Web: onnxruntime-web 1.31.1, matching npm's integrity hash. Headers are 1.31.1's and the bindings are regenerated for C API 31. ORT only appends to OrtApi: the 427 existing entries are unchanged and 6 are added at the end. The keyword spotter no longer sets mlas.disable_kleidiai: 1.31.1 has the fix for the 1.27.0 KleidiAI convolution bug (microsoft/onnxruntime#28571), and the keyword spotter tests, which detect and transcribe real speech, pass without it on an M4 Max (SME). Tested on macOS (M4 Max): the native model and runtime tests, Kokoro and Misaki, the memory and ASan/UBSan tests, the web runtime in Node and in Chrome (dart2js, dart2wasm), and the iOS integration tests on an iPhone 17 Pro simulator. Time per inference after warm-up on macOS, M4 Max, the median over 8 alternating rounds per version; p is the two-sided Mann-Whitney p-value: | Model | 1.27.0 | 1.31.1 | Change | p | |---|---|---|---|---| | **NeMo FastConformer CTC** (4 s audio) | 34.0 ms | 25.9 ms | **−24%** | <0.001 | | **Whisper tiny** (4 s audio) | 98.6 ms | 83.9 ms | **−15%** | 0.02 | | **MiniLM-L6-v2** | 1.72 ms | 1.56 ms | **−9%** | 0.02 | | **Keyword spotter** (4 s, streamed) | 139 ms | 131 ms | **−6%** | 0.05 | | msmarco-MiniLM-L6-v3 | 1.67 ms | 1.59 ms | −5% | 0.07 | | Magika | 1.23 ms | 1.14 ms | −8% | 0.23 | | Pyannote seg3 (6 s) | 13.9 ms | 13.5 ms | −3% | 0.44 | | SenseVoice | 44.5 ms | 46.4 ms | +4% | 0.44 | | Silero VAD (32 ms chunk) | 0.120 ms | 0.127 ms | +5% | 0.46 | | potion-8M | 0.067 ms | 0.070 ms | +5% | 0.36 | | potion-32M | 0.071 ms | 0.074 ms | +6% | 0.52 | The keyword spotter on 1.27.0 ran with KleidiAI off, as it shipped. The first call, which loads the model, is slower for NeMo (517 → 616 ms) and for the first model loaded, MiniLM (497 → 537 ms, including starting ORT). prebuilt.json still names the 1.27.0 kiln release until the next one.



Description
This PR fixes a convolution performance regression affecting some OCR models with large-kernel convolutions when the KleidiAI SME IGEMM convolution path is selected.
The change has 2 parts:
ArmKleidiAI::SelectConvRoutethat decides betweenIgemm,GemmFallbackandNonebased on convolution parameters and a workload size-based heuristic.The function
CheckCapabilitiesSmerunsSelectConvRouteand only returns true if the selected route isIgemm. The patch also adds a standard GEMM fallback to theConvRoutepossibilities, and runsMlasGemmif said fallback is selected. If the function selectsNone, then the convolution falls back toMlasSgemmOperation.Motivation and Context
Fixes #27633.