GEOS
HypreUtils.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2024 TotalEnergies
7  * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
8  * Copyright (c) 2023-2024 Chevron
9  * Copyright (c) 2019- GEOS/GEOSX Contributors
10  * All rights reserved
11  *
12  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
13  * ------------------------------------------------------------------------------------------------------------
14  */
15 
20 #ifndef GEOS_LINEARALGEBRA_INTERFACES_HYPREUTILS_HPP_
21 #define GEOS_LINEARALGEBRA_INTERFACES_HYPREUTILS_HPP_
22 
23 #include "common/DataTypes.hpp"
24 #include "common/GEOS_RAJA_Interface.hpp"
25 #include "common/MpiWrapper.hpp"
26 
27 #include "codingUtilities/Utilities.hpp"
29 
30 #include <HYPRE_krylov.h>
31 #include <HYPRE_parcsr_ls.h>
32 
37 #define GEOS_HYPRE_DEVICE GEOS_HOST_DEVICE
38 
39 namespace geos
40 {
41 
42 class HypreMatrix;
43 class HypreVector;
44 
52 {
54  using SetupFunc = HYPRE_Int (*)( HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector );
55 
57  using SolveFunc = HYPRE_Int (*)( HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector );
58 
60  using DestroyFunc = HYPRE_Int (*)( HYPRE_Solver );
61 
62  HYPRE_Solver ptr{};
66 };
67 
71 namespace hypre
72 {
73 
78 constexpr HYPRE_MemoryLocation getMemoryLocation( LvArray::MemorySpace const space )
79 {
80  switch( space )
81  {
82  case hostMemorySpace: return HYPRE_MEMORY_HOST;
83 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_CUDA
84  case LvArray::MemorySpace::cuda: return HYPRE_MEMORY_DEVICE;
85 #endif
86 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_HIP
87  case LvArray::MemorySpace::hip: return HYPRE_MEMORY_DEVICE;
88 #endif
89  default: return HYPRE_MEMORY_HOST;
90  }
91 }
92 
97 constexpr LvArray::MemorySpace getLvArrayMemorySpace( HYPRE_MemoryLocation const location )
98 {
99  switch( location )
100  {
101  case HYPRE_MEMORY_HOST: return hostMemorySpace;
102 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_CUDA
103  case HYPRE_MEMORY_DEVICE: return parallelDeviceMemorySpace;
104 #endif
105 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_HIP
106  case HYPRE_MEMORY_DEVICE: return parallelDeviceMemorySpace;
107 #endif
108  default: return hostMemorySpace;
109  }
110 }
111 
112 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_CUDA || GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_HIP
113 
115 using execPolicy = parallelDevicePolicy<>;
117 constexpr LvArray::MemorySpace memorySpace = parallelDeviceMemorySpace;
119 constexpr HYPRE_MemoryLocation memoryLocation = HYPRE_MEMORY_DEVICE;
120 
121 #else
122 
124 using execPolicy = parallelHostPolicy;
126 constexpr LvArray::MemorySpace memorySpace = hostMemorySpace;
128 constexpr HYPRE_MemoryLocation memoryLocation = HYPRE_MEMORY_HOST;
129 
130 #endif
131 
132 // Check matching requirements on index/value types between GEOS and Hypre
133 
134 // WARNING. We don't have consistent types between HYPRE_Int and localIndex.
135 // Decision needs to be made either to use bigint option, or change
136 // localIndex to int. We are getting away with this because we do not
137 // pass ( localIndex * ) to hypre except when it is on the GPU, in
138 // which case we are using int for localIndex.
139 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_CUDA || GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_HIP
140 static_assert( sizeof( HYPRE_Int ) == sizeof( geos::localIndex ),
141  "HYPRE_Int and geos::localIndex must have the same size" );
142 static_assert( std::is_signed< HYPRE_Int >::value == std::is_signed< geos::localIndex >::value,
143  "HYPRE_Int and geos::localIndex must both be signed or unsigned" );
144 #endif
145 
152 inline void checkDeviceErrors( char const * msg, char const * file, int const line )
153 {
154 #if GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_CUDA
155  cudaError_t const err = cudaGetLastError();
156  GEOS_ERROR_IF( err != cudaSuccess, GEOS_FMT( "Previous CUDA errors found: {} ({} at {}:{})", msg, cudaGetErrorString( err ), file, line ) );
157 #elif GEOS_USE_HYPRE_DEVICE == GEOS_USE_HYPRE_HIP
158  hipError_t const err = hipGetLastError();
159  GEOS_UNUSED_VAR( msg, file, line ); // on crusher geos_error_if ultimately resolves to an assert, which drops the content on release
160  // builds
161  GEOS_ERROR_IF( err != hipSuccess, GEOS_FMT( "Previous HIP errors found: {} ({} at {}:{})", msg, hipGetErrorString( err ), file, line ) );
162 #else
163  GEOS_UNUSED_VAR( msg, file, line );
164 #endif
165 }
166 
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 
212 HYPRE_Vector parVectorToVectorAll( HYPRE_ParVector const vec );
213 
221 HYPRE_Vector parVectorToVector( HYPRE_ParVector const vec, int const targetRank );
222 
229 HYPRE_Int dummySetup( HYPRE_Solver,
230  HYPRE_ParCSRMatrix,
231  HYPRE_ParVector,
232  HYPRE_ParVector );
233 
244  array1d< int > & labels );
245 
254  MPI_Comm const comm,
255  array1d< HYPRE_Int > & tags,
256  HYPRE_Int & numTags );
257 
258 namespace testing
259 {
260 
267 
272 
273 }
274 
283 HYPRE_Int SuperLUDistSolve( HYPRE_Solver solver,
284  HYPRE_ParCSRMatrix A,
285  HYPRE_ParVector b,
286  HYPRE_ParVector x );
287 
293 HYPRE_Int SuperLUDistDestroy( HYPRE_Solver solver );
294 
301 HYPRE_Int relaxationCreate( HYPRE_Solver & solver,
302  HYPRE_Int const type );
303 
312 HYPRE_Int relaxationSetup( HYPRE_Solver solver,
313  HYPRE_ParCSRMatrix A,
314  HYPRE_ParVector b,
315  HYPRE_ParVector x );
316 
325 HYPRE_Int relaxationSolve( HYPRE_Solver solver,
326  HYPRE_ParCSRMatrix A,
327  HYPRE_ParVector b,
328  HYPRE_ParVector x );
329 
335 HYPRE_Int relaxationDestroy( HYPRE_Solver solver );
336 
344 HYPRE_Int chebyshevCreate( HYPRE_Solver & solver,
345  HYPRE_Int const order,
346  HYPRE_Int const eigNumIter );
347 
356 HYPRE_Int chebyshevSetup( HYPRE_Solver solver,
357  HYPRE_ParCSRMatrix A,
358  HYPRE_ParVector b,
359  HYPRE_ParVector x );
360 
369 HYPRE_Int chebyshevSolve( HYPRE_Solver solver,
370  HYPRE_ParCSRMatrix A,
371  HYPRE_ParVector b,
372  HYPRE_ParVector x );
373 
379 HYPRE_Int chebyshevDestroy( HYPRE_Solver solver );
380 
387 {
389  {
392  };
393  return findOption( typeMap, type, "multigrid cycle", "HyprePreconditioner" );
394 }
395 
402 {
404  {
413  };
414  return findOption( typeMap, type, "multigrid relaxation", "HyprePreconditioner" );
415 }
416 
423 {
425  {
437  };
438  return findOption( typeMap, type, "multigrid interpolation", "HyprePreconditioner" );
439 }
440 
447 {
449  {
459  };
460  return findOption( typeMap, type, "multigrid aggressive interpolation", "HyprePreconditioner" );
461 }
462 
469 {
471  {
474  };
475  return findOption( typeMap, type, "ILU", "HyprePreconditioner" );
476 }
477 
484 {
486  {
498  };
499  return findOption( typeMap, type, "multigrid coarse solver", "HyprePreconditioner" );
500 }
501 
508 {
510  {
517  };
518  return findOption( typeMap, type, "multigrid coarsening", "HyprePreconditioner" );
519 }
520 
527 {
529  {
537  };
538  return findOption( typeMap, type, "relaxation", "HyprePreconditioner" );
539 }
540 
547 {
549  {
552  };
553  return findOption( typeMap, type, "ILU", "HyprePreconditioner" );
554 }
555 
560 enum class AMGCoarseningType : HYPRE_Int
561 {
562  CLJP = 0,
563  Ruge_Stueben = 3,
564  Falgout = 6,
565  CLJPDebug = 7,
566  PMIS = 8,
567  PMISDebug = 9,
568  HMIS = 10,
569  CGC = 21,
570  CGC_E = 22
571 };
572 
577 enum class MGRInterpolationType : HYPRE_Int
578 {
579  injection = 0,
580  l1jacobi = 1,
581  jacobi = 2,
583  approximateInverse = 4,
584  blockJacobi = 12
585 };
586 
592 enum class MGRRestrictionType : HYPRE_Int
593 {
594  injection = 0,
595  jacobi = 2,
596  approximateInverse = 3,
597  blockJacobi = 12,
598  cprLike = 13,
599  blockColLumped = 14,
600  partialColLumped = 15
601 };
602 
607 enum class MGRCoarseGridMethod : HYPRE_Int
608 {
609  galerkin = 0,
610  nonGalerkin = 1,
612  cprLikeDiag = 2,
614  cprLikeBlockDiag = 3,
616  approximateInverse = 4
618 };
619 
624 enum class MGRFRelaxationType : HYPRE_Int
625 {
626  none = -1,
628  amgVCycle = 2,
632  jacobi = 7,
634  gsElim = 9,
635  l1forwardGaussSeidel = 13,
636  l1backwardGaussSeidel = 14,
637  l1jacobi = 18,
638  ilu = 32,
639  gsElimWPivoting = 99,
640  gsElimWInverse = 199
641 };
642 
647 enum class MGRGlobalSmootherType : HYPRE_Int
648 {
649  none = -1,
650  blockJacobi = 0,
651  blockGaussSeidel = 1,
652  jacobi = 2,
653  ilu0 = 16
654 };
655 
656 } // namespace hypre
657 
658 } // namespace geos
659 
660 #endif /*GEOS_LINEARALGEBRA_INTERFACES_HYPREUTILS_HPP_*/
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
void setKrylovDofLabels(arrayView1d< int const > const &labels)
Install fallback Krylov DoF labels for unit tests without a DofManager.
void clearKrylovDofLabels()
Clear fallback Krylov DoF labels installed by setKrylovDofLabels().
#define GEOS_ERROR_IF(COND,...)
Conditionally raise a hard error and terminate the program.
Definition: Logger.hpp:216
Wrapper class for hypre's ParCSRMatrix.
Definition: HypreMatrix.hpp:56
Base template for ordered and unordered maps.
HYPRE_Int getAMGInterpolationType(LinearSolverParameters::AMG::InterpType const &type)
Returns hypre's identifier of the AMG interpolation type.
Definition: HypreUtils.hpp:422
MGRCoarseGridMethod
This enum class specifies the strategy for level coarse grid computation in MGR.
Definition: HypreUtils.hpp:608
@ 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:593
@ blockColLumped
Block column-lumped approximation.
@ partialColLumped
Partial column-lumped approximation.
@ approximateInverse
Approximate inverse.
@ cprLike
CPR-like restriction.
HYPRE_Int chebyshevSetup(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector b, HYPRE_ParVector x)
Setup a Chebyshev smoother.
HYPRE_Int getAMGAggressiveInterpolationType(LinearSolverParameters::AMG::AggInterpType const &type)
Returns hypre's identifier of the AMG aggressive interpolation type.
Definition: HypreUtils.hpp:446
HYPRE_Vector parVectorToVectorAll(HYPRE_ParVector const vec)
Gather a parallel vector on every rank.
HYPRE_Int getRelaxationType(LinearSolverParameters::PreconditionerType const type)
Returns hypre's identifier of the relaxation preconditioner type.
Definition: HypreUtils.hpp:526
HYPRE_BigInt * toHypreBigInt(geos::globalIndex *const index)
Converts a non-const array from GEOS 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:119
HYPRE_Int getILUType(LinearSolverParameters::AMG::SmootherType const type)
Returns hypre's identifier of the AMG ILU smoother type.
Definition: HypreUtils.hpp:468
MGRFRelaxationType
This enum class specifies the F-relaxation type.
Definition: HypreUtils.hpp:625
@ 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
@ ilu
incomplete LU factorization
@ 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:401
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:561
@ 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:78
HYPRE_Int getAMGCoarseType(LinearSolverParameters::AMG::CoarseType const &type)
Returns hypre's identifier of the AMG coarse solver type.
Definition: HypreUtils.hpp:483
constexpr LvArray::MemorySpace getLvArrayMemorySpace(HYPRE_MemoryLocation const location)
Definition: HypreUtils.hpp:97
HYPRE_Int chebyshevDestroy(HYPRE_Solver solver)
Destroy a Chebyshev smoother.
HYPRE_Int getAMGCycleType(LinearSolverParameters::AMG::CycleType const &type)
Returns hypre's identifier of the AMG cycle type.
Definition: HypreUtils.hpp:386
HYPRE_Vector parVectorToVector(HYPRE_ParVector const vec, int const targetRank)
Gather a parallel vector onto a single rank.
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:507
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:152
HYPRE_Int chebyshevSolve(HYPRE_Solver solver, HYPRE_ParCSRMatrix A, HYPRE_ParVector b, HYPRE_ParVector x)
Solve with a Chebyshev smoother.
HYPRE_Int chebyshevCreate(HYPRE_Solver &solver, HYPRE_Int const order, HYPRE_Int const eigNumIter)
Create a Chebyshev smoother.
MGRInterpolationType
This enum class specifies the strategy for computing the level intepolation operator in MGR.
Definition: HypreUtils.hpp:578
@ classicalModifiedInterpolation
Classical modified interpolation.
@ approximateInverse
Approximate inverse.
void assignKrylovDofTags(arrayView1d< int const > const &labels, MPI_Comm const comm, array1d< HYPRE_Int > &tags, HYPRE_Int &numTags)
Convert local DoF-component labels into hypre Krylov tag arrays.
constexpr LvArray::MemorySpace memorySpace
Memory space used by hypre matrix/vector objects.
Definition: HypreUtils.hpp:117
void fillKrylovDofLabels(HypreMatrix const &mat, array1d< int > &labels)
Copy DoF-component labels used to tag hypre Krylov vectors.
MGRGlobalSmootherType
This enum class specifies the global smoother type.
Definition: HypreUtils.hpp:648
@ none
no global smoothing is performed (default)
@ ilu0
incomplete LU factorization
parallelDevicePolicy<> execPolicy
Execution policy for operations on hypre data.
Definition: HypreUtils.hpp:115
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Definition: DataTypes.hpp:179
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
Definition: DataTypes.hpp:87
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:84
Array< T, 1 > array1d
Alias for 1D array.
Definition: DataTypes.hpp:175
Container for hypre preconditioner function pointers.
Definition: HypreUtils.hpp:52
HYPRE_Int(*)(HYPRE_Solver) DestroyFunc
Alias for destroy function type.
Definition: HypreUtils.hpp:60
HYPRE_Int(*)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector) SolveFunc
Alias for apply function type.
Definition: HypreUtils.hpp:57
HYPRE_Int(*)(HYPRE_Solver, HYPRE_ParCSRMatrix, HYPRE_ParVector, HYPRE_ParVector) SetupFunc
Alias for setup function type.
Definition: HypreUtils.hpp:54
HYPRE_Solver ptr
pointer to preconditioner
Definition: HypreUtils.hpp:62
SetupFunc setup
pointer to setup function
Definition: HypreUtils.hpp:63
DestroyFunc destroy
pointer to destroy function
Definition: HypreUtils.hpp:65
SolveFunc solve
pointer to apply function
Definition: HypreUtils.hpp:64
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.
@ 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)
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)
@ gsElimWInverse
Direct inverse with Gaussian Elimination.
@ direct
Direct solver as preconditioner.
@ gsElimWPivoting
Gaussian Elimination with pivoting direct solver.
@ 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)