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).

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,7 +108,64 @@ 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 ;
 
@@ -165,6 +222,65 @@ namespace Dune {
     }
   };
 
+
+  template<>
+  struct UMFPackMethodChooser<std::complex<double>, std::false_type>
+  {
+    static constexpr bool valid = true ;
+
+    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 long int* cs, const long int* 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(long int m, const long int* cs, const long int* 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(long int m, long int n, const long int* cs, const long int* ri, const double* val, A... args)
+    {
+      umfpack_zi_symbolic(m,n,cs,ri,val,NULL,args...);
+    }
+  };
+
   namespace Impl
   {
     template<class M>
@@ -532,7 +648,8 @@ 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 UMFPackMatrix::size_type) == 8)> Caller;
+      typedef typename Dune::UMFPackMethodChooser<T,std::integral_constant<bool, true>> Caller;
 
     template<class Mat,class X, class TM, class TD, class T1>
     friend class SeqOverlappingSchwarz;
