Actual source code: petscsystypes.h
1: /* Portions of this code are under:
2: Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved.
3: */
5: #pragma once
7: #include <petscconf.h>
8: #include <petscconf_poison.h>
9: #include <petscfix.h>
10: #include <petscmacros.h>
11: #include <stddef.h>
13: /* SUBMANSEC = Sys */
15: #include <limits.h> // INT_MIN, INT_MAX, CHAR_BIT
17: #if defined(__clang__) || (PETSC_CPP_VERSION >= 17)
18: // clang allows both [[nodiscard]] and __attribute__((warn_unused_result)) on type
19: // definitions. GCC, however, does not, so check that we are using C++17 [[nodiscard]]
20: // instead of __attribute__((warn_unused_result))
21: #define PETSC_ERROR_CODE_NODISCARD PETSC_NODISCARD
22: #else
23: #define PETSC_ERROR_CODE_NODISCARD
24: #endif
26: #ifdef PETSC_CLANG_STATIC_ANALYZER
27: #undef PETSC_USE_STRICT_PETSCERRORCODE
28: #endif
30: #ifdef PETSC_USE_STRICT_PETSCERRORCODE
31: #define PETSC_ERROR_CODE_TYPEDEF typedef
32: #define PETSC_ERROR_CODE_ENUM_NAME PetscErrorCode
33: #else
34: #define PETSC_ERROR_CODE_TYPEDEF
35: #define PETSC_ERROR_CODE_ENUM_NAME
36: #endif
38: /*E
39: PetscErrorCode - Datatype used to return PETSc error codes.
41: Level: beginner
43: Notes:
44: Virtually all PETSc functions return an error code. It is the callers responsibility to check
45: the value of the returned error code after each PETSc call to determine if any errors
46: occurred. A set of convenience macros (e.g. `PetscCall()`, `PetscCallVoid()`) are provided
47: for this purpose. Failing to properly check for errors is not supported, as errors may leave
48: PETSc in an undetermined state.
50: One can retrieve the error string corresponding to a particular error code using
51: `PetscErrorMessage()`.
53: The user can also configure PETSc with the `--with-strict-petscerrorcode` option to enable
54: compiler warnings when the returned error codes are not captured and checked. Users are
55: *heavily* encouraged to opt-in to this option, as it will become enabled by default in a
56: future release.
58: Developer Notes:
59: These are the generic error codes. These error codes are used in many different places in the
60: PETSc source code. The C-string versions are at defined in `PetscErrorStrings[]` in
61: `src/sys/error/err.c`, while the Fortran versions are defined in
62: `src/sys/f90-mod/petscerror.h`. Any changes here must also be made in both locations.
64: .seealso: `PetscErrorMessage()`, `PetscCall()`, `SETERRQ()`
65: E*/
66: PETSC_ERROR_CODE_TYPEDEF enum PETSC_ERROR_CODE_NODISCARD {
67: PETSC_SUCCESS = 0,
68: PETSC_ERR_BOOLEAN_MACRO_FAILURE = 1, /* do not use */
70: PETSC_ERR_MIN_VALUE = 54, /* should always be one less than the smallest value */
72: PETSC_ERR_MEM = 55, /* unable to allocate requested memory */
73: PETSC_ERR_SUP = 56, /* no support for requested operation */
74: PETSC_ERR_SUP_SYS = 57, /* no support for requested operation on this computer system */
75: PETSC_ERR_ORDER = 58, /* operation done in wrong order */
76: PETSC_ERR_SIG = 59, /* signal received */
77: PETSC_ERR_FP = 72, /* floating point exception */
78: PETSC_ERR_COR = 74, /* corrupted PETSc object */
79: PETSC_ERR_LIB = 76, /* error in library called by PETSc */
80: PETSC_ERR_PLIB = 77, /* PETSc library generated inconsistent data */
81: PETSC_ERR_MEMC = 78, /* memory corruption */
82: PETSC_ERR_CONV_FAILED = 82, /* iterative method (KSP or SNES) failed */
83: PETSC_ERR_USER = 83, /* user has not provided needed function */
84: PETSC_ERR_SYS = 88, /* error in system call */
85: PETSC_ERR_POINTER = 70, /* pointer does not point to valid address */
86: PETSC_ERR_MPI_LIB_INCOMP = 87, /* MPI library at runtime is not compatible with MPI user compiled with */
88: PETSC_ERR_ARG_SIZ = 60, /* nonconforming object sizes used in operation */
89: PETSC_ERR_ARG_IDN = 61, /* two arguments not allowed to be the same */
90: PETSC_ERR_ARG_WRONG = 62, /* wrong argument (but object probably ok) */
91: PETSC_ERR_ARG_CORRUPT = 64, /* null or corrupted PETSc object as argument */
92: PETSC_ERR_ARG_OUTOFRANGE = 63, /* input argument, out of range */
93: PETSC_ERR_ARG_BADPTR = 68, /* invalid pointer argument */
94: PETSC_ERR_ARG_NOTSAMETYPE = 69, /* two args must be same object type */
95: PETSC_ERR_ARG_NOTSAMECOMM = 80, /* two args must be same communicators */
96: PETSC_ERR_ARG_WRONGSTATE = 73, /* object in argument is in wrong state, e.g. unassembled mat */
97: PETSC_ERR_ARG_TYPENOTSET = 89, /* the type of the object has not yet been set */
98: PETSC_ERR_ARG_INCOMP = 75, /* two arguments are incompatible */
99: PETSC_ERR_ARG_NULL = 85, /* argument is null that should not be */
100: PETSC_ERR_ARG_UNKNOWN_TYPE = 86, /* type name doesn't match any registered type */
102: PETSC_ERR_FILE_OPEN = 65, /* unable to open file */
103: PETSC_ERR_FILE_READ = 66, /* unable to read from file */
104: PETSC_ERR_FILE_WRITE = 67, /* unable to write to file */
105: PETSC_ERR_FILE_UNEXPECTED = 79, /* unexpected data in file */
107: PETSC_ERR_MAT_LU_ZRPVT = 71, /* detected a zero pivot during LU factorization */
108: PETSC_ERR_MAT_CH_ZRPVT = 81, /* detected a zero pivot during Cholesky factorization */
110: PETSC_ERR_INT_OVERFLOW = 84,
111: PETSC_ERR_FLOP_COUNT = 90,
112: PETSC_ERR_NOT_CONVERGED = 91, /* solver did not converge */
113: PETSC_ERR_MISSING_FACTOR = 92, /* MatGetFactor() failed */
114: PETSC_ERR_OPT_OVERWRITE = 93, /* attempted to over write options which should not be changed */
115: PETSC_ERR_WRONG_MPI_SIZE = 94, /* example/application run with number of MPI ranks it does not support */
116: PETSC_ERR_USER_INPUT = 95, /* missing or incorrect user input */
117: PETSC_ERR_GPU_RESOURCE = 96, /* unable to load a GPU resource, for example cuBLAS */
118: PETSC_ERR_GPU = 97, /* An error from a GPU call, this may be due to lack of resources on the GPU or a true error in the call */
119: PETSC_ERR_MPI = 98, /* general MPI error */
120: PETSC_ERR_RETURN = 99, /* PetscError() incorrectly returned an error code of 0 */
121: PETSC_ERR_MEM_LEAK = 100, /* memory alloc/free imbalance */
122: PETSC_ERR_MAX_VALUE = 101, /* this is always the one more than the largest error code */
124: /*
125: do not use, exist purely to make the enum bounds equal that of a regular int (so conversion
126: to int in main() is not undefined behavior)
127: */
128: PETSC_ERR_MIN_SIGNED_BOUND_DO_NOT_USE = INT_MIN,
129: PETSC_ERR_MAX_SIGNED_BOUND_DO_NOT_USE = INT_MAX
130: } PETSC_ERROR_CODE_ENUM_NAME;
132: #ifndef PETSC_USE_STRICT_PETSCERRORCODE
133: typedef int PetscErrorCode;
135: /*
136: Needed so that C++ lambdas can deduce the return type as PetscErrorCode from
137: PetscFunctionReturn(PETSC_SUCCESS). Otherwise we get
139: error: return type '(unnamed enum at include/petscsystypes.h:50:1)' must match previous
140: return type 'int' when lambda expression has unspecified explicit return type
141: PetscFunctionReturn(PETSC_SUCCESS);
142: ^
143: */
144: #define PETSC_SUCCESS ((PetscErrorCode)0)
145: #endif
147: #undef PETSC_ERROR_CODE_NODISCARD
148: #undef PETSC_ERROR_CODE_TYPEDEF
149: #undef PETSC_ERROR_CODE_ENUM_NAME
151: /*MC
152: PetscClassId - A unique id used to identify each PETSc class.
154: Level: developer
156: Note:
157: Use `PetscClassIdRegister()` to obtain a new value for a new class being created. Usually
158: XXXInitializePackage() calls it for each class it defines.
160: Developer Note:
161: Internal integer stored in the `_p_PetscObject` data structure. These are all computed by an offset from the lowest one, `PETSC_SMALLEST_CLASSID`.
163: .seealso: `PetscClassIdRegister()`, `PetscLogEventRegister()`, `PetscHeaderCreate()`
164: M*/
165: typedef int PetscClassId;
167: /*MC
168: PetscMPIInt - datatype used to represent 'int' parameters to MPI functions.
170: Level: intermediate
172: Notes:
173: This is always a 32-bit integer, sometimes it is the same as `PetscInt`, but if PETSc was built with `--with-64-bit-indices` but
174: standard C/Fortran integers are 32-bit then this is NOT the same as `PetscInt`; it remains 32-bit.
176: `PetscMPIIntCast`(a,&b) checks if the given `PetscInt` a will fit in a `PetscMPIInt`, if not it
177: generates a `PETSC_ERR_ARG_OUTOFRANGE` error.
179: .seealso: `PetscBLASInt`, `PetscInt`, `PetscMPIIntCast()`
180: M*/
181: typedef int PetscMPIInt;
183: /* Limit MPI to 32-bits */
184: enum {
185: PETSC_MPI_INT_MIN = INT_MIN,
186: PETSC_MPI_INT_MAX = INT_MAX
187: };
189: /*MC
190: PetscSizeT - datatype used to represent sizes in memory (like `size_t`)
192: Level: intermediate
194: Notes:
195: This is equivalent to `size_t`, but defined for consistency with Fortran, which lacks a native equivalent of `size_t`.
197: .seealso: `PetscInt`, `PetscInt64`, `PetscCount`
198: M*/
199: typedef size_t PetscSizeT;
201: /*MC
202: PetscCount - signed datatype used to represent counts
204: Level: intermediate
206: Notes:
207: This is equivalent to `ptrdiff_t`, but defined for consistency with Fortran, which lacks a native equivalent of `ptrdiff_t`.
209: Use `PetscCount_FMT` to format with `PetscPrintf()`, `printf()`, and related functions.
211: .seealso: `PetscInt`, `PetscInt64`, `PetscSizeT`
212: M*/
213: typedef ptrdiff_t PetscCount;
214: #define PetscCount_FMT "td"
216: /*MC
217: PetscEnum - datatype used to pass enum types within PETSc functions.
219: Level: intermediate
221: .seealso: `PetscOptionsGetEnum()`, `PetscOptionsEnum()`, `PetscBagRegisterEnum()`
222: M*/
223: typedef enum {
224: ENUM_DUMMY
225: } PetscEnum;
227: typedef short PetscShort;
228: typedef char PetscChar;
229: typedef float PetscFloat;
231: /*MC
232: PetscInt - PETSc type that represents an integer, used primarily to
233: represent size of arrays and indexing into arrays. Its size can be configured with the option `--with-64-bit-indices` to be either 32-bit (default) or 64-bit.
235: Level: beginner
237: Notes:
238: For MPI calls that require datatypes, use `MPIU_INT` as the datatype for `PetscInt`. It will automatically work correctly regardless of the size of `PetscInt`.
240: .seealso: `PetscBLASInt`, `PetscMPIInt`, `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`, `PetscIntCast()`
241: M*/
243: #if defined(PETSC_HAVE_STDINT_H)
244: #include <stdint.h>
245: #endif
246: #if defined(PETSC_HAVE_INTTYPES_H)
249: #endif
250: #include <inttypes.h>
251: #if !defined(PRId64)
252: #define PRId64 "ld"
253: #endif
254: #endif
256: #if defined(PETSC_HAVE_STDINT_H) && defined(PETSC_HAVE_INTTYPES_H) && (defined(PETSC_HAVE_MPIUNI) || defined(PETSC_HAVE_MPI_INT64_T)) /* MPI_INT64_T is not guaranteed to be a macro */
257: typedef int64_t PetscInt64;
259: #define PETSC_INT64_MIN INT64_MIN
260: #define PETSC_INT64_MAX INT64_MAX
262: #elif (PETSC_SIZEOF_LONG_LONG == 8)
263: typedef long long PetscInt64;
265: #define PETSC_INT64_MIN LLONG_MIN
266: #define PETSC_INT64_MAX LLONG_MAX
268: #elif defined(PETSC_HAVE___INT64)
269: typedef __int64 PetscInt64;
271: #define PETSC_INT64_MIN INT64_MIN
272: #define PETSC_INT64_MAX INT64_MAX
274: #else
275: #error "cannot determine PetscInt64 type"
276: #endif
278: typedef int32_t PetscInt32;
279: #define PETSC_INT32_MIN INT32_MIN
280: #define PETSC_INT32_MAX INT32_MAX
282: #if defined(PETSC_USE_64BIT_INDICES)
283: typedef PetscInt64 PetscInt;
285: #define PETSC_INT_MIN PETSC_INT64_MIN
286: #define PETSC_INT_MAX PETSC_INT64_MAX
287: #define PetscInt_FMT PetscInt64_FMT
288: #else
289: typedef int PetscInt;
291: enum {
292: PETSC_INT_MIN = INT_MIN,
293: PETSC_INT_MAX = INT_MAX
294: };
296: #define PetscInt_FMT "d"
297: #endif
299: #define PETSC_MIN_INT PETSC_INT_MIN
300: #define PETSC_MAX_INT PETSC_INT_MAX
301: #define PETSC_MAX_UINT16 65535
303: #if defined(PETSC_HAVE_STDINT_H) && defined(PETSC_HAVE_INTTYPES_H) && (defined(PETSC_HAVE_MPIUNI) || defined(PETSC_HAVE_MPI_INT64_T)) /* MPI_INT64_T is not guaranteed to be a macro */
304: #define MPIU_INT64 MPI_INT64_T
305: #define PetscInt64_FMT PRId64
306: #elif (PETSC_SIZEOF_LONG_LONG == 8)
307: #define MPIU_INT64 MPI_LONG_LONG_INT
308: #define PetscInt64_FMT "lld"
309: #elif defined(PETSC_HAVE___INT64)
310: #define MPIU_INT64 MPI_INT64_T
311: #define PetscInt64_FMT "ld"
312: #else
313: #error "cannot determine PetscInt64 type"
314: #endif
316: #define MPIU_INT32 MPI_INT32_T
317: #define PetscInt32_FMT PRId32
319: /*MC
320: PetscBLASInt - datatype used to represent 'int' parameters to BLAS/LAPACK functions.
322: Level: intermediate
324: Notes:
325: Usually this is the same as `PetscInt`, but if PETSc was built with `--with-64-bit-indices` but
326: standard C/Fortran integers are 32-bit then this may not be the same as `PetscInt`,
327: except on some BLAS/LAPACK implementations that support 64-bit integers see the notes below.
329: `PetscErrorCode` `PetscBLASIntCast`(a,&b) checks if the given `PetscInt` a will fit in a `PetscBLASInt`, if not it
330: generates a `PETSC_ERR_ARG_OUTOFRANGE` error
332: Installation Notes\:
333: ./configure automatically determines the size of the integers used by BLAS/LAPACK except when `--with-batch` is used
334: in that situation one must know (by some other means) if the integers used by BLAS/LAPACK are 64-bit and if so pass the flag `--known-64-bit-blas-indices`
336: MATLAB ships with BLAS and LAPACK that use 64-bit integers, for example if you run ./configure with, the option
337: `--with-blaslapack-lib`=[/Applications/MATLAB_R2010b.app/bin/maci64/libmwblas.dylib,/Applications/MATLAB_R2010b.app/bin/maci64/libmwlapack.dylib]
339: MKL ships with both 32 and 64-bit integer versions of the BLAS and LAPACK. If you pass the flag `-with-64-bit-blas-indices` PETSc will link
340: against the 64-bit version, otherwise it uses the 32-bit version
342: OpenBLAS can be built to use 64-bit integers. The ./configure options `--download-openblas` `-with-64-bit-blas-indices` will build a 64-bit integer version
344: External packages such as hypre, ML, SuperLU etc do not provide any support for passing 64-bit integers to BLAS/LAPACK so cannot
345: be used with PETSc when PETSc links against 64-bit integer BLAS/LAPACK. ./configure will generate an error if you attempt to link PETSc against any of
346: these external libraries while using 64-bit integer BLAS/LAPACK.
348: .seealso: `PetscMPIInt`, `PetscInt`, `PetscBLASIntCast()`
349: M*/
350: #if defined(PETSC_HAVE_64BIT_BLAS_INDICES)
351: typedef PetscInt64 PetscBLASInt;
353: #define PETSC_BLAS_INT_MIN PETSC_INT64_MIN
354: #define PETSC_BLAS_INT_MAX PETSC_INT64_MAX
355: #define PetscBLASInt_FMT PetscInt64_FMT
356: #else
357: typedef int PetscBLASInt;
359: enum {
360: PETSC_BLAS_INT_MIN = INT_MIN,
361: PETSC_BLAS_INT_MAX = INT_MAX
362: };
364: #define PetscBLASInt_FMT "d"
365: #endif
367: /*MC
368: PetscCuBLASInt - datatype used to represent 'int' parameters to cuBLAS/cuSOLVER functions.
370: Level: intermediate
372: Notes:
373: As of this writing `PetscCuBLASInt` is always the system `int`.
375: `PetscErrorCode` `PetscCuBLASIntCast`(a,&b) checks if the given `PetscInt` a will fit in a `PetscCuBLASInt`, if not it
376: generates a `PETSC_ERR_ARG_OUTOFRANGE` error
378: .seealso: `PetscBLASInt`, `PetscMPIInt`, `PetscInt`, `PetscCuBLASIntCast()`
379: M*/
380: typedef int PetscCuBLASInt;
382: enum {
383: PETSC_CUBLAS_INT_MIN = INT_MIN,
384: PETSC_CUBLAS_INT_MAX = INT_MAX
385: };
387: /*MC
388: PetscHipBLASInt - datatype used to represent 'int' parameters to hipBLAS/hipSOLVER functions.
390: Level: intermediate
392: Notes:
393: `PetscHipBLASInt` is always the system `int`.
395: `PetscErrorCode` `PetscHipBLASIntCast`(a,&b) checks if the given `PetscInt` a will fit in a `PetscHipBLASInt`, if not it
396: generates a `PETSC_ERR_ARG_OUTOFRANGE` error
398: .seealso: PetscBLASInt, PetscMPIInt, PetscInt, PetscHipBLASIntCast()
399: M*/
400: typedef int PetscHipBLASInt;
402: enum {
403: PETSC_HIPBLAS_INT_MIN = INT_MIN,
404: PETSC_HIPBLAS_INT_MAX = INT_MAX
405: };
407: /*E
408: PetscBool - Logical variable. Actually an enum in C and a logical in Fortran.
410: Level: beginner
412: Developer Note:
413: Why have `PetscBool`, why not use bool in C? The problem is that K and R C, C99 and C++ all have different mechanisms for
414: Boolean values. It is not easy to have a simple macro that will work properly in all circumstances with all three mechanisms.
416: .seealso: `PETSC_TRUE`, `PETSC_FALSE`, `PetscNot()`, `PetscBool3`
417: E*/
418: typedef enum {
419: PETSC_FALSE,
420: PETSC_TRUE
421: } PetscBool;
422: PETSC_EXTERN const char *const PetscBools[];
424: /*E
425: PetscBool3 - Ternary logical variable. Actually an enum in C and a 4 byte integer in Fortran.
427: Level: beginner
429: Note:
430: Should not be used with the if (flg) or if (!flg) syntax.
432: .seealso: `PETSC_TRUE`, `PETSC_FALSE`, `PetscNot()`, `PETSC_BOOL3_TRUE`, `PETSC_BOOL3_FALSE`, `PETSC_BOOL3_UNKNOWN`
433: E*/
434: typedef enum {
435: PETSC_BOOL3_FALSE,
436: PETSC_BOOL3_TRUE,
437: PETSC_BOOL3_UNKNOWN = -1
438: } PetscBool3;
440: #define PetscBool3ToBool(a) ((a) == PETSC_BOOL3_TRUE ? PETSC_TRUE : PETSC_FALSE)
441: #define PetscBoolToBool3(a) ((a) == PETSC_TRUE ? PETSC_BOOL3_TRUE : PETSC_BOOL3_FALSE)
443: /*MC
444: PetscReal - PETSc type that represents a real number version of `PetscScalar`
446: Level: beginner
448: Notes:
449: For MPI calls that require datatypes, use `MPIU_REAL` as the datatype for `PetscReal` and `MPIU_SUM`, `MPIU_MAX`, etc. for operations.
450: They will automatically work correctly regardless of the size of `PetscReal`.
452: See `PetscScalar` for details on how to ./configure the size of `PetscReal`.
454: .seealso: `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`
455: M*/
457: #if defined(PETSC_USE_REAL_SINGLE)
458: typedef float PetscReal;
459: #elif defined(PETSC_USE_REAL_DOUBLE)
460: typedef double PetscReal;
461: #elif defined(PETSC_USE_REAL___FLOAT128)
462: #if defined(__cplusplus)
463: extern "C" {
464: #endif
465: #include <quadmath.h>
466: #if defined(__cplusplus)
467: }
468: #endif
469: typedef __float128 PetscReal;
470: #elif defined(PETSC_USE_REAL___FP16)
471: typedef __fp16 PetscReal;
472: #endif /* PETSC_USE_REAL_* */
474: /*MC
475: PetscComplex - PETSc type that represents a complex number with precision matching that of `PetscReal`.
477: Synopsis:
478: #include <petscsys.h>
479: PetscComplex number = 1. + 2.*PETSC_i;
481: Level: beginner
483: Notes:
484: For MPI calls that require datatypes, use `MPIU_COMPLEX` as the datatype for `PetscComplex` and `MPIU_SUM` etc for operations.
485: They will automatically work correctly regardless of the size of `PetscComplex`.
487: See `PetscScalar` for details on how to ./configure the size of `PetscReal`
489: Complex numbers are automatically available if PETSc was able to find a working complex implementation
491: PETSc has a 'fix' for complex numbers to support expressions such as `std::complex<PetscReal>` + `PetscInt`, which are not supported by the standard
492: C++ library, but are convenient for petsc users. If the C++ compiler is able to compile code in `petsccxxcomplexfix.h` (This is checked by
493: configure), we include `petsccxxcomplexfix.h` to provide this convenience.
495: If the fix causes conflicts, or one really does not want this fix for a particular C++ file, one can define `PETSC_SKIP_CXX_COMPLEX_FIX`
496: at the beginning of the C++ file to skip the fix.
498: .seealso: `PetscReal`, `PetscScalar`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`, `PETSC_i`
499: M*/
500: #if !defined(PETSC_SKIP_COMPLEX)
501: #if defined(PETSC_CLANGUAGE_CXX)
502: #if !defined(PETSC_USE_REAL___FP16) && !defined(PETSC_USE_REAL___FLOAT128)
503: #if defined(__cplusplus) && defined(PETSC_HAVE_CXX_COMPLEX) /* enable complex for library code */
504: #define PETSC_HAVE_COMPLEX 1
505: #elif !defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX) && defined(PETSC_HAVE_CXX_COMPLEX) /* User code only - conditional on library code complex support */
506: #define PETSC_HAVE_COMPLEX 1
507: #endif
508: #elif defined(PETSC_USE_REAL___FLOAT128) && defined(PETSC_HAVE_C99_COMPLEX)
509: #define PETSC_HAVE_COMPLEX 1
510: #endif
511: #else /* !PETSC_CLANGUAGE_CXX */
512: #if !defined(PETSC_USE_REAL___FP16)
514: #define PETSC_HAVE_COMPLEX 1
515: #elif defined(__cplusplus) && defined(PETSC_HAVE_C99_COMPLEX) && defined(PETSC_HAVE_CXX_COMPLEX) /* User code only - conditional on library code complex support */
516: #define PETSC_HAVE_COMPLEX 1
517: #endif
518: #endif
519: #endif /* PETSC_CLANGUAGE_CXX */
520: #endif /* !PETSC_SKIP_COMPLEX */
522: #if defined(PETSC_HAVE_COMPLEX)
523: #if defined(__cplusplus) /* C++ complex support */
524: /* Locate a C++ complex template library */
525: #if defined(PETSC_DESIRE_KOKKOS_COMPLEX) /* Defined in petscvec_kokkos.hpp for *.kokkos.cxx files */
526: #define petsccomplexlib Kokkos
527: #include <Kokkos_Complex.hpp>
528: #elif defined(__CUDACC__) || defined(__HIPCC__)
529: #define petsccomplexlib thrust
530: #include <thrust/complex.h>
531: #elif defined(PETSC_USE_REAL___FLOAT128)
532: #include <complex.h>
533: #else
534: #define petsccomplexlib std
535: #include <complex>
536: #endif
538: /* Define PetscComplex based on the precision */
539: #if defined(PETSC_USE_REAL_SINGLE)
540: typedef petsccomplexlib::complex<float> PetscComplex;
541: #elif defined(PETSC_USE_REAL_DOUBLE)
542: typedef petsccomplexlib::complex<double> PetscComplex;
543: #elif defined(PETSC_USE_REAL___FLOAT128)
544: typedef __complex128 PetscComplex;
545: #endif
547: /* Include a PETSc C++ complex 'fix'. Check PetscComplex manual page for details */
548: #if defined(PETSC_HAVE_CXX_COMPLEX_FIX) && !defined(PETSC_SKIP_CXX_COMPLEX_FIX)
549: #include <petsccxxcomplexfix.h>
550: #endif
551: #else /* c99 complex support */
552: #include <complex.h>
553: #if defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL___FP16)
554: typedef float _Complex PetscComplex;
555: #elif defined(PETSC_USE_REAL_DOUBLE)
556: typedef double _Complex PetscComplex;
557: #elif defined(PETSC_USE_REAL___FLOAT128)
558: typedef __complex128 PetscComplex;
559: #endif /* PETSC_USE_REAL_* */
560: #endif /* !__cplusplus */
561: #endif /* PETSC_HAVE_COMPLEX */
563: /*MC
564: PetscScalar - PETSc type that represents either a double precision real number, a double precision
565: complex number, a single precision real number, a __float128 real or complex or a __fp16 real - if the code is configured
566: with `--with-scalar-type`=real,complex `--with-precision`=single,double,__float128,__fp16
568: Level: beginner
570: Note:
571: For MPI calls that require datatypes, use `MPIU_SCALAR` as the datatype for `PetscScalar` and `MPIU_SUM`, etc for operations. They will automatically work correctly regardless of the size of `PetscScalar`.
573: .seealso: `PetscReal`, `PetscComplex`, `PetscInt`, `MPIU_REAL`, `MPIU_SCALAR`, `MPIU_COMPLEX`, `MPIU_INT`, `PetscRealPart()`, `PetscImaginaryPart()`
574: M*/
576: #if defined(PETSC_USE_COMPLEX) && defined(PETSC_HAVE_COMPLEX)
577: typedef PetscComplex PetscScalar;
578: #else /* PETSC_USE_COMPLEX */
579: typedef PetscReal PetscScalar;
580: #endif /* PETSC_USE_COMPLEX */
582: /*E
583: PetscCopyMode - Determines how an array or `PetscObject` passed to certain functions is copied or retained by the aggregate `PetscObject`
585: Values for array input:
586: + `PETSC_COPY_VALUES` - the array values are copied into new space, the user is free to reuse or delete the passed in array
587: . `PETSC_OWN_POINTER` - the array values are NOT copied, the object takes ownership of the array and will free it later, the user cannot change or
588: delete the array. The array MUST have been obtained with `PetscMalloc()`. Hence this mode cannot be used in Fortran.
589: - `PETSC_USE_POINTER` - the array values are NOT copied, the object uses the array but does NOT take ownership of the array. The user cannot use
590: the array but the user must delete the array after the object is destroyed.
592: Values for PetscObject:
593: + `PETSC_COPY_VALUES` - the input `PetscObject` is cloned into the aggregate `PetscObject`; the user is free to reuse/modify the input `PetscObject` without side effects.
594: . `PETSC_OWN_POINTER` - the input `PetscObject` is referenced by pointer (with reference count), thus should not be modified by the user.
595: increases its reference count).
596: - `PETSC_USE_POINTER` - invalid for `PetscObject` inputs.
598: Level: beginner
600: .seealso: `PetscInsertMode`
601: E*/
602: typedef enum {
603: PETSC_COPY_VALUES,
604: PETSC_OWN_POINTER,
605: PETSC_USE_POINTER
606: } PetscCopyMode;
607: PETSC_EXTERN const char *const PetscCopyModes[];
609: /*MC
610: PETSC_FALSE - False value of `PetscBool`
612: Level: beginner
614: Note:
615: Zero integer
617: .seealso: `PetscBool`, `PetscBool3`, `PETSC_TRUE`
618: M*/
620: /*MC
621: PETSC_TRUE - True value of `PetscBool`
623: Level: beginner
625: Note:
626: Nonzero integer
628: .seealso: `PetscBool`, `PetscBool3`, `PETSC_FALSE`
629: M*/
631: /*MC
632: PetscLogDouble - Used for logging times
634: Level: developer
636: Note:
637: Contains double precision numbers that are not used in the numerical computations, but rather in logging, timing etc.
639: .seealso: `PetscBool`, `PetscDataType`
640: M*/
641: typedef double PetscLogDouble;
643: /*E
644: PetscDataType - Used for handling different basic data types.
646: Level: beginner
648: Notes:
649: Use of this should be avoided if one can directly use `MPI_Datatype` instead.
651: `PETSC_INT` is the datatype for a `PetscInt`, regardless of whether it is 4 or 8 bytes.
652: `PETSC_REAL`, `PETSC_COMPLEX` and `PETSC_SCALAR` are the datatypes for `PetscReal`, `PetscComplex` and `PetscScalar`, regardless of their sizes.
654: Developer Notes:
655: It would be nice if we could always just use MPI Datatypes, why can we not?
657: If you change any values in `PetscDatatype` make sure you update their usage in
658: share/petsc/matlab/PetscBagRead.m and share/petsc/matlab/@PetscOpenSocket/read/write.m
660: TODO:
661: Remove use of improper `PETSC_ENUM`
663: .seealso: `PetscBinaryRead()`, `PetscBinaryWrite()`, `PetscDataTypeToMPIDataType()`,
664: `PetscDataTypeGetSize()`
665: E*/
666: typedef enum {
667: PETSC_DATATYPE_UNKNOWN = 0,
668: PETSC_DOUBLE = 1,
669: PETSC_COMPLEX = 2,
670: PETSC_LONG = 3,
671: PETSC_SHORT = 4,
672: PETSC_FLOAT = 5,
673: PETSC_CHAR = 6,
674: PETSC_BIT_LOGICAL = 7,
675: PETSC_ENUM = 8,
676: PETSC_BOOL = 9,
677: PETSC___FLOAT128 = 10,
678: PETSC_OBJECT = 11,
679: PETSC_FUNCTION = 12,
680: PETSC_STRING = 13,
681: PETSC___FP16 = 14,
682: PETSC_STRUCT = 15,
683: PETSC_INT = 16,
684: PETSC_INT64 = 17,
685: PETSC_COUNT = 18,
686: PETSC_INT32 = 19,
687: } PetscDataType;
688: PETSC_EXTERN const char *const PetscDataTypes[];
690: #if defined(PETSC_USE_REAL_SINGLE)
691: #define PETSC_REAL PETSC_FLOAT
692: #elif defined(PETSC_USE_REAL_DOUBLE)
693: #define PETSC_REAL PETSC_DOUBLE
694: #elif defined(PETSC_USE_REAL___FLOAT128)
695: #define PETSC_REAL PETSC___FLOAT128
696: #elif defined(PETSC_USE_REAL___FP16)
697: #define PETSC_REAL PETSC___FP16
698: #else
699: #define PETSC_REAL PETSC_DOUBLE
700: #endif
702: #if defined(PETSC_USE_COMPLEX)
703: #define PETSC_SCALAR PETSC_COMPLEX
704: #else
705: #define PETSC_SCALAR PETSC_REAL
706: #endif
708: #define PETSC_FORTRANADDR PETSC_LONG
710: /*S
711: PetscToken - 'Token' used for managing tokenizing strings
713: Level: intermediate
715: .seealso: `PetscTokenCreate()`, `PetscTokenFind()`, `PetscTokenDestroy()`
716: S*/
717: typedef struct _p_PetscToken *PetscToken;
719: /*S
720: PetscObject - any PETSc object, `PetscViewer`, `Mat`, `Vec`, `KSP` etc
722: Level: beginner
724: Notes:
725: This is the base class from which all PETSc objects are derived from.
727: In certain situations one can cast an object, for example a `Vec`, to a `PetscObject` with (`PetscObject`)vec
729: .seealso: `PetscObjectDestroy()`, `PetscObjectView()`, `PetscObjectGetName()`, `PetscObjectSetName()`, `PetscObjectReference()`, `PetscObjectDereference()`
730: S*/
731: typedef struct _p_PetscObject *PetscObject;
733: /*MC
734: PetscObjectId - unique integer Id for a `PetscObject`
736: Level: developer
738: Note:
739: Unlike pointer values, object ids are never reused so one may save a `PetscObjectId` and compare it to one obtained later from a `PetscObject` to determine
740: if the objects are the same. Never compare two object pointer values.
742: .seealso: `PetscObjectState`, `PetscObjectGetId()`
743: M*/
744: typedef PetscInt64 PetscObjectId;
746: /*MC
747: PetscObjectState - integer state for a `PetscObject`
749: Level: developer
751: Note:
752: Object state is always-increasing and (for objects that track state) can be used to determine if an object has
753: changed since the last time you interacted with it. It is 64-bit so that it will not overflow for a very long time.
755: .seealso: `PetscObjectId`, `PetscObjectStateGet()`, `PetscObjectStateIncrease()`, `PetscObjectStateSet()`
756: M*/
757: typedef PetscInt64 PetscObjectState;
759: /*S
760: PetscFunctionList - Linked list of functions, possibly stored in dynamic libraries, accessed
761: by string name
763: Level: advanced
765: .seealso: `PetscFunctionListAdd()`, `PetscFunctionListDestroy()`
766: S*/
767: typedef struct _n_PetscFunctionList *PetscFunctionList;
769: /*E
770: PetscFileMode - Access mode for a file.
772: Values:
773: + `FILE_MODE_UNDEFINED` - initial invalid value
774: . `FILE_MODE_READ` - open a file at its beginning for reading
775: . `FILE_MODE_WRITE` - open a file at its beginning for writing (will create if the file does not exist)
776: . `FILE_MODE_APPEND` - open a file at end for writing
777: . `FILE_MODE_UPDATE` - open a file for updating, meaning for reading and writing
778: - `FILE_MODE_APPEND_UPDATE` - open a file for updating, meaning for reading and writing, at the end
780: Level: beginner
782: .seealso: `PetscViewerFileSetMode()`
783: E*/
784: typedef enum {
785: FILE_MODE_UNDEFINED = -1,
786: FILE_MODE_READ = 0,
787: FILE_MODE_WRITE,
788: FILE_MODE_APPEND,
789: FILE_MODE_UPDATE,
790: FILE_MODE_APPEND_UPDATE
791: } PetscFileMode;
792: PETSC_EXTERN const char *const PetscFileModes[];
794: typedef void *PetscDLHandle;
795: typedef enum {
796: PETSC_DL_DECIDE = 0,
797: PETSC_DL_NOW = 1,
798: PETSC_DL_LOCAL = 2
799: } PetscDLMode;
801: /*S
802: PetscObjectList - Linked list of PETSc objects, each accessible by string name
804: Level: developer
806: Note:
807: Used by `PetscObjectCompose()` and `PetscObjectQuery()`
809: .seealso: `PetscObjectListAdd()`, `PetscObjectListDestroy()`, `PetscObjectListFind()`, `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscFunctionList`
810: S*/
811: typedef struct _n_PetscObjectList *PetscObjectList;
813: /*S
814: PetscDLLibrary - Linked list of dynamic libraries to search for functions
816: Level: developer
818: .seealso: `PetscDLLibraryOpen()`
819: S*/
820: typedef struct _n_PetscDLLibrary *PetscDLLibrary;
822: /*S
823: PetscContainer - Simple PETSc object that contains a pointer to any required data
825: Level: advanced
827: Note:
828: This is useful to attach arbitrary data to a `PetscObject` with `PetscObjectCompose()` and `PetscObjectQuery()`
830: .seealso: `PetscObject`, `PetscContainerCreate()`, `PetscObjectCompose()`, `PetscObjectQuery()`
831: S*/
832: typedef struct _p_PetscContainer *PetscContainer;
834: /*S
835: PetscRandom - Abstract PETSc object that manages generating random numbers
837: Level: intermediate
839: .seealso: `PetscRandomCreate()`, `PetscRandomGetValue()`, `PetscRandomType`
840: S*/
841: typedef struct _p_PetscRandom *PetscRandom;
843: /*
844: In binary files variables are stored using the following lengths,
845: regardless of how they are stored in memory on any one particular
846: machine. Use these rather than sizeof() in computing sizes for
847: PetscBinarySeek().
848: */
849: #define PETSC_BINARY_INT_SIZE (32 / 8)
850: #define PETSC_BINARY_FLOAT_SIZE (32 / 8)
851: #define PETSC_BINARY_CHAR_SIZE (8 / 8)
852: #define PETSC_BINARY_SHORT_SIZE (16 / 8)
853: #define PETSC_BINARY_DOUBLE_SIZE (64 / 8)
854: #define PETSC_BINARY_SCALAR_SIZE sizeof(PetscScalar)
856: /*E
857: PetscBinarySeekType - argument to `PetscBinarySeek()`
859: Values:
860: + `PETSC_BINARY_SEEK_SET` - offset is an absolute location in the file
861: . `PETSC_BINARY_SEEK_CUR` - offset is an offset from the current location of the file pointer
862: - `PETSC_BINARY_SEEK_END` - offset is an offset from the end of the file
864: Level: advanced
866: .seealso: `PetscBinarySeek()`, `PetscBinarySynchronizedSeek()`
867: E*/
868: typedef enum {
869: PETSC_BINARY_SEEK_SET = 0,
870: PETSC_BINARY_SEEK_CUR = 1,
871: PETSC_BINARY_SEEK_END = 2
872: } PetscBinarySeekType;
874: /*E
875: PetscBuildTwoSidedType - algorithm for setting up two-sided communication for use with `PetscSF`
877: Values:
878: + `PETSC_BUILDTWOSIDED_ALLREDUCE` - classical algorithm using an `MPI_Allreduce()` with
879: a buffer of length equal to the communicator size. Not memory-scalable due to
880: the large reduction size. Requires only an MPI-1 implementation.
881: . `PETSC_BUILDTWOSIDED_IBARRIER` - nonblocking algorithm based on `MPI_Issend()` and `MPI_Ibarrier()`.
882: Proved communication-optimal in Hoefler, Siebert, and Lumsdaine (2010). Requires an MPI-3 implementation.
883: - `PETSC_BUILDTWOSIDED_REDSCATTER` - similar to above, but use more optimized function
884: that only communicates the part of the reduction that is necessary. Requires an MPI-2 implementation.
886: Level: developer
888: .seealso: `PetscCommBuildTwoSided()`, `PetscCommBuildTwoSidedSetType()`, `PetscCommBuildTwoSidedGetType()`
889: E*/
890: typedef enum {
891: PETSC_BUILDTWOSIDED_NOTSET = -1,
892: PETSC_BUILDTWOSIDED_ALLREDUCE = 0,
893: PETSC_BUILDTWOSIDED_IBARRIER = 1,
894: PETSC_BUILDTWOSIDED_REDSCATTER = 2
895: /* Updates here must be accompanied by updates in finclude/petscsys.h and the string array in mpits.c */
896: } PetscBuildTwoSidedType;
897: PETSC_EXTERN const char *const PetscBuildTwoSidedTypes[];
899: /* NOTE: If you change this, you must also change the values in src/vec/f90-mod/petscvec.h */
900: /*E
901: InsertMode - How the entries are combined with the current values in the vectors or matrices
903: Values:
904: + `NOT_SET_VALUES` - do not actually use the values
905: . `INSERT_VALUES` - replace the current values with the provided values, unless the index is marked as constrained by the `PetscSection`
906: . `ADD_VALUES` - add the values to the current values, unless the index is marked as constrained by the `PetscSection`
907: . `MAX_VALUES` - use the maximum of each current value and provided value
908: . `MIN_VALUES` - use the minimum of each current value and provided value
909: . `INSERT_ALL_VALUES` - insert, even if indices that are not marked as constrained by the `PetscSection`
910: . `ADD_ALL_VALUES` - add, even if indices that are not marked as constrained by the `PetscSection`
911: . `INSERT_BC_VALUES` - insert, but ignore indices that are not marked as constrained by the `PetscSection`
912: - `ADD_BC_VALUES` - add, but ignore indices that are not marked as constrained by the `PetscSection`
914: Level: beginner
916: Note:
917: The `PetscSection` that determines the effects of the `InsertMode` values can be obtained by the `Vec` object with `VecGetDM()`
918: and `DMGetLocalSection()`.
920: Not all options are supported for all operations or PETSc object types.
922: .seealso: `VecSetValues()`, `MatSetValues()`, `VecSetValue()`, `VecSetValuesBlocked()`,
923: `VecSetValuesLocal()`, `VecSetValuesBlockedLocal()`, `MatSetValuesBlocked()`,
924: `MatSetValuesBlockedLocal()`, `MatSetValuesLocal()`, `VecScatterBegin()`, `VecScatterEnd()`
925: E*/
926: typedef enum {
927: NOT_SET_VALUES,
928: INSERT_VALUES,
929: ADD_VALUES,
930: MAX_VALUES,
931: MIN_VALUES,
932: INSERT_ALL_VALUES,
933: ADD_ALL_VALUES,
934: INSERT_BC_VALUES,
935: ADD_BC_VALUES
936: } InsertMode;
938: /*MC
939: INSERT_VALUES - Put a value into a vector or matrix, overwrites any previous value
941: Level: beginner
943: .seealso: `InsertMode`, `VecSetValues()`, `MatSetValues()`, `VecSetValue()`, `VecSetValuesBlocked()`,
944: `VecSetValuesLocal()`, `VecSetValuesBlockedLocal()`, `MatSetValuesBlocked()`, `ADD_VALUES`,
945: `MatSetValuesBlockedLocal()`, `MatSetValuesLocal()`, `VecScatterBegin()`, `VecScatterEnd()`, `MAX_VALUES`
946: M*/
948: /*MC
949: ADD_VALUES - Adds a value into a vector or matrix, if there previously was no value, just puts the
950: value into that location
952: Level: beginner
954: .seealso: `InsertMode`, `VecSetValues()`, `MatSetValues()`, `VecSetValue()`, `VecSetValuesBlocked()`,
955: `VecSetValuesLocal()`, `VecSetValuesBlockedLocal()`, `MatSetValuesBlocked()`, `INSERT_VALUES`,
956: `MatSetValuesBlockedLocal()`, `MatSetValuesLocal()`, `VecScatterBegin()`, `VecScatterEnd()`, `MAX_VALUES`
957: M*/
959: /*MC
960: MAX_VALUES - Puts the maximum of the scattered/gathered value and the current value into each location
962: Level: beginner
964: .seealso: `InsertMode`, `VecScatterBegin()`, `VecScatterEnd()`, `ADD_VALUES`, `INSERT_VALUES`
965: M*/
967: /*MC
968: MIN_VALUES - Puts the minimal of the scattered/gathered value and the current value into each location
970: Level: beginner
972: .seealso: `InsertMode`, `VecScatterBegin()`, `VecScatterEnd()`, `ADD_VALUES`, `INSERT_VALUES`
973: M*/
975: /*S
976: PetscSubcomm - A decomposition of an MPI communicator into subcommunicators
978: Values:
979: + `PETSC_SUBCOMM_GENERAL` - similar to `MPI_Comm_split()` each process sets the new communicator (color) they will belong to and the order within that communicator
980: . `PETSC_SUBCOMM_CONTIGUOUS` - each new communicator contains a set of process with contiguous ranks in the original MPI communicator
981: - `PETSC_SUBCOMM_INTERLACED` - each new communictor contains a set of processes equally far apart in rank from the others in that new communicator
983: Sample Usage:
984: .vb
985: PetscSubcommCreate()
986: PetscSubcommSetNumber()
987: PetscSubcommSetType(PETSC_SUBCOMM_INTERLACED);
988: ccomm = PetscSubcommChild()
989: PetscSubcommDestroy()
990: .ve
992: Example:
993: Consider a communicator with six processes split into 3 subcommunicators.
994: .vb
995: PETSC_SUBCOMM_CONTIGUOUS - the first communicator contains rank 0,1 the second rank 2,3 and the third rank 4,5 in the original ordering of the original communicator
996: PETSC_SUBCOMM_INTERLACED - the first communicator contains rank 0,3, the second 1,4 and the third 2,5
997: .ve
999: Level: advanced
1001: Note:
1002: After a call to `PetscSubcommSetType()`, `PetscSubcommSetTypeGeneral()`, or `PetscSubcommSetFromOptions()` one may call
1003: .vb
1004: PetscSubcommChild() returns the associated subcommunicator on this process
1005: PetscSubcommContiguousParent() returns a parent communitor but with all child of the same subcommunicator having contiguous rank
1006: .ve
1008: Developer Note:
1009: This is used in objects such as `PCREDUNDANT` to manage the subcommunicators on which the redundant computations
1010: are performed.
1012: .seealso: `PetscSubcommCreate()`, `PetscSubcommSetNumber()`, `PetscSubcommSetType()`, `PetscSubcommView()`, `PetscSubcommSetFromOptions()`
1013: S*/
1014: typedef struct _n_PetscSubcomm *PetscSubcomm;
1015: typedef enum {
1016: PETSC_SUBCOMM_GENERAL = 0,
1017: PETSC_SUBCOMM_CONTIGUOUS = 1,
1018: PETSC_SUBCOMM_INTERLACED = 2
1019: } PetscSubcommType;
1020: PETSC_EXTERN const char *const PetscSubcommTypes[];
1022: /*S
1023: PetscHeap - A simple class for managing heaps
1025: Level: intermediate
1027: .seealso: `PetscHeapCreate()`, `PetscHeapAdd()`, `PetscHeapPop()`, `PetscHeapPeek()`, `PetscHeapStash()`, `PetscHeapUnstash()`, `PetscHeapView()`, `PetscHeapDestroy()`
1028: S*/
1029: typedef struct _PetscHeap *PetscHeap;
1031: typedef struct _n_PetscShmComm *PetscShmComm;
1032: typedef struct _n_PetscOmpCtrl *PetscOmpCtrl;
1034: /*S
1035: PetscSegBuffer - a segmented extendable buffer
1037: Level: developer
1039: .seealso: `PetscSegBufferCreate()`, `PetscSegBufferGet()`, `PetscSegBufferExtract()`, `PetscSegBufferDestroy()`
1040: S*/
1041: typedef struct _n_PetscSegBuffer *PetscSegBuffer;
1043: typedef struct _n_PetscOptionsHelpPrinted *PetscOptionsHelpPrinted;
1045: /*S
1046: PetscBT - PETSc bitarrays, efficient storage of arrays of boolean values
1048: Level: advanced
1050: Notes:
1051: The following routines do not have their own manual pages
1053: .vb
1054: PetscBTCreate(m,&bt) - creates a bit array with enough room to hold m values
1055: PetscBTDestroy(&bt) - destroys the bit array
1056: PetscBTMemzero(m,bt) - zeros the entire bit array (sets all values to false)
1057: PetscBTSet(bt,index) - sets a particular entry as true
1058: PetscBTClear(bt,index) - sets a particular entry as false
1059: PetscBTLookup(bt,index) - returns the value
1060: PetscBTLookupSet(bt,index) - returns the value and then sets it true
1061: PetscBTLookupClear(bt,index) - returns the value and then sets it false
1062: PetscBTLength(m) - returns number of bytes in array with m bits
1063: PetscBTView(m,bt,viewer) - prints all the entries in a bit array
1064: .ve
1066: PETSc does not check error flags on `PetscBTLookup()`, `PetcBTLookupSet()`, `PetscBTLength()` because error checking
1067: would cost hundreds more cycles then the operation.
1069: S*/
1070: typedef char *PetscBT;
1072: /* The number of bits in a byte */
1073: #define PETSC_BITS_PER_BYTE CHAR_BIT