// Copyright 2021 Google LLC
//
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree.

$assert REQUANTIZATION == "FP32"
$assert VARIANT in ["FMAGIC", "IMAGIC", "LRINTF"]
$assert DATATYPE in ["QC8", "QS8", "QU8"]
#include <assert.h>
$if VARIANT == "LRINTF":
  #include <math.h>

#include <xnnpack/math.h>
#include <xnnpack/gemm.h>
$if NR % 4 != 0:
  #include <xnnpack/unaligned.h>


$PARAMS_STRUCT = REQUANTIZATION.lower() + "_scalar" + ("_" + VARIANT.lower() if VARIANT else "")
$PARAMS_UNION = "xnn_%s_conv_minmax_params" % DATATYPE.lower()
$XINT8_T = "uint8_t" if DATATYPE == "QU8" else "int8_t"
$MIN_F32 = "__builtin_wasm_min_f32" if WASM else "math_min_f32"
$MAX_F32 = "__builtin_wasm_max_f32" if WASM else "math_max_f32"
void xnn_${DATATYPE.lower()}_igemm_minmax_${REQUANTIZATION.lower()}_ukernel_${MR}x${NR}__${"wasm" if WASM else "scalar"}_${VARIANT.lower()}(
    size_t mr,
    size_t nc,
    size_t kc,
    size_t ks,
    const ${XINT8_T}**restrict a,
    const void*restrict w,
    ${XINT8_T}*restrict c,
    size_t cm_stride,
    size_t cn_stride,
    size_t a_offset,
    const ${XINT8_T}* zero,
    const union ${PARAMS_UNION} params[restrict XNN_MIN_ELEMENTS(1)])
{
  assert(mr != 0);
  assert(mr <= ${MR});
  assert(nc != 0);
  assert(kc != 0);
  assert(ks != 0);
  assert(ks % (${MR} * sizeof(void*)) == 0);
  assert(a != NULL);
  assert(w != NULL);
  assert(c != NULL);

  ${XINT8_T}* c0 = c;
  $for M in range(1, MR):
    ${XINT8_T}* c${M} = (${XINT8_T}*) ((uintptr_t) c${M-1} + cm_stride);
    $if M % 2 == 0:
      if XNN_UNPREDICTABLE(mr <= ${M}) {
        c${M} = c${M-1};
      }
    $elif M + 1 == MR:
      if XNN_UNPREDICTABLE(mr != ${M+1}) {
        c${M} = c${M-1};
      }
    $else:
      if XNN_UNPREDICTABLE(mr < ${M+1}) {
        c${M} = c${M-1};
      }

  $if DATATYPE == "QU8":
    const int32_t vb_zero_point = params->${PARAMS_STRUCT}.kernel_zero_point;
  do {
    $if NR % 4 != 0:
      $for N in range(NR):
        int32_t vacc0x${N} = unaligned_indexed_load_s32(w, ${N});
    $else:
      $for N in range(NR):
        int32_t vacc0x${N} = ((const int32_t*) w)[${N}];
    $for M in range(1, MR):
      $for N in range(NR):
        int32_t vacc${M}x${N} = vacc0x${N};
    w = (const void*) ((const int32_t*) w + ${NR});

    size_t p = ks;
    do {
      $for M in range(MR):
        const ${XINT8_T}* restrict a${M} = a[${M}];
        assert(a${M} != NULL);
        if XNN_UNPREDICTABLE(a${M} != zero) {
          a${M} = (const ${XINT8_T}*) ((uintptr_t) a${M} + a_offset);
        }
      a += ${MR};

      size_t k = kc;
      do {
        $for M in range(MR):
          $if DATATYPE == "QU8":
            const int32_t va${M} = (int32_t) (uint32_t) *a${M}++;
          $else:
            const int32_t va${M} = (int32_t) *a${M}++;

        $for N in range(NR):
          $if DATATYPE == "QU8":
            const int32_t vb${N} = (int32_t) (uint32_t) ((const uint8_t*) w)[${N}] - vb_zero_point;
          $else:
            const int32_t vb${N} = (int32_t) ((const int8_t*) w)[${N}];
        w = (const void*) ((const ${XINT8_T}*) w + ${NR});

        $for M in range(MR):
          $for N in range(NR):
            vacc${M}x${N} += va${M} * vb${N};

        k -= sizeof(${XINT8_T});
      } while (k != 0);
      p -= ${MR} * sizeof(void*);
    } while (p != 0);

    $for M in range(MR):
      $for N in range(NR):
        float vfpacc${M}x${N} = (float) vacc${M}x${N};

    $if DATATYPE == "QC8":
      $if NR % 4 != 0:
        $for N in range(NR):
          const float vscale${N} = unaligned_indexed_load_f32(w, ${N});
          $for M in range(MR):
            vfpacc${M}x${N} *= vscale${N};
      $else:
        $for N in range(NR):
          const float vscale${N} = ((const float*) w)[${N}];
          $for M in range(MR):
            vfpacc${M}x${N} *= vscale${N};
      w = (const void*) ((const float*) w + ${NR});
    $else:
      const float vscale = params->${PARAMS_STRUCT}.scale;
      $for M in range(MR):
        $for N in range(NR):
          vfpacc${M}x${N} *= vscale;

    $if VARIANT == "FMAGIC":
      const float voutput_min_less_zero_point = params->${PARAMS_STRUCT}.output_min_less_zero_point;
      $for M in range(MR):
        $for N in range(NR):
          vfpacc${M}x${N} = ${MAX_F32}(vfpacc${M}x${N}, voutput_min_less_zero_point);

      const float voutput_max_less_zero_point = params->${PARAMS_STRUCT}.output_max_less_zero_point;
      $for M in range(MR):
        $for N in range(NR):
          vfpacc${M}x${N} = ${MIN_F32}(vfpacc${M}x${N}, voutput_max_less_zero_point);

      const float vmagic_bias = params->${PARAMS_STRUCT}.magic_bias;
      $for M in range(MR):
        $for N in range(NR):
          vfpacc${M}x${N} += vmagic_bias;

      const int32_t vmagic_bias_less_output_zero_point = params->${PARAMS_STRUCT}.magic_bias_less_output_zero_point;
      $for M in range(MR):
        $for N in range(NR):
          int32_t vout${M}x${N} = (int32_t) float_as_uint32(vfpacc${M}x${N}) - vmagic_bias_less_output_zero_point;
    $elif VARIANT == "IMAGIC":
      const float vmagic_bias = params->${PARAMS_STRUCT}.magic_bias;
      $for M in range(MR):
        $for N in range(NR):
          vfpacc${M}x${N} += vmagic_bias;

      $for M in range(MR):
        $for N in range(NR):
          int32_t vout${M}x${N} = (int32_t) float_as_uint32(vfpacc${M}x${N});

      const int32_t vmagic_min = params->${PARAMS_STRUCT}.magic_min;
      $for M in range(MR):
        $for N in range(NR):
          vout${M}x${N} = math_max_s32(vout${M}x${N}, vmagic_min);

      const int32_t vmagic_max = params->${PARAMS_STRUCT}.magic_max;
      $for M in range(MR):
        $for N in range(NR):
          vout${M}x${N} = math_min_s32(vout${M}x${N}, vmagic_max);

      const int32_t vmagic_bias_less_zero_point = params->${PARAMS_STRUCT}.magic_bias_less_zero_point;
      $for M in range(MR):
        $for N in range(NR):
          vout${M}x${N} -= vmagic_bias_less_zero_point;
    $elif VARIANT == "LRINTF":
      const float voutput_min_less_zero_point = params->${PARAMS_STRUCT}.output_min_less_zero_point;
      $for M in range(MR):
        $for N in range(NR):
          vfpacc${M}x${N} = ${MAX_F32}(vfpacc${M}x${N}, voutput_min_less_zero_point);

      const float voutput_max_less_zero_point = params->${PARAMS_STRUCT}.output_max_less_zero_point;
      $for M in range(MR):
        $for N in range(NR):
          vfpacc${M}x${N} = ${MIN_F32}(vfpacc${M}x${N}, voutput_max_less_zero_point);

      $for M in range(MR):
        $for N in range(NR):
          const int32_t vrndacc${M}x${N} = (int32_t) lrintf(vfpacc${M}x${N});

      const int32_t voutput_zero_point = params->${PARAMS_STRUCT}.output_zero_point;
      $for M in range(MR):
        $for N in range(NR):
          int32_t vout${M}x${N} = vrndacc${M}x${N} + voutput_zero_point;

    if XNN_LIKELY(nc >= ${NR}) {
      $for M in reversed(range(MR)):
        $for N in range(NR):
          c${M}[${N}] = (${XINT8_T}) vout${M}x${N};

      $for M in reversed(range(MR)):
        c${M} = (${XINT8_T}*) ((uintptr_t) c${M} + cn_stride);

      a = (const ${XINT8_T}**restrict) ((uintptr_t) a - ks);
      nc -= ${NR};
    } else {
      $for LOG2N in reversed(range(NR.bit_length() - 1)):
        if (nc & ${1 << LOG2N}) {
          $for M in reversed(range(MR)):
            $for N in range(1 << LOG2N):
              c${M}[${N}] = (${XINT8_T}) vout${M}x${N};
            $if LOG2N != 0:
              $for N in range(1 << (LOG2N - 1)):
                vout${M}x${N} = vout${M}x${N + (1 << LOG2N)};
              c${M} += ${1 << LOG2N};
        }

      nc = 0;
    }
  } while (nc != 0);
}
