/*
 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
 ********************************************************************************
*/
// SPDX-License-Identifier: BSD-3-Clause

#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 sparsity 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 have the same sparsity as 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, nullptr, nullptr);
      m_isInitialized = false;
    }
  }

  void pardisoInit(int type) {
    m_type = type;
    bool symmetric = numext::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. (Was number of processors / 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, nullptr, nullptr);
  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, nullptr, nullptr);

  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, nullptr, nullptr);

  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 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 selfadjoint 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 selfadjoint 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
