/* Copyright 2018 The TensorFlow Authors. All Rights Reserved.

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

// Need to #include Eigen's Tensor class first because Eigen/CXX11/FixedPoint
// depends on the file but doesn't include it. This breaks compilation on
// clang.
// clang-format off
#include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor"
// clang-format on
#include "third_party/eigen3/unsupported/Eigen/CXX11/FixedPoint"
#include "tensorflow/core/kernels/eigen_contraction_kernel.h"
#include "tensorflow/core/platform/test.h"

namespace Eigen {
namespace internal {

namespace {
template <typename Index, int NumDims>
Eigen::array<Index, NumDims> RandomDims(int min_dim = 1, int max_dim = 20) {
  Eigen::array<Index, NumDims> dims;
  for (int i = 0; i < NumDims; ++i) {
    dims[i] = internal::random<int>(min_dim, max_dim);
  }
  return dims;
}
}  // namespace

using Scalar = float;
using Index = Eigen::Index;

TEST(EigenMkldnnTest, GemmPackColMajor) {
  // Packing with gemm_pack_colmajor_block is the same as taking a slice of 2
  // dimensional Tensor.

  // Mkldnn pack and gemm are used only in Tensor contractions, and it's
  // guaranteed that Tensors will have ColMajor layout.
  static const int Options = ColMajor;

  using DataMapper = blas_data_mapper<Scalar, Index, ColMajor>;
  using GemmPackColMajor =
      gemm_pack_colmajor_block<Scalar, Index, DataMapper, ColMajor>;
  using Tensor2d = Tensor<Scalar, 2, Options, Index>;

  Eigen::array<Index, 2> dims = RandomDims<Index, 2>(1, 500);

  // Create a tensor initialized with random data.
  Tensor2d src(dims);
  src.setRandom();

  // Pick a random slice of src tensor.
  Eigen::array<Index, 2> slice_start = RandomDims<Index, 2>(0, 250);
  Eigen::array<Index, 2> slice_size = RandomDims<Index, 2>(100, 500);

  // Make sure that slice start + size do not overflow tensor dims.
  for (int i = 0; i < 2; ++i) {
    slice_start[i] = numext::mini(dims[i] - 1, slice_start[i]);
    slice_size[i] = numext::mini(slice_size[i], dims[i] - slice_start[i]);
  }

  // Prepare tensors for packing and slicing results.
  Tensor2d pack_dst(slice_size[0], slice_size[1]);
  Tensor2d slice_dst(slice_size[0], slice_size[1]);

  // Pack memory using gemm_pack_colmajor_block.
  DataMapper data_mapper(src.data(), dims[0]);
  GemmPackColMajor gemm_pack;
  gemm_pack(pack_dst.data(),
            data_mapper.getSubMapper(slice_start[0], slice_start[1]),
            slice_size[0], slice_size[1]);

  // Slice the source tensor.
  slice_dst = src.slice(slice_start, slice_size);

  // Verify that dst tensors are equal.
  EXPECT_EQ(pack_dst.dimensions().TotalSize(),
            slice_dst.dimensions().TotalSize());
  for (size_t i = 0; i < pack_dst.dimensions().TotalSize(); ++i) {
    Scalar packed = pack_dst.coeff(i);
    Scalar sliced = slice_dst.coeff(i);
    EXPECT_EQ(packed, sliced);
  }
}

TEST(EigenMkldnnTest, MkldnnGemm) {
  // Mkldnn pack and gemm are used only in Tensor contractions, and it's
  // guaranteed that Tensors will have ColMajor layout.
  static const int Options = ColMajor;

  using Tensor2d = Tensor<Scalar, 2, Options, Index>;

  int m = internal::random<int>(1, 100);
  int n = internal::random<int>(1, 100);
  int k = internal::random<int>(1, 100);

  Tensor2d lhs(m, k);
  lhs.setRandom();

  Tensor2d rhs(k, n);
  rhs.setRandom();

  // Compute matmul with mkldnn gemm kernel.
  using OutputMapper = blas_data_mapper<Scalar, Index, ColMajor>;
  using MkldnnGemmKernel =
      mkldnn_gemm_kernel<Scalar, Index, OutputMapper, ColMajor>;

  Tensor2d mkldnn_result(m, n);
  mkldnn_result.setZero();
  OutputMapper output_mapper(mkldnn_result.data(), m);

  MkldnnGemmKernel gemm_kernel;
  gemm_kernel(output_mapper, lhs.data(), rhs.data(), m, k, n, /*alpha=*/1.0);

  // Compute matmul with Eigen::Matrix.
  using Matrix = Eigen::Matrix<Scalar, Dynamic, Dynamic, ColMajor>;
  using MatrixMap = Map<Eigen::Matrix<Scalar, Dynamic, Dynamic, ColMajor>>;

  MatrixMap lhs_mat(lhs.data(), m, k);
  MatrixMap rhs_mat(rhs.data(), k, n);

  Matrix matmul_result(m, n);
  matmul_result.setZero();
  matmul_result = lhs_mat * rhs_mat;

  // Verify that results are equal.
  for (Index i = 0; i < m * n; ++i) {
    Scalar gemm = mkldnn_result(i);
    Scalar matmul = matmul_result(i % m, i / m);

    Scalar delta = std::abs(gemm - matmul);

    // NOTE(rmlarsen): Compute proper forward error bound.
    Scalar sum = Scalar(0.0);
    for (int k1 = 0; k1 < k; ++k1) {
      sum += std::abs(lhs_mat(i % m, k1) * rhs_mat(k1, i / m));
    }
    Scalar epsilon = std::numeric_limits<Scalar>::epsilon();
    Scalar upper_bound = Scalar(1.01) * epsilon * k * sum;

    EXPECT_LE(delta, upper_bound);
  }
}

