/*
 * Copyright 2024 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Convolution based on Kelvin ops
// Data types: input: s8, filter: s8, bias: s32

#include "tflm/opt/conv_s8.h"

#include <algorithm>

#include "tensorflow/lite/kernels/internal/reference/integer_ops/conv.h"
#include "tflm/opt/conv_util.h"

namespace kelvin::opt {
namespace {
void ConvS8Generic(
    const tflite::ConvParams& params, const int32_t* output_multiplier,
    const int32_t* output_shift, const tflite::RuntimeShape& input_shape,
    const int8_t* input_data, const tflite::RuntimeShape& filter_shape,
    const int8_t* filter_data, const tflite::RuntimeShape& bias_shape,
    const int32_t* bias_data, const tflite::RuntimeShape& output_shape,
    int8_t* output_data) {
  const auto batches = MatchingDim(input_shape, 0, output_shape, 0);
  const auto stride_width = params.stride_width;
  const auto stride_height = params.stride_height;
  const auto dilation_width_factor = params.dilation_width_factor;
  const auto dilation_height_factor = params.dilation_height_factor;
  const auto pad_width = params.padding_values.width;
  const auto pad_height = params.padding_values.height;
  const auto input_height = input_shape.Dims(1);
  const auto input_width = input_shape.Dims(2);
  const auto input_depth = input_shape.Dims(3);
  const auto input_offset = params.input_offset;
  const auto filter_height = filter_shape.Dims(1);
  const auto filter_width = filter_shape.Dims(2);
  const auto filter_depth = filter_shape.Dims(3);
  const auto output_height = output_shape.Dims(1);
  const auto output_width = output_shape.Dims(2);
  const auto output_depth = output_shape.Dims(3);
  const auto output_offset = params.output_offset;
  const auto output_activation_min = params.quantized_activation_min;
  const auto output_activation_max = params.quantized_activation_max;
  const auto groups = input_depth / filter_depth;
  const auto filters_per_group = output_depth / groups;

  if (pad_width > 0 || pad_height > 0 || dilation_width_factor > 1 ||
      dilation_height_factor > 1) {
    // use reference implementation
    tflite::reference_integer_ops::ConvPerChannel(
        params, output_multiplier, output_shift, input_shape, input_data,
        filter_shape, filter_data, bias_shape, bias_data, output_shape,
        output_data);
    return;
  }

  union {
    vconv_u8_t conv;
    uint32_t raw;
  } cmds;
  cmds.conv.mode = 0;
  cmds.conv.start = 0;
  cmds.conv.stop = 7;
  cmds.conv.sbias1 = input_offset;
  cmds.conv.sdata1 = true;
  cmds.conv.sbias2 = 0;
  cmds.conv.sdata2 = true;

  // Zero out accumulators.
  vdup_b_x(v0, 0);
  acset_v(ACC, v0);
  vdup_b_x_m(ACC0, 0);
  for (int batch = 0; batch < batches; ++batch) {
    for (int out_y = 0; out_y < output_height; ++out_y) {
      const int in_y_origin = (out_y * stride_height) - pad_height;
      for (int out_x = 0; out_x < output_width; /*out_x += 32*/ ++out_x) {
        const int in_x_origin = (out_x * stride_width) - pad_width;
        for (int out_channel = 0; out_channel < output_depth; ++out_channel) {
          auto group = out_channel / filters_per_group;

          for (int filter_y = 0; filter_y < filter_height; ++filter_y) {
            const int in_y = in_y_origin + dilation_height_factor * filter_y;
            const int in_x = in_x_origin + dilation_width_factor * 0;

            // Zero padding by omitting the areas outside the image.
            const bool is_point_inside_image =
                (in_x >= 0) && (in_x < input_width) && (in_y >= 0) &&
                (in_y < input_height);
            if (!is_point_inside_image) {
              continue;
            }

            int q = filter_width * filter_depth;
            for (int i = 0; i < q; i += 32) {
              int count = std::min(q - i, 32);
              count = std::min(
                  count, static_cast<int>((input_width - in_x) * filter_depth));
              int input_offset = tflite::Offset(input_shape, batch, in_y, in_x,
                                                group * filter_depth) +
                                 i;
              vdup_w_x_m(vm0, 0);
              vdup_w_x_m(vm1, 0);
              vld_b_l_xx(INA0, &input_data[input_offset], count);
              int filter_offset =
                  tflite::Offset(filter_shape, out_channel, filter_y, 0, 0) + i;
              vdup_w_x_m(FLTA0, 0);
              vdup_w_x_m(FLTA4, 0);
              if (count > 0) {
                vld_b_l_xx(FLTA0, &filter_data[filter_offset],
                           std::min(count, 4));
              }
              if (count > 4) {
                vld_b_l_xx(FLTA1, &filter_data[filter_offset + 4],
                           std::min(count - 4, 4));
              }
              if (count > 8) {
                vld_b_l_xx(FLTA2, &filter_data[filter_offset + 8],
                           std::min(count - 8, 4));
              }
              if (count > 12) {
                vld_b_l_xx(FLTA3, &filter_data[filter_offset + 12],
                           std::min(count - 12, 4));
              }
              if (count > 16) {
                vld_b_l_xx(FLTA4, &filter_data[filter_offset + 16],
                           std::min(count - 16, 4));
              }
              if (count > 20) {
                vld_b_l_xx(FLTA5, &filter_data[filter_offset + 20],
                           std::min(count - 20, 4));
              }
              if (count > 24) {
                vld_b_l_xx(FLTA6, &filter_data[filter_offset + 24],
                           std::min(count - 24, 4));
              }
              if (count > 28) {
                vld_b_l_xx(FLTA7, &filter_data[filter_offset + 28],
                           std::min(count - 28, 4));
              }
              aconv_vxv(ACC, INA0, cmds, FLTA0);
            }
          }
          vcget(ACC);
          vadd_w_vx_m(ACC0, ACC0, bias_data[out_channel]);
          vsll_w_vx_m(ACC0, ACC0, LEFT_SHIFT(output_shift[out_channel]));
          vdmulh_w_r_vx_m(ACC0, ACC0, output_multiplier[out_channel]);
          vsha_w_r_vx_m(ACC0, ACC0, RIGHT_SHIFT(output_shift[out_channel]));
          vadd_w_vx_m(ACC0, ACC0, output_offset);
          vmin_w_vx_m(ACC0, ACC0, output_activation_max);
          vmax_w_vx_m(ACC0, ACC0, output_activation_min);
          vsraqs_b_vx(OUT0, ACC0, 0);
          size_t output_offset =
              tflite::Offset(output_shape, batch, out_y, out_x, out_channel);
          vst_b_l_xx(OUT0, &output_data[output_offset], 1);
        }
      }
    }
  }
}
}  // namespace

