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