/*
 Copyright (c) 2011, Intel Corporation. All rights reserved.

 Redistribution and use in source and binary forms, with or without modification,
 are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
 * Neither the name of Intel Corporation nor the names of its contributors may
   be used to endorse or promote products derived from this software without
   specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 ********************************************************************************
 *   Content : Eigen bindings to Intel(R) MKL PARDISO
 ********************************************************************************
*/

#ifndef EIGEN_PARDISOSUPPORT_H
#define EIGEN_PARDISOSUPPORT_H

// IWYU pragma: private
#include "./InternalHeaderCheck.h"

namespace Eigen {

template <typename MatrixType_>
class PardisoLU;
template <typename MatrixType_, int Options = Upper>
class PardisoLLT;
template <typename MatrixType_, int Options = Upper>
class PardisoLDLT;

namespace internal {
template <typename IndexType>
struct pardiso_run_selector {
  static IndexType run(_MKL_DSS_HANDLE_t pt, IndexType maxfct, IndexType mnum, IndexType type, IndexType phase,
                       IndexType n, void* a, IndexType* ia, IndexType* ja, IndexType* perm, IndexType nrhs,
                       IndexType* iparm, IndexType msglvl, void* b, void* x) {
    IndexType error = 0;
    ::pardiso(pt, &maxfct, &mnum, &type, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x, &error);
    return error;
  }
};
template <>
struct pardiso_run_selector<long long int> {
  typedef long long int IndexType;
  static IndexType run(_MKL_DSS_HANDLE_t pt, IndexType maxfct, IndexType mnum, IndexType type, IndexType phase,
                       IndexType n, void* a, IndexType* ia, IndexType* ja, IndexType* perm, IndexType nrhs,
                       IndexType* iparm, IndexType msglvl, void* b, void* x) {
    IndexType error = 0;
    ::pardiso_64(pt, &maxfct, &mnum, &type, &phase, &n, a, ia, ja, perm, &nrhs, iparm, &msglvl, b, x, &error);
    return error;
  }
};

template <class Pardiso>
struct pardiso_traits;

template <typename MatrixType_>
struct pardiso_traits<PardisoLU<MatrixType_> > {
  typedef MatrixType_ MatrixType;
  typedef typename MatrixType_::Scalar Scalar;
  typedef typename MatrixType_::RealScalar RealScalar;
  typedef typename MatrixType_::StorageIndex StorageIndex;
};

template <typename MatrixType_, int Options>
struct pardiso_traits<PardisoLLT<MatrixType_, Options> > {
  typedef MatrixType_ MatrixType;
  typedef typename MatrixType_::Scalar Scalar;
  typedef typename MatrixType_::RealScalar RealScalar;
  typedef typename MatrixType_::StorageIndex StorageIndex;
};

template <typename MatrixType_, int Options>
struct pardiso_traits<PardisoLDLT<MatrixType_, Options> > {
  typedef MatrixType_ MatrixType;
  typedef typename MatrixType_::Scalar Scalar;
  typedef typename MatrixType_::RealScalar RealScalar;
  typedef typename MatrixType_::StorageIndex StorageIndex;
};

}  // end namespace internal

template <class Derived>
class PardisoImpl : public SparseSolverBase<Derived> {
 protected:
  typedef SparseSolverBase<Derived> Base;
  using Base::derived;
  using Base::m_isInitialized;

  typedef internal::pardiso_traits<Derived> Traits;

 public:
  using Base::_solve_impl;

  typedef typename Traits::MatrixType MatrixType;
  typedef typename Traits::Scalar Scalar;
  typedef typename Traits::RealScalar RealScalar;
  typedef typename Traits::StorageIndex StorageIndex;
  typedef SparseMatrix<Scalar, RowMajor, StorageIndex> SparseMatrixType;
  typedef Matrix<Scalar, Dynamic, 1> VectorType;
  typedef Matrix<StorageIndex, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
  typedef Matrix<StorageIndex, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
  typedef Array<StorageIndex, 64, 1, DontAlign> ParameterType;
  enum { ScalarIsComplex = NumTraits<Scalar>::IsComplex, ColsAtCompileTime = Dynamic, MaxColsAtCompileTime = Dynamic };