void ConvS8(const tflite::ConvParams& params, const int32_t* output_multiplier,
            const int32_t* output_shift,
            const tflite::RuntimeShape& input_shape, const int8_t* input_data,
            const tflite::RuntimeShape& filter_shape, const int8_t* filter_data,
            const tflite::RuntimeShape& bias_shape, const int32_t* bias_data,
            const tflite::RuntimeShape& output_shape, int8_t* output_data) {
  const auto batches = MatchingDim(input_shape, 0, output_shape, 0);
  const auto stride_width = params.stride_width;
  const auto stride_height = params.stride_height;
  const auto dilation_width_factor = params.dilation_width_factor;
  const auto dilation_height_factor = params.dilation_height_factor;
  const auto pad_width = params.padding_values.width;
  const auto pad_height = params.padding_values.height;
  const auto input_height = input_shape.Dims(1);
  const auto input_width = input_shape.Dims(2);
  const auto input_depth = input_shape.Dims(3);
  const auto filter_height = filter_shape.Dims(1);
  const auto filter_width = filter_shape.Dims(2);
  const auto filter_depth = filter_shape.Dims(3);
  const auto output_height = output_shape.Dims(1);
  const auto output_width = output_shape.Dims(2);
  const auto output_depth = output_shape.Dims(3);

#define RUN_KERNEL(kernel) {\
  kernel(\
      params, output_multiplier, output_shift, input_shape, input_data,\
      filter_shape, filter_data, bias_shape, bias_data, output_shape,\
      output_data);\
  return; \
}

  if (dilation_width_factor == 1 && dilation_height_factor == 1 &&
      stride_width == 2 && stride_height == 2 && filter_depth == 3 &&
      input_depth == 3 && output_depth % 8 == 0 && output_width % 4 == 0 &&
      output_height % 2 == 0 && pad_height == 0 && pad_width == 0) {
    RUN_KERNEL(kelvin::opt::ConvS8I3xD8);
  }

  // special case of filter size 1x1
  if (filter_height == 1 && filter_width == 1 && stride_height == 1 &&
      stride_width == 1 && dilation_height_factor == 1 &&
      dilation_width_factor == 1 && pad_height == 0 && pad_width == 0 &&
      (input_depth == filter_depth)) {
    if ((input_depth == 32) && (batches * input_height * input_width) >= 4) {
      RUN_KERNEL(kelvin::opt::ConvS8K1x1D32);
    }

    if ((output_depth % 8) == 0 && (input_depth % 32) == 0) {
      RUN_KERNEL(kelvin::opt::ConvS8K1x1DMod32);
    }

    // TODO: Relax this kernel for all output_depths
    if ((output_depth < 8) && (input_depth % 32) == 0) {
      RUN_KERNEL(kelvin::opt::ConvS8K1x1DMod32);
    }

    if ((output_depth % 16) == 0 && (input_depth == 16)) {
      RUN_KERNEL(kelvin::opt::ConvS8K1x1D16);
    }
  }

  if (input_depth == 1 && filter_width == 5 && filter_height == 5 &&
      stride_width == 2 && dilation_width_factor == 1 && output_depth == 24 &&
      params.quantized_activation_min == -128 &&
      params.quantized_activation_max == 127 &&
      // Special limitations of the implementation.
      pad_height < 5 && pad_width < 5 &&
      (output_height - 1) * stride_height - pad_height < input_height &&
      (output_width - 1) * stride_width - pad_width < input_width &&
      input_width >= 19) {
    RUN_KERNEL(kelvin::opt::ConvPerChannelD1OD24_5x5);
  }

  // special case of filter_depth = 4n, stride 2 and min width
  if (dilation_width_factor == 1 && dilation_height_factor == 1 &&
      stride_width == 2 && stride_height == 2 && filter_depth % 4 == 0 &&
      output_depth >= 8 && output_width >= 8 && pad_width <= 1) {
    RUN_KERNEL(kelvin::opt::ConvS8W8D4);
  }

  // special case of filter_depth = 4n
  if (dilation_width_factor == 1 && dilation_height_factor == 1 &&
      stride_width <= 2 && stride_height <= 2 && filter_depth % 4 == 0 &&
      output_depth >= 8 && output_width >= 8 && pad_width <= 1) {
    RUN_KERNEL(kelvin::opt::ConvS8D4);
  }

  // special case of filter depth = 32n
  if (dilation_width_factor == 1 && dilation_height_factor == 1 &&
      stride_width <= 2 && stride_height <= 2 && filter_depth % 32 == 0) {
    RUN_KERNEL(kelvin::opt::ConvS8D32);
  }

  // special case of filter size 48x3x1x48
  if (batches == 1 && filter_height == 3 && filter_width == 1 &&
      input_width == 1 && input_depth == 48 && output_depth == 48 &&
      stride_height == 1 && stride_width == 1 && dilation_height_factor == 1 &&
      dilation_width_factor == 1 && pad_height == 0 && pad_width == 0) {
    RUN_KERNEL(kelvin::opt::ConvS8K3x1D48);
  }

  if (input_depth == 1 && ((output_depth % 4) == 0)) {
    RUN_KERNEL(kelvin::opt::ConvPerChannelD1);
  }

  RUN_KERNEL(ConvS8Generic);
}

}  // namespace kelvin::opt
