Actual source code: petschypre.h

  1: #pragma once

  3: #include <petscsys.h>
  4: #include <petscpkg_version.h>
  5: #include <HYPRE_config.h>
  6: #include <HYPRE_utilities.h>

  8: /* from version 2.16 on, HYPRE_BigInt is 64-bit for 64-bit pointer installations
  9:    and 32-bit for 32-bit installations -> not the best name for a variable */
 10: #if PETSC_PKG_HYPRE_VERSION_LT(2, 16, 0)
 11: typedef PetscInt HYPRE_BigInt;
 12: #endif

 14: #if defined(HYPRE_BIGINT) || defined(HYPRE_MIXEDINT)
 15:   #define PetscHYPRE_BigInt_FMT "lld"
 16:   #ifdef __cplusplus /* make sure our format specifiers line up */
 17:     #include <type_traits>
 18: static_assert(std::is_same<HYPRE_BigInt, long long int>::value, "");
 19:   #endif
 20: #else
 21:   #define PetscHYPRE_BigInt_FMT "d"
 22:   #ifdef __cplusplus /* make sure our format specifiers line up */
 23:     #include <type_traits>
 24: static_assert(std::is_same<HYPRE_BigInt, int>::value, "");
 25:   #endif
 26: #endif

 28: #if defined(PETSC_CLANG_STATIC_ANALYZER)
 29: void PetscCallHYPRE(HYPRE_Int);
 30: #else
 31:   #if PETSC_PKG_HYPRE_VERSION_GT(2, 0, 0) /* HYPRE_DescribeError() added in 2.0.0 */
 32:     #define PetscCallHYPRE(...) \
 33:       do { \
 34:         if (PetscUnlikelyDebug(HYPRE_GetError() != 0)) { \
 35:           char err_str[PETSC_MAX_PATH_LEN]; \
 36:           HYPRE_DescribeError(HYPRE_GetError(), err_str); \
 37:           SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "HYPRE error from previous HYPRE call, error code %" PetscInt_FMT ": %s", (PetscInt)HYPRE_GetError(), err_str); \
 38:         } \
 39:         HYPRE_Int ierr_hypre_ = __VA_ARGS__; \
 40:         if (PetscUnlikely(ierr_hypre_ != 0)) { \
 41:           char err_str[PETSC_MAX_PATH_LEN]; \
 42:           HYPRE_DescribeError(ierr_hypre_, err_str); \
 43:           SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "HYPRE error code %" PetscInt_FMT ": %s", (PetscInt)ierr_hypre_, err_str); \
 44:         } \
 45:       } while (0)
 46:   #elif PETSC_PKG_HYPRE_VERSION_GE(1, 11, 0) /* HYPRE_GetError() added in 1.11.0b */
 47:     #define PetscCallHYPRE(...) \
 48:       do { \
 49:         PetscAssert(HYPRE_GetError() == 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "HYPRE error from previous HYPRE call, error code %" PetscInt_FMT, (PetscInt)HYPRE_GetError()); \
 50:         HYPRE_Int ierr_hypre_ = __VA_ARGS__; \
 51:         PetscCheck(ierr_hypre_ == 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "HYPRE error code %" PetscInt_FMT, (PetscInt)ierr_hypre_); \
 52:       } while (0)
 53:   #else /* PETSC_PKG_HYPRE_VERSION_LT(1, 11, 0) */
 54:     #define PetscCallHYPRE(...) \
 55:       do { \
 56:         HYPRE_Int ierr_hypre_ = __VA_ARGS__; \
 57:         PetscCheck(ierr_hypre_ == 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "HYPRE error code %" PetscInt_FMT, (PetscInt)ierr_hypre_); \
 58:       } while (0)
 59:   #endif /* PETSC_PKG_HYPRE_VERSION */
 60: #endif   /* PETSC_CLANG_STATIC_ANALYZER */

 62: /*
 63:   With scalar type == real, HYPRE_Complex == PetscScalar;
 64:   With scalar type == complex,  HYPRE_Complex is double __complex__ while PetscScalar may be std::complex<double>
 65: */
 66: static inline PetscErrorCode PetscHYPREScalarCast(PetscScalar a, HYPRE_Complex *b)
 67: {
 68:   PetscFunctionBegin;
 69: #if defined(HYPRE_COMPLEX)
 70:   ((PetscReal *)b)[0] = PetscRealPart(a);
 71:   ((PetscReal *)b)[1] = PetscImaginaryPart(a);
 72: #else
 73:   *b = a;
 74: #endif
 75:   PetscFunctionReturn(PETSC_SUCCESS);
 76: }

 78: static inline PetscErrorCode PetscHYPREIntCast(PetscInt a, HYPRE_Int *b)
 79: {
 80:   PetscFunctionBegin;
 81:   PetscCheck(sizeof(PetscInt) <= sizeof(HYPRE_Int) || (a <= (PetscInt)HYPRE_INT_MAX && a >= (PetscInt)HYPRE_INT_MIN), PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "%" PetscInt_FMT " is too big for HYPRE_Int, you may need to configure hypre with --enable-bigint", a);
 82:   if (b) *b = (HYPRE_Int)a;
 83:   PetscFunctionReturn(PETSC_SUCCESS);
 84: }

 86: #if PETSC_PKG_HYPRE_VERSION_GT(2, 28, 0) || (PETSC_PKG_HYPRE_VERSION_EQ(2, 28, 0) && defined(HYPRE_DEVELOP_NUMBER) && HYPRE_DEVELOP_NUMBER >= 22)
 87: static inline PetscErrorCode PetscHYPREFinalize_Private(void)
 88: {
 89:   PetscFunctionBegin;
 90:   if (HYPRE_Initialized() && !HYPRE_Finalized()) PetscCallHYPRE(HYPRE_Finalize());
 91:   PetscFunctionReturn(PETSC_SUCCESS);
 92: }

 94: PETSC_EXTERN PetscBool use_gpu_aware_mpi;
 95: /*
 96:   Options Database Keys:
 97: . -hypre_umpire_device_pool_size <n>  - set the Umpire device memory pool size (in MiB). HYPRE uses 4 GiB by default.
 98: */
 99: static inline PetscErrorCode PetscHYPREInitialize(void)