  PardisoImpl() : m_analysisIsOk(false), m_factorizationIsOk(false) {
    eigen_assert((sizeof(StorageIndex) >= sizeof(_INTEGER_t) && sizeof(StorageIndex) <= 8) &&
                 "Non-supported index type");
    m_iparm.setZero();
    m_msglvl = 0;  // No output
    m_isInitialized = false;
  }

  ~PardisoImpl() { pardisoRelease(); }

  inline Index cols() const { return m_size; }
  inline Index rows() const { return m_size; }

  /** \brief Reports whether previous computation was successful.
   *
   * \returns \c Success if computation was successful,
   *          \c NumericalIssue if the matrix appears to be negative.
   */
  ComputationInfo info() const {
    eigen_assert(m_isInitialized && "Decomposition is not initialized.");
    return m_info;
  }

  /** \warning for advanced usage only.
   * \returns a reference to the parameter array controlling PARDISO.
   * See the PARDISO manual to know how to use it. */
  ParameterType& pardisoParameterArray() { return m_iparm; }

  /** Performs a symbolic decomposition on the sparcity of \a matrix.
   *
   * This function is particularly useful when solving for several problems having the same structure.
   *
   * \sa factorize()
   */
  Derived& analyzePattern(const MatrixType& matrix);

  /** Performs a numeric decomposition of \a matrix
   *
   * The given matrix must has the same sparcity than the matrix on which the symbolic decomposition has been performed.
   *
   * \sa analyzePattern()
   */
  Derived& factorize(const MatrixType& matrix);

  Derived& compute(const MatrixType& matrix);

  template <typename Rhs, typename Dest>
  void _solve_impl(const MatrixBase<Rhs>& b, MatrixBase<Dest>& dest) const;

 protected:
  void pardisoRelease() {
    if (m_isInitialized)  // Factorization ran at least once
    {
      internal::pardiso_run_selector<StorageIndex>::run(m_pt, 1, 1, m_type, -1,
                                                        internal::convert_index<StorageIndex>(m_size), 0, 0, 0,
                                                        m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL);
      m_isInitialized = false;
    }
  }

  void pardisoInit(int type) {
    m_type = type;
    bool symmetric = std::abs(m_type) < 10;
    m_iparm[0] = 1;                   // No solver default
    m_iparm[1] = 2;                   // use Metis for the ordering
    m_iparm[2] = 0;                   // Reserved. Set to zero. (??Numbers of processors, value of OMP_NUM_THREADS??)
    m_iparm[3] = 0;                   // No iterative-direct algorithm
    m_iparm[4] = 0;                   // No user fill-in reducing permutation
    m_iparm[5] = 0;                   // Write solution into x, b is left unchanged
    m_iparm[6] = 0;                   // Not in use
    m_iparm[7] = 2;                   // Max numbers of iterative refinement steps
    m_iparm[8] = 0;                   // Not in use
    m_iparm[9] = 13;                  // Perturb the pivot elements with 1E-13
    m_iparm[10] = symmetric ? 0 : 1;  // Use nonsymmetric permutation and scaling MPS
    m_iparm[11] = 0;                  // Not in use
    m_iparm[12] = symmetric ? 0 : 1;  // Maximum weighted matching algorithm is switched-off (default for symmetric).
                                      // Try m_iparm[12] = 1 in case of inappropriate accuracy
    m_iparm[13] = 0;                  // Output: Number of perturbed pivots
    m_iparm[14] = 0;                  // Not in use
    m_iparm[15] = 0;                  // Not in use
    m_iparm[16] = 0;                  // Not in use
    m_iparm[17] = -1;                 // Output: Number of nonzeros in the factor LU
    m_iparm[18] = -1;                 // Output: Mflops for LU factorization
    m_iparm[19] = 0;                  // Output: Numbers of CG Iterations

    m_iparm[20] = 0;  // 1x1 pivoting
    m_iparm[26] = 0;  // No matrix checker
    m_iparm[27] = (sizeof(RealScalar) == 4) ? 1 : 0;
    m_iparm[34] = 1;  // C indexing
    m_iparm[36] = 0;  // CSR
    m_iparm[59] = 0;  // 0 - In-Core ; 1 - Automatic switch between In-Core and Out-of-Core modes ; 2 - Out-of-Core

    memset(m_pt, 0, sizeof(m_pt));
  }

