// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// SPDX-License-Identifier: MPL-2.0

#define EIGEN_TEST_ANNOYING_SCALAR_DONT_THROW

#include "main.h"

#include <Eigen/Core>
#include <Eigen/Tensor>

#include "AnnoyingScalar.h"

using Eigen::MatrixXf;
using Eigen::Tensor;

static void test_simple() {
  MatrixXf m1(3, 3);
  MatrixXf m2(3, 3);
  m1.setRandom();
  m2.setRandom();

  TensorMap<Tensor<float, 2> > mat1(m1.data(), 3, 3);
  TensorMap<Tensor<float, 2> > mat2(m2.data(), 3, 3);

  Tensor<float, 2> mat3(3, 3);
  mat3 = mat1;

  typedef Tensor<float, 1>::DimensionPair DimPair;
  Eigen::array<DimPair, 1> dims;
  dims[0] = DimPair(1, 0);

  mat3 = mat3.contract(mat2, dims).eval();

  VERIFY_IS_APPROX(mat3(0, 0), (m1 * m2).eval()(0, 0));
  VERIFY_IS_APPROX(mat3(0, 1), (m1 * m2).eval()(0, 1));
  VERIFY_IS_APPROX(mat3(0, 2), (m1 * m2).eval()(0, 2));
  VERIFY_IS_APPROX(mat3(1, 0), (m1 * m2).eval()(1, 0));
  VERIFY_IS_APPROX(mat3(1, 1), (m1 * m2).eval()(1, 1));
  VERIFY_IS_APPROX(mat3(1, 2), (m1 * m2).eval()(1, 2));
  VERIFY_IS_APPROX(mat3(2, 0), (m1 * m2).eval()(2, 0));
  VERIFY_IS_APPROX(mat3(2, 1), (m1 * m2).eval()(2, 1));
  VERIFY_IS_APPROX(mat3(2, 2), (m1 * m2).eval()(2, 2));
}

static void test_const() {
  MatrixXf input(3, 3);
  input.setRandom();
  MatrixXf output = input;
  output.rowwise() -= input.colwise().maxCoeff();

  Eigen::array<int, 1> depth_dim;
  depth_dim[0] = 0;
  Tensor<float, 2>::Dimensions dims2d;
  dims2d[0] = 1;
  dims2d[1] = 3;
  Eigen::array<int, 2> bcast;
  bcast[0] = 3;
  bcast[1] = 1;
  const TensorMap<const Tensor<float, 2> > input_tensor(input.data(), 3, 3);
  Tensor<float, 2> output_tensor =
      (input_tensor - input_tensor.maximum(depth_dim).eval().reshape(dims2d).broadcast(bcast));

  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 3; ++j) {
      VERIFY_IS_APPROX(output(i, j), output_tensor(i, j));
    }
  }
}

// Bug #1530: forced-eval of a non-POD tensor leaked elements because
// TensorForcedEvalOp::cleanup() never called destructors on the placement-new'd
// buffer.
static void test_non_pod_no_leak() {
  AnnoyingScalar::instances = 0;
  {
    Tensor<AnnoyingScalar, 1> a(8);
    Tensor<AnnoyingScalar, 1> b(8);
    b = a.eval();  // forces TensorForcedEvalOp
  }
  VERIFY_IS_EQUAL(AnnoyingScalar::instances, 0);
}

EIGEN_DECLARE_TEST(tensor_forced_eval) {
  CALL_SUBTEST(test_simple());
  CALL_SUBTEST(test_const());
  CALL_SUBTEST(test_non_pod_no_leak());
}
