Description: Call int32_t variants of umfpack methods if size_t is 32bit
On systems where size_t is only 32bit calling the umfpack methods for long integer types (int64_t), i.e.
umfpack_dl* and umfpack_zl*,  does not work.
Hence now check the size of the size_type used in UMPackMatrix and use the umfpack method for integer (umfpack_di*
and umfpackzi* instead) and use the correct interger type for the UMFPack matrix.

This should close #1069532 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1069532

The build has been breaking on armel with the following errors:

 In file included from /<<PKGBUILDDIR>>/dune/istl/paamg/amg.hh:17,
                  from /<<PKGBUILDDIR>>/dune/istl/paamg/test/pthreadamgtest.cc:24:
 /<<PKGBUILDDIR>>/dune/istl/umfpack.hh: In instantiation of ‘static void Dune::UMFPackMethodChooser<double>::symbolic(A ...) [with A = {int, int, long int*, long int*, double*, void**, double*, double*}]’:
 /<<PKGBUILDDIR>>/dune/istl/umfpack.hh:545:23:   required from ‘void Dune::UMFPack<M>::decompose() [with M = Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >]’
 /<<PKGBUILDDIR>>/dune/istl/umfpack.hh:459:7:   required from ‘void Dune::UMFPack<M>::setMatrix(const Matrix&) [with M = Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >; Matrix = Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >]’
 /<<PKGBUILDDIR>>/dune/istl/umfpack.hh:270:7:   required from ‘Dune::UMFPack<M>::UMFPack(const Matrix&, int, bool) [with M = Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >; Matrix = Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >]’
 /<<PKGBUILDDIR>>/dune/istl/paamg/amg.hh:658:18:   required from ‘static Dune::Amg::DirectSolverSelector<Matrix, Vector>::Solver<M, Dune::Amg::DirectSolverSelector<Matrix, Vector>::umfpack>::type* Dune::Amg::DirectSolverSelector<Matrix, Vector>::Solver<M, Dune::Amg::DirectSolverSelector<Matrix, Vector>::umfpack>::create(const M&, bool, bool) [with M = Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >; Matrix = Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >; Vector = Dune::BlockVector<Dune::FieldVector<double, 1> >; type = Dune::UMFPack<Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> > >]’
 /<<PKGBUILDDIR>>/dune/istl/paamg/amg.hh:683:40:   required from ‘static Dune::Amg::DirectSolverSelector<Matrix, Vector>::DirectSolver* Dune::Amg::DirectSolverSelector<Matrix, Vector>::create(const Matrix&, bool, bool) [with Matrix = Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >; Vector = Dune::BlockVector<Dune::FieldVector<double, 1> >; DirectSolver = Dune::UMFPack<Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> > >]’
 /<<PKGBUILDDIR>>/dune/istl/paamg/amg.hh:745:51:   required from ‘void Dune::Amg::AMG<M, X, S, PI, A>::createHierarchies(C&, const std::shared_ptr<const _Tp>&, const PI&) [with C = const Dune::Amg::CoarsenCriterion<Dune::Amg::UnSymmetricCriterion<Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >, Dune::Amg::FirstDiagonal> >; M = Dune::MatrixAdapter<Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> > >; X = Dune::BlockVector<Dune::FieldVector<double, 1> >; S = Dune::SeqSSOR<Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> > >; PI = Dune::Amg::SequentialInformation; A = std::allocator<Dune::BlockVector<Dune::FieldVector<double, 1> > >]’
 /<<PKGBUILDDIR>>/dune/istl/paamg/amg.hh:448:24:   required from ‘Dune::Amg::AMG<M, X, S, PI, A>::AMG(const Operator&, const C&, const SmootherArgs&, const PI&) [with C = Dune::Amg::CoarsenCriterion<Dune::Amg::UnSymmetricCriterion<Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >, Dune::Amg::FirstDiagonal> >; M = Dune::MatrixAdapter<Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> > >; X = Dune::BlockVector<Dune::FieldVector<double, 1> >; S = Dune::SeqSSOR<Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> > >; PI = Dune::Amg::SequentialInformation; A = std::allocator<Dune::BlockVector<Dune::FieldVector<double, 1> > >; Operator = Dune::MatrixAdapter<Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> > >; SmootherArgs = Dune::Amg::DefaultSmootherArgs<double>]’
 /<<PKGBUILDDIR>>/dune/istl/paamg/test/pthreadamgtest.cc:176:7:   required from ‘void testAMG(int, int, int) [with int BS = 1; AMG = Dune::Amg::AMG<Dune::MatrixAdapter<Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> > >, Dune::BlockVector<Dune::FieldVector<double, 1> >, Dune::SeqSSOR<Dune::BCRSMatrix<Dune::FieldMatrix<double, 1, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> >, Dune::BlockVector<Dune::FieldVector<double, 1> > > >]’
 /<<PKGBUILDDIR>>/dune/istl/paamg/test/pthreadamgtest.cc:232:19:   required from here
 /<<PKGBUILDDIR>>/dune/istl/umfpack.hh:106:27: error: cannot convert ‘long int*’ to ‘const int64_t*’ {aka ‘const long long int*’}
   106 |       umfpack_dl_symbolic(args...);
       |                           ^~~~
       |                           |
       |                           long int*
