// 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.

#include <assert.h>
#include <math.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>

#include <xnnpack.h>
#include <xnnpack/allocator.h>
#include <xnnpack/operator.h>
#include <xnnpack/log.h>


typedef float (*xnn_lut_init_fn)(float, const void*);

static enum xnn_status create_lut_elementwise_nc(
    size_t channels,
    size_t input_stride,
    size_t output_stride,
    int32_t input_zero_point,
    float input_scale,
    long output_zero_point,
    float output_scale,
    long output_min,
    long output_max,
    uint32_t flags,
    xnn_lut_init_fn init_fn,
    const void* init_params,
    enum xnn_operator_type operator_type,
    xnn_operator_t* lut_elementwise_op_out)
{
  xnn_operator_t lut_elementwise_op = NULL;
  enum xnn_status status = xnn_status_uninitialized;

  if ((xnn_params.init_flags & XNN_INIT_FLAG_XNNPACK) == 0) {
    xnn_log_error("failed to create %s operator: XNNPACK is not initialized",
      xnn_operator_type_to_string(operator_type));
    goto error;
  }

  status = xnn_status_invalid_parameter;

  if (channels == 0) {
    xnn_log_error(
      "failed to create %s operator with %zu channels: number of channels must be non-zero",
      xnn_operator_type_to_string(operator_type), channels);
    goto error;
  }

  if (input_stride < channels) {
    xnn_log_error(
      "failed to create %s operator with input element stride of %zu: "
      "stride must be at least as large as the number of channels (%zu)",
      xnn_operator_type_to_string(operator_type), input_stride, channels);
    goto error;
  }

  if (output_stride < channels) {
    xnn_log_error(
      "failed to create %s operator with output element stride of %zu: "
      "stride must be at least as large as the number of channels (%zu)",
      xnn_operator_type_to_string(operator_type), output_stride, channels);
    goto error;
  }

  if (input_scale <= 0.0f || !isnormal(input_scale)) {
    xnn_log_error(
      "failed to create %s operator with %.7g input scale: scale must be finite, normalized, and positive",
      xnn_operator_type_to_string(operator_type), input_scale);
    goto error;
  }

  if (output_scale <= 0.0f || !isnormal(output_scale)) {
    xnn_log_error(
      "failed to create %s operator with %.7g output scale: scale must be finite, normalized, and positive",
      xnn_operator_type_to_string(operator_type), output_scale);
    goto error;
  }

  if (output_min >= output_max) {
    xnn_log_error(
      "failed to create %s operator with [%ld, %ld] output range: range min must be below range max",
      xnn_operator_type_to_string(operator_type), output_min, output_max);
    goto error;
  }

  status = xnn_status_out_of_memory;

  lut_elementwise_op = xnn_allocate_zero_simd_memory(sizeof(struct xnn_operator));
  if (lut_elementwise_op == NULL) {
    xnn_log_error(
      "failed to allocate %zu bytes for %s operator descriptor",
      sizeof(struct xnn_operator), xnn_operator_type_to_string(operator_type));
    goto error;
  }

  lut_elementwise_op->lookup_table = xnn_allocate_simd_memory(256 * sizeof(uint8_t));
  if (lut_elementwise_op->lookup_table == NULL) {
    xnn_log_error(
      "failed to allocate 256 bytes for %s operator lookup table",
      xnn_operator_type_to_string(operator_type));
    goto error;
  }

  uint8_t* lookup_table = lut_elementwise_op->lookup_table;
  const float inv_output_scale = 1.0f / output_scale;
  for (int32_t i = 0; i < 256; i++) {
    const float dequantized_input = (i - input_zero_point) * input_scale;
    const float dequantized_output = init_fn(dequantized_input, init_params);
    long quantized_output = lrintf(dequantized_output * inv_output_scale) + output_zero_point;
    quantized_output = XNN_UNPREDICTABLE(quantized_output < output_min) ? output_min : quantized_output;
    quantized_output = XNN_UNPREDICTABLE(quantized_output > output_max) ? output_max : quantized_output;
    lookup_table[i] = (uint8_t) quantized_output;
  }

  lut_elementwise_op->channels = channels;
  lut_elementwise_op->input_pixel_stride = input_stride;
  lut_elementwise_op->output_pixel_stride = output_stride;

  lut_elementwise_op->type = operator_type;
  lut_elementwise_op->flags = flags;

  lut_elementwise_op->state = xnn_run_state_invalid;

  *lut_elementwise_op_out = lut_elementwise_op;
  return xnn_status_success;

error:
  xnn_delete_operator(lut_elementwise_op);
  return status;
}