 protected:
  // cached data to reduce reallocation, etc.

  void manageErrorCode(Index error) const {
    switch (error) {
      case 0:
        m_info = Success;
        break;
      case -4:
      case -7:
        m_info = NumericalIssue;
        break;
      default:
        m_info = InvalidInput;
    }
  }

  mutable SparseMatrixType m_matrix;
  mutable ComputationInfo m_info;
  bool m_analysisIsOk, m_factorizationIsOk;
  StorageIndex m_type, m_msglvl;
  mutable void* m_pt[64];
  mutable ParameterType m_iparm;
  mutable IntColVectorType m_perm;
  Index m_size;
};

template <class Derived>
Derived& PardisoImpl<Derived>::compute(const MatrixType& a) {
  m_size = a.rows();
  eigen_assert(a.rows() == a.cols());

  pardisoRelease();
  m_perm.setZero(m_size);
  derived().getMatrix(a);

  Index error;
  error = internal::pardiso_run_selector<StorageIndex>::run(
      m_pt, 1, 1, m_type, 12, internal::convert_index<StorageIndex>(m_size), m_matrix.valuePtr(),
      m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL);
  manageErrorCode(error);
  m_analysisIsOk = m_info == Eigen::Success;
  m_factorizationIsOk = m_info == Eigen::Success;
  m_isInitialized = true;
  return derived();
}

template <class Derived>
Derived& PardisoImpl<Derived>::analyzePattern(const MatrixType& a) {
  m_size = a.rows();
  eigen_assert(m_size == a.cols());

  pardisoRelease();
  m_perm.setZero(m_size);
  derived().getMatrix(a);

  Index error;
  error = internal::pardiso_run_selector<StorageIndex>::run(
      m_pt, 1, 1, m_type, 11, internal::convert_index<StorageIndex>(m_size), m_matrix.valuePtr(),
      m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL);

  manageErrorCode(error);
  m_analysisIsOk = m_info == Eigen::Success;
  m_factorizationIsOk = false;
  m_isInitialized = true;
  return derived();
}

template <class Derived>
Derived& PardisoImpl<Derived>::factorize(const MatrixType& a) {
  eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
  eigen_assert(m_size == a.rows() && m_size == a.cols());

  derived().getMatrix(a);

  Index error;
  error = internal::pardiso_run_selector<StorageIndex>::run(
      m_pt, 1, 1, m_type, 22, internal::convert_index<StorageIndex>(m_size), m_matrix.valuePtr(),
      m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), m_perm.data(), 0, m_iparm.data(), m_msglvl, NULL, NULL);

  manageErrorCode(error);
  m_factorizationIsOk = m_info == Eigen::Success;
  return derived();
}