TEST(EigenMkldnnTest, MkldnnGemmQInt8xQUInt8) {
  // Mkldnn pack and gemm are used only in Tensor contractions, and it's
  // guaranteed that Tensors will have ColMajor layout.
  static const int Options = ColMajor;

  using Tensor2dQInt8 = Eigen::Tensor<Eigen::QInt8, 2, Options, Index>;
  using Tensor2dQUInt8 = Eigen::Tensor<Eigen::QUInt8, 2, Options, Index>;
  using Tensor2dQInt32 = Eigen::Tensor<Eigen::QInt32, 2, Options, Index>;

  int m = internal::random<int>(1, 1000);
  int n = internal::random<int>(1, 1000);
  int k = internal::random<int>(1, 1000);

  Tensor2dQInt8 lhs(m, k);
  lhs.setRandom();

  Tensor2dQUInt8 rhs(k, n);
  rhs.setRandom();
  // NOTE: 's8*u8 + s8*u8 -> s16' saturation might lead to incorrect results. In
  // practice in FusedConv2DBiasActivationKernel we use 7 bit inputs.
  rhs = rhs.clip(0, 127);

  Eigen::array<Eigen::IndexPair<Eigen::DenseIndex>, 1> contract_dims;
  contract_dims[0].first = 1;
  contract_dims[0].second = 0;

  Tensor2dQInt32 res = lhs.contract(rhs, contract_dims);

  // Compute matmul with Eigen::Matrix. We explicitly cast inputs to int32_t not
  // to test QInt8->QInt32 type promotion during accumulation.
  using Matrix = Eigen::Matrix<int32_t, Dynamic, Dynamic, ColMajor>;

  Matrix lhs_mat(m, k);
  Matrix rhs_mat(k, n);

  for (int i = 0; i < m; ++i) {
    for (int j = 0; j < k; ++j) {
      lhs_mat(i, j) = static_cast<int32_t>(lhs(i, j));
    }
  }

  for (int i = 0; i < k; ++i) {
    for (int j = 0; j < n; ++j) {
      rhs_mat(i, j) = static_cast<int32_t>(rhs(i, j));
    }
  }

  Matrix matmul_result(m, n);
  matmul_result.setZero();
  matmul_result = lhs_mat * rhs_mat;

  // Verify that results are equal.
  for (Index i = 0; i < m; ++i) {
    for (Index j = 0; j < n; ++j) {
      Scalar gemm = res(i, j);
      Scalar matmul = matmul_result(i, j);
      EXPECT_EQ(gemm, matmul);
    }
  }
}

}  // namespace internal
}  // namespace Eigen
