// Benchmarks for Eigen Tensor coefficient-wise operations.
// Covers activation functions, normalization, and element-wise arithmetic.
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0

#define EIGEN_USE_THREADS

#include <benchmark/benchmark.h>
#include <contrib/Eigen/SpecialFunctions>
#include <contrib/Eigen/Tensor>
#include <Eigen/ThreadPool>

using namespace Eigen;

typedef float Scalar;

// Macro to define a benchmark for a unary tensor operation.
#define BENCH_TENSOR_UNARY(NAME, EXPR)                                        \
  static void BM_##NAME(benchmark::State& state) {                            \
    const int M = state.range(0);                                             \
    const int N = state.range(1);                                             \
    Tensor<Scalar, 2> a(M, N);                                                \
    a.setRandom();                                                            \
    Tensor<Scalar, 2> b(M, N);                                                \
    for (auto _ : state) {                                                    \
      b = EXPR;                                                               \
      benchmark::DoNotOptimize(b.data());                                     \
      benchmark::ClobberMemory();                                             \
    }                                                                         \
    state.SetBytesProcessed(state.iterations() * M * N * sizeof(Scalar) * 2); \
  }

// Macro for ThreadPool variant of a unary tensor operation.
#define BENCH_TENSOR_UNARY_THREADPOOL(NAME, EXPR)                             \
  static void BM_##NAME##_ThreadPool(benchmark::State& state) {               \
    const int M = state.range(0);                                             \
    const int N = state.range(1);                                             \
    const int threads = state.range(2);                                       \
    Tensor<Scalar, 2> a(M, N);                                                \
    a.setRandom();                                                            \
    Tensor<Scalar, 2> b(M, N);                                                \
    ThreadPool tp(threads);                                                   \
    ThreadPoolDevice dev(&tp, threads);                                       \
    for (auto _ : state) {                                                    \
      b.device(dev) = EXPR;                                                   \
      benchmark::DoNotOptimize(b.data());                                     \
      benchmark::ClobberMemory();                                             \
    }                                                                         \
    state.SetBytesProcessed(state.iterations() * M * N * sizeof(Scalar) * 2); \
    state.counters["threads"] = threads;                                      \
  }

BENCH_TENSOR_UNARY(Exp, a.exp())
BENCH_TENSOR_UNARY(Log, a.abs().log())
BENCH_TENSOR_UNARY(Tanh, a.tanh())
BENCH_TENSOR_UNARY(Sigmoid, a.sigmoid())
BENCH_TENSOR_UNARY(ReLU, a.cwiseMax(Scalar(0)))
BENCH_TENSOR_UNARY(Sqrt, a.abs().sqrt())

BENCH_TENSOR_UNARY_THREADPOOL(Tanh, a.tanh())
BENCH_TENSOR_UNARY_THREADPOOL(ReLU, a.cwiseMax(Scalar(0)))

