// Copyright 2019 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 <algorithm>
#include <cfloat>
#include <cmath>
#include <functional>
#include <random>
#include <vector>

#include <cpuinfo.h>

#include <benchmark/benchmark.h>
#include "bench/dconv.h"
#include "bench/utils.h"
#include <xnnpack/AlignedAllocator.h>
#include <xnnpack/common.h>
#include <xnnpack/conv.h>
#include <xnnpack/pack.h>
#include <xnnpack/params-init.h>
#include <xnnpack/params.h>


static void DConvHWC2CHW3X3S2P1Benchmark(benchmark::State& state,
  xnn_f32_conv_hwc2chw_ukernel_function conv,
  uint32_t output_channels_tile)
{
  if (!cpuinfo_initialize()) {
    state.SkipWithError("cpuinfo initialization failed");
  }

  const size_t input_height = state.range(0);
  const size_t input_width = state.range(1);
  const size_t output_channels = state.range(2);

  std::random_device random_device;
  auto rng = std::mt19937(random_device());
  auto f32rng = std::bind(std::uniform_real_distribution<float>(0.0f, 1.0f), rng);

  const size_t input_channels = 3;
  const size_t kernel_size = 3;
  const size_t padding = 1;
  const size_t subsampling = 2;

  const size_t output_height = (input_height + 2 * padding - kernel_size) / subsampling + 1;
  const size_t output_width = (input_width + 2 * padding - kernel_size) / subsampling + 1;

  std::vector<float> input(input_height * input_width * input_channels + XNN_EXTRA_BYTES / sizeof(float));
  std::generate(input.begin(), input.end(), std::ref(f32rng));
  std::vector<float> kernel(output_channels * kernel_size * kernel_size * input_channels);
  std::generate(kernel.begin(), kernel.end(), std::ref(f32rng));
  std::vector<float> bias(output_channels);
  std::generate(bias.begin(), bias.end(), std::ref(f32rng));

  std::vector<float, AlignedAllocator<float, 32>> zero(input_channels * input_width + XNN_EXTRA_BYTES / sizeof(float));

  const size_t weights_elements = (kernel_size * kernel_size * input_channels + 1) *
    benchmark::utils::RoundUp<size_t>(output_channels, output_channels_tile);
  const size_t output_elements = output_height * output_width * output_channels;
  const size_t num_buffers = 1 +
    benchmark::utils::DivideRoundUp<size_t>(benchmark::utils::GetMaxCacheSize(),
      sizeof(float) * (weights_elements + output_elements));

  std::vector<float, AlignedAllocator<float, 32>> packed_weights(weights_elements * num_buffers);
  std::fill(packed_weights.begin(), packed_weights.end(), 0.0f);
  xnn_pack_f32_dconv_oki_w(
    output_channels, input_channels, output_channels_tile,
    kernel_size /* kernel height */, kernel_size /* kernel width */,
    kernel.data(), bias.data(), packed_weights.data(), NULL);
  for (size_t n = 1; n < num_buffers; n++) {
    std::copy(packed_weights.cbegin(),
      packed_weights.cbegin() + weights_elements,
      packed_weights.begin() + n * weights_elements);
  }

  std::vector<float> output(output_elements * num_buffers);
  std::fill(output.begin(), output.end(), std::nanf(""));

  xnn_f32_minmax_params params =
    xnn_init_f32_minmax_params(-std::numeric_limits<float>::infinity(), +std::numeric_limits<float>::infinity());

  size_t buffer_index = 0;
  for (auto _ : state) {
    state.PauseTiming();
    benchmark::utils::PrefetchToL1(input.data(), input.size() * sizeof(float));
    buffer_index = (buffer_index + 1) % num_buffers;
    state.ResumeTiming();

    conv(
      input_height, input_width,
      0 /* output_y_start */, output_height /* output_y_end */,
      input.data(), zero.data(),
      packed_weights.data() + buffer_index * weights_elements,
      output.data() + buffer_index * output_elements,
      padding, output_channels,
      output_channels * output_width * sizeof(float),
      output_channels * sizeof(float),
      &params);
  }

  state.counters["Freq"] = benchmark::utils::GetCurrentCpuFrequency();
  state.counters["FLOPS"] = benchmark::Counter(
    uint64_t(state.iterations()) * 2 *
      output_height * output_width *
      input_channels * output_channels *
      kernel_size * kernel_size,
    benchmark::Counter::kIsRate);
}

#if XNN_ARCH_ARM64
  static void f32_conv_hwc2chw_3x3s2p1c3x4__neonfma_2x2(benchmark::State& state, const char* net) {
    DConvHWC2CHW3X3S2P1Benchmark(state, xnn_f32_conv_hwc2chw_ukernel_3x3s2p1c3x4__neonfma_2x2, 4);
  }

  BENCHMARK_DCONV(f32_conv_hwc2chw_3x3s2p1c3x4__neonfma_2x2);
#endif

#if XNN_ARCH_X86 || XNN_ARCH_X86_64
  static void f32_conv_hwc2chw_3x3s2p1c3x4__sse_1x1(benchmark::State& state, const char* net) {
    DConvHWC2CHW3X3S2P1Benchmark(state, xnn_f32_conv_hwc2chw_ukernel_3x3s2p1c3x4__sse_1x1, 4);
  }

  BENCHMARK_DCONV(f32_conv_hwc2chw_3x3s2p1c3x4__sse_1x1);

  static void f32_conv_hwc2chw_3x3s2p1c3x4__sse_2x2(benchmark::State& state, const char* net) {
    DConvHWC2CHW3X3S2P1Benchmark(state, xnn_f32_conv_hwc2chw_ukernel_3x3s2p1c3x4__sse_2x2, 4);
  }

  BENCHMARK_DCONV(f32_conv_hwc2chw_3x3s2p1c3x4__sse_2x2);
#endif

#if !XNN_ARCH_WASM && !XNN_COMPILER_MSVC && !XNN_COMPILER_ICC
  static void f32_conv_hwc2chw_3x3s2p1c3x4__psimd_2x2(benchmark::State& state, const char* net) {
    DConvHWC2CHW3X3S2P1Benchmark(state, xnn_f32_conv_hwc2chw_ukernel_3x3s2p1c3x4__psimd_2x2, 4);
  }

  BENCHMARK_DCONV(f32_conv_hwc2chw_3x3s2p1c3x4__psimd_2x2);
#endif  // !XNN_ARCH_WASM && !XNN_COMPILER_MSVC && !XNN_COMPILER_ICC

static void f32_conv_hwc2chw_3x3s2p1c3x4__scalar_1x1(benchmark::State& state, const char* net) {
  DConvHWC2CHW3X3S2P1Benchmark(state, xnn_f32_conv_hwc2chw_ukernel_3x3s2p1c3x4__scalar_1x1, 4);
}

BENCHMARK_DCONV(f32_conv_hwc2chw_3x3s2p1c3x4__scalar_1x1);

#ifndef XNNPACK_BENCHMARK_NO_MAIN
BENCHMARK_MAIN();
#endif