template <class Derived>
template <typename BDerived, typename XDerived>
void PardisoImpl<Derived>::_solve_impl(const MatrixBase<BDerived>& b, MatrixBase<XDerived>& x) const {
  if (m_iparm[0] == 0)  // Factorization was not computed
  {
    m_info = InvalidInput;
    return;
  }

  // Index n = m_matrix.rows();
  Index nrhs = Index(b.cols());
  eigen_assert(m_size == b.rows());
  eigen_assert(((MatrixBase<BDerived>::Flags & RowMajorBit) == 0 || nrhs == 1) &&
               "Row-major right hand sides are not supported");
  eigen_assert(((MatrixBase<XDerived>::Flags & RowMajorBit) == 0 || nrhs == 1) &&
               "Row-major matrices of unknowns are not supported");
  eigen_assert(((nrhs == 1) || b.outerStride() == b.rows()));

  //  switch (transposed) {
  //    case SvNoTrans    : m_iparm[11] = 0 ; break;
  //    case SvTranspose  : m_iparm[11] = 2 ; break;
  //    case SvAdjoint    : m_iparm[11] = 1 ; break;
  //    default:
  //      //std::cerr << "Eigen: transposition  option \"" << transposed << "\" not supported by the PARDISO backend\n";
  //      m_iparm[11] = 0;
  //  }

  Scalar* rhs_ptr = const_cast<Scalar*>(b.derived().data());
  Matrix<Scalar, Dynamic, Dynamic, ColMajor> tmp;

  // Pardiso cannot solve in-place
  if (rhs_ptr == x.derived().data()) {
    tmp = b;
    rhs_ptr = tmp.data();
  }

  Index error;
  error = internal::pardiso_run_selector<StorageIndex>::run(
      m_pt, 1, 1, m_type, 33, internal::convert_index<StorageIndex>(m_size), m_matrix.valuePtr(),
      m_matrix.outerIndexPtr(), m_matrix.innerIndexPtr(), m_perm.data(), internal::convert_index<StorageIndex>(nrhs),
      m_iparm.data(), m_msglvl, rhs_ptr, x.derived().data());

  manageErrorCode(error);
}

/** \ingroup PardisoSupport_Module
 * \class PardisoLU
 * \brief A sparse direct LU factorization and solver based on the PARDISO library
 *
 * This class allows to solve for A.X = B sparse linear problems via a direct LU factorization
 * using the Intel MKL PARDISO library. The sparse matrix A must be squared and invertible.
 * The vectors or matrices X and B can be either dense or sparse.
 *
 * By default, it runs in in-core mode. To enable PARDISO's out-of-core feature, set:
 * \code solver.pardisoParameterArray()[59] = 1; \endcode
 *
 * \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
 *
 * \implsparsesolverconcept
 *
 * \sa \ref TutorialSparseSolverConcept, class SparseLU
 */
template <typename MatrixType>
class PardisoLU : public PardisoImpl<PardisoLU<MatrixType> > {
 protected:
  typedef PardisoImpl<PardisoLU> Base;
  using Base::m_matrix;
  using Base::pardisoInit;
  friend class PardisoImpl<PardisoLU<MatrixType> >;

 public:
  typedef typename Base::Scalar Scalar;
  typedef typename Base::RealScalar RealScalar;

  using Base::compute;
  using Base::solve;

  PardisoLU() : Base() { pardisoInit(Base::ScalarIsComplex ? 13 : 11); }

  explicit PardisoLU(const MatrixType& matrix) : Base() {
    pardisoInit(Base::ScalarIsComplex ? 13 : 11);
    compute(matrix);
  }

 protected:
  void getMatrix(const MatrixType& matrix) {
    m_matrix = matrix;
    m_matrix.makeCompressed();
  }
};

/** \ingroup PardisoSupport_Module
 * \class PardisoLLT
 * \brief A sparse direct Cholesky (LLT) factorization and solver based on the PARDISO library
 *
 * This class allows to solve for A.X = B sparse linear problems via a LL^T Cholesky factorization
 * using the Intel MKL PARDISO library. The sparse matrix A must be selfajoint and positive definite.
 * The vectors or matrices X and B can be either dense or sparse.
 *
 * By default, it runs in in-core mode. To enable PARDISO's out-of-core feature, set:
 * \code solver.pardisoParameterArray()[59] = 1; \endcode
 *
 * \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
 * \tparam UpLo can be any bitwise combination of Upper, Lower. The default is Upper, meaning only the upper triangular
 * part has to be used. Upper|Lower can be used to tell both triangular parts can be used as input.
 *
 * \implsparsesolverconcept
 *
 * \sa \ref TutorialSparseSolverConcept, class SimplicialLLT
 */