// --- Element-wise binary operations ---
static void BM_Add(benchmark::State& state) {
  const int M = state.range(0);
  const int N = state.range(1);

  Tensor<Scalar, 2> a(M, N);
  Tensor<Scalar, 2> b(M, N);
  Tensor<Scalar, 2> c(M, N);
  a.setRandom();
  b.setRandom();

  for (auto _ : state) {
    c = a + b;
    benchmark::DoNotOptimize(c.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * M * N * sizeof(Scalar) * 3);
}

static void BM_Mul(benchmark::State& state) {
  const int M = state.range(0);
  const int N = state.range(1);

  Tensor<Scalar, 2> a(M, N);
  Tensor<Scalar, 2> b(M, N);
  Tensor<Scalar, 2> c(M, N);
  a.setRandom();
  b.setRandom();

  for (auto _ : state) {
    c = a * b;
    benchmark::DoNotOptimize(c.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * M * N * sizeof(Scalar) * 3);
}

// --- Fused multiply-add ---
static void BM_FMA(benchmark::State& state) {
  const int M = state.range(0);
  const int N = state.range(1);

  Tensor<Scalar, 2> a(M, N);
  Tensor<Scalar, 2> b(M, N);
  Tensor<Scalar, 2> c(M, N);
  Tensor<Scalar, 2> d(M, N);
  a.setRandom();
  b.setRandom();
  c.setRandom();

  for (auto _ : state) {
    d = a * b + c;
    benchmark::DoNotOptimize(d.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * M * N * sizeof(Scalar) * 4);
}

// --- Ternary op (betainc) with broadcast parameters ---
// The ternary node's block support decides whether the parameter broadcasts
// run tiled (bulk row copies) or on the per-packet index-remapping path.
static void BM_BetaincBroadcast(benchmark::State& state) {
  const int M = state.range(0);
  const int N = state.range(1);

  Tensor<Scalar, 2> a_row(1, N);
  Tensor<Scalar, 2> b_row(1, N);
  Tensor<Scalar, 2> x(M, N);
  a_row.setRandom();
  b_row.setRandom();
  x.setRandom();
  // betainc requires a > 0, b > 0 and x in [0, 1].
  a_row = a_row.abs() + a_row.constant(Scalar(0.5));
  b_row = b_row.abs() + b_row.constant(Scalar(0.5));
  x = (x + x.constant(Scalar(1))) * x.constant(Scalar(0.5));

  Eigen::array<Index, 2> bcast = {M, 1};

  Tensor<Scalar, 2> result(M, N);
  for (auto _ : state) {
    result = Eigen::betainc(a_row.broadcast(bcast), b_row.broadcast(bcast), x);
    benchmark::DoNotOptimize(result.data());
    benchmark::ClobberMemory();
  }

  // Validate samples against scalar evaluation outside the timed loop.
  const Eigen::array<int, 3> sample_rows = {0, M / 2, M - 1};
  for (int i : sample_rows) {
    for (int j = 0; j < N; ++j) {
      const Scalar ref = numext::betainc(a_row(0, j), b_row(0, j), x(i, j));
      if (result(i, j) != ref) {
        state.SkipWithError("validation failed");
        return;
      }
    }
  }
  state.SetBytesProcessed(state.iterations() * M * N * sizeof(Scalar) * 4);
}

// --- ThreadPool binary operations ---
static void BM_Add_ThreadPool(benchmark::State& state) {
  const int M = state.range(0);
  const int N = state.range(1);
  const int threads = state.range(2);

  Tensor<Scalar, 2> a(M, N);
  Tensor<Scalar, 2> b(M, N);
  Tensor<Scalar, 2> c(M, N);
  a.setRandom();
  b.setRandom();

  ThreadPool tp(threads);
  ThreadPoolDevice dev(&tp, threads);

  for (auto _ : state) {
    c.device(dev) = a + b;
    benchmark::DoNotOptimize(c.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * M * N * sizeof(Scalar) * 3);
  state.counters["threads"] = threads;
}

static void BM_Mul_ThreadPool(benchmark::State& state) {
  const int M = state.range(0);
  const int N = state.range(1);
  const int threads = state.range(2);

  Tensor<Scalar, 2> a(M, N);
  Tensor<Scalar, 2> b(M, N);
  Tensor<Scalar, 2> c(M, N);
  a.setRandom();
  b.setRandom();

  ThreadPool tp(threads);
  ThreadPoolDevice dev(&tp, threads);

  for (auto _ : state) {
    c.device(dev) = a * b;
    benchmark::DoNotOptimize(c.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * M * N * sizeof(Scalar) * 3);
  state.counters["threads"] = threads;
}

static void BM_FMA_ThreadPool(benchmark::State& state) {
  const int M = state.range(0);
  const int N = state.range(1);
  const int threads = state.range(2);

  Tensor<Scalar, 2> a(M, N);
  Tensor<Scalar, 2> b(M, N);
  Tensor<Scalar, 2> c(M, N);
  Tensor<Scalar, 2> d(M, N);
  a.setRandom();
  b.setRandom();
  c.setRandom();

  ThreadPool tp(threads);
  ThreadPoolDevice dev(&tp, threads);

  for (auto _ : state) {
    d.device(dev) = a * b + c;
    benchmark::DoNotOptimize(d.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * M * N * sizeof(Scalar) * 4);
  state.counters["threads"] = threads;
}

// --- Rank-4 coefficient-wise (CNN feature maps) ---
static void BM_ReLU_Rank4(benchmark::State& state) {
  const int batch = state.range(0);
  const int C = state.range(1);
  const int H = state.range(2);

  Tensor<Scalar, 4> a(batch, C, H, H);
  Tensor<Scalar, 4> b(batch, C, H, H);
  a.setRandom();

  for (auto _ : state) {
    b = a.cwiseMax(Scalar(0));
    benchmark::DoNotOptimize(b.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * batch * C * H * H * sizeof(Scalar) * 2);
}

// --- Ternary boolean mask select: mask.select(a, b) ---
template <typename T>
static void BM_Select(benchmark::State& state) {
  const int M = state.range(0);
  const int N = state.range(1);

  Tensor<bool, 2> mask(M, N);
  Tensor<T, 2> a(M, N);
  Tensor<T, 2> b(M, N);
  Tensor<T, 2> c(M, N);
  mask.setRandom();
  a.setRandom();
  b.setRandom();

  for (auto _ : state) {
    c = mask.select(a, b);
    benchmark::DoNotOptimize(c.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * M * N * (sizeof(bool) + sizeof(T) * 3));
}

template <typename T>
static void BM_Select_ThreadPool(benchmark::State& state) {
  const int M = state.range(0);
  const int N = state.range(1);
  const int threads = state.range(2);

  Tensor<bool, 2> mask(M, N);
  Tensor<T, 2> a(M, N);
  Tensor<T, 2> b(M, N);
  Tensor<T, 2> c(M, N);
  mask.setRandom();
  a.setRandom();
  b.setRandom();

  ThreadPool tp(threads);
  ThreadPoolDevice dev(&tp, threads);

  for (auto _ : state) {
    c.device(dev) = mask.select(a, b);
    benchmark::DoNotOptimize(c.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * M * N * (sizeof(bool) + sizeof(T) * 3));
  state.counters["threads"] = threads;
}

// --- Element-wise type casting: a.cast<Tgt>() ---
template <typename Src, typename Tgt>
static void BM_Cast(benchmark::State& state) {
  const int M = state.range(0);
  const int N = state.range(1);

  Tensor<Src, 2> a(M, N);
  Tensor<Tgt, 2> b(M, N);
  a.setRandom();

  for (auto _ : state) {
    b = a.template cast<Tgt>();
    benchmark::DoNotOptimize(b.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * M * N * (sizeof(Src) + sizeof(Tgt)));
}

template <typename T>
static void BM_Sigmoid_Typed(benchmark::State& state) {
  const int M = state.range(0);
  const int N = state.range(1);

  Tensor<T, 2> a(M, N);
  Tensor<T, 2> b(M, N);
  a.setRandom();

  for (auto _ : state) {
    b = a.sigmoid();
    benchmark::DoNotOptimize(b.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * M * N * sizeof(T) * 2);
}

template <typename T>
static void BM_Inverse_Typed(benchmark::State& state) {
  const int M = state.range(0);
  const int N = state.range(1);

  Tensor<T, 2> a(M, N);
  Tensor<T, 2> b(M, N);
  a.setRandom();
  a = a.abs() + a.constant(T(1));

  for (auto _ : state) {
    b = a.inverse();
    benchmark::DoNotOptimize(b.data());
    benchmark::ClobberMemory();
  }
  state.SetBytesProcessed(state.iterations() * M * N * sizeof(T) * 2);
}

// clang-format off
#define CWISE_SIZES \
  ->Args({256, 256})->Args({1024, 1024})

#define CWISE_THREADPOOL_SIZES \
  ->Args({256, 256, 1})->Args({256, 256, 2})->Args({256, 256, 4}) \
  ->Args({256, 256, 8})->Args({256, 256, 12})->Args({256, 256, 16}) \
  ->Args({1024, 1024, 1})->Args({1024, 1024, 2})->Args({1024, 1024, 4}) \
  ->Args({1024, 1024, 8})->Args({1024, 1024, 12})->Args({1024, 1024, 16})

#define RANK4_SIZES \
  ->Args({32, 64, 16})->Args({8, 128, 32})->Args({1, 256, 64})
// clang-format on

BENCHMARK(BM_Exp) CWISE_SIZES;
BENCHMARK(BM_Log) CWISE_SIZES;
BENCHMARK(BM_Tanh) CWISE_SIZES;
BENCHMARK(BM_Sigmoid) CWISE_SIZES;
BENCHMARK(BM_ReLU) CWISE_SIZES;
BENCHMARK(BM_Sqrt) CWISE_SIZES;
BENCHMARK(BM_Add) CWISE_SIZES;
BENCHMARK(BM_Mul) CWISE_SIZES;
BENCHMARK(BM_FMA) CWISE_SIZES;
BENCHMARK(BM_BetaincBroadcast) CWISE_SIZES;
BENCHMARK(BM_ReLU_Rank4) RANK4_SIZES;
BENCHMARK_TEMPLATE(BM_Select, float) CWISE_SIZES;
BENCHMARK_TEMPLATE(BM_Select, int32_t) CWISE_SIZES;
BENCHMARK_TEMPLATE(BM_Select, Eigen::half) CWISE_SIZES;
BENCHMARK_TEMPLATE(BM_Select, Eigen::bfloat16) CWISE_SIZES;
BENCHMARK_TEMPLATE(BM_Cast, Eigen::half, bool) CWISE_SIZES;
BENCHMARK_TEMPLATE(BM_Cast, Eigen::bfloat16, bool) CWISE_SIZES;
BENCHMARK_TEMPLATE(BM_Sigmoid_Typed, Eigen::half) CWISE_SIZES;
BENCHMARK_TEMPLATE(BM_Sigmoid_Typed, Eigen::bfloat16) CWISE_SIZES;
BENCHMARK_TEMPLATE(BM_Inverse_Typed, Eigen::half) CWISE_SIZES;
BENCHMARK_TEMPLATE(BM_Inverse_Typed, Eigen::bfloat16) CWISE_SIZES;
BENCHMARK(BM_Add_ThreadPool) CWISE_THREADPOOL_SIZES->UseRealTime();
BENCHMARK(BM_Mul_ThreadPool) CWISE_THREADPOOL_SIZES->UseRealTime();
BENCHMARK(BM_FMA_ThreadPool) CWISE_THREADPOOL_SIZES->UseRealTime();
BENCHMARK(BM_Tanh_ThreadPool) CWISE_THREADPOOL_SIZES->UseRealTime();
BENCHMARK(BM_ReLU_ThreadPool) CWISE_THREADPOOL_SIZES->UseRealTime();
BENCHMARK_TEMPLATE(BM_Select_ThreadPool, float) CWISE_THREADPOOL_SIZES->UseRealTime();