static float calculate_leaky_relu(float x, const float* negative_slope_ptr) {
  const float negative_slope = *negative_slope_ptr;
  return signbit(x) ? x * negative_slope : x;
}

enum xnn_status xnn_create_leaky_relu_nc_qu8(
    size_t channels,
    size_t input_stride,
    size_t output_stride,
    float negative_slope,
    uint8_t input_zero_point,
    float input_scale,
    uint8_t output_zero_point,
    float output_scale,
    uint8_t output_min,
    uint8_t output_max,
    uint32_t flags,
    xnn_operator_t* leaky_relu_op_out)
{
  if (negative_slope <= 0.0f || !isnormal(negative_slope)) {
    xnn_log_error(
      "failed to create %s operator with %.7g negative slope: slope must be finite, normalized, and positive",
      xnn_operator_type_to_string(xnn_operator_type_leaky_relu_nc_qu8), negative_slope);
    return xnn_status_invalid_parameter;
  }

  if (negative_slope > 1.0f) {
    xnn_log_error(
      "failed to create %s operator with %.7g negative slope: slope must not exceed 1.0",
      xnn_operator_type_to_string(xnn_operator_type_leaky_relu_nc_qu8), negative_slope);
    return xnn_status_invalid_parameter;
  }

  const float input_output_scale = input_scale / output_scale;
  if (input_output_scale < 0x1.0p-8f || input_output_scale >= 0x1.0p+8f) {
    xnn_log_error(
      "failed to create %s operator with %.7g input-to-output scale ratio: "
      "scale ratio must be in [2**-8, 2**8) range",
      xnn_operator_type_to_string(xnn_operator_type_leaky_relu_nc_qu8), input_output_scale);
    return xnn_status_unsupported_parameter;
  }

  return create_lut_elementwise_nc(
    channels, input_stride, output_stride,
    (int32_t) (uint32_t) input_zero_point, input_scale,
    (long) (unsigned long) output_zero_point, output_scale,
    (long) (unsigned long) output_min, (long) (unsigned long) output_max,
    flags,
    (xnn_lut_init_fn) &calculate_leaky_relu, &negative_slope,
    xnn_operator_type_leaky_relu_nc_qu8, leaky_relu_op_out);
}

static float calculate_sigmoid(float x, const void* params) {
  return signbit(x) ? 1.0f / (1.0f + expf(-x)) : 1.0f - 1.0f / (1.0f + expf(x));
}

enum xnn_status xnn_create_sigmoid_nc_qu8(
    size_t channels,
    size_t input_stride,
    size_t output_stride,
    uint8_t input_zero_point,
    float input_scale,
    uint8_t output_zero_point,
    float output_scale,
    uint8_t output_min,
    uint8_t output_max,
    uint32_t flags,
    xnn_operator_t* sigmoid_op_out)
{
  if (output_scale != 0x1.0p-8f) {
    xnn_log_error(
      "failed to create %s operator with %.7g output scale: only output scale of 1/256 is supported",
      xnn_operator_type_to_string(xnn_operator_type_sigmoid_nc_qu8), output_scale);
    return xnn_status_unsupported_parameter;
  }

  if (output_zero_point != 0) {
    xnn_log_error(
      "failed to create %s operator with %" PRIu8 " output zero point: only output zero point of 0 is supported",
      xnn_operator_type_to_string(xnn_operator_type_sigmoid_nc_qu8), output_zero_point);
    return xnn_status_unsupported_parameter;
  }

  return create_lut_elementwise_nc(
    channels, input_stride, output_stride,
    (int32_t) (uint32_t) input_zero_point, input_scale,
    (long) (unsigned long) output_zero_point, output_scale,
    (long) (unsigned long) output_min, (long) (unsigned long) output_max,
    flags,
    (xnn_lut_init_fn) &calculate_sigmoid, NULL,
    xnn_operator_type_sigmoid_nc_qu8, sigmoid_op_out);
}

