From 03b2971ac69a86f10a1566938d1a25afee15746c Mon Sep 17 00:00:00 2001 From: Viet-Hoa Do Date: Wed, 1 Jun 2022 11:47:14 +0100 Subject: Integrate SME2 kernels * Add SME/SME2 detection. * Integrate SME2 implementation for: - Normal convolution - Winograd - Depthwise convolution - Pooling Resolves: COMPMID-5700 Signed-off-by: Viet-Hoa Do Change-Id: I2f1ca1d05f8cfeee9309ed1c0a36096a4a6aad5c Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/8692 Reviewed-by: Gunes Bayir Tested-by: Arm Jenkins Comments-Addressed: Arm Jenkins --- .../winograd/input_transforms/sme_fp32_mla_6x6.cpp | 363 +++++++++ .../convolution/winograd/input_transforms_fp32.cpp | 6 + .../output_transforms/sme_fp32_mopa_4x4_3x3.cpp | 892 +++++++++++++++++++++ .../winograd/output_transforms_fp32.cpp | 8 + 4 files changed, 1269 insertions(+) create mode 100644 src/core/NEON/kernels/convolution/winograd/input_transforms/sme_fp32_mla_6x6.cpp create mode 100644 src/core/NEON/kernels/convolution/winograd/output_transforms/sme_fp32_mopa_4x4_3x3.cpp (limited to 'src/core/NEON/kernels/convolution') diff --git a/src/core/NEON/kernels/convolution/winograd/input_transforms/sme_fp32_mla_6x6.cpp b/src/core/NEON/kernels/convolution/winograd/input_transforms/sme_fp32_mla_6x6.cpp new file mode 100644 index 0000000000..e2397cd750 --- /dev/null +++ b/src/core/NEON/kernels/convolution/winograd/input_transforms/sme_fp32_mla_6x6.cpp @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2022 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if defined(ARM_COMPUTE_ENABLE_SME) + +#include + +namespace arm_conv { +namespace winograd { +namespace input_transform { + +void sme_fp32_mla_6x6( + const unsigned int num_channels, + const float *input, + const size_t input_row_stride, + const size_t input_col_stride, + float *output, + const size_t output_col_stride +) +{ + const float B_values[4] = { 1.0f, 2.0f, 4.0f, 5.0f }; + long long_channels = num_channels; + + // Generated by armasmgen (February 04th, 2021) + __asm__ __volatile__( + ".inst 0xd503477f // SMSTART ZA\n" + "fmov z16.s, #4.0\n" + "ptrue p1.b\n" + "ld1rqw { z2.s }, p1/Z, [%x[B_values]]\n" + "add x16, %x[input_row_0], %x[input_row_stride], LSL #2\n" + "add x15, %x[output_row_0], %x[output_row_stride], LSL #2\n" + "add x14, %x[input_row_0], %x[input_row_stride], LSL #3\n" + "add x13, %x[output_row_0], %x[output_row_stride], LSL #3\n" + "add x12, x14, %x[input_row_stride], LSL #2\n" + "add x11, x13, %x[output_row_stride], LSL #2\n" + "add x10, %x[input_row_0], %x[input_row_stride], LSL #4\n" + "add x9, %x[output_row_0], %x[output_row_stride], LSL #4\n" + "add x28, x10, %x[input_row_stride], LSL #2\n" + "add x27, x9, %x[output_row_stride], LSL #2\n" + "lsl x26, %x[input_col_1_stride], #0x1\n" + "lsl x25, %x[output_col_1_stride], #0x1\n" + "add x24, x26, %x[input_col_1_stride]\n" + "add x23, x25, %x[output_col_1_stride]\n" + "lsl x22, %x[input_col_1_stride], #0x2\n" + "lsl x21, %x[output_col_1_stride], #0x2\n" + "add x20, x22, %x[input_col_1_stride]\n" + "add x19, x21, %x[output_col_1_stride]\n" + "whilelt p0.s, XZR, %x[num_channels]\n" + "beq 2f\n" + "1:" // channel_loop + "ld1w { z31.s }, p0/Z, [%x[input_row_0]]\n" + "decw %x[num_channels]\n" + "ld1w { z28.s }, p0/Z, [%x[input_row_0], %x[input_col_1_stride], LSL #2]\n" + "fmul z13.s, z28.s, z2.s[1]\n" + "ld1w { z27.s }, p0/Z, [%x[input_row_0], x26, LSL #2]\n" + "ld1w { z11.s }, p0/Z, [%x[input_row_0], x24, LSL #2]\n" + "fneg z13.s, p1/M, z13.s\n" + "ld1w { z7.s }, p0/Z, [%x[input_row_0], x22, LSL #2]\n" + "fsub z15.s, z7.s, z27.s\n" + "fmad z31.s, p1/M, z16.s, z7.s\n" + "ld1w { z3.s }, p0/Z, [%x[input_row_0], x20, LSL #2]\n" + "fmla z13.s, z11.s, z2.s[1]\n" + "ld1w { z12.s }, p0/Z, [x14]\n" + "incb %x[input_row_0]\n" + "fmls z31.s, z27.s, z2.s[3]\n" + "ld1w { z14.s }, p0/Z, [x14, %x[input_col_1_stride], LSL #2]\n" + "fsub z25.s, z15.s, z13.s\n" + "fadd z8.s, z13.s, z15.s\n" + "ld1w { z24.s }, p0/Z, [x14, x26, LSL #2]\n" + "fmsb z27.s, p1/M, z16.s, z7.s\n" + "ld1w { z22.s }, p0/Z, [x14, x24, LSL #2]\n" + "fmul z7.s, z28.s, z2.s[2]\n" + "ld1w { z1.s }, p0/Z, [x14, x22, LSL #2]\n" + "fsub z15.s, z1.s, z24.s\n" + "fneg z7.s, p1/M, z7.s\n" + "ld1w { z20.s }, p0/Z, [x14, x20, LSL #2]\n" + "fadd z7.s, z7.s, z11.s\n" + "ld1w { z29.s }, p0/Z, [x10]\n" + "incb x14\n" + "fmad z28.s, p1/M, z16.s, z3.s\n" + "ld1w { z10.s }, p0/Z, [x10, %x[input_col_1_stride], LSL #2]\n" + "fmad z12.s, p1/M, z16.s, z1.s\n" + "ld1w { z18.s }, p0/Z, [x10, x26, LSL #2]\n" + "fmul z13.s, z14.s, z2.s[1]\n" + "ld1w { z19.s }, p0/Z, [x10, x24, LSL #2]\n" + "fadd z17.s, z7.s, z27.s\n" + "ld1w { z9.s }, p0/Z, [x10, x22, LSL #2]\n" + "fsub z27.s, z27.s, z7.s\n" + "fmls z28.s, z11.s, z2.s[3]\n" + "ld1w { z21.s }, p0/Z, [x10, x20, LSL #2]\n" + "incb x10\n" + "fmls z12.s, z24.s, z2.s[3]\n" + "fneg z13.s, p1/M, z13.s\n" + "fmla z13.s, z22.s, z2.s[1]\n" + "fsub z30.s, z15.s, z13.s\n" + "fadd z4.s, z13.s, z15.s\n" + "fmsb z24.s, p1/M, z16.s, z1.s\n" + "fsub z15.s, z9.s, z18.s\n" + "fmul z1.s, z14.s, z2.s[2]\n" + "fmad z14.s, p1/M, z16.s, z20.s\n" + "fmad z29.s, p1/M, z16.s, z9.s\n" + "fmul z13.s, z10.s, z2.s[1]\n" + "fneg z1.s, p1/M, z1.s\n" + "fadd z1.s, z1.s, z22.s\n" + "fmls z14.s, z22.s, z2.s[3]\n" + "fmls z29.s, z18.s, z2.s[3]\n" + "fadd z5.s, z1.s, z24.s\n" + "fsub z24.s, z24.s, z1.s\n" + "fneg z13.s, p1/M, z13.s\n" + "fmla z13.s, z19.s, z2.s[1]\n" + "fsub z23.s, z15.s, z13.s\n" + "fadd z11.s, z13.s, z15.s\n" + "fmsb z18.s, p1/M, z16.s, z9.s\n" + "fmul z9.s, z10.s, z2.s[2]\n" + "fmad z10.s, p1/M, z16.s, z21.s\n" + "fmad z31.s, p1/M, z16.s, z29.s\n" + "fmad z8.s, p1/M, z16.s, z11.s\n" + "fneg z9.s, p1/M, z9.s\n" + "fadd z9.s, z9.s, z19.s\n" + "fmls z10.s, z19.s, z2.s[3]\n" + "fmls z31.s, z12.s, z2.s[3]\n" + "st1w { z31.s }, p0, [%x[output_row_0]]\n" + "fadd z26.s, z9.s, z18.s\n" + "fsub z18.s, z18.s, z9.s\n" + "fmls z8.s, z4.s, z2.s[3]\n" + "fmad z25.s, p1/M, z16.s, z23.s\n" + "fmad z28.s, p1/M, z16.s, z10.s\n" + "fmad z17.s, p1/M, z16.s, z26.s\n" + "fmad z27.s, p1/M, z16.s, z18.s\n" + "fmls z25.s, z30.s, z2.s[3]\n" + "fmls z28.s, z14.s, z2.s[3]\n" + "fmls z17.s, z5.s, z2.s[3]\n" + "st1w { z17.s }, p0, [%x[output_row_0], %x[output_col_1_stride], LSL #2]\n" + "fmls z27.s, z24.s, z2.s[3]\n" + "st1w { z27.s }, p0, [%x[output_row_0], x25, LSL #2]\n" + "st1w { z8.s }, p0, [%x[output_row_0], x23, LSL #2]\n" + "st1w { z25.s }, p0, [%x[output_row_0], x21, LSL #2]\n" + "st1w { z28.s }, p0, [%x[output_row_0], x19, LSL #2]\n" + "incb %x[output_row_0]\n" + "ld1w { z19.s }, p0/Z, [x16]\n" + "ld1w { z7.s }, p0/Z, [x16, %x[input_col_1_stride], LSL #2]\n" + "fmul z13.s, z7.s, z2.s[1]\n" + "ld1w { z6.s }, p0/Z, [x16, x26, LSL #2]\n" + "ld1w { z27.s }, p0/Z, [x16, x24, LSL #2]\n" + "fneg z13.s, p1/M, z13.s\n" + "ld1w { z25.s }, p0/Z, [x16, x22, LSL #2]\n" + "fsub z15.s, z25.s, z6.s\n" + "fmad z19.s, p1/M, z16.s, z25.s\n" + "ld1w { z20.s }, p0/Z, [x16, x20, LSL #2]\n" + "fmla z13.s, z27.s, z2.s[1]\n" + "ld1w { z0.s }, p0/Z, [x12]\n" + "incb x16\n" + "fmls z19.s, z6.s, z2.s[3]\n" + "ld1w { z31.s }, p0/Z, [x12, %x[input_col_1_stride], LSL #2]\n" + "fsub z8.s, z15.s, z13.s\n" + "fadd z28.s, z13.s, z15.s\n" + "ld1w { z1.s }, p0/Z, [x12, x26, LSL #2]\n" + "fmsb z6.s, p1/M, z16.s, z25.s\n" + "ld1w { z21.s }, p0/Z, [x12, x24, LSL #2]\n" + "fmul z25.s, z7.s, z2.s[2]\n" + "ld1w { z22.s }, p0/Z, [x12, x22, LSL #2]\n" + "fsub z15.s, z22.s, z1.s\n" + "fneg z25.s, p1/M, z25.s\n" + "ld1w { z17.s }, p0/Z, [x12, x20, LSL #2]\n" + "fadd z25.s, z25.s, z27.s\n" + "incb x12\n" + "fmad z7.s, p1/M, z16.s, z20.s\n" + "fmad z0.s, p1/M, z16.s, z22.s\n" + "fmul z13.s, z31.s, z2.s[1]\n" + "fadd z3.s, z25.s, z6.s\n" + "fsub z6.s, z6.s, z25.s\n" + "fmls z7.s, z27.s, z2.s[3]\n" + "fmls z0.s, z1.s, z2.s[3]\n" + "fneg z13.s, p1/M, z13.s\n" + "fmla z13.s, z21.s, z2.s[1]\n" + "fsub z9.s, z15.s, z13.s\n" + "fadd z27.s, z13.s, z15.s\n" + "fmsb z1.s, p1/M, z16.s, z22.s\n" + "fsub z15.s, z29.s, z12.s\n" + "fmul z22.s, z31.s, z2.s[2]\n" + "fmad z31.s, p1/M, z16.s, z17.s\n" + "fmul z13.s, z19.s, z2.s[1]\n" + "fmsb z12.s, p1/M, z16.s, z29.s\n" + "fneg z22.s, p1/M, z22.s\n" + "fadd z22.s, z22.s, z21.s\n" + "fmls z31.s, z21.s, z2.s[3]\n" + "fneg z13.s, p1/M, z13.s\n" + "fadd z25.s, z22.s, z1.s\n" + "fsub z1.s, z1.s, z22.s\n" + "fmla z13.s, z0.s, z2.s[1]\n" + "fmul z29.s, z19.s, z2.s[2]\n" + "fadd z22.s, z13.s, z15.s\n" + "st1w { z22.s }, p0, [x11]\n" + "fneg z29.s, p1/M, z29.s\n" + "fsub z22.s, z15.s, z13.s\n" + "fadd z29.s, z29.s, z0.s\n" + "st1w { z22.s }, p0, [x9]\n" + "fadd z22.s, z29.s, z12.s\n" + "fsub z15.s, z26.s, z5.s\n" + "fmul z13.s, z3.s, z2.s[1]\n" + "fsub z12.s, z12.s, z29.s\n" + "fmsb z5.s, p1/M, z16.s, z26.s\n" + "fmul z26.s, z3.s, z2.s[2]\n" + "fneg z13.s, p1/M, z13.s\n" + "fmla z13.s, z25.s, z2.s[1]\n" + "fneg z26.s, p1/M, z26.s\n" + "fadd z26.s, z26.s, z25.s\n" + "fadd z21.s, z13.s, z15.s\n" + "st1w { z21.s }, p0, [x11, %x[output_col_1_stride], LSL #2]\n" + "fsub z21.s, z15.s, z13.s\n" + "fmul z13.s, z6.s, z2.s[1]\n" + "fneg z13.s, p1/M, z13.s\n" + "st1w { z21.s }, p0, [x9, %x[output_col_1_stride], LSL #2]\n" + "fadd z21.s, z26.s, z5.s\n" + "fsub z15.s, z18.s, z24.s\n" + "fmla z13.s, z1.s, z2.s[1]\n" + "fsub z5.s, z5.s, z26.s\n" + "fmsb z24.s, p1/M, z16.s, z18.s\n" + "fmul z18.s, z6.s, z2.s[2]\n" + "fadd z20.s, z13.s, z15.s\n" + "st1w { z20.s }, p0, [x11, x25, LSL #2]\n" + "fneg z18.s, p1/M, z18.s\n" + "fsub z20.s, z15.s, z13.s\n" + "fadd z18.s, z18.s, z1.s\n" + "st1w { z20.s }, p0, [x9, x25, LSL #2]\n" + "fadd z20.s, z18.s, z24.s\n" + "fsub z15.s, z11.s, z4.s\n" + "fmul z13.s, z28.s, z2.s[1]\n" + "fsub z24.s, z24.s, z18.s\n" + "fmsb z4.s, p1/M, z16.s, z11.s\n" + "fmul z11.s, z28.s, z2.s[2]\n" + "fneg z13.s, p1/M, z13.s\n" + "fmla z13.s, z27.s, z2.s[1]\n" + "fneg z11.s, p1/M, z11.s\n" + "fadd z11.s, z11.s, z27.s\n" + "fadd z26.s, z13.s, z15.s\n" + "st1w { z26.s }, p0, [x11, x23, LSL #2]\n" + "fsub z26.s, z15.s, z13.s\n" + "fmul z13.s, z8.s, z2.s[1]\n" + "fneg z13.s, p1/M, z13.s\n" + "st1w { z26.s }, p0, [x9, x23, LSL #2]\n" + "fadd z26.s, z11.s, z4.s\n" + "fsub z15.s, z23.s, z30.s\n" + "fmla z13.s, z9.s, z2.s[1]\n" + "fsub z4.s, z4.s, z11.s\n" + "fmsb z30.s, p1/M, z16.s, z23.s\n" + "fmul z23.s, z8.s, z2.s[2]\n" + "fadd z18.s, z13.s, z15.s\n" + "st1w { z18.s }, p0, [x11, x21, LSL #2]\n" + "fneg z23.s, p1/M, z23.s\n" + "fsub z18.s, z15.s, z13.s\n" + "fadd z23.s, z23.s, z9.s\n" + "st1w { z18.s }, p0, [x9, x21, LSL #2]\n" + "fadd z18.s, z23.s, z30.s\n" + "fsub z15.s, z10.s, z14.s\n" + "fmul z13.s, z7.s, z2.s[1]\n" + "fsub z30.s, z30.s, z23.s\n" + "fmsb z14.s, p1/M, z16.s, z10.s\n" + "fmul z10.s, z7.s, z2.s[2]\n" + "fneg z13.s, p1/M, z13.s\n" + "fmla z13.s, z31.s, z2.s[1]\n" + "fneg z10.s, p1/M, z10.s\n" + "fadd z10.s, z10.s, z31.s\n" + "fadd z17.s, z13.s, z15.s\n" + "st1w { z17.s }, p0, [x11, x19, LSL #2]\n" + "fsub z17.s, z15.s, z13.s\n" + "incb x11\n" + "st1w { z17.s }, p0, [x9, x19, LSL #2]\n" + "fadd z17.s, z10.s, z14.s\n" + "fsub z14.s, z14.s, z10.s\n" + "st1w { z22.s }, p0, [x15]\n" + "incb x9\n" + "st1w { z12.s }, p0, [x13]\n" + "st1w { z21.s }, p0, [x15, %x[output_col_1_stride], LSL #2]\n" + "st1w { z5.s }, p0, [x13, %x[output_col_1_stride], LSL #2]\n" + "st1w { z20.s }, p0, [x15, x25, LSL #2]\n" + "st1w { z24.s }, p0, [x13, x25, LSL #2]\n" + "st1w { z26.s }, p0, [x15, x23, LSL #2]\n" + "st1w { z4.s }, p0, [x13, x23, LSL #2]\n" + "st1w { z18.s }, p0, [x15, x21, LSL #2]\n" + "st1w { z30.s }, p0, [x13, x21, LSL #2]\n" + "st1w { z17.s }, p0, [x15, x19, LSL #2]\n" + "incb x15\n" + "st1w { z14.s }, p0, [x13, x19, LSL #2]\n" + "incb x13\n" + "ld1w { z23.s }, p0/Z, [x28]\n" + "ld1w { z22.s }, p0/Z, [x28, %x[input_col_1_stride], LSL #2]\n" + "fmul z13.s, z22.s, z2.s[1]\n" + "ld1w { z21.s }, p0/Z, [x28, x26, LSL #2]\n" + "ld1w { z20.s }, p0/Z, [x28, x24, LSL #2]\n" + "fneg z13.s, p1/M, z13.s\n" + "ld1w { z26.s }, p0/Z, [x28, x22, LSL #2]\n" + "fsub z15.s, z26.s, z21.s\n" + "fmad z23.s, p1/M, z16.s, z26.s\n" + "ld1w { z18.s }, p0/Z, [x28, x20, LSL #2]\n" + "fmla z13.s, z20.s, z2.s[1]\n" + "incb x28\n" + "fmls z23.s, z21.s, z2.s[3]\n" + "fsub z17.s, z15.s, z13.s\n" + "fadd z30.s, z13.s, z15.s\n" + "fmsb z21.s, p1/M, z16.s, z26.s\n" + "fmul z26.s, z22.s, z2.s[2]\n" + "fmad z22.s, p1/M, z16.s, z18.s\n" + "fmad z19.s, p1/M, z16.s, z23.s\n" + "fmad z28.s, p1/M, z16.s, z30.s\n" + "fneg z26.s, p1/M, z26.s\n" + "fadd z26.s, z26.s, z20.s\n" + "fmls z22.s, z20.s, z2.s[3]\n" + "fmls z19.s, z0.s, z2.s[3]\n" + "st1w { z19.s }, p0, [x27]\n" + "fadd z23.s, z26.s, z21.s\n" + "fsub z21.s, z21.s, z26.s\n" + "fmls z28.s, z27.s, z2.s[3]\n" + "fmad z8.s, p1/M, z16.s, z17.s\n" + "fmad z7.s, p1/M, z16.s, z22.s\n" + "fmad z3.s, p1/M, z16.s, z23.s\n" + "fmad z6.s, p1/M, z16.s, z21.s\n" + "fmls z8.s, z9.s, z2.s[3]\n" + "fmls z7.s, z31.s, z2.s[3]\n" + "fmls z3.s, z25.s, z2.s[3]\n" + "st1w { z3.s }, p0, [x27, %x[output_col_1_stride], LSL #2]\n" + "fmls z6.s, z1.s, z2.s[3]\n" + "st1w { z6.s }, p0, [x27, x25, LSL #2]\n" + "st1w { z28.s }, p0, [x27, x23, LSL #2]\n" + "st1w { z8.s }, p0, [x27, x21, LSL #2]\n" + "st1w { z7.s }, p0, [x27, x19, LSL #2]\n" + "incb x27\n" + "whilelt p0.s, XZR, %x[num_channels]\n" + "bne 1b\n" + "2:" // channel_loop_end + ".inst 0xd503467f // SMSTOP\n" + : [input_row_0] "+&r" (input), [num_channels] "+&r" (long_channels), [output_row_0] "+&r" (output) + : [B_values] "r" (B_values), [input_col_1_stride] "r" ((long) input_col_stride), [input_row_stride] "r" ((long) input_row_stride), [output_col_1_stride] "r" ((long) output_col_stride), [output_row_stride] "r" (6 * (long) output_col_stride) + : "cc", "memory", "p0", "p1", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28", "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10", "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21", "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31" + ); +} + +} // namespace input_transform +} // namespace winograd +} // namespace arm_conv + +#endif // defined(ARM_COMPUTE_ENABLE_SME) diff --git a/src/core/NEON/kernels/convolution/winograd/input_transforms_fp32.cpp b/src/core/NEON/kernels/convolution/winograd/input_transforms_fp32.cpp index ec4e954f71..df633903ca 100644 --- a/src/core/NEON/kernels/convolution/winograd/input_transforms_fp32.cpp +++ b/src/core/NEON/kernels/convolution/winograd/input_transforms_fp32.cpp @@ -34,6 +34,9 @@ namespace input_transform { #if defined(__aarch64__) #if defined(ARM_COMPUTE_ENABLE_SVE) +#if defined(ARM_COMPUTE_ENABLE_SME) +void sme_fp32_mla_6x6(unsigned int, const float *, size_t, size_t, float *, size_t); +#endif // defined(ARM_COMPUTE_ENABLE_SME) void sve_fp32_6x6(unsigned int, const float *, size_t, size_t, float *, size_t); #endif // defined(ARM_COMPUTE_ENABLE_SVE) void a64_fp32_6x6(unsigned int, const float *, size_t, size_t, float *, size_t); @@ -48,6 +51,9 @@ void arm_fp32_1x8(unsigned int, const float *, size_t, size_t, float *, size_t); static const TransformImplementation transforms_fp32[] = { #if defined(__aarch64__) #if defined(ARM_COMPUTE_ENABLE_SVE) +#if defined(ARM_COMPUTE_ENABLE_SME) + { IMPL(6, 6, sme_fp32_mla_6x6, Unpadded), MethodConstraints::RequiresSME }, +#endif // defined(ARM_COMPUTE_ENABLE_SME) { IMPL(6, 6, sve_fp32_6x6, Unpadded), MethodConstraints::RequiresSVE }, #endif // defined(ARM_COMPUTE_ENABLE_SVE) { IMPL(6, 6, a64_fp32_6x6, Unpadded) }, diff --git a/src/core/NEON/kernels/convolution/winograd/output_transforms/sme_fp32_mopa_4x4_3x3.cpp b/src/core/NEON/kernels/convolution/winograd/output_transforms/sme_fp32_mopa_4x4_3x3.cpp new file mode 100644 index 0000000000..9d3c751d78 --- /dev/null +++ b/src/core/NEON/kernels/convolution/winograd/output_transforms/sme_fp32_mopa_4x4_3x3.cpp @@ -0,0 +1,892 @@ +/* + * Copyright (c) 2022 Arm Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if defined(__aarch64__) && defined(ARM_COMPUTE_ENABLE_SVE) && defined(ARM_COMPUTE_ENABLE_SME) + +#include + +namespace arm_conv { +namespace winograd { +namespace output_transform { + +void sme_fp32_mopa_4x4_3x3( + const unsigned int n_channels, + const float* inptr, + const size_t matrix_stride, + const float* bptr, + float* const output, + const size_t output_row_stride, + const size_t output_col_stride, + const float output_min, + const float output_max +) +{ + // The below assembler uses the Kronecker product and the "vec trick" to + // implement the Winograd output transform (y = AT Y A) using the SME + // array. This code REQUIRES that the vectors are 512b long (or longer, if + // we add some predication). + // + // The "vec trick" uses the identity $vec(AT Y A) = (AT (x) AT) vec(Y)$ to + // convert the chain of matrix multiplications into a matrix-vector + // product. We then stack multiple channels of vec(Y) together to allow us + // to perform multiple channels of the transformation simultaneously. + // + // Since the complete matrix (AT (x) AT) is quite big [16 x 36], we compute + // it on the fly. To do so, we store two representations of the matrix AT. + // The first representation (the outer terms) contains, within each quad, + // four coefficients of the matrix AT. + const float outer_terms[32] = { + 1, 1, 1, 1, + 0, 1, -1, 2, + 0, 1, 1, 4, + 0, 1, -1, 8, + // The following rows are continuations of the first four rows, and each + // contains two columns of padding values which aren't used in the + // computation but are there to ensure that the coefficients end up in + // the right quads of the vector into which they're read. + 1, 0, 0, 0, + -2, 0, 0, 0, + 4, 0, 0, 0, + -8, 1, 0, 0 + }; + // This should be loaded completely into two Z registers. + // + // We can then use by-element FMLA to construct columns of (AT (x) AT) by + // multiplying elements of the outer terms against the following inner + // terms (again split into quads, but expected to be loaded replicated such + // that each of the six required Z registers contains a repeated quad of + // the values). + const float inner_terms[24] = { + 1, 0, 0, 0, + 1, 1, 1, 1, + 1, -1, 1, -1, + 1, 2, 4, 8, + 1, -2, 4, -8, + 0, 0, 0, 1 + }; + + struct Params + { + const float *outer_terms; + const float *inner_terms; + float act_min; + float act_max; + + Params(const float *outer_terms, + const float *inner_terms, + float act_min, + float act_max) + : outer_terms(outer_terms), inner_terms(inner_terms), + act_min(act_min), act_max(act_max) + { + } + }; + + Params params(outer_terms, inner_terms, output_min, output_max); + + __asm__ __volatile__( + "ldr x20, [%x[params], %[offsetof_Params_outer_terms]]\n" + ".inst 0xd503477f // SMSTART ZA\n" + "ptrue p5.b\n" + "ld1rw { z12.s }, p5/Z, [%x[params], %[offsetof_Params_act_min]]\n" + "ld1rw { z10.s }, p5/Z, [%x[params], %[offsetof_Params_act_max]]\n" + "pfalse p8.b\n" + "ldr x19, [%x[params], %[offsetof_Params_inner_terms]]\n" + "ld1w { z6.s }, p5/Z, [x20]\n" + "ld1w { z7.s }, p5/Z, [x20, #1, MUL VL]\n" + "ld1rqw { z9.s }, p5/Z, [x19]\n" + "ld1rqw { z8.s }, p5/Z, [x19, #16]\n" + "ld1rqw { z15.s }, p5/Z, [x19, #32]\n" + "fmul z11.s, z9.s, z6.s[0]\n" + "fmul z5.s, z9.s, z6.s[1]\n" + "ld1rqw { z4.s }, p5/Z, [x19, #48]\n" + "ld1rqw { z3.s }, p5/Z, [x19, #64]\n" + "ld1rqw { z2.s }, p5/Z, [x19, #80]\n" + "cbz %x[bptr], 1f\n" + "ptrue p8.s\n" + "1:" // Set bias predicate: Done + ".inst 0xc00800ff // zero { zad0, zad1, zad2, zad3, zad4, zad5, zad6, zad7 }\n" + "fmov z1.s, #1.0\n" + "mov x25, #0x0\n" + "cntw x24\n" + "cntw x23, ALL, MUL #2\n" + "cntw x22, ALL, MUL #3\n" + "whilelt p4.s, x25, %x[n_channels]\n" + "whilelt p3.s, x24, %x[n_channels]\n" + "ld1w { z31.s }, p4/Z, [%x[inptr], x25, LSL #2]\n" + "ld1w { z30.s }, p3/Z, [%x[inptr], x24, LSL #2]\n" + "whilelt p2.s, x23, %x[n_channels]\n" + "whilelt p1.s, x22, %x[n_channels]\n" + "ld1w { z29.s }, p2/Z, [%x[inptr], x23, LSL #2]\n" + "add x21, %x[inptr], %x[matrix_stride], LSL #2\n" + "and p0.b, p5/Z, p8.b, p4.b\n" + "ld1w { z28.s }, p1/Z, [%x[inptr], x22, LSL #2]\n" + "ld1w { z27.s }, p4/Z, [x21, x25, LSL #2]\n" + "ld1w { z26.s }, p3/Z, [x21, x24, LSL #2]\n" + "ld1w { z25.s }, p2/Z, [x21, x23, LSL #2]\n" + "ld1w { z24.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + "ld1w { z23.s }, p4/Z, [x21, x25, LSL #2]\n" + "ld1w { z22.s }, p3/Z, [x21, x24, LSL #2]\n" + "ld1w { z21.s }, p2/Z, [x21, x23, LSL #2]\n" + "ld1w { z20.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + "ld1w { z19.s }, p4/Z, [x21, x25, LSL #2]\n" + "ld1w { z18.s }, p3/Z, [x21, x24, LSL #2]\n" + "ld1w { z17.s }, p2/Z, [x21, x23, LSL #2]\n" + "ld1w { z16.s }, p1/Z, [x21, x22, LSL #2]\n" + "ld1w { z0.s }, p0/Z, [%x[bptr], x25, LSL #2]\n" + "and p0.b, p5/Z, p8.b, p3.b\n" + ".inst 0x8080b420 // fmopa za0.s, p5/M, p5/M, z1.s, z0.s\n" + "ld1w { z0.s }, p0/Z, [%x[bptr], x24, LSL #2]\n" + "and p0.b, p5/Z, p8.b, p2.b\n" + ".inst 0x8080b421 // fmopa za1.s, p5/M, p5/M, z1.s, z0.s\n" + "ld1w { z0.s }, p0/Z, [%x[bptr], x23, LSL #2]\n" + "and p0.b, p5/Z, p8.b, p1.b\n" + ".inst 0x8080b422 // fmopa za2.s, p5/M, p5/M, z1.s, z0.s\n" + "ld1w { z0.s }, p0/Z, [%x[bptr], x22, LSL #2]\n" + ".inst 0x8080b423 // fmopa za3.s, p5/M, p5/M, z1.s, z0.s\n" + "2:" // Loop + ".inst 0x809fb560 // fmopa za0.s, p5/M, p5/M, z11.s, z31.s\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + "mov x14, #0xc\n" + ".inst 0x809eb561 // fmopa za1.s, p5/M, p5/M, z11.s, z30.s\n" + "ld1w { z31.s }, p4/Z, [x21, x25, LSL #2]\n" + "whilelt p0.s, x25, %x[n_channels]\n" + "add x20, %x[output], %x[output_col_stride], LSL #2\n" + ".inst 0x809db562 // fmopa za2.s, p5/M, p5/M, z11.s, z29.s\n" + "ld1w { z30.s }, p3/Z, [x21, x24, LSL #2]\n" + "add x19, %x[output], %x[output_row_stride], LSL #2\n" + ".inst 0x809cb563 // fmopa za3.s, p5/M, p5/M, z11.s, z28.s\n" + "fmul z11.s, z9.s, z6.s[2]\n" + "ld1w { z29.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809bb4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z27.s\n" + "ld1w { z28.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809ab4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z26.s\n" + "ld1w { z27.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8099b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z25.s\n" + "ld1w { z26.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8098b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z24.s\n" + "fmul z5.s, z9.s, z6.s[3]\n" + "ld1w { z25.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8097b560 // fmopa za0.s, p5/M, p5/M, z11.s, z23.s\n" + "ld1w { z24.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8096b561 // fmopa za1.s, p5/M, p5/M, z11.s, z22.s\n" + "ld1w { z23.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8095b562 // fmopa za2.s, p5/M, p5/M, z11.s, z21.s\n" + "ld1w { z22.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8094b563 // fmopa za3.s, p5/M, p5/M, z11.s, z20.s\n" + "fmul z11.s, z9.s, z7.s[0]\n" + "ld1w { z21.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8093b4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z19.s\n" + "ld1w { z20.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8092b4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z18.s\n" + "ld1w { z19.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8091b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z17.s\n" + "ld1w { z18.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8090b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z16.s\n" + "fmul z5.s, z9.s, z7.s[1]\n" + "ld1w { z17.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809fb560 // fmopa za0.s, p5/M, p5/M, z11.s, z31.s\n" + "ld1w { z16.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809eb561 // fmopa za1.s, p5/M, p5/M, z11.s, z30.s\n" + "ld1w { z31.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x809db562 // fmopa za2.s, p5/M, p5/M, z11.s, z29.s\n" + "ld1w { z30.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x809cb563 // fmopa za3.s, p5/M, p5/M, z11.s, z28.s\n" + "fmul z11.s, z8.s, z6.s[0]\n" + "ld1w { z29.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809bb4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z27.s\n" + "ld1w { z28.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809ab4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z26.s\n" + "ld1w { z27.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8099b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z25.s\n" + "ld1w { z26.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8098b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z24.s\n" + "fmul z5.s, z8.s, z6.s[1]\n" + "ld1w { z25.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8097b560 // fmopa za0.s, p5/M, p5/M, z11.s, z23.s\n" + "ld1w { z24.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8096b561 // fmopa za1.s, p5/M, p5/M, z11.s, z22.s\n" + "ld1w { z23.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8095b562 // fmopa za2.s, p5/M, p5/M, z11.s, z21.s\n" + "ld1w { z22.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8094b563 // fmopa za3.s, p5/M, p5/M, z11.s, z20.s\n" + "fmul z11.s, z8.s, z6.s[2]\n" + "ld1w { z21.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8093b4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z19.s\n" + "ld1w { z20.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8092b4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z18.s\n" + "ld1w { z19.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8091b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z17.s\n" + "ld1w { z18.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8090b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z16.s\n" + "fmul z5.s, z8.s, z6.s[3]\n" + "ld1w { z17.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809fb560 // fmopa za0.s, p5/M, p5/M, z11.s, z31.s\n" + "ld1w { z16.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809eb561 // fmopa za1.s, p5/M, p5/M, z11.s, z30.s\n" + "ld1w { z31.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x809db562 // fmopa za2.s, p5/M, p5/M, z11.s, z29.s\n" + "ld1w { z30.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x809cb563 // fmopa za3.s, p5/M, p5/M, z11.s, z28.s\n" + "fmul z11.s, z8.s, z7.s[0]\n" + "ld1w { z29.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809bb4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z27.s\n" + "ld1w { z28.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809ab4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z26.s\n" + "ld1w { z27.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8099b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z25.s\n" + "ld1w { z26.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8098b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z24.s\n" + "fmul z5.s, z8.s, z7.s[1]\n" + "ld1w { z25.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8097b560 // fmopa za0.s, p5/M, p5/M, z11.s, z23.s\n" + "ld1w { z24.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8096b561 // fmopa za1.s, p5/M, p5/M, z11.s, z22.s\n" + "ld1w { z23.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8095b562 // fmopa za2.s, p5/M, p5/M, z11.s, z21.s\n" + "ld1w { z22.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8094b563 // fmopa za3.s, p5/M, p5/M, z11.s, z20.s\n" + "fmul z11.s, z15.s, z6.s[0]\n" + "ld1w { z21.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8093b4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z19.s\n" + "ld1w { z20.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8092b4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z18.s\n" + "ld1w { z19.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8091b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z17.s\n" + "ld1w { z18.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8090b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z16.s\n" + "fmul z5.s, z15.s, z6.s[1]\n" + "ld1w { z17.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809fb560 // fmopa za0.s, p5/M, p5/M, z11.s, z31.s\n" + "ld1w { z16.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809eb561 // fmopa za1.s, p5/M, p5/M, z11.s, z30.s\n" + "ld1w { z31.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x809db562 // fmopa za2.s, p5/M, p5/M, z11.s, z29.s\n" + "ld1w { z30.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x809cb563 // fmopa za3.s, p5/M, p5/M, z11.s, z28.s\n" + "fmul z11.s, z15.s, z6.s[2]\n" + "ld1w { z29.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809bb4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z27.s\n" + "ld1w { z28.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809ab4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z26.s\n" + "ld1w { z27.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8099b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z25.s\n" + "ld1w { z26.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8098b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z24.s\n" + "fmul z5.s, z15.s, z6.s[3]\n" + "ld1w { z25.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8097b560 // fmopa za0.s, p5/M, p5/M, z11.s, z23.s\n" + "ld1w { z24.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8096b561 // fmopa za1.s, p5/M, p5/M, z11.s, z22.s\n" + "ld1w { z23.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8095b562 // fmopa za2.s, p5/M, p5/M, z11.s, z21.s\n" + "ld1w { z22.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8094b563 // fmopa za3.s, p5/M, p5/M, z11.s, z20.s\n" + "fmul z11.s, z15.s, z7.s[0]\n" + "ld1w { z21.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8093b4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z19.s\n" + "ld1w { z20.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8092b4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z18.s\n" + "ld1w { z19.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8091b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z17.s\n" + "ld1w { z18.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8090b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z16.s\n" + "fmul z5.s, z15.s, z7.s[1]\n" + "ld1w { z17.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809fb560 // fmopa za0.s, p5/M, p5/M, z11.s, z31.s\n" + "ld1w { z16.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809eb561 // fmopa za1.s, p5/M, p5/M, z11.s, z30.s\n" + "ld1w { z31.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x809db562 // fmopa za2.s, p5/M, p5/M, z11.s, z29.s\n" + "ld1w { z30.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x809cb563 // fmopa za3.s, p5/M, p5/M, z11.s, z28.s\n" + "fmul z11.s, z4.s, z6.s[0]\n" + "ld1w { z29.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809bb4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z27.s\n" + "ld1w { z28.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809ab4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z26.s\n" + "ld1w { z27.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8099b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z25.s\n" + "ld1w { z26.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8098b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z24.s\n" + "fmul z5.s, z4.s, z6.s[1]\n" + "ld1w { z25.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8097b560 // fmopa za0.s, p5/M, p5/M, z11.s, z23.s\n" + "ld1w { z24.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8096b561 // fmopa za1.s, p5/M, p5/M, z11.s, z22.s\n" + "ld1w { z23.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8095b562 // fmopa za2.s, p5/M, p5/M, z11.s, z21.s\n" + "ld1w { z22.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8094b563 // fmopa za3.s, p5/M, p5/M, z11.s, z20.s\n" + "fmul z11.s, z4.s, z6.s[2]\n" + "ld1w { z21.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8093b4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z19.s\n" + "ld1w { z20.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8092b4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z18.s\n" + "ld1w { z19.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8091b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z17.s\n" + "ld1w { z18.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8090b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z16.s\n" + "fmul z5.s, z4.s, z6.s[3]\n" + "ld1w { z17.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809fb560 // fmopa za0.s, p5/M, p5/M, z11.s, z31.s\n" + "ld1w { z16.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809eb561 // fmopa za1.s, p5/M, p5/M, z11.s, z30.s\n" + "ld1w { z31.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x809db562 // fmopa za2.s, p5/M, p5/M, z11.s, z29.s\n" + "ld1w { z30.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x809cb563 // fmopa za3.s, p5/M, p5/M, z11.s, z28.s\n" + "fmul z11.s, z4.s, z7.s[0]\n" + "ld1w { z29.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809bb4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z27.s\n" + "ld1w { z28.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809ab4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z26.s\n" + "ld1w { z27.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8099b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z25.s\n" + "ld1w { z26.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8098b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z24.s\n" + "fmul z5.s, z4.s, z7.s[1]\n" + "ld1w { z25.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8097b560 // fmopa za0.s, p5/M, p5/M, z11.s, z23.s\n" + "ld1w { z24.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8096b561 // fmopa za1.s, p5/M, p5/M, z11.s, z22.s\n" + "ld1w { z23.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8095b562 // fmopa za2.s, p5/M, p5/M, z11.s, z21.s\n" + "ld1w { z22.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8094b563 // fmopa za3.s, p5/M, p5/M, z11.s, z20.s\n" + "fmul z11.s, z3.s, z6.s[0]\n" + "ld1w { z21.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8093b4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z19.s\n" + "ld1w { z20.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8092b4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z18.s\n" + "ld1w { z19.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8091b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z17.s\n" + "ld1w { z18.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8090b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z16.s\n" + "fmul z5.s, z3.s, z6.s[1]\n" + "ld1w { z17.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809fb560 // fmopa za0.s, p5/M, p5/M, z11.s, z31.s\n" + "ld1w { z16.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809eb561 // fmopa za1.s, p5/M, p5/M, z11.s, z30.s\n" + "ld1w { z31.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x809db562 // fmopa za2.s, p5/M, p5/M, z11.s, z29.s\n" + "ld1w { z30.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x809cb563 // fmopa za3.s, p5/M, p5/M, z11.s, z28.s\n" + "fmul z11.s, z3.s, z6.s[2]\n" + "ld1w { z29.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809bb4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z27.s\n" + "ld1w { z28.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809ab4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z26.s\n" + "ld1w { z27.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8099b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z25.s\n" + "ld1w { z26.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8098b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z24.s\n" + "fmul z5.s, z3.s, z6.s[3]\n" + "ld1w { z25.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8097b560 // fmopa za0.s, p5/M, p5/M, z11.s, z23.s\n" + "ld1w { z24.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8096b561 // fmopa za1.s, p5/M, p5/M, z11.s, z22.s\n" + "ld1w { z23.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8095b562 // fmopa za2.s, p5/M, p5/M, z11.s, z21.s\n" + "ld1w { z22.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8094b563 // fmopa za3.s, p5/M, p5/M, z11.s, z20.s\n" + "fmul z11.s, z3.s, z7.s[0]\n" + "ld1w { z21.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8093b4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z19.s\n" + "ld1w { z20.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8092b4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z18.s\n" + "ld1w { z19.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8091b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z17.s\n" + "ld1w { z18.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8090b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z16.s\n" + "fmul z5.s, z3.s, z7.s[1]\n" + "ld1w { z17.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809fb560 // fmopa za0.s, p5/M, p5/M, z11.s, z31.s\n" + "ld1w { z16.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809eb561 // fmopa za1.s, p5/M, p5/M, z11.s, z30.s\n" + "ld1w { z31.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x809db562 // fmopa za2.s, p5/M, p5/M, z11.s, z29.s\n" + "ld1w { z30.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x809cb563 // fmopa za3.s, p5/M, p5/M, z11.s, z28.s\n" + "fmul z11.s, z2.s, z6.s[0]\n" + "ld1w { z29.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809bb4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z27.s\n" + "ld1w { z28.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x809ab4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z26.s\n" + "ld1w { z27.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8099b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z25.s\n" + "ld1w { z26.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8098b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z24.s\n" + "fmul z5.s, z2.s, z6.s[1]\n" + "ld1w { z25.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8097b560 // fmopa za0.s, p5/M, p5/M, z11.s, z23.s\n" + "ld1w { z24.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8096b561 // fmopa za1.s, p5/M, p5/M, z11.s, z22.s\n" + "ld1w { z23.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8095b562 // fmopa za2.s, p5/M, p5/M, z11.s, z21.s\n" + "ld1w { z22.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8094b563 // fmopa za3.s, p5/M, p5/M, z11.s, z20.s\n" + "fmul z11.s, z2.s, z6.s[2]\n" + "ld1w { z21.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x8093b4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z19.s\n" + "ld1w { z20.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + ".inst 0x8092b4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z18.s\n" + "ld1w { z19.s }, p4/Z, [x21, x25, LSL #2]\n" + ".inst 0x8091b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z17.s\n" + "ld1w { z18.s }, p3/Z, [x21, x24, LSL #2]\n" + ".inst 0x8090b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z16.s\n" + "fmul z5.s, z2.s, z6.s[3]\n" + "ld1w { z17.s }, p2/Z, [x21, x23, LSL #2]\n" + ".inst 0x809fb560 // fmopa za0.s, p5/M, p5/M, z11.s, z31.s\n" + "ld1w { z16.s }, p1/Z, [x21, x22, LSL #2]\n" + ".inst 0x809eb561 // fmopa za1.s, p5/M, p5/M, z11.s, z30.s\n" + ".inst 0x809db562 // fmopa za2.s, p5/M, p5/M, z11.s, z29.s\n" + ".inst 0x809cb563 // fmopa za3.s, p5/M, p5/M, z11.s, z28.s\n" + "fmul z11.s, z2.s, z7.s[0]\n" + ".inst 0x809bb4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z27.s\n" + ".inst 0x809ab4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z26.s\n" + ".inst 0x8099b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z25.s\n" + ".inst 0x8098b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z24.s\n" + "fmul z5.s, z2.s, z7.s[1]\n" + ".inst 0x8097b560 // fmopa za0.s, p5/M, p5/M, z11.s, z23.s\n" + ".inst 0x8096b561 // fmopa za1.s, p5/M, p5/M, z11.s, z22.s\n" + ".inst 0x8095b562 // fmopa za2.s, p5/M, p5/M, z11.s, z21.s\n" + ".inst 0x8094b563 // fmopa za3.s, p5/M, p5/M, z11.s, z20.s\n" + "fmul z11.s, z9.s, z6.s[0]\n" + ".inst 0x8093b4a0 // fmopa za0.s, p5/M, p5/M, z5.s, z19.s\n" + ".inst 0x8092b4a1 // fmopa za1.s, p5/M, p5/M, z5.s, z18.s\n" + ".inst 0x8091b4a2 // fmopa za2.s, p5/M, p5/M, z5.s, z17.s\n" + ".inst 0x8090b4a3 // fmopa za3.s, p5/M, p5/M, z5.s, z16.s\n" + "fmul z5.s, z9.s, z6.s[1]\n" + ".inst 0xc082741f // mova z31.s, p5/M, za0h.s[XZR]\n" + ".inst 0xc082541c // mova z28.s, p5/M, za0h.s[x14]\n" + "fmin z31.s, p5/M, z31.s, z10.s\n" + ".inst 0xc082743b // mova z27.s, p5/M, za0h.s[XZR, #1]\n" + "fmin z28.s, p5/M, z28.s, z10.s\n" + ".inst 0xc0825438 // mova z24.s, p5/M, za0h.s[x14, #1]\n" + "fmin z27.s, p5/M, z27.s, z10.s\n" + "mov x13, #0x4\n" + "mov x12, #0x8\n" + ".inst 0xc082341e // mova z30.s, p5/M, za0h.s[x13]\n" + "fmin z24.s, p5/M, z24.s, z10.s\n" + ".inst 0xc082141d // mova z29.s, p5/M, za0h.s[x12]\n" + "fmax z31.s, p5/M, z31.s, z12.s\n" + "fmin z30.s, p5/M, z30.s, z10.s\n" + ".inst 0xc082343a // mova z26.s, p5/M, za0h.s[x13, #1]\n" + "fmin z29.s, p5/M, z29.s, z10.s\n" + "fmax z28.s, p5/M, z28.s, z12.s\n" + ".inst 0xc0821439 // mova z25.s, p5/M, za0h.s[x12, #1]\n" + "fmax z27.s, p5/M, z27.s, z12.s\n" + "fmin z26.s, p5/M, z26.s, z10.s\n" + ".inst 0xc0827457 // mova z23.s, p5/M, za0h.s[XZR, #2]\n" + "fmin z25.s, p5/M, z25.s, z10.s\n" + "fmax z24.s, p5/M, z24.s, z12.s\n" + ".inst 0xc0823456 // mova z22.s, p5/M, za0h.s[x13, #2]\n" + "fmax z30.s, p5/M, z30.s, z12.s\n" + "fmin z23.s, p5/M, z23.s, z10.s\n" + ".inst 0xc0821455 // mova z21.s, p5/M, za0h.s[x12, #2]\n" + "fmax z29.s, p5/M, z29.s, z12.s\n" + "fmin z22.s, p5/M, z22.s, z10.s\n" + ".inst 0xc0825454 // mova z20.s, p5/M, za0h.s[x14, #2]\n" + "fmax z26.s, p5/M, z26.s, z12.s\n" + "fmin z21.s, p5/M, z21.s, z10.s\n" + ".inst 0xc0827473 // mova z19.s, p5/M, za0h.s[XZR, #3]\n" + "fmax z25.s, p5/M, z25.s, z12.s\n" + "fmin z20.s, p5/M, z20.s, z10.s\n" + ".inst 0xc0823472 // mova z18.s, p5/M, za0h.s[x13, #3]\n" + "fmax z23.s, p5/M, z23.s, z12.s\n" + "fmin z19.s, p5/M, z19.s, z10.s\n" + ".inst 0xc0821471 // mova z17.s, p5/M, za0h.s[x12, #3]\n" + "fmax z22.s, p5/M, z22.s, z12.s\n" + "fmin z18.s, p5/M, z18.s, z10.s\n" + ".inst 0xc0825470 // mova z16.s, p5/M, za0h.s[x14, #3]\n" + "fmax z21.s, p5/M, z21.s, z12.s\n" + "fmin z17.s, p5/M, z17.s, z10.s\n" + "fmax z20.s, p5/M, z20.s, z12.s\n" + "fmin z16.s, p5/M, z16.s, z10.s\n" + "st1w { z31.s }, p0, [%x[output], x25, LSL #2]\n" + "fmax z19.s, p5/M, z19.s, z12.s\n" + "st1w { z30.s }, p0, [x20, x25, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "fmax z18.s, p5/M, z18.s, z12.s\n" + "st1w { z29.s }, p0, [x20, x25, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "fmax z17.s, p5/M, z17.s, z12.s\n" + "st1w { z28.s }, p0, [x20, x25, LSL #2]\n" + "add x20, x19, %x[output_col_stride], LSL #2\n" + "fmax z16.s, p5/M, z16.s, z12.s\n" + "st1w { z27.s }, p0, [x19, x25, LSL #2]\n" + "add x19, x19, %x[output_row_stride], LSL #2\n" + "st1w { z26.s }, p0, [x20, x25, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z25.s }, p0, [x20, x25, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z24.s }, p0, [x20, x25, LSL #2]\n" + "add x20, x19, %x[output_col_stride], LSL #2\n" + "st1w { z23.s }, p0, [x19, x25, LSL #2]\n" + "add x19, x19, %x[output_row_stride], LSL #2\n" + "st1w { z22.s }, p0, [x20, x25, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z21.s }, p0, [x20, x25, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z20.s }, p0, [x20, x25, LSL #2]\n" + "add x20, x19, %x[output_col_stride], LSL #2\n" + "st1w { z19.s }, p0, [x19, x25, LSL #2]\n" + "st1w { z18.s }, p0, [x20, x25, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z17.s }, p0, [x20, x25, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z16.s }, p0, [x20, x25, LSL #2]\n" + "whilelt p0.s, x24, %x[n_channels]\n" + "b.none 3f\n" + ".inst 0xc082749f // mova z31.s, p5/M, za1h.s[XZR]\n" + ".inst 0xc082349e // mova z30.s, p5/M, za1h.s[x13]\n" + "fmin z31.s, p5/M, z31.s, z10.s\n" + ".inst 0xc082149d // mova z29.s, p5/M, za1h.s[x12]\n" + "fmin z30.s, p5/M, z30.s, z10.s\n" + ".inst 0xc082549c // mova z28.s, p5/M, za1h.s[x14]\n" + "fmin z29.s, p5/M, z29.s, z10.s\n" + ".inst 0xc08274bb // mova z27.s, p5/M, za1h.s[XZR, #1]\n" + "fmin z28.s, p5/M, z28.s, z10.s\n" + ".inst 0xc08234ba // mova z26.s, p5/M, za1h.s[x13, #1]\n" + "fmax z31.s, p5/M, z31.s, z12.s\n" + "fmin z27.s, p5/M, z27.s, z10.s\n" + ".inst 0xc08214b9 // mova z25.s, p5/M, za1h.s[x12, #1]\n" + "fmax z30.s, p5/M, z30.s, z12.s\n" + "fmin z26.s, p5/M, z26.s, z10.s\n" + ".inst 0xc08254b8 // mova z24.s, p5/M, za1h.s[x14, #1]\n" + "fmax z29.s, p5/M, z29.s, z12.s\n" + "fmin z25.s, p5/M, z25.s, z10.s\n" + ".inst 0xc08274d7 // mova z23.s, p5/M, za1h.s[XZR, #2]\n" + "fmax z28.s, p5/M, z28.s, z12.s\n" + "fmin z24.s, p5/M, z24.s, z10.s\n" + ".inst 0xc08234d6 // mova z22.s, p5/M, za1h.s[x13, #2]\n" + "fmax z27.s, p5/M, z27.s, z12.s\n" + "fmin z23.s, p5/M, z23.s, z10.s\n" + ".inst 0xc08214d5 // mova z21.s, p5/M, za1h.s[x12, #2]\n" + "fmax z26.s, p5/M, z26.s, z12.s\n" + "fmin z22.s, p5/M, z22.s, z10.s\n" + "add x20, %x[output], %x[output_col_stride], LSL #2\n" + ".inst 0xc08254d4 // mova z20.s, p5/M, za1h.s[x14, #2]\n" + "fmax z25.s, p5/M, z25.s, z12.s\n" + "fmin z21.s, p5/M, z21.s, z10.s\n" + "add x19, %x[output], %x[output_row_stride], LSL #2\n" + ".inst 0xc08274f3 // mova z19.s, p5/M, za1h.s[XZR, #3]\n" + "fmax z24.s, p5/M, z24.s, z12.s\n" + "fmin z20.s, p5/M, z20.s, z10.s\n" + ".inst 0xc08234f2 // mova z18.s, p5/M, za1h.s[x13, #3]\n" + "fmax z23.s, p5/M, z23.s, z12.s\n" + "fmin z19.s, p5/M, z19.s, z10.s\n" + ".inst 0xc08214f1 // mova z17.s, p5/M, za1h.s[x12, #3]\n" + "fmax z22.s, p5/M, z22.s, z12.s\n" + "fmin z18.s, p5/M, z18.s, z10.s\n" + ".inst 0xc08254f0 // mova z16.s, p5/M, za1h.s[x14, #3]\n" + "fmax z21.s, p5/M, z21.s, z12.s\n" + "fmin z17.s, p5/M, z17.s, z10.s\n" + "fmax z20.s, p5/M, z20.s, z12.s\n" + "fmin z16.s, p5/M, z16.s, z10.s\n" + "st1w { z31.s }, p0, [%x[output], x24, LSL #2]\n" + "fmax z19.s, p5/M, z19.s, z12.s\n" + "st1w { z30.s }, p0, [x20, x24, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "fmax z18.s, p5/M, z18.s, z12.s\n" + "st1w { z29.s }, p0, [x20, x24, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "fmax z17.s, p5/M, z17.s, z12.s\n" + "st1w { z28.s }, p0, [x20, x24, LSL #2]\n" + "add x20, x19, %x[output_col_stride], LSL #2\n" + "fmax z16.s, p5/M, z16.s, z12.s\n" + "st1w { z27.s }, p0, [x19, x24, LSL #2]\n" + "add x19, x19, %x[output_row_stride], LSL #2\n" + "st1w { z26.s }, p0, [x20, x24, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z25.s }, p0, [x20, x24, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z24.s }, p0, [x20, x24, LSL #2]\n" + "add x20, x19, %x[output_col_stride], LSL #2\n" + "st1w { z23.s }, p0, [x19, x24, LSL #2]\n" + "add x19, x19, %x[output_row_stride], LSL #2\n" + "st1w { z22.s }, p0, [x20, x24, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z21.s }, p0, [x20, x24, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z20.s }, p0, [x20, x24, LSL #2]\n" + "add x20, x19, %x[output_col_stride], LSL #2\n" + "st1w { z19.s }, p0, [x19, x24, LSL #2]\n" + "st1w { z18.s }, p0, [x20, x24, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z17.s }, p0, [x20, x24, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z16.s }, p0, [x20, x24, LSL #2]\n" + "whilelt p0.s, x23, %x[n_channels]\n" + "b.none 3f\n" + ".inst 0xc082751f // mova z31.s, p5/M, za2h.s[XZR]\n" + ".inst 0xc082351e // mova z30.s, p5/M, za2h.s[x13]\n" + "fmin z31.s, p5/M, z31.s, z10.s\n" + ".inst 0xc082151d // mova z29.s, p5/M, za2h.s[x12]\n" + "fmin z30.s, p5/M, z30.s, z10.s\n" + ".inst 0xc082551c // mova z28.s, p5/M, za2h.s[x14]\n" + "fmin z29.s, p5/M, z29.s, z10.s\n" + ".inst 0xc082753b // mova z27.s, p5/M, za2h.s[XZR, #1]\n" + "fmin z28.s, p5/M, z28.s, z10.s\n" + ".inst 0xc082353a // mova z26.s, p5/M, za2h.s[x13, #1]\n" + "fmax z31.s, p5/M, z31.s, z12.s\n" + "fmin z27.s, p5/M, z27.s, z10.s\n" + ".inst 0xc0821539 // mova z25.s, p5/M, za2h.s[x12, #1]\n" + "fmax z30.s, p5/M, z30.s, z12.s\n" + "fmin z26.s, p5/M, z26.s, z10.s\n" + ".inst 0xc0825538 // mova z24.s, p5/M, za2h.s[x14, #1]\n" + "fmax z29.s, p5/M, z29.s, z12.s\n" + "fmin z25.s, p5/M, z25.s, z10.s\n" + ".inst 0xc0827557 // mova z23.s, p5/M, za2h.s[XZR, #2]\n" + "fmax z28.s, p5/M, z28.s, z12.s\n" + "fmin z24.s, p5/M, z24.s, z10.s\n" + ".inst 0xc0823556 // mova z22.s, p5/M, za2h.s[x13, #2]\n" + "fmax z27.s, p5/M, z27.s, z12.s\n" + "fmin z23.s, p5/M, z23.s, z10.s\n" + ".inst 0xc0821555 // mova z21.s, p5/M, za2h.s[x12, #2]\n" + "fmax z26.s, p5/M, z26.s, z12.s\n" + "fmin z22.s, p5/M, z22.s, z10.s\n" + "add x20, %x[output], %x[output_col_stride], LSL #2\n" + ".inst 0xc0825554 // mova z20.s, p5/M, za2h.s[x14, #2]\n" + "fmax z25.s, p5/M, z25.s, z12.s\n" + "fmin z21.s, p5/M, z21.s, z10.s\n" + "add x19, %x[output], %x[output_row_stride], LSL #2\n" + ".inst 0xc0827573 // mova z19.s, p5/M, za2h.s[XZR, #3]\n" + "fmax z24.s, p5/M, z24.s, z12.s\n" + "fmin z20.s, p5/M, z20.s, z10.s\n" + ".inst 0xc0823572 // mova z18.s, p5/M, za2h.s[x13, #3]\n" + "fmax z23.s, p5/M, z23.s, z12.s\n" + "fmin z19.s, p5/M, z19.s, z10.s\n" + ".inst 0xc0821571 // mova z17.s, p5/M, za2h.s[x12, #3]\n" + "fmax z22.s, p5/M, z22.s, z12.s\n" + "fmin z18.s, p5/M, z18.s, z10.s\n" + ".inst 0xc0825570 // mova z16.s, p5/M, za2h.s[x14, #3]\n" + "fmax z21.s, p5/M, z21.s, z12.s\n" + "fmin z17.s, p5/M, z17.s, z10.s\n" + "fmax z20.s, p5/M, z20.s, z12.s\n" + "fmin z16.s, p5/M, z16.s, z10.s\n" + "st1w { z31.s }, p0, [%x[output], x23, LSL #2]\n" + "fmax z19.s, p5/M, z19.s, z12.s\n" + "st1w { z30.s }, p0, [x20, x23, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "fmax z18.s, p5/M, z18.s, z12.s\n" + "st1w { z29.s }, p0, [x20, x23, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "fmax z17.s, p5/M, z17.s, z12.s\n" + "st1w { z28.s }, p0, [x20, x23, LSL #2]\n" + "add x20, x19, %x[output_col_stride], LSL #2\n" + "fmax z16.s, p5/M, z16.s, z12.s\n" + "st1w { z27.s }, p0, [x19, x23, LSL #2]\n" + "add x19, x19, %x[output_row_stride], LSL #2\n" + "st1w { z26.s }, p0, [x20, x23, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z25.s }, p0, [x20, x23, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z24.s }, p0, [x20, x23, LSL #2]\n" + "add x20, x19, %x[output_col_stride], LSL #2\n" + "st1w { z23.s }, p0, [x19, x23, LSL #2]\n" + "add x19, x19, %x[output_row_stride], LSL #2\n" + "st1w { z22.s }, p0, [x20, x23, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z21.s }, p0, [x20, x23, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z20.s }, p0, [x20, x23, LSL #2]\n" + "add x20, x19, %x[output_col_stride], LSL #2\n" + "st1w { z19.s }, p0, [x19, x23, LSL #2]\n" + "st1w { z18.s }, p0, [x20, x23, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z17.s }, p0, [x20, x23, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z16.s }, p0, [x20, x23, LSL #2]\n" + "whilelt p0.s, x22, %x[n_channels]\n" + "b.none 3f\n" + "fmov z1.s, #1.0\n" + ".inst 0xc082759f // mova z31.s, p5/M, za3h.s[XZR]\n" + ".inst 0xc082359e // mova z30.s, p5/M, za3h.s[x13]\n" + "fmin z31.s, p5/M, z31.s, z10.s\n" + ".inst 0xc082159d // mova z29.s, p5/M, za3h.s[x12]\n" + "fmin z30.s, p5/M, z30.s, z10.s\n" + ".inst 0xc082559c // mova z28.s, p5/M, za3h.s[x14]\n" + "fmin z29.s, p5/M, z29.s, z10.s\n" + ".inst 0xc08275bb // mova z27.s, p5/M, za3h.s[XZR, #1]\n" + "fmin z28.s, p5/M, z28.s, z10.s\n" + ".inst 0xc08235ba // mova z26.s, p5/M, za3h.s[x13, #1]\n" + "fmax z31.s, p5/M, z31.s, z12.s\n" + "fmin z27.s, p5/M, z27.s, z10.s\n" + ".inst 0xc08215b9 // mova z25.s, p5/M, za3h.s[x12, #1]\n" + "fmax z30.s, p5/M, z30.s, z12.s\n" + "fmin z26.s, p5/M, z26.s, z10.s\n" + ".inst 0xc08255b8 // mova z24.s, p5/M, za3h.s[x14, #1]\n" + "fmax z29.s, p5/M, z29.s, z12.s\n" + "fmin z25.s, p5/M, z25.s, z10.s\n" + ".inst 0xc08275d7 // mova z23.s, p5/M, za3h.s[XZR, #2]\n" + "fmax z28.s, p5/M, z28.s, z12.s\n" + "fmin z24.s, p5/M, z24.s, z10.s\n" + ".inst 0xc08235d6 // mova z22.s, p5/M, za3h.s[x13, #2]\n" + "fmax z27.s, p5/M, z27.s, z12.s\n" + "fmin z23.s, p5/M, z23.s, z10.s\n" + ".inst 0xc08215d5 // mova z21.s, p5/M, za3h.s[x12, #2]\n" + "fmax z26.s, p5/M, z26.s, z12.s\n" + "fmin z22.s, p5/M, z22.s, z10.s\n" + ".inst 0xc08255d4 // mova z20.s, p5/M, za3h.s[x14, #2]\n" + "fmax z25.s, p5/M, z25.s, z12.s\n" + "fmin z21.s, p5/M, z21.s, z10.s\n" + "add x20, %x[output], %x[output_col_stride], LSL #2\n" + ".inst 0xc08275f3 // mova z19.s, p5/M, za3h.s[XZR, #3]\n" + "fmax z24.s, p5/M, z24.s, z12.s\n" + "fmin z20.s, p5/M, z20.s, z10.s\n" + "add x19, %x[output], %x[output_row_stride], LSL #2\n" + ".inst 0xc08235f2 // mova z18.s, p5/M, za3h.s[x13, #3]\n" + "fmax z23.s, p5/M, z23.s, z12.s\n" + "fmin z19.s, p5/M, z19.s, z10.s\n" + "incw x25, ALL, MUL #4\n" + ".inst 0xc08215f1 // mova z17.s, p5/M, za3h.s[x12, #3]\n" + "fmax z22.s, p5/M, z22.s, z12.s\n" + "fmin z18.s, p5/M, z18.s, z10.s\n" + "incw x24, ALL, MUL #4\n" + ".inst 0xc08255f0 // mova z16.s, p5/M, za3h.s[x14, #3]\n" + "fmax z21.s, p5/M, z21.s, z12.s\n" + "fmin z17.s, p5/M, z17.s, z10.s\n" + "incw x23, ALL, MUL #4\n" + ".inst 0xc00800ff // zero { zad0, zad1, zad2, zad3, zad4, zad5, zad6, zad7 }\n" + "fmax z20.s, p5/M, z20.s, z12.s\n" + "fmin z16.s, p5/M, z16.s, z10.s\n" + "add x21, %x[inptr], %x[matrix_stride], LSL #2\n" + "fmax z19.s, p5/M, z19.s, z12.s\n" + "st1w { z31.s }, p0, [%x[output], x22, LSL #2]\n" + "fmax z18.s, p5/M, z18.s, z12.s\n" + "st1w { z30.s }, p0, [x20, x22, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "fmax z17.s, p5/M, z17.s, z12.s\n" + "st1w { z29.s }, p0, [x20, x22, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "fmax z16.s, p5/M, z16.s, z12.s\n" + "st1w { z28.s }, p0, [x20, x22, LSL #2]\n" + "add x20, x19, %x[output_col_stride], LSL #2\n" + "st1w { z27.s }, p0, [x19, x22, LSL #2]\n" + "add x19, x19, %x[output_row_stride], LSL #2\n" + "st1w { z26.s }, p0, [x20, x22, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z25.s }, p0, [x20, x22, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z24.s }, p0, [x20, x22, LSL #2]\n" + "add x20, x19, %x[output_col_stride], LSL #2\n" + "st1w { z23.s }, p0, [x19, x22, LSL #2]\n" + "add x19, x19, %x[output_row_stride], LSL #2\n" + "st1w { z22.s }, p0, [x20, x22, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z21.s }, p0, [x20, x22, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z20.s }, p0, [x20, x22, LSL #2]\n" + "add x20, x19, %x[output_col_stride], LSL #2\n" + "st1w { z19.s }, p0, [x19, x22, LSL #2]\n" + "st1w { z18.s }, p0, [x20, x22, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z17.s }, p0, [x20, x22, LSL #2]\n" + "add x20, x20, %x[output_col_stride], LSL #2\n" + "st1w { z16.s }, p0, [x20, x22, LSL #2]\n" + "incw x22, ALL, MUL #4\n" + "whilelt p1.s, x22, %x[n_channels]\n" + "ld1w { z28.s }, p1/Z, [%x[inptr], x22, LSL #2]\n" + "ld1w { z24.s }, p1/Z, [x21, x22, LSL #2]\n" + "whilelt p2.s, x23, %x[n_channels]\n" + "whilelt p3.s, x24, %x[n_channels]\n" + "ld1w { z30.s }, p3/Z, [%x[inptr], x24, LSL #2]\n" + "whilelt p4.s, x25, %x[n_channels]\n" + "ld1w { z31.s }, p4/Z, [%x[inptr], x25, LSL #2]\n" + "and p0.b, p5/Z, p8.b, p4.b\n" + "ld1w { z29.s }, p2/Z, [%x[inptr], x23, LSL #2]\n" + "ld1w { z27.s }, p4/Z, [x21, x25, LSL #2]\n" + "ld1w { z26.s }, p3/Z, [x21, x24, LSL #2]\n" + "ld1w { z25.s }, p2/Z, [x21, x23, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + "ld1w { z23.s }, p4/Z, [x21, x25, LSL #2]\n" + "ld1w { z22.s }, p3/Z, [x21, x24, LSL #2]\n" + "ld1w { z21.s }, p2/Z, [x21, x23, LSL #2]\n" + "ld1w { z20.s }, p1/Z, [x21, x22, LSL #2]\n" + "add x21, x21, %x[matrix_stride], LSL #2\n" + "ld1w { z19.s }, p4/Z, [x21, x25, LSL #2]\n" + "ld1w { z18.s }, p3/Z, [x21, x24, LSL #2]\n" + "ld1w { z17.s }, p2/Z, [x21, x23, LSL #2]\n" + "ld1w { z16.s }, p1/Z, [x21, x22, LSL #2]\n" + "ld1w { z0.s }, p0/Z, [%x[bptr], x25, LSL #2]\n" + "and p0.b, p5/Z, p8.b, p3.b\n" + ".inst 0x8080b420 // fmopa za0.s, p5/M, p5/M, z1.s, z0.s\n" + "ld1w { z0.s }, p0/Z, [%x[bptr], x24, LSL #2]\n" + "and p0.b, p5/Z, p8.b, p2.b\n" + ".inst 0x8080b421 // fmopa za1.s, p5/M, p5/M, z1.s, z0.s\n" + "ld1w { z0.s }, p0/Z, [%x[bptr], x23, LSL #2]\n" + "and p0.b, p5/Z, p8.b, p1.b\n" + ".inst 0x8080b422 // fmopa za2.s, p5/M, p5/M, z1.s, z0.s\n" + "ld1w { z0.s }, p0/Z, [%x[bptr], x22, LSL #2]\n" + ".inst 0x8080b423 // fmopa za3.s, p5/M, p5/M, z1.s, z0.s\n" + "b.any 2b\n" + "3:" // End + ".inst 0xd503467f // SMSTOP\n" + : + : [bptr] "r" (bptr), [inptr] "r" (inptr), [matrix_stride] "r" (matrix_stride), [n_channels] "r" (n_channels), [offsetof_Params_act_max] "I" (offsetof(Params, act_max)), [offsetof_Params_act_min] "I" (offsetof(Params, act_min)), [offsetof_Params_inner_terms] "I" (offsetof(Params, inner_terms)), [offsetof_Params_outer_terms] "I" (offsetof(Params, outer_terms)), [output] "r" (output), [output_col_stride] "r" (output_col_stride), [output_row_stride] "r" (output_row_stride), [params] "r" (¶ms) + : "cc", "memory", "p0", "p1", "p2", "p3", "p4", "p5", "p8", "x12", "x13", "x14", "x19", "x20", "x21", "x22", "x23", "x24", "x25", "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10", "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21", "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31" + ); +} + +} // namespace output_transform +} // namespace winograd +} // namespace arm_conv + +#endif //defined(__aarch64__) && defined(ARM_COMPUTE_ENABLE_SVE) && defined(ARM_COMPUTE_ENABLE_SME) + diff --git a/src/core/NEON/kernels/convolution/winograd/output_transforms_fp32.cpp b/src/core/NEON/kernels/convolution/winograd/output_transforms_fp32.cpp index 73abe8b945..a221aee5d8 100644 --- a/src/core/NEON/kernels/convolution/winograd/output_transforms_fp32.cpp +++ b/src/core/NEON/kernels/convolution/winograd/output_transforms_fp32.cpp @@ -29,6 +29,11 @@ namespace arm_conv { namespace winograd { namespace output_transform { +#if defined(__aarch64__) +#if defined(ARM_COMPUTE_ENABLE_SVE) && defined(ARM_COMPUTE_ENABLE_SME) +void sme_fp32_mopa_4x4_3x3(unsigned int, const float *, size_t, const float *, float *, size_t, size_t, float, float); +#endif // defined(ARM_COMPUTE_ENABLE_SVE) && defined(ARM_COMPUTE_ENABLE_SME) +#endif // defined(__aarch64__) void arm_fp32_4x4_3x3(unsigned int, const float *, size_t, const float *, float *, size_t, size_t, float, float); void arm_fp32_2x2_3x3(unsigned int, const float *, size_t, const float *, float *, size_t, size_t, float, float); void arm_fp32_2x2_5x5(unsigned int, const float *, size_t, const float *, float *, size_t, size_t, float, float); @@ -44,6 +49,9 @@ void arm_fp32_1x2_1x7(unsigned int, const float *, size_t, const float *, float static const TransformImplementation transforms_fp32[] = { #if defined(__aarch64__) +#if defined(ARM_COMPUTE_ENABLE_SVE) && defined(ARM_COMPUTE_ENABLE_SME) + { IMPL(4, 4, 3, 3, sme_fp32_mopa_4x4_3x3, Unpadded), MethodConstraints::RequiresSME }, +#endif // defined(ARM_COMPUTE_ENABLE_SVE) && defined(ARM_COMPUTE_ENABLE_SME) #endif // defined(__aarch64__) { IMPL(4, 4, 3, 3, arm_fp32_4x4_3x3, Unpadded), MethodConstraints::LargerShape }, { IMPL(2, 2, 3, 3, arm_fp32_2x2_3x3, Unpadded) }, -- cgit v1.2.1