feat: enable QASYMM8_SIGNED to F32 assembly dequantization#1302
feat: enable QASYMM8_SIGNED to F32 assembly dequantization#1302morgolock wants to merge 1 commit into
Conversation
5aa921d to
002c426
Compare
Enable QASYMM8_SIGNED input and weights to use the F32 DequantizeFloat assembly output stage, including the direct convolution selection path. Propagate input and weight zero-points plus the unrounded mathematical K depth so asymmetric offset correction uses the real GEMM/convolution depth rather than arm_gemm's padded internal K. Fix the interleaved no-merge DequantizeFloat scheduler stride so kernels that do not pack row-sum slots advance between A panels correctly. Guard the symmetric no-merge dequant support helper with the SME/SME2 feature macros. The helper is only referenced when those no-merge dequantized kernels are compiled, so non-SME builds must not define it unconditionally under Werror. Add NEON validation coverage for the direct I8S8F32 convolution path. Performance was checked on a Cortex-A76, pinned to CPU 4 with one thread. The change is neutral on large workloads and improves the small NHWC signed int8 to F32 convolution path: QASYMM8_SIGNED/RunSmallDequantizeF32 NHWC/no-activation cases show a 1.36x geomean speedup over github/main, with the tiniest single-batch cases improving by roughly 1.45x to 3.13x. Validate GEMM3D convolution probes with the real weights and output tensor metadata instead of reusing the input data type for every dummy tensor. This prevents QASYMM8 input with QSYMM8_PER_CHANNEL weights from selecting a 3D path that the real lowp operation cannot safely configure. When QASYMM8 output is handled through the signed lowp assembly path, route fused assembly through the signed intermediate output, keep the adjusted output stage in sync for configure/validate/runtime quantization updates, and convert back to QASYMM8 after the fused assembly path as well as the fallback path. This fixes quantized per-channel GEMM convolution and deconvolution validation crashes introduced by admitting the int8 per-channel RHS assembly path. Signed-off-by: Pablo Marquez Tello <pablo.tello@arm.com> Change-Id: I945c24e5cd3d21d857b68de90d27aa18a31f7547
002c426 to
8381408
Compare
|
Hi, I've been testing this PR for OpenVINO's ARM CPU plugin int8 enablement and found a possible validation gap in the new QASYMM8_SIGNED->F32 dequantization path.
I create minimal repo to test this: all-ones i8 input, all-ones 3×3×3 i8 weights, bias 0, distinct per-channel scales s[c] -> each interior output should be 27·s[c]:
I am thinking of rejecting |
| "We could not find an optimized kernel for U8/QASYMM8 input and U32 output"); | ||
| } | ||
| else if (b->data_type() == DataType::QASYMM8_SIGNED) | ||
| else if (b->data_type() == DataType::S8 || b->data_type() == DataType::QASYMM8_SIGNED) |
There was a problem hiding this comment.
Why do we add S8 data type to here?
| * |:--------------|:--------------|:--------------|:--------------| | ||
| * |QASYMM8 |QASYMM8 |S32 |QASYMM8 | | ||
| * |QASYMM8_SIGNED |QASYMM8_SIGNED |S32 |QASYMM8_SIGNED | | ||
| * |QASYMM8_SIGNED |QASYMM8_SIGNED |F32 |F32 | |
There was a problem hiding this comment.
How about Fp16? And, Do we support mixed sign inputs? Such as UInt8 inputs and Int8 weights. That's what I felt from the changes in the glue layer. I also don't see the tests for mixed sign inputs.
| {TensorInfo(TensorShape(8U, 6U, 6U), 1, DataType::F32, DataLayout::NHWC), | ||
| TensorInfo(TensorShape(16U, 4U, 4U), 1, DataType::F32, DataLayout::NHWC), | ||
| TensorInfo(TensorShape(8U, 6U, 6U), 1, DataType::F32, DataLayout::NHWC), | ||
| TensorInfo(TensorShape(8U, 6U, 6U), 1, DataType::F32, DataLayout::NHWC)}), |
There was a problem hiding this comment.
Shouldn't we make some F16 & adjust the expected in the body with cpu_supports_dtypes?
| ARM_COMPUTE_EXPECT(bool(s) == expected, framework::LogLevel::ERRORS); | ||
| } | ||
|
|
||
| /** Verify GEMM_CONV2D is returned automatically for NHWC QASYMM8_SIGNED to F32 dequantized convolution. */ |
| const QuantizationInfo qi(0.25f, 0); | ||
| TensorInfo src_info(TensorShape(16U, 8U, 8U), 1, DataType::QASYMM8_SIGNED, DataLayout::NHWC); | ||
| TensorInfo wgt_info(TensorShape(16U, 3U, 3U, 8U), 1, DataType::QASYMM8_SIGNED, DataLayout::NHWC); | ||
| TensorInfo dst_info(TensorShape(8U, 6U, 6U), 1, DataType::F32, DataLayout::NHWC); |
There was a problem hiding this comment.
I'd say, loop over F32 and F16 and back with cpu_supports_dtypes function.
| NEDequantizeFloatConvolutionFixture, | ||
| framework::DatasetMode::ALL, | ||
| combine(zip(make("InputShape", {TensorShape(8U, 8U, 16U), TensorShape(16U, 16U, 32U)}), | ||
| make("WeightsShape", {TensorShape(3U, 3U, 16U, 8U), TensorShape(3U, 3U, 32U, 16U)}), |
There was a problem hiding this comment.
Could we add another conv size other than 3x3? As far as I can see we only test 3x3 and 1x1.
Or better, why don't we directly use something like SmallConvolutionLayerDataset?
There was a problem hiding this comment.
By using a pre-defined dataset like SmallConvolutionLayerDataset, I'm talking about removing all the different combs below, like padded, strided etc. Not just for this particular suite of tests. I think it'll reduce the test code we maintain. Please let me know if we're missing any coverage by not using those pre-defined datasets.
Also, I'd like to repeat my comments about Fp16 output here.
Enable QASYMM8_SIGNED input and weights to use the F32 DequantizeFloat assembly output stage, including the direct convolution selection path.
Propagate input and weight zero-points plus the unrounded mathematical K depth so asymmetric offset correction uses the real GEMM/convolution depth rather than arm_gemm's padded internal K.
Add NEON validation coverage for the direct I8S8F32 convolution path.
Performance was checked on a A76, pinned to CPU 4 with one thread. The change is neutral on large workloads and improves the small NHWC signed int8 to F32 convolution path: QASYMM8_SIGNED/RunSmallDequantizeF32 NHWC/no-activation cases show a 1.36x geomean speedup over github/main, with the tiniest single-batch cases improving by roughly 1.45x to 3.13x.
Change-Id: Ie723d3da629d48de6de737c425bf7ad48e0f7feb