static enum xnn_status setup_lut_elementwise_nc(
    xnn_operator_t lut_elementwise_op,
    enum xnn_operator_type expected_operator_type,
    size_t batch_size,
    const void* input,
    void* output)
{
  if (lut_elementwise_op->type != expected_operator_type) {
    xnn_log_error("failed to setup operator: operator type mismatch (expected %s, got %s)",
      xnn_operator_type_to_string(expected_operator_type),
      xnn_operator_type_to_string(lut_elementwise_op->type));
    return xnn_status_invalid_parameter;
  }
  lut_elementwise_op->state = xnn_run_state_invalid;

  if ((xnn_params.init_flags & XNN_INIT_FLAG_XNNPACK) == 0) {
    xnn_log_error(
      "failed to setup %s operator: XNNPACK is not initialized",
      xnn_operator_type_to_string(expected_operator_type));
    return xnn_status_uninitialized;
  }

  if (batch_size == 0) {
    lut_elementwise_op->state = xnn_run_state_skip;
    return xnn_status_success;
  }

  const size_t channels = lut_elementwise_op->channels;
  const size_t input_stride = lut_elementwise_op->input_pixel_stride;
  const size_t output_stride = lut_elementwise_op->output_pixel_stride;
  if ((((input_stride ^ channels) | (output_stride ^ channels)) == 0) || batch_size == 1) {
    const size_t block_size = 1024;
    lut_elementwise_op->context.lut_contiguous = (struct lut_contiguous_context) {
      .x = input,
      .x_stride = input_stride * sizeof(uint8_t),
      .t = lut_elementwise_op->lookup_table,
      .y = output,
      .y_stride = output_stride * sizeof(uint8_t),
      .ukernel = xnn_params.x8.lut,
    };
    lut_elementwise_op->compute.type = xnn_parallelization_type_1d_tile_1d;
    lut_elementwise_op->compute.task_1d_tile_1d = (pthreadpool_task_1d_tile_1d_t) xnn_compute_lut_contiguous;
    lut_elementwise_op->compute.range[0] = batch_size * channels * sizeof(uint8_t);
    lut_elementwise_op->compute.tile[0] = block_size;
  } else {
    lut_elementwise_op->context.lut_strided = (struct lut_strided_context) {
      .n = channels,
      .x = input,
      .x_stride = input_stride * sizeof(uint8_t),
      .t = lut_elementwise_op->lookup_table,
      .y = output,
      .y_stride = output_stride * sizeof(uint8_t),
      .ukernel = xnn_params.x8.lut,
    };
    lut_elementwise_op->compute.type = xnn_parallelization_type_1d;
    lut_elementwise_op->compute.task_1d = (pthreadpool_task_1d_t) xnn_compute_lut_strided;
    lut_elementwise_op->compute.range[0] = batch_size;
    lut_elementwise_op->compute.tile[0] = 0;
  }
  lut_elementwise_op->state = xnn_run_state_ready;

  return xnn_status_success;
}

enum xnn_status xnn_setup_leaky_relu_nc_qu8(
    xnn_operator_t leaky_relu_op,
    size_t batch_size,
    const uint8_t* input,
    uint8_t* output,
    pthreadpool_t threadpool)
{
  return setup_lut_elementwise_nc(
    leaky_relu_op, xnn_operator_type_leaky_relu_nc_qu8,
    batch_size, input, output);
}

enum xnn_status xnn_setup_sigmoid_nc_qu8(
    xnn_operator_t sigmoid_op,
    size_t batch_size,
    const uint8_t* input,
    uint8_t* output,
    pthreadpool_t threadpool)
{
  return setup_lut_elementwise_nc(
    sigmoid_op, xnn_operator_type_sigmoid_nc_qu8,
    batch_size, input, output);
}