100: {
101:   PetscFunctionBegin;
102:   if (!HYPRE_Initialized()) {
103:     PetscCallHYPRE(HYPRE_Initialize());
104:   #if defined(HYPRE_USING_UMPIRE_DEVICE)
105:     PetscInt  size = 0;
106:     PetscBool set  = PETSC_FALSE;

108:     PetscCall(PetscOptionsGetInt(NULL, NULL, "-hypre_umpire_device_pool_size", &size, &set));
109:     if (set) {
110:       PetscCheck(size >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "-hypre_umpire_device_pool_size must be non-negative");
111:       PetscCallHYPRE(HYPRE_SetUmpireDevicePoolSize((size_t)(size << 20))); // converr to size in bytes
112:     } else if (PetscCIEnabled) {
113:       // Set smaller pool size for CI tests to avoid OOM, but keep the default for users
114:       PetscCallHYPRE(HYPRE_SetUmpireDevicePoolSize((size_t)(256 << 20))); // 256 MiB
115:     }
116:   #endif
117:   // hypre-2.31.0 added HYPRE_SetGpuAwareMPI.
118:   // HYPRE_USING_GPU_AWARE_MPI indicates hypre is configured with --enable-gpu-aware-mpi.
119:   // HYPRE_SetGpuAwareMPI() controls whether to actually use GPU-aware MPI.
120:   #if PETSC_PKG_HYPRE_VERSION_GE(2, 31, 0) && defined(HYPRE_USING_GPU_AWARE_MPI)
121:     PetscCallHYPRE(HYPRE_SetGpuAwareMPI(use_gpu_aware_mpi ? 1 : 0));
122:   #endif
123:     PetscCall(PetscRegisterFinalize(PetscHYPREFinalize_Private));
124:   }
125:   PetscFunctionReturn(PETSC_SUCCESS);
126: }
127: #else
128: static inline PetscErrorCode PetscHYPREInitialize(void)
129: {
130:   PetscFunctionBegin;
131:   PetscFunctionReturn(PETSC_SUCCESS);
132: }
133: #endif

135: #if PETSC_PKG_HYPRE_VERSION_LT(2, 19, 0)
136: typedef int HYPRE_MemoryLocation;
137:   #define hypre_IJVectorMemoryLocation(a) 0
138:   #define hypre_IJMatrixMemoryLocation(a) 0
139: #endif