template <typename MatrixType, int UpLo_>
class PardisoLLT : public PardisoImpl<PardisoLLT<MatrixType, UpLo_> > {
 protected:
  typedef PardisoImpl<PardisoLLT<MatrixType, UpLo_> > Base;
  using Base::m_matrix;
  using Base::pardisoInit;
  friend class PardisoImpl<PardisoLLT<MatrixType, UpLo_> >;

 public:
  typedef typename Base::Scalar Scalar;
  typedef typename Base::RealScalar RealScalar;
  typedef typename Base::StorageIndex StorageIndex;
  enum { UpLo = UpLo_ };
  using Base::compute;

  PardisoLLT() : Base() { pardisoInit(Base::ScalarIsComplex ? 4 : 2); }

  explicit PardisoLLT(const MatrixType& matrix) : Base() {
    pardisoInit(Base::ScalarIsComplex ? 4 : 2);
    compute(matrix);
  }

 protected:
  void getMatrix(const MatrixType& matrix) {
    // PARDISO supports only upper, row-major matrices
    PermutationMatrix<Dynamic, Dynamic, StorageIndex> p_null;
    m_matrix.resize(matrix.rows(), matrix.cols());
    m_matrix.template selfadjointView<Upper>() = matrix.template selfadjointView<UpLo>().twistedBy(p_null);
    m_matrix.makeCompressed();
  }
};

/** \ingroup PardisoSupport_Module
 * \class PardisoLDLT
 * \brief A sparse direct Cholesky (LDLT) factorization and solver based on the PARDISO library
 *
 * This class allows to solve for A.X = B sparse linear problems via a LDL^T Cholesky factorization
 * using the Intel MKL PARDISO library. The sparse matrix A is assumed to be selfajoint and positive definite.
 * For complex matrices, A can also be symmetric only, see the \a Options template parameter.
 * The vectors or matrices X and B can be either dense or sparse.
 *
 * By default, it runs in in-core mode. To enable PARDISO's out-of-core feature, set:
 * \code solver.pardisoParameterArray()[59] = 1; \endcode
 *
 * \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
 * \tparam Options can be any bitwise combination of Upper, Lower, and Symmetric. The default is Upper, meaning only the
 * upper triangular part has to be used. Symmetric can be used for symmetric, non-selfadjoint complex matrices, the
 * default being to assume a selfadjoint matrix. Upper|Lower can be used to tell both triangular parts can be used as
 * input.
 *
 * \implsparsesolverconcept
 *
 * \sa \ref TutorialSparseSolverConcept, class SimplicialLDLT
 */
template <typename MatrixType, int Options>
class PardisoLDLT : public PardisoImpl<PardisoLDLT<MatrixType, Options> > {
 protected:
  typedef PardisoImpl<PardisoLDLT<MatrixType, Options> > Base;
  using Base::m_matrix;
  using Base::pardisoInit;
  friend class PardisoImpl<PardisoLDLT<MatrixType, Options> >;

 public:
  typedef typename Base::Scalar Scalar;
  typedef typename Base::RealScalar RealScalar;
  typedef typename Base::StorageIndex StorageIndex;
  using Base::compute;
  enum { UpLo = Options & (Upper | Lower) };

  PardisoLDLT() : Base() { pardisoInit(Base::ScalarIsComplex ? (bool(Options & Symmetric) ? 6 : -4) : -2); }

  explicit PardisoLDLT(const MatrixType& matrix) : Base() {
    pardisoInit(Base::ScalarIsComplex ? (bool(Options & Symmetric) ? 6 : -4) : -2);
    compute(matrix);
  }

  void getMatrix(const MatrixType& matrix) {
    // PARDISO supports only upper, row-major matrices
    PermutationMatrix<Dynamic, Dynamic, StorageIndex> p_null;
    m_matrix.resize(matrix.rows(), matrix.cols());
    m_matrix.template selfadjointView<Upper>() = matrix.template selfadjointView<UpLo>().twistedBy(p_null);
    m_matrix.makeCompressed();
  }
};

}  // end namespace Eigen

#endif  // EIGEN_PARDISOSUPPORT_H
