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