// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// 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

static int nb_load;
static int nb_loadu;
static int nb_store;
static int nb_storeu;

#define EIGEN_DEBUG_ALIGNED_LOAD \
  { nb_load++; }
#define EIGEN_DEBUG_UNALIGNED_LOAD \
  { nb_loadu++; }
#define EIGEN_DEBUG_ALIGNED_STORE \
  { nb_store++; }
#define EIGEN_DEBUG_UNALIGNED_STORE \
  { nb_storeu++; }

#define VERIFY_ALIGNED_UNALIGNED_COUNT(XPR, AL, UL, AS, US)                                                \
  {                                                                                                        \
    nb_load = nb_loadu = nb_store = nb_storeu = 0;                                                         \
    XPR;                                                                                                   \
    if (!(nb_load == AL && nb_loadu == UL && nb_store == AS && nb_storeu == US))                           \
      std::cerr << " >> " << nb_load << ", " << nb_loadu << ", " << nb_store << ", " << nb_storeu << "\n"; \
    VERIFY((#XPR) && nb_load == AL && nb_loadu == UL && nb_store == AS && nb_storeu == US);                \
  }

#include "main.h"
#include <Eigen/Core>

template <typename Scalar, int Options = ColMajor>
void assignment_packet_boundaries() {
  using VectorType = Matrix<Scalar, Options == RowMajor ? 1 : Dynamic, Options == RowMajor ? Dynamic : 1, Options>;
  using MapType = Map<VectorType>;
  using Traits = internal::copy_using_evaluator_traits<internal::evaluator<MapType>, internal::evaluator<MapType>,
                                                       internal::assign_op<Scalar, Scalar>>;
  STATIC_CHECK((!internal::packet_traits<Scalar>::Vectorizable || Traits::Traversal == LinearVectorizedTraversal));
  STATIC_CHECK(Traits::Unrolling == NoUnrolling);
  constexpr int packetSize = internal::packet_traits<Scalar>::size;
  for (Index offset = 0; offset < packetSize; ++offset) {
    for (Index size = 0; size <= 9 * packetSize + 1; ++size) {
      VectorType sourceStorage(size + 2 * packetSize), storage(size + 2 * packetSize);
      MapType source(sourceStorage.data() + (packetSize - offset) % packetSize, size);
      for (Index i = 0; i < size; ++i) source(i) = Scalar(i % 7 + 1);
      storage.setConstant(Scalar(-1));
      MapType destination(storage.data() + offset, size);
      destination = source;
      for (Index i = 0; i < size; ++i) VERIFY_IS_EQUAL(destination(i), Scalar(i % 7 + 1));
      destination += source;
      for (Index i = 0; i < size; ++i) VERIFY_IS_EQUAL(destination(i), Scalar(2 * (i % 7 + 1)));
      destination -= source;
      for (Index i = 0; i < size; ++i) VERIFY_IS_EQUAL(destination(i), Scalar(i % 7 + 1));
      destination.array() = source.array().square();
      for (Index i = 0; i < size; ++i) VERIFY_IS_EQUAL(destination(i), Scalar((i % 7 + 1) * (i % 7 + 1)));
      destination.array() += destination.array();
      for (Index i = 0; i < size; ++i) VERIFY_IS_EQUAL(destination(i), Scalar(2 * (i % 7 + 1) * (i % 7 + 1)));
      for (Index i = 0; i < offset; ++i) VERIFY_IS_EQUAL(storage(i), Scalar(-1));
      for (Index i = offset + size; i < storage.size(); ++i) VERIFY_IS_EQUAL(storage(i), Scalar(-1));
    }
  }
}

EIGEN_DECLARE_TEST(unalignedcount) {
  CALL_SUBTEST(assignment_packet_boundaries<float>());
  CALL_SUBTEST(assignment_packet_boundaries<double>());
  CALL_SUBTEST((assignment_packet_boundaries<float, RowMajor>()));
  CALL_SUBTEST(assignment_packet_boundaries<int>());
  CALL_SUBTEST(assignment_packet_boundaries<std::complex<float>>());
  CALL_SUBTEST(assignment_packet_boundaries<std::complex<double>>());
#if defined(EIGEN_VECTORIZE_AVX512)
  VectorXf a(48), b(48);
  a.fill(0);
  b.fill(1);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a += b, 6, 0, 3, 0);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0, 48) += b.segment(0, 48), 3, 3, 3, 0);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0, 48) -= b.segment(0, 48), 3, 3, 3, 0);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0, 48) *= 3.5, 3, 0, 3, 0);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0, 48) /= 3.5, 3, 0, 3, 0);
#elif defined(EIGEN_VECTORIZE_AVX)
  VectorXf a(40), b(40);
  a.fill(0);
  b.fill(1);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a += b, 10, 0, 5, 0);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0, 40) += b.segment(0, 40), 5, 5, 5, 0);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0, 40) -= b.segment(0, 40), 5, 5, 5, 0);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0, 40) *= 3.5, 5, 0, 5, 0);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0, 40) /= 3.5, 5, 0, 5, 0);
#elif defined(EIGEN_VECTORIZE_SSE)
  VectorXf a(40), b(40);
  a.fill(0);
  b.fill(1);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a += b, 20, 0, 10, 0);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0, 40) += b.segment(0, 40), 10, 10, 10, 0);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0, 40) -= b.segment(0, 40), 10, 10, 10, 0);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0, 40) *= 3.5, 10, 0, 10, 0);
  VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0, 40) /= 3.5, 10, 0, 10, 0);
#else
  // The following line is to eliminate "variable not used" warnings
  nb_load = nb_loadu = nb_store = nb_storeu = 0;
  int a(0), b(0);
  VERIFY(a == b);
#endif
}
