[MLAS][KleidiAI] Add MLAS Arm64 half GEMM and convolution support - #28786
Conversation
There was a problem hiding this comment.
Pull request overview
This PR expands ONNX Runtime’s MLAS Arm64 KleidiAI integration to support FP16 (half) GEMM and convolution via new public MLAS APIs, KleidiAI override wiring, and additional kernel selection logic, with accompanying unit tests and some test-harness exclusions/tolerance tweaks.
Changes:
- Adds public MLAS FP16 HalfGemm packed-B APIs (generic + backend-native) and FP16 HalfConv prepare/execute/pack APIs.
- Wires KleidiAI FP16 HalfGemm/HalfConv overrides into MLAS platform dispatch and adds SME/SME2 FP16 ukernel selection.
- Extends MLAS/unit and ORT operator tests to cover new behaviors (packed-B contracts, selector opt-out, zero-K handling, HalfConv prepare behavior), plus minor EP exclusions/tolerance adjustments.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| onnxruntime/test/providers/cpu/tensor/resize_op_test.cc | Excludes additional EPs for FP16 Resize(13) coverage gaps. |
| onnxruntime/test/optimizer/nhwc_transformer_test.cc | Adjusts transformer tester invocation to use explicit tolerances/opset. |
| onnxruntime/test/mlas/unittest/test_util.h | Ensures guard buffer state is fully reset (guard pointer). |
| onnxruntime/test/mlas/unittest/test_halfgemm.h | Adds FP16-native comparison tolerance + new execution modes for HalfGemm tests. |
| onnxruntime/test/mlas/unittest/test_halfgemm.cpp | Adds HalfGemm tests for selector routing, packed-B behavior, overflow handling, and more shape/bias cases. |
| onnxruntime/test/mlas/unittest/test_conv2d.cpp | Adds HalfConv prepare tests for selector config handling and working-buffer sizing. |
| onnxruntime/test/contrib_ops/nhwc_pool_in_op_test.cc | Excludes non-owning EPs from internal NHWC fp16 pool tests. |
| onnxruntime/test/contrib_ops/matmul_4bits_test.cc | Adjusts abs error tolerance for FP16, conditional on WebGPU. |
| onnxruntime/test/contrib_ops/attention_op_test.cc | Disables WebGPU for a FP16 Attention test that uses unsupported mask_index. |
| onnxruntime/core/mlas/lib/platform.cpp | Enables KleidiAI overrides under SME or SME2 and wires HalfGemm/HalfConv overrides. |
| onnxruntime/core/mlas/lib/mlasi.h | Adds size_t overflow helpers used by KleidiAI/packing paths. |
| onnxruntime/core/mlas/lib/kleidiai/sgemm_kleidiai.cpp | Switches overflow checks to shared helpers. |
| onnxruntime/core/mlas/lib/kleidiai/sbgemm_kleidiai.cpp | Switches overflow checks to shared helpers. |
| onnxruntime/core/mlas/lib/kleidiai/qgemm_kleidiai.cpp | Renames BatchSize→BatchN for clarity/consistency and updates uses. |
| onnxruntime/core/mlas/lib/kleidiai/mlasi_kleidiai.h | Refactors includes and adds scratch-buffer shrinking helper declarations. |
| onnxruntime/core/mlas/lib/kleidiai/halfgemm_kleidiai.cpp | Adds KleidiAI FP16 HalfGemm implementation and native RHS pack. |
| onnxruntime/core/mlas/lib/kleidiai/halfconv_kleidiai.cpp | Adds KleidiAI FP16 convolution implementation (IMATMUL-based) and packing. |
| onnxruntime/core/mlas/lib/kleidiai/convolve_kleidiai.cpp | Minor cache-lookup refactor for indirection table cache. |
| onnxruntime/core/mlas/lib/kai_ukernel_interface.h | Adds FP16 IMATMUL/HGEMM kernel wrapper types and selection APIs. |
| onnxruntime/core/mlas/lib/kai_ukernel_interface.cpp | Implements FP16 kernel selection (SME vs SME2) and new ukernel wrappers. |
| onnxruntime/core/mlas/lib/halfgemm.h | Adds shared packed-B sizing helper + implements generic CopyPackB with padding. |
| onnxruntime/core/mlas/lib/halfgemm.cpp | Adds zero-K behavior, selector-config routing, native-pack APIs, and enables CopyPackB dispatch. |
| onnxruntime/core/mlas/lib/halfgemm_kernel_neon.cpp | Enables CopyPackB dispatch for NEON halfgemm. |
| onnxruntime/core/mlas/lib/halfconv.cpp | Adds public dispatch wrappers for HalfConv prepare/execute/pack APIs. |
| onnxruntime/core/mlas/inc/mlas.h | Exposes new HalfGemm/HalfConv APIs and extends parameter structs for new flags/config. |
| cmake/onnxruntime_mlas.cmake | Adds new MLAS sources (halfconv + KleidiAI halfgemm/halfconv). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
9ac8626 to
e60a7a6
Compare
Review of PR #28786 —
|
6858af7 to
e920588
Compare
Review — PR #28786
|
Avoid holding a reference into lhs_ptrs_cache_by_pad across the lookup/update sequence so the cache remains keyed by the current pad buffer identity. Source-commit: 923422f Signed-off-by: Cathal Lawlor <cathal.lawlor@arm.com>
Native fp16 accumulation paths need a slightly wider tolerance, and WebGPU needs a separate bound for this coverage. Source-commit: 2483990 Source-commit: 08f4c6a8c51dc018b4440c63d279bf5995d3386a Signed-off-by: Cathal Lawlor <cathal.lawlor@arm.com>
The Resize(13) MLFloat16 test should not run against EPs that do not provide this kernel. Source-commit: 2483990 Signed-off-by: Cathal Lawlor <cathal.lawlor@arm.com>
Allow the fp16 FusedConvWithSum transformer test to tolerate native fp16 numerical drift. Source-commit: 2483990 Signed-off-by: Cathal Lawlor <cathal.lawlor@arm.com>
These internal-domain NHWC fp16 pool tests target ORT CPU/MLAS coverage and should not be offered to unrelated registered EPs. Source-commit: a504a0c Signed-off-by: Cathal Lawlor <cathal.lawlor@arm.com>
Signed-off-by: Cathal Lawlor <cathal.lawlor@arm.com>
- Add validation for null HalfGemm data parameters and reject invalid backend-native packed-B parameter combinations before the zero-K fast path. - Make HalfGemm packed-B size calculation return a valid zero size for degenerate N/K shapes. - Restore the KleidiAI header include needed by debug logging in mlasi_kleidiai.h. - Update HalfGemm PackB tests to avoid exception-only gtest macros in no-exception builds, and add sentinel checks for early-return paths. Signed-off-by: Cathal Lawlor <cathal.lawlor@arm.com>
Set MLAS_CONV_PARAMETERS::ChannelsLast in the HalfConv prepare path so Prepare fully initializes the convolution parameter layout state. Add a focused MLAS test that verifies Prepare overwrites stale layout flag values for both NCHW and NHWC HalfConv configurations. Signed-off-by: Cathal Lawlor <cathal.lawlor@arm.com>
Signed-off-by: Jonathan Clohessy <Jonathan.Clohessy@arm.com>
Signed-off-by: Jonathan Clohessy <Jonathan.Clohessy@arm.com>
d92c50d to
a8861ad
Compare
Re-review: PR #28786 —
|
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
) ### Description This PR builds on [fp16-split/02-mlas-half-api-squashed](#28786) by connecting its FP16 MLAS APIs and KleidiAI backends to the CPU Execution Provider. ```markdown It: - Registers CPU `MLFloat16` kernels for: - `MatMul` opsets 1–8, 9–12, and 13+ - `Gemm` opsets 7–8, 9–10, 11–12, and 13+ - Adds a dedicated FP16 `MatMul` implementation which: - Preserves ONNX broadcasting and batched execution through `MatMulComputeHelper`. - Handles empty outputs and zero-K inputs. - Uses the existing HGEMM path for eligible small, unpacked matrices. - Otherwise dispatches through `MlasHalfGemmBatch`. - Carries the configured MLAS backend selector through every batch entry. - Pre-packs constant two-dimensional B matrices into the selected backend’s native layout when supported. - Keeps backend-native FP16 MatMul packs owned by the kernel. These layouts depend on the active backend, so they are not placed in the cross-session shared-prepack cache without suitable layout metadata. - Adds an explicit kernel-owned packed-weights marker to `PrePackedWeights`. Session initialization continues to reject broken kernels which report successful prepacking without either providing cacheable buffers or explicitly identifying a valid kernel-owned pack. - Extends FP16 `Gemm` to use `MlasHalfGemmBatch` for supported no-transpose, `alpha == 1` cases: - No effective bias, including a missing C input or `beta == 0`. - `beta == 1` with an MLAS-compatible N-element bias. - Unsupported transpose, scaling, or bias-broadcast combinations retain the existing Eigen fallback. - Adds an MLAS HalfConv fast path to the existing FP16 CPU Conv implementation: - Uses `MlasHalfConvPrepare` to determine runtime and backend eligibility for two-dimensional convolutions without a fused Sum input. - Runs eligible convolutions through `MlasHalfConv`. - Supports NCHW and NHWC layouts and forwards padding, stride, dilation, activation, and workspace information. - Pre-packs eligible constant filters using `MlasHalfConvPackWeightsAndBias`. - Includes a compatible constant bias in the native pack when safe. - Falls back to the existing reordered-weight/im2col plus HalfGemm implementation when HalfConv is unavailable or rejects the configuration. - Keeps combined HalfConv weight-and-bias packs session-local because their contents depend on the bias while the existing shared-prepack key identifies only W. Generic Conv weight packs remain shareable across sessions. - Centralizes HalfGemm backend-selector handling in the public MLAS dispatcher and updates the affected MatMul, Gemm, Conv, and MoE call sites. - Updates the CPU operator documentation to advertise FP16 support for `MatMul` and `Gemm`. Test coverage includes: - FP16 Gemm with no C input and with `beta == 0`. - FP16 MatMul with constant and dynamic B inputs. - MatMul backend-native B prepacking. - Kernel-owned MatMul packs remaining intentionally unshared across sessions. - Session-state validation for broken prepacking implementations. - HalfConv-eligible NCHW and NHWC convolutions. - HalfConv execution with and without bias. - Correct fallback behavior when KleidiAI is explicitly disabled. - Safe sharing of generic Conv prepacked weights while keeping bias-dependent HalfConv packs local. - Updated HalfGemm selector and backend-native packed-B contract coverage. ``` ### Motivation and Context This is pr 3 of 5 as per #28786 splitting suggestion The preceding PR introduces the MLAS primitives for FP16 HalfGemm, backend-native B packing, and HalfConv, but standard ONNX CPU operators do not yet consume them. This PR connects those primitives to CPU `MatMul`, `Gemm`, and `Conv`, making native FP16 execution and KleidiAI acceleration available to the operator layer while retaining portable fallback behavior for unsupported hardware, shapes, attributes, or backend configurations. The prepacking changes avoid repeatedly packing constant weights while preventing backend-specific or bias-dependent layouts from being incorrectly reused through the shared prepack cache. This PR is limited to CPU kernel registration and execution. The follow-up InsertCastTransformer PR introduces the opt-in policy and shape heuristics that decide when graph optimization should preserve FP16 CPU nodes. Apple ARM64 build enablement is also handled separately. --------- Signed-off-by: Cathal Lawlor <cathal.lawlor@arm.com> Signed-off-by: Jonathan Clohessy <Jonathan.Clohessy@arm.com> Co-authored-by: Cathal Lawlor <cathal.lawlor@arm.com>
Description
Adds MLAS half-precision GEMM and convolution support for Arm64 KleidiAI paths.
This change:
Motivation and Context
This is the second MR in the FP16 split and introduces the MLAS API and Arm64 backend plumbing needed for accelerated FP16 CPU kernels.
The later CPU operator changes can use these MLAS HalfGemm and HalfConv entry points without carrying KleidiAI-specific details at the operator layer. The backend selector support also preserves an explicit fallback path when KleidiAI should not be used for a given call.
Note: This PR is the second offshoot from 28487