SparseCholesky: skip Scalar-typed AMD prep when OrderingType is AMD

libeigen/eigen!2494

Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
diff --git a/Eigen/src/SparseCholesky/SimplicialCholesky.h b/Eigen/src/SparseCholesky/SimplicialCholesky.h
index 997bc22..e91c3be 100644
--- a/Eigen/src/SparseCholesky/SimplicialCholesky.h
+++ b/Eigen/src/SparseCholesky/SimplicialCholesky.h
@@ -32,6 +32,37 @@
   typedef MatrixType const* ConstMatrixPtr;
   static void run(const MatrixType& input, ConstMatrixPtr& pmat, MatrixType& /*tmp*/) { pmat = &input; }
 };
+
+// Compute a fill-reducing permutation for SimplicialCholesky. The generic path
+// builds the full Scalar-valued symmetric matrix that the user's OrderingType
+// expects. The AMDOrdering specialization below skips that copy: AMD reads
+// only the sparsity pattern, so we can hand it a SparseSelfAdjointView<UpLo>
+// whose pattern-only overload materializes the underlying triangle as
+// SparseMatrix<signed char> and expands once.
+template <bool UseAMDFastPath>
+struct simplicial_cholesky_amd_dispatch {
+  template <int UpLo_, bool NonHermitian, typename Ordering, typename MatrixType, typename CholMatrixType,
+            typename Perm>
+  static void run(const MatrixType& a, CholMatrixType& C, Perm& perm) {
+    permute_symm_to_fullsymm<UpLo_, NonHermitian>(a, C, NULL);
+    Ordering ordering;
+    ordering(C, perm);
+  }
+};
+
+template <>
+struct simplicial_cholesky_amd_dispatch<true> {
+  template <int UpLo_, bool /*NonHermitian*/, typename Ordering, typename MatrixType, typename CholMatrixType,
+            typename Perm>
+  static void run(const MatrixType& a, CholMatrixType& /*C*/, Perm& perm) {
+    // Pattern-only: works for both Hermitian and NonHermitian variants because
+    // AMD's selfadjointView overload never reads scalar values, so the
+    // selfadjoint-vs-symmetric distinction (which only affects value
+    // expansion) is irrelevant.
+    Ordering ordering;
+    ordering(a.template selfadjointView<UpLo_>(), perm);
+  }
+};
 }  // end namespace internal
 
 /** \ingroup SparseCholesky_Module
@@ -838,10 +869,9 @@
   if (!internal::is_same<OrderingType, NaturalOrdering<StorageIndex> >::value) {
     {
       CholMatrixType C;
-      internal::permute_symm_to_fullsymm<UpLo, NonHermitian>(a, C, NULL);
-
-      OrderingType ordering;
-      ordering(C, m_Pinv);
+      constexpr bool kUseAMDFastPath = internal::is_same<OrderingType, AMDOrdering<StorageIndex> >::value;
+      internal::simplicial_cholesky_amd_dispatch<kUseAMDFastPath>::template run<UpLo, NonHermitian, OrderingType>(
+          a, C, m_Pinv);
     }
 
     if (m_Pinv.size() > 0)