Author: Markus Blatt <markus@dr-blatt.de>
Origin: other
Forwarded: no
Last-Update: 2024-05-08
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/dune/istl/paamg/amg.hh
+++ b/dune/istl/paamg/amg.hh
@@ -630,7 +630,7 @@ namespace Dune
 #if DISABLE_AMG_DIRECTSOLVER
         none;
 #elif HAVE_SUITESPARSE_UMFPACK
-        UMFPackMethodChooser< field_type > :: valid ? umfpack : none ;
+        UMFPackMethodChooser< field_type, std::true_type > :: valid ? umfpack : none ;
 #elif HAVE_SUPERLU
         superlu ;
 #else
--- a/dune/istl/umfpack.hh
+++ b/dune/istl/umfpack.hh
@@ -44,14 +44,14 @@ namespace Dune {
 
   // wrapper class for C-Function Calls in the backend. Choose the right function namespace
   // depending on the template parameter used.
-  template<typename T>
+template<typename SCalar, typename Integer>
   struct UMFPackMethodChooser
   {
     static constexpr bool valid = false ;
   };
 
   template<>
-  struct UMFPackMethodChooser<double>
+  struct UMFPackMethodChooser<double, std::true_type>
   {
     static constexpr bool valid = true ;
 
@@ -108,13 +108,72 @@ namespace Dune {
   };
 
   template<>
-  struct UMFPackMethodChooser<std::complex<double> >
+  struct UMFPackMethodChooser<double, std::false_type>
   {
     static constexpr bool valid = true ;
 
     template<typename... A>
     static void defaults(A... args)
     {
+      umfpack_di_defaults(args...);
+    }
+    template<typename... A>
+    static void free_numeric(A... args)
+    {
+      umfpack_di_free_numeric(args...);
+    }
+    template<typename... A>
+    static void free_symbolic(A... args)
+    {
+      umfpack_di_free_symbolic(args...);
+    }
+    template<typename... A>
+    static int load_numeric(A... args)
+    {
+      return umfpack_di_load_numeric(args...);
+    }
+    template<typename... A>
+    static void numeric(A... args)
+    {
+      umfpack_di_numeric(args...);
+    }
+    template<typename... A>
+    static void report_info(A... args)
+    {
+      umfpack_di_report_info(args...);
+    }
+    template<typename... A>
+    static void report_status(A... args)
+    {
+      umfpack_di_report_status(args...);
+    }
+    template<typename... A>
+    static int save_numeric(A... args)
+    {
+      return umfpack_di_save_numeric(args...);
+    }
+    template<typename... A>
+    static void solve(A... args)
+    {
+      umfpack_di_solve(args...);
+    }
+    template<typename... A>
+    static void symbolic(A... args)
+    {
+      umfpack_di_symbolic(args...);
+    }
+  };
+
+  template<>
+  struct UMFPackMethodChooser<std::complex<double>, std::true_type>
+  {
+    static constexpr bool valid = true ;
+
+    using umf_int_type = int64_t;
+
+    template<typename... A>
+    static void defaults(A... args)
+    {
       umfpack_zl_defaults(args...);
     }
     template<typename... A>
@@ -133,7 +192,7 @@ namespace Dune {
       return umfpack_zl_load_numeric(args...);
     }
     template<typename... A>
-    static void numeric(const long int* cs, const long int* ri, const double* val, A... args)
+    static void numeric(const umf_int_type* cs, const umf_int_type* ri, const double* val, A... args)
     {
       umfpack_zl_numeric(cs,ri,val,NULL,args...);
     }
@@ -153,18 +212,79 @@ namespace Dune {
       return umfpack_zl_save_numeric(args...);
     }
     template<typename... A>
-    static void solve(long int m, const long int* cs, const long int* ri, std::complex<double>* val, double* x, const double* b,A... args)
+    static void solve(umf_int_type m, const umf_int_type* cs, const umf_int_type* ri, std::complex<double>* val, double* x, const double* b,A... args)
     {
       const double* cval = reinterpret_cast<const double*>(val);
       umfpack_zl_solve(m,cs,ri,cval,NULL,x,NULL,b,NULL,args...);
     }
     template<typename... A>
-    static void symbolic(long int m, long int n, const long int* cs, const long int* ri, const double* val, A... args)
+    static void symbolic(umf_int_type m, umf_int_type n, const umf_int_type* cs, const umf_int_type* ri, const double* val, A... args)
     {
       umfpack_zl_symbolic(m,n,cs,ri,val,NULL,args...);
     }
   };
 
+
+  template<>
+  struct UMFPackMethodChooser<std::complex<double>, std::false_type>
+  {
+    static constexpr bool valid = true ;
+
+    using umf_int_type = int32_t;
+
+    template<typename... A>
+    static void defaults(A... args)
+    {
+      umfpack_zi_defaults(args...);
+    }
+    template<typename... A>
+    static void free_numeric(A... args)
+    {
+      umfpack_zi_free_numeric(args...);
+    }
+    template<typename... A>
+    static void free_symbolic(A... args)
+    {
+      umfpack_zi_free_symbolic(args...);
+    }
+    template<typename... A>
+    static int load_numeric(A... args)
+    {
+      return umfpack_zi_load_numeric(args...);
+    }
+    template<typename... A>
+    static void numeric(const umf_int_type* cs, const umf_int_type* ri, const double* val, A... args)
+    {
+      umfpack_zi_numeric(cs,ri,val,NULL,args...);
+    }
+    template<typename... A>
+    static void report_info(A... args)
+    {
+      umfpack_zi_report_info(args...);
+    }
+    template<typename... A>
+    static void report_status(A... args)
+    {
+      umfpack_zi_report_status(args...);
+    }
+    template<typename... A>
+    static int save_numeric(A... args)
+    {
+      return umfpack_zi_save_numeric(args...);
+    }
+    template<typename... A>
+    static void solve(umf_int_type m, const umf_int_type* cs, const umf_int_type* ri, std::complex<double>* val, double* x, const double* b,A... args)
+    {
+      const double* cval = reinterpret_cast<const double*>(val);
+      umfpack_zi_solve(m,cs,ri,cval,NULL,x,NULL,b,NULL,args...);
+    }
+    template<typename... A>
+    static void symbolic(umf_int_type m, std::size_t n, const umf_int_type* cs, const umf_int_type* ri, const double* val, A... args)
+    {
+      umfpack_zi_symbolic(m,n,cs,ri,val,NULL,args...);
+    }
+  };
+
   namespace Impl
   {
     template<class M>
@@ -219,10 +339,11 @@ namespace Dune {
     /** @brief The matrix type. */
     using Matrix = M;
     using matrix_type = M;
+    using umf_int_type = std::conditional_t<(sizeof(typename M::size_type) == 8), int64_t, int32_t>;
     /** @brief The corresponding UMFPack matrix type.*/
-    typedef ISTL::Impl::BCCSMatrix<typename Matrix::field_type, long int> UMFPackMatrix;
+    typedef ISTL::Impl::BCCSMatrix<typename Matrix::field_type, umf_int_type> UMFPackMatrix;
     /** @brief Type of an associated initializer class. */
-    typedef ISTL::Impl::BCCSMatrixInitializer<M, long int> MatrixInitializer;
+    typedef ISTL::Impl::BCCSMatrixInitializer<M, umf_int_type> MatrixInitializer;
     /** @brief The type of the domain of the solver. */
     using domain_type = typename Impl::UMFPackVectorChooser<M>::domain_type;
     /** @brief The type of the range of the solver. */
@@ -452,7 +573,7 @@ namespace Dune {
         umfpackMatrix_.free();
       umfpackMatrix_.setSize(MatrixDimension<Matrix>::rowdim(matrix),
                              MatrixDimension<Matrix>::coldim(matrix));
-      ISTL::Impl::BCCSMatrixInitializer<Matrix, long int> initializer(umfpackMatrix_);
+      ISTL::Impl::BCCSMatrixInitializer<Matrix, umf_int_type> initializer(umfpackMatrix_);
 
       copyToBCCSMatrix(initializer, matrix);
 
@@ -470,7 +591,7 @@ namespace Dune {
 
       umfpackMatrix_.setSize(rowIndexSet.size()*MatrixDimension<Matrix>::rowdim(_mat) / _mat.N(),
                              rowIndexSet.size()*MatrixDimension<Matrix>::coldim(_mat) / _mat.M());
-      ISTL::Impl::BCCSMatrixInitializer<Matrix, long int> initializer(umfpackMatrix_);
+      ISTL::Impl::BCCSMatrixInitializer<Matrix, umf_int_type> initializer(umfpackMatrix_);
 
       copyToBCCSMatrix(initializer, ISTL::Impl::MatrixRowSubset<Matrix,std::set<std::size_t> >(_mat,rowIndexSet));
 
@@ -532,7 +653,7 @@ namespace Dune {
     const char* name() { return "UMFPACK"; }
 
     private:
-    typedef typename Dune::UMFPackMethodChooser<T> Caller;
+      typedef typename Dune::UMFPackMethodChooser<T,std::integral_constant<bool, (sizeof(typename M::size_type) == 8)>> Caller;
 
     template<class Mat,class X, class TM, class TD, class T1>
     friend class SeqOverlappingSchwarz;
@@ -542,8 +663,8 @@ namespace Dune {
     void decompose()
     {
       double UMF_Decomposition_Info[UMFPACK_INFO];
-      Caller::symbolic(static_cast<int>(umfpackMatrix_.N()),
-                       static_cast<int>(umfpackMatrix_.N()),
+      Caller::symbolic(static_cast<umf_int_type>(umfpackMatrix_.N()),
+                       static_cast<umf_int_type>(umfpackMatrix_.N()),
                        umfpackMatrix_.getColStart(),
                        umfpackMatrix_.getRowIndex(),
                        reinterpret_cast<double*>(umfpackMatrix_.getValues()),
