1 #pragma once
2
3 #include <petscsys.h>
4 #include <petscpkg_version.h>
5 #include <HYPRE_config.h>
6 #include <HYPRE_utilities.h>
7
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
13
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
27
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 */
61
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 */
PetscHYPREScalarCast(PetscScalar a,HYPRE_Complex * b)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 }
77
78 #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)
PetscHYPREFinalize_Private(void)79 static inline PetscErrorCode PetscHYPREFinalize_Private(void)
80 {
81 PetscFunctionBegin;
82 if (HYPRE_Initialized() && !HYPRE_Finalized()) PetscCallHYPRE(HYPRE_Finalize());
83 PetscFunctionReturn(PETSC_SUCCESS);
84 }
85
86 PETSC_EXTERN PetscBool use_gpu_aware_mpi;
87 /*
88 Options Database Keys:
89 . -hypre_umpire_device_pool_size <n> - set the Umpire device memory pool size (in MiB). HYPRE uses 4 GiB by default.
90 */
PetscHYPREInitialize(void)91 static inline PetscErrorCode PetscHYPREInitialize(void)
92 {
93 PetscFunctionBegin;
94 if (!HYPRE_Initialized()) {
95 PetscCallHYPRE(HYPRE_Initialize());
96 #if defined(HYPRE_USING_UMPIRE_DEVICE)
97 PetscInt size = 0;
98 PetscBool set = PETSC_FALSE;
99
100 PetscCall(PetscOptionsGetInt(NULL, NULL, "-hypre_umpire_device_pool_size", &size, &set));
101 if (set) {
102 PetscCheck(size >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "-hypre_umpire_device_pool_size must be non-negative");
103 PetscCallHYPRE(HYPRE_SetUmpireDevicePoolSize((size_t)(size << 20))); // converr to size in bytes
104 } else if (PetscCIEnabled) {
105 // Set smaller pool size for CI tests to avoid OOM, but keep the default for users
106 PetscCallHYPRE(HYPRE_SetUmpireDevicePoolSize((size_t)(256 << 20))); // 256 MiB
107 }
108 #endif
109 // hypre-2.31.0 added HYPRE_SetGpuAwareMPI.
110 // HYPRE_USING_GPU_AWARE_MPI indicates hypre is configured with --enable-gpu-aware-mpi.
111 // HYPRE_SetGpuAwareMPI() controls whether to actually use GPU-aware MPI.
112 #if PETSC_PKG_HYPRE_VERSION_GE(2, 31, 0) && defined(HYPRE_USING_GPU_AWARE_MPI)
113 PetscCallHYPRE(HYPRE_SetGpuAwareMPI(use_gpu_aware_mpi ? 1 : 0));
114 #endif
115 PetscCall(PetscRegisterFinalize(PetscHYPREFinalize_Private));
116 }
117 PetscFunctionReturn(PETSC_SUCCESS);
118 }
119 #else
PetscHYPREInitialize(void)120 static inline PetscErrorCode PetscHYPREInitialize(void)
121 {
122 PetscFunctionBegin;
123 PetscFunctionReturn(PETSC_SUCCESS);
124 }
125 #endif
126
127 #if PETSC_PKG_HYPRE_VERSION_LT(2, 19, 0)
128 typedef int HYPRE_MemoryLocation;
129 #define hypre_IJVectorMemoryLocation(a) 0
130 #define hypre_IJMatrixMemoryLocation(a) 0
131 #endif
132