GEOSX
HypreUtils.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2018-2020 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2020 The Board of Trustees of the Leland Stanford Junior University
7  * Copyright (c) 2018-2020 TotalEnergies
8  * Copyright (c) 2019- GEOSX Contributors
9  * All rights reserved
10  *
11  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
12  * ------------------------------------------------------------------------------------------------------------
13  */
14 
19 #ifndef GEOS_LINEARALGEBRA_INTERFACES_HYPREUTILS_HPP_
20 #define GEOS_LINEARALGEBRA_INTERFACES_HYPREUTILS_HPP_
21 
22 #include "common/DataTypes.hpp"
23 #include "common/GEOS_RAJA_Interface.hpp"
24 
25 #include "codingUtilities/Utilities.hpp"
27 
28 #include <HYPRE_krylov.h>
29 #include <HYPRE_parcsr_ls.h>
30 
31 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_CUDA || GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_HIP
33 #define GEOS_HYPRE_DEVICE GEOS_DEVICE
35 #define GEOS_HYPRE_HOST_DEVICE GEOS_HOST_DEVICE
36 #else
38 #define GEOS_HYPRE_DEVICE
40 #define GEOS_HYPRE_HOST_DEVICE
41 #endif
42 
43 namespace geos
44 {
45 
53 {
55  using SetupFunc = HYPRE_Int (*)( HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector );
56 
58  using SolveFunc = HYPRE_Int (*)( HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector );
59 
61  using DestroyFunc = HYPRE_Int (*)( HYPRE_Solver );
62 
63  HYPRE_Solver ptr{};
67 };
68 
72 namespace hypre
73 {
74 
79 constexpr HYPRE_MemoryLocation getMemoryLocation( LvArray::MemorySpace const space )
80 {
81  switch( space )
82  {
83  case hostMemorySpace: return HYPRE_MEMORY_HOST;
84 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_CUDA
85  case LvArray::MemorySpace::cuda: return HYPRE_MEMORY_DEVICE;
86 #endif
87 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_HIP
88  case LvArray::MemorySpace::hip: return HYPRE_MEMORY_DEVICE;
89 #endif
90  default: return HYPRE_MEMORY_HOST;
91  }
92 }
93 
98 constexpr LvArray::MemorySpace getLvArrayMemorySpace( HYPRE_MemoryLocation const location )
99 {
100  switch( location )
101  {
102  case HYPRE_MEMORY_HOST: return hostMemorySpace;
103 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_CUDA
104  case HYPRE_MEMORY_DEVICE: return parallelDeviceMemorySpace;
105 #endif
106 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_HIP
107  case HYPRE_MEMORY_DEVICE: return parallelDeviceMemorySpace;
108 #endif
109  default: return hostMemorySpace;
110  }
111 }
112 
113 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_CUDA || GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_HIP
114 
116 using execPolicy = parallelDevicePolicy<>;
118 constexpr LvArray::MemorySpace memorySpace = parallelDeviceMemorySpace;
120 constexpr HYPRE_MemoryLocation memoryLocation = HYPRE_MEMORY_DEVICE;
121 
122 #else
123 
125 using execPolicy = parallelHostPolicy;
127 constexpr LvArray::MemorySpace memorySpace = hostMemorySpace;
129 constexpr HYPRE_MemoryLocation memoryLocation = HYPRE_MEMORY_HOST;
130 
131 #endif
132 
133 // Check matching requirements on index/value types between GEOSX and Hypre
134 
135 // WARNING. We don't have consistent types between HYPRE_Int and localIndex.
136 // Decision needs to be made either to use bigint option, or change
137 // localIndex to int. We are getting away with this because we do not
138 // pass ( localIndex * ) to hypre except when it is on the GPU, in
139 // which case we are using int for localIndex.
140 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_CUDA || GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_HIP
141 static_assert( sizeof( HYPRE_Int ) == sizeof( geos::localIndex ),
142  "HYPRE_Int and geos::localIndex must have the same size" );
143 static_assert( std::is_signed< HYPRE_Int >::value == std::is_signed< geos::localIndex >::value,
144  "HYPRE_Int and geos::localIndex must both be signed or unsigned" );
145 #endif
146 
153 inline void checkDeviceErrors( char const * msg, char const * file, int const line )
154 {
155 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_CUDA
156  cudaError_t const err = cudaGetLastError();
157  GEOS_ERROR_IF( err != cudaSuccess, GEOS_FMT( "Previous CUDA errors found: {} ({} at {}:{})", msg, cudaGetErrorString( err ), file, line ) );
158 #elif GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_HIP
159  hipError_t const err = hipGetLastError();
160  GEOS_UNUSED_VAR( msg, file, line ); // on crusher geosx_error_if ultimately resolves to an assert, which drops the content on release
161  // builds
162  GEOS_ERROR_IF( err != hipSuccess, GEOS_FMT( "Previous HIP errors found: {} ({} at {}:{})", msg, hipGetErrorString( err ), file, line ) );
163 #else
164  GEOS_UNUSED_VAR( msg, file, line );
165 #endif
166 }
167 
172 #define GEOS_HYPRE_CHECK_DEVICE_ERRORS( msg ) ::geos::hypre::checkDeviceErrors( msg, __FILE__, __LINE__ )
173 
174 static_assert( sizeof( HYPRE_BigInt ) == sizeof( geos::globalIndex ),
175  "HYPRE_BigInt and geos::globalIndex must have the same size" );
176 
177 static_assert( std::is_signed< HYPRE_BigInt >::value == std::is_signed< geos::globalIndex >::value,
178  "HYPRE_BigInt and geos::globalIndex must both be signed or unsigned" );
179 
180 static_assert( std::is_same< HYPRE_Real, geos::real64 >::value,
181  "HYPRE_Real and geos::real64 must be the same type" );
182 
188 inline HYPRE_BigInt * toHypreBigInt( geos::globalIndex * const index )
189 {
190  return reinterpret_cast< HYPRE_BigInt * >(index);
191 }
192 
198 inline HYPRE_BigInt const * toHypreBigInt( geos::globalIndex const * const index )
199 {
200  return reinterpret_cast< HYPRE_BigInt const * >(index);
201 }
202 
211 HYPRE_Vector parVectorToVectorAll( HYPRE_ParVector const vec );
212 
219 HYPRE_Int dummySetup( HYPRE_Solver,
220  HYPRE_ParCSRMatrix,
221  HYPRE_ParVector,
222  HYPRE_ParVector );
223 
232 HYPRE_Int SuperLUDistSolve( HYPRE_Solver solver,
233  HYPRE_ParCSRMatrix A,
234  HYPRE_ParVector b,
235  HYPRE_ParVector x );
236 
242 HYPRE_Int SuperLUDistDestroy( HYPRE_Solver solver );
243 
250 HYPRE_Int relaxationCreate( HYPRE_Solver & solver,
251  HYPRE_Int const type );
252 
261 HYPRE_Int relaxationSetup( HYPRE_Solver solver,
262  HYPRE_ParCSRMatrix A,
263  HYPRE_ParVector b,
264  HYPRE_ParVector x );
265 
274 HYPRE_Int relaxationSolve( HYPRE_Solver solver,
275  HYPRE_ParCSRMatrix A,
276  HYPRE_ParVector b,
277  HYPRE_ParVector x );
278 
284 HYPRE_Int relaxationDestroy( HYPRE_Solver solver );
285 
292 {
294  {
297  };
298  return findOption( typeMap, type, "multigrid cycle", "HyprePreconditioner" );
299 }
300 
307 {
309  {
318  };
319  return findOption( typeMap, type, "multigrid relaxation", "HyprePreconditioner" );
320 }
321 
328 {
330  {
342  };
343  return findOption( typeMap, type, "multigrid interpolation", "HyprePreconditioner" );
344 }
345 
352 {
354  {
364  };
365  return findOption( typeMap, type, "multigrid aggressive interpolation", "HyprePreconditioner" );
366 }
367 
374 {
376  {
379  };
380  return findOption( typeMap, type, "ILU", "HyprePreconditioner" );
381 }
382 
389 {
391  {
401  };
402  return findOption( typeMap, type, "multigrid coarse solver", "HyprePreconditioner" );
403 }
404 
411 {
413  {
420  };
421  return findOption( typeMap, type, "multigrid coarsening", "HyprePreconditioner" );
422 }
423 
430 {
432  {
440  };
441  return findOption( typeMap, type, "relaxation", "HyprePreconditioner" );
442 }
443 
450 {
452  {
455  };
456  return findOption( typeMap, type, "ILU", "HyprePreconditioner" );
457 }
458 
463 enum class AMGCoarseningType : HYPRE_Int
464 {
465  CLJP = 0,
466  Ruge_Stueben = 3,
467  Falgout = 6,
468  CLJPDebug = 7,
469  PMIS = 8,
470  PMISDebug = 9,
471  HMIS = 10,
472  CGC = 21,
473  CGC_E = 22
474 };
475 
480 enum class MGRInterpolationType : HYPRE_Int
481 {
482  injection = 0,
483  l1jacobi = 1,
484  jacobi = 2,
486  approximateInverse = 4,
487  blockJacobi = 12
488 };
489 
495 enum class MGRRestrictionType : HYPRE_Int
496 {
497  injection = 0,
498  jacobi = 2,
499  approximateInverse = 3,
500  blockJacobi = 12,
501  cprLike = 13,
502  blockColLumped = 14
503 };
504 
509 enum class MGRCoarseGridMethod : HYPRE_Int
510 {
511  galerkin = 0,
512  nonGalerkin = 1,
514  cprLikeDiag = 2,
516  cprLikeBlockDiag = 3,
518  approximateInverse = 4,
520  galerkinRAI = 5
521 };
522 
527 enum class MGRFRelaxationType : HYPRE_Int
528 {
529  none = -1,
531  amgVCycle = 2,
535  jacobi = 7,
537  gsElim = 9,
538  l1forwardGaussSeidel = 13,
539  l1backwardGaussSeidel = 14,
540  l1jacobi = 18,
541  gsElimWPivoting = 99,
542  gsElimWInverse = 199
543 };
544 
549 enum class MGRGlobalSmootherType : HYPRE_Int
550 {
551  none = -1,
552  blockJacobi = 0,
553  blockGaussSeidel = 1,
554  jacobi = 2,
555  ilu0 = 16
556 };
557 
558 } // namespace hypre
559 
560 } // namespace geos
561 
562 #endif /*GEOS_LINEARALGEBRA_INTERFACES_HYPREUTILS_HPP_*/
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
Definition: GeosxMacros.hpp:83
#define GEOS_ERROR_IF(EXP, msg)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:107
Base template for ordered and unordered maps.
Definition: DataTypes.hpp:369
HYPRE_Int getAMGInterpolationType(LinearSolverParameters::AMG::InterpType const &type)
Returns hypre's identifier of the AMG interpolation type.
Definition: HypreUtils.hpp:327
MGRCoarseGridMethod
This enum class specifies the strategy for level coarse grid computation in MGR.
Definition: HypreUtils.hpp:510
@ galerkinRAI
Galerkin coarse grid computation with arbitrary classical restriction and injective prolongation.
@ galerkin
Galerkin coarse grid computation using RAP.
MGRRestrictionType
This enum class specifies the strategy for computing the level restriction operator in MGR.
Definition: HypreUtils.hpp:496
@ blockColLumped
Block column-lumped approximation.
@ approximateInverse
Approximate inverse.
@ cprLike
CPR-like restriction.
HYPRE_Int getAMGAggressiveInterpolationType(LinearSolverParameters::AMG::AggInterpType const &type)
Returns hypre's identifier of the AMG aggressive interpolation type.
Definition: HypreUtils.hpp:351
HYPRE_Vector parVectorToVectorAll(HYPRE_ParVector const vec)
Gather a parallel vector on a every rank.
HYPRE_Int getRelaxationType(LinearSolverParameters::PreconditionerType const type)
Returns hypre's identifier of the relaxation preconditioner type.
Definition: HypreUtils.hpp:429
HYPRE_BigInt * toHypreBigInt(geos::globalIndex *const index)
Converts a non-const array from GEOSX globalIndex type to HYPRE_BigInt.
Definition: HypreUtils.hpp:188
HYPRE_Int relaxationSolve(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector b, HYPRE_ParVector x)
Solve with a relaxation-based smoother.
constexpr HYPRE_MemoryLocation memoryLocation
Memory location used by hypre matrix/vector objects.
Definition: HypreUtils.hpp:120
HYPRE_Int getILUType(LinearSolverParameters::AMG::SmootherType const type)
Returns hypre's identifier of the AMG ILU smoother type.
Definition: HypreUtils.hpp:373
MGRFRelaxationType
This enum class specifies the F-relaxation type.
Definition: HypreUtils.hpp:528
@ amgVCycle
Full AMG VCycle solver.
@ none
no F-relaxation if performed
@ l1forwardGaussSeidel
Gauss-Seidel, forward solve
@ forwardHybridGaussSeidel
hybrid Gauss-Seidel or SOR, forward solve
@ gsElimWInverse
Direct Inversion with Gaussian Elimination (OK for larger systems)
@ backwardHybridGaussSeidel
hybrid Gauss-Seidel or SOR, backward solve
@ hybridSymmetricGaussSeidel
hybrid symmetric Gauss-Seidel or SSOR
@ l1hybridSymmetricGaussSeidel
-scaled hybrid symmetric Gauss-Seidel
@ l1backwardGaussSeidel
Gauss-Seidel, backward solve
@ singleVCycleSmoother
V(1,0) cycle smoother.
@ gsElimWPivoting
Gaussian Elimination with pivoting direct solver (for small systems)
@ gsElim
Gaussian Elimination direct solver (for small systems)
HYPRE_Int getAMGRelaxationType(LinearSolverParameters::AMG::SmootherType const &type)
Returns hypre's identifier of the AMG smoother type.
Definition: HypreUtils.hpp:306
HYPRE_Int dummySetup(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector)
Dummy function that does nothing but conform to hypre's signature for preconditioner setup/apply func...
AMGCoarseningType
This enum class specifies the AMG parallel coarsening algorithm.
Definition: HypreUtils.hpp:464
@ CLJP
Parallel coarsening algorithm using independent sets.
@ Falgout
Uses Ruge_Stueben first, followed by CLJP.
@ Ruge_Stueben
Classical Ruge-Stueben coarsening on each processor.
@ PMIS
Parallel coarsening algorithm using independent sets.
@ CGC_E
Coarsening by M. Griebel, B. Metsch and A. Schweitzer.
@ HMIS
Uses one pass Ruge-Stueben on each processor independently, followed by PMIS.
@ CLJPDebug
Using a fixed random vector, for debugging purposes only.
@ PMISDebug
Using a fixed random vector, for debugging purposes only.
@ CGC
Coarsening by M. Griebel, B. Metsch and A. Schweitzer.
HYPRE_Int relaxationSetup(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector b, HYPRE_ParVector x)
Setup a relaxation-based smoother.
HYPRE_Int relaxationCreate(HYPRE_Solver &solver, HYPRE_Int const type)
Create a relaxation-based smoother.
constexpr HYPRE_MemoryLocation getMemoryLocation(LvArray::MemorySpace const space)
Definition: HypreUtils.hpp:79
HYPRE_Int getAMGCoarseType(LinearSolverParameters::AMG::CoarseType const &type)
Returns hypre's identifier of the AMG coarse solver type.
Definition: HypreUtils.hpp:388
constexpr LvArray::MemorySpace getLvArrayMemorySpace(HYPRE_MemoryLocation const location)
Definition: HypreUtils.hpp:98
HYPRE_Int getAMGCycleType(LinearSolverParameters::AMG::CycleType const &type)
Returns hypre's identifier of the AMG cycle type.
Definition: HypreUtils.hpp:291
HYPRE_Int relaxationDestroy(HYPRE_Solver solver)
Destroy a relaxation-based smoother.
HYPRE_Int getAMGCoarseningType(LinearSolverParameters::AMG::CoarseningType const &type)
Returns hypre's identifier of the AMG coarsening type.
Definition: HypreUtils.hpp:410
HYPRE_Int SuperLUDistSolve(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector b, HYPRE_ParVector x)
The missing wrapper compatible with hypre solver solve signature.
HYPRE_Int SuperLUDistDestroy(HYPRE_Solver solver)
The missing wrapper compatible with hypre solver destroy signature.
void checkDeviceErrors(char const *msg, char const *file, int const line)
Definition: HypreUtils.hpp:153
MGRInterpolationType
This enum class specifies the strategy for computing the level intepolation operator in MGR.
Definition: HypreUtils.hpp:481
@ classicalModifiedInterpolation
Classical modified interpolation.
@ approximateInverse
Approximate inverse.
constexpr LvArray::MemorySpace memorySpace
Memory space used by hypre matrix/vector objects.
Definition: HypreUtils.hpp:118
MGRGlobalSmootherType
This enum class specifies the global smoother type.
Definition: HypreUtils.hpp:550
@ none
no global smoothing is performed (default)
@ ilu0
incomplete LU factorization
parallelDevicePolicy<> execPolicy
Execution policy for operations on hypre data.
Definition: HypreUtils.hpp:116
GEOSX_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:128
GEOSX_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:125
Container for hypre preconditioner function pointers.
Definition: HypreUtils.hpp:53
HYPRE_Int(*)(HYPRE_Solver) DestroyFunc
Alias for destroy function type.
Definition: HypreUtils.hpp:61
HYPRE_Int(*)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector) SolveFunc
Alias for apply function type.
Definition: HypreUtils.hpp:58
HYPRE_Int(*)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector) SetupFunc
Alias for setup function type.
Definition: HypreUtils.hpp:55
HYPRE_Solver ptr
pointer to preconditioner
Definition: HypreUtils.hpp:63
SetupFunc setup
pointer to setup function
Definition: HypreUtils.hpp:64
DestroyFunc destroy
pointer to destroy function
Definition: HypreUtils.hpp:66
SolveFunc solve
pointer to apply function
Definition: HypreUtils.hpp:65
InterpType
AMG interpolation type (HYPRE only)
@ modifiedExtendedI
Modularized extended+i (GPU support)
@ modifiedExtendedE
Modularized extended+e (GPU support)
@ modifiedExtended
Modularized extended classical (GPU support)
@ directBAMG
Direct with separation of weights (GPU support)
@ extended
Extended classical (GPU support)
@ chebyshev
Chebyshev polynomial smoothing.
@ l1sgs
l1-Symmetric Gauss-Seidel smoothing
@ ilut
Incomplete LU with thresholding.
@ sgs
Symmetric Gauss-Seidel smoothing.
@ bgs
Gauss-Seidel smoothing (backward sweep)
@ fgs
Gauss-Seidel smoothing (forward sweep)
CoarseningType
AMG coarsening types (HYPRE only)
@ CLJP
A parallel coarsening algorithm using independent sets.
@ Falgout
Ruge-Stueben followed by CLJP.
@ RugeStueben
Classical Ruge-Stueben on each processor, followed by a third pass.
@ PMIS
Parallel coarsening as CLJP but with lower complexities (GPU support)
AggInterpType
AMG interpolation type for aggressive coarsening levels (HYPRE only)
@ modifiedExtendedI
Modularized Extended+i (GPU support)
@ extendedIStage2
Extended+i 2-stage (GPU support)
@ modifiedExtendedE
Modularized Extended+e (GPU support)
@ modifiedExtended
Modularized Extended (GPU support)
@ modifiedMultipass
Modularized Multipass (GPU support)
@ extendedStage2
Extended 2-stage (GPU support)
@ jacobi
Jacobi (GPU support in hypre)
@ chebyshev
Chebyshev polynomial (GPU support in hypre)
@ l1jacobi
l1-Jacobi (GPU support in hypre)
@ direct
Direct solver as preconditioner.
@ bgs
Gauss-Seidel smoothing (backward sweep)
@ chebyshev
Chebyshev polynomial smoothing.
@ iluk
Incomplete LU with k-level of fill.
@ l1sgs
l1-Symmetric Gauss-Seidel smoothing
@ ilut
Incomplete LU with thresholding.
@ sgs
Symmetric Gauss-Seidel smoothing.
@ bgs
Gauss-Seidel smoothing (backward sweep)
@ fgs
Gauss-Seidel smoothing (forward sweep)