feat: optimized QASYMM8_SIGNED->F32 direct convolution path#1298
Open
alvoron wants to merge 1 commit into
Open
feat: optimized QASYMM8_SIGNED->F32 direct convolution path#1298alvoron wants to merge 1 commit into
alvoron wants to merge 1 commit into
Conversation
Signed-off-by: Aleksandr Voron <aleksandr.voron@intel.com>
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.
Motivation
Inference frameworks (e.g., OpenVINO) often run int8-quantized activations with float32 output. Previously this required a multi-step chain: quantized GEMM accumulating into int32, a separate
GEMMLowpoutput-stage operator, and a dequantize/cast step. This adds a single-kernel path that takesQASYMM8_SIGNEDinput and weights and writes F32 output directly, reducing memory traffic and operator overhead.Dependency
Requires #1297 to be merged first.
That branch provides the
dequant_a_offset/dequant_b_offsetfields onAsmGemmInfo, the relaxed type guard inCpuGemmAssemblyDispatch::validate(removing the "Only S32 output" restriction for S8 input), and thecreate_arm_gemm_dequantchanges that pass offsets intoDequantizeFloatwith the correct combined scale. Without it this branch does not build correctly standalone.Technical approach
The existing
DequantizeFloatoutput stage is extended witha_offsetandb_offsetfields.GemmInterleavedis taught to:transforms_quantizedwith multiplier = 1) whenb_offset != 0, for per-row offset correction.set_pretransposed_B_arraywhena_offset != 0, stored alongside the pretransposed weight buffer.dequantize_block_32<float>at merge time.K-blocking is conservatively disabled for the
DequantizeFloat + MergeStepcase (matching the existingRequantize32policy) since row sums must cover full K.CpuGemmDirectConv2ddetects theQASYMM8_SIGNED→F32path by type, reads zero-points fromQuantizationInfo, and passes them to the dispatch viaAsmGemmInfo.CpuConv2d::get_convolution_methodautomatically routes NHWCQASYMM8_SIGNED→F32convolutions toGEMM_CONV2D(no explicit flag).Also fixes a latent bug in
dequantize_block_32<float>: the expressionval * qp.scale(integer × float, silently truncating for large accumulators) is corrected tostatic_cast<float>(val) * qp.scale.Asymmetric correction formula
out[m,n] = (raw_acc[m,n]
− a_offset · Σ_k b[k,n] (per-column, from col sums)
− b_offset · Σ_k a[m,k] (per-row, from row sums)
+ a_offset · b_offset · K (cross-term)
) · (scale_a · scale_b) + bias[n]