Actual source code: petscmacros.h
1: #pragma once
3: #include <petscconf.h>
4: #include <petscconf_poison.h> /* for PetscDefined() error checking */
6: /* SUBMANSEC = Sys */
8: #if defined(__cplusplus)
9: #if __cplusplus <= 201103L
10: #define PETSC_CPP_VERSION 11
11: #elif __cplusplus <= 201402L
12: #define PETSC_CPP_VERSION 14
13: #elif __cplusplus <= 201703L
14: #define PETSC_CPP_VERSION 17
15: #elif __cplusplus <= 202002L
16: #define PETSC_CPP_VERSION 20
17: #else
18: #define PETSC_CPP_VERSION 22 // current year, or date of c++2b ratification
19: #endif
20: #endif // __cplusplus
22: #if !defined(PETSC_CPP_VERSION)
23: #define PETSC_CPP_VERSION 0
24: #endif
26: #if defined(__STDC_VERSION__)
27: #if __STDC_VERSION__ <= 199901L
28: // C99 except that 99 is >= 11 or 17 so we shorten it to 9 instead
29: #define PETSC_C_VERSION 9
30: #elif __STDC_VERSION__ <= 201112L
31: #define PETSC_C_VERSION 11
32: #elif __STDC_VERSION__ <= 201710L
33: #define PETSC_C_VERSION 17
34: #else
35: #define PETSC_C_VERSION 22 // current year, or date of c2b ratification
36: #endif
37: #endif // __STDC_VERSION__
39: #if !defined(PETSC_C_VERSION)
40: #define PETSC_C_VERSION 0
41: #endif
43: /* ========================================================================== */
44: /* This facilitates using the C version of PETSc from C++ and the C++ version from C. */
45: #if defined(__cplusplus)
46: #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_CXX
47: #else
48: #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_C
49: #endif
51: /* ========================================================================== */
52: /* Since PETSc manages its own extern "C" handling users should never include PETSc include
53: * files within extern "C". This will generate a compiler error if a user does put the include
54: * file within an extern "C".
55: */
56: #if defined(__cplusplus)
57: void assert_never_put_petsc_headers_inside_an_extern_c(int);
58: void assert_never_put_petsc_headers_inside_an_extern_c(double);
59: #endif
61: #if defined(__cplusplus)
62: #define PETSC_RESTRICT PETSC_CXX_RESTRICT
63: #else
64: #define PETSC_RESTRICT restrict
65: #endif
67: #define PETSC_INLINE PETSC_DEPRECATED_MACRO(3, 17, 0, "inline", ) inline
68: #define PETSC_STATIC_INLINE PETSC_DEPRECATED_MACRO(3, 17, 0, "static inline", ) static inline
70: #if defined(_WIN32) && defined(PETSC_USE_SHARED_LIBRARIES) /* For Win32 shared libraries */
71: #define __declspec(dllexport)
72: #define PETSC_DLLIMPORT __declspec(dllimport)
73: #define PETSC_VISIBILITY_INTERNAL
74: #elif defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_CXX)
75: #define __attribute__((visibility("default")))
76: #define PETSC_DLLIMPORT __attribute__((visibility("default")))
77: #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden")))
78: #elif !defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_C)
79: #define __attribute__((visibility("default")))
80: #define PETSC_DLLIMPORT __attribute__((visibility("default")))
81: #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden")))
82: #else
83: #define
84: #define PETSC_DLLIMPORT
85: #define PETSC_VISIBILITY_INTERNAL
86: #endif
88: #if defined(petsc_EXPORTS) /* CMake defines this when building the shared library */
89: #define PETSC_VISIBILITY_PUBLIC
90: #else /* Win32 users need this to import symbols from petsc.dll */
91: #define PETSC_VISIBILITY_PUBLIC PETSC_DLLIMPORT
92: #endif
94: /* Functions tagged with PETSC_EXTERN in the header files are always defined as extern "C" when
95: * compiled with C++ so they may be used from C and are always visible in the shared libraries
96: */
97: #if defined(__cplusplus)
98: #define PETSC_EXTERN extern "C" PETSC_VISIBILITY_PUBLIC
99: #define PETSC_EXTERN_TYPEDEF extern "C"
100: #define PETSC_INTERN extern "C" PETSC_VISIBILITY_INTERNAL
101: #else
102: #define PETSC_EXTERN extern PETSC_VISIBILITY_PUBLIC
103: #define PETSC_EXTERN_TYPEDEF
104: #define PETSC_INTERN extern PETSC_VISIBILITY_INTERNAL
105: #endif
107: /*MC
108: PETSC_TLS - Marks a variable as thread-local when PETSc is configured with thread safety
110: Synopsis:
111: #include <petscmacros.h>
112: PETSC_TLS type variable;
114: Level: developer
116: Notes:
117: When configured with `--with-threadsafety=1`, each thread has its own instance of the variable, whose lifetime is the lifetime of that thread.
118: With `--with-threadsafety=0`, `PETSC_TLS` expands to nothing.
120: In C, this macro uses C11 `_Thread_local`. In C++, it uses C++11 `thread_local`, except with Clang, where it uses `_Thread_local`
121: to allow C++ code to access thread-local variables defined in C without requiring C++ initialization wrappers.
123: Use `PETSC_EXTERN PETSC_TLS` for an exported declaration or `PETSC_INTERN PETSC_TLS` for an internal declaration.
125: Example Usage:
126: .vb
127: // In a header
128: PETSC_EXTERN PETSC_TLS int counter;
130: // In the source file that defines the variable
131: PETSC_TLS int counter = 0;
132: .ve
134: .seealso: `PetscStack`, `PetscStackView()`
135: M*/
136: #if defined(PETSC_HAVE_THREADSAFETY)
137: /* Clang's C++ thread_local can require initialization wrappers absent from C definitions. */
138: #if defined(__cplusplus) && !defined(__clang__)
139: #define PETSC_TLS thread_local
140: #else
141: #define PETSC_TLS _Thread_local
142: #endif
143: #else
144: #define PETSC_TLS
145: #endif
147: #if defined(PETSC_USE_SINGLE_LIBRARY)
148: #define PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL PETSC_VISIBILITY_INTERNAL
149: #define PETSC_SINGLE_LIBRARY_INTERN PETSC_INTERN
150: #else
151: #define PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL PETSC_VISIBILITY_PUBLIC
152: #define PETSC_SINGLE_LIBRARY_INTERN PETSC_EXTERN
153: #endif
157: #endif
161: #endif
163: /*MC
164: PetscHasAttribute - Determine whether a particular __attribute__ is supported by the compiler
166: Synopsis:
167: #include <petscmacros.h>
168: int PetscHasAttribute(name)
170: Input Parameter:
171: . name - The name of the attribute to test
173: Level: intermediate
175: Notes:
176: name should be identical to what you might pass to the __attribute__ declaration itself --
177: plain, unbroken text.
179: As `PetscHasAttribute()` is wrapper over the function-like macro `__has_attribute()`, the
180: exact type and value returned is implementation defined. In practice however, it usually
181: returns `1` if the attribute is supported and `0` if the attribute is not supported.
183: Example Usage:
184: Typical usage is using the preprocessor
186: .vb
187: #if PetscHasAttribute(always_inline)
188: # define MY_ALWAYS_INLINE __attribute__((always_inline))
189: #else
190: # define MY_ALWAYS_INLINE
191: #endif
193: void foo(void) MY_ALWAYS_INLINE;
194: .ve
196: but it can also be used in regular code
198: .vb
199: if (PetscHasAttribute(some_attribute)) {
200: foo();
201: } else {
202: bar();
203: }
204: .ve
206: .seealso: `PetscHasBuiltin()`, `PetscDefined()`, `PetscLikely()`, `PetscUnlikely()`,
207: `PETSC_ATTRIBUTE_FORMAT`, `PETSC_ATTRIBUTE_MAY_ALIAS`
208: M*/
209: #define PetscHasAttribute(name) __has_attribute(name)
213: #endif
215: /*MC
216: PetscHasBuiltin - Determine whether a particular builtin method is supported by the compiler
218: Synopsis:
219: #include <petscmacros.h>
220: int PetscHasBuiltin(name)
222: Input Parameter:
223: . name - the name of the builtin routine
225: Level: intermediate
227: Notes:
228: Evaluates to `1` if the builtin is supported and `0` otherwise. Note the term "evaluates"
229: (vs "expands") is deliberate; even though `PetscHasBuiltin()` is a macro the underlying
230: detector is itself is a compiler extension with implementation-defined return type and
231: semantics. Some compilers implement it as a macro, others as a compiler function. In practice
232: however, all supporting compilers return an integer Boolean as described.
234: Example Usage:
235: Typical usage is in preprocessor directives
237: .vb
238: #if PetscHasBuiltin(__builtin_trap)
239: __builtin_trap();
240: #else
241: abort();
242: #endif
243: .ve
245: But it may also be used in regular code
247: .vb
248: if (PetscHasBuiltin(__builtin_alloca)) {
249: foo();
250: } else {
251: bar();
252: }
253: .ve
255: Developer Note:
256: Clang's `__has_builtin()` prior to Clang 10 did not properly handle non-function builtins such as
257: `__builtin_types_compatible_p()` which take types or other non-functiony things as
258: arguments. The correct way to detect these then is to use `__is_identifier()` (also a Clang
259: extension). GCC has always worked as expected. See https://stackoverflow.com/a/45043153
261: .seealso: `PetscHasAttribute()`, `PetscAssume()`
262: M*/
263: #if defined(__clang__) && defined(__clang_major__) && (__clang_major__ < 10) && defined(__is_identifier)
264: #define PetscHasBuiltin(name) __is_identifier(name)
265: #else
266: #define PetscHasBuiltin(name) __has_builtin(name)
267: #endif
269: #if !defined(PETSC_SKIP_ATTRIBUTE_MPI_TYPE_TAG)
270: /*
271: Support for Clang (>=3.2) matching type tag arguments with void* buffer types.
272: This allows the compiler to detect cases where the MPI datatype argument passed to a MPI routine
273: does not match the actual type of the argument being passed in
274: */
275: #if PetscHasAttribute(pointer_with_type_tag)
276: #define PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE(bufno, typeno) __attribute__((pointer_with_type_tag(MPI, bufno, typeno)))
277: #endif
279: #if PetscHasAttribute(type_tag_for_datatype)
280: #define PETSC_ATTRIBUTE_MPI_TYPE_TAG(type) __attribute__((type_tag_for_datatype(MPI, type)))
281: #define PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(type) __attribute__((type_tag_for_datatype(MPI, type, layout_compatible)))
282: #endif
283: #endif // PETSC_SKIP_ATTRIBUTE_MPI_TYPE_TAG
285: #if !defined(PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE)
286: #define PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE(bufno, typeno)
287: #endif
289: #if !defined(PETSC_ATTRIBUTE_MPI_TYPE_TAG)
290: #define PETSC_ATTRIBUTE_MPI_TYPE_TAG(type)
291: #endif
293: #if !defined(PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE)
294: #define PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(type)
295: #endif
297: /*MC
298: PETSC_ATTRIBUTE_FORMAT - Indicate to the compiler that specified arguments should be treated
299: as format specifiers and checked for validity
301: Synopsis:
302: #include <petscmacros.h>
303: <attribute declaration> PETSC_ATTRIBUTE_FORMAT(int strIdx, int vaArgIdx)
305: Input Parameters:
306: + strIdx - The (1-indexed) location of the format string in the argument list
307: - vaArgIdx - The (1-indexed) location of the first formattable argument in the argument list
309: Level: developer
311: Notes:
312: This function attribute causes the compiler to issue warnings when the format specifier does
313: not match the type of the variable that will be formatted, or when there exists a mismatch
314: between the number of format specifiers and variables to be formatted. It is safe to use this
315: macro if your compiler does not support format specifier checking (though this is
316: exceeedingly rare).
318: Both `strIdx` and `vaArgIdx` must be compile-time constant integer literals and cannot have the
319: same value.
321: The arguments to be formatted (and therefore checked by the compiler) must be "contiguous" in
322: the argument list, that is, there is no way to indicate gaps which should not be checked.
324: Definition is suppressed by defining `PETSC_SKIP_ATTRIBUTE_FORMAT` prior to including PETSc
325: header files. In this case the macro will expand empty.
327: Example Usage:
328: .vb
329: // format string is 2nd argument, variable argument list containing args is 3rd argument
330: void my_printf(void *obj, const char *fmt_string, ...) PETSC_ATTRIBUTE_FORMAT(2,3)
332: int x = 1;
333: double y = 50.0;
335: my_printf(NULL,"%g",x); // WARNING, format specifier does not match for 'int'!
336: my_printf(NULL,"%d",x,y); // WARNING, more arguments than format specifiers!
337: my_printf(NULL,"%d %g",x,y); // OK
338: .ve
340: .seealso: `PETSC_ATTRIBUTE_COLD`, `PetscHasAttribute()`
341: M*/
342: #if PetscHasAttribute(format) && !defined(PETSC_SKIP_ATTRIBUTE_FORMAT)
343: #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx) __attribute__((format(printf, strIdx, vaArgIdx)))
344: #else
345: #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx)
346: #endif
348: /*MC
349: PETSC_ATTRIBUTE_COLD - Indicate to the compiler that a function is very unlikely to be
350: executed
352: Level: intermediate
354: Notes:
355: The marked function is often optimized for size rather than speed and may be grouped alongside
356: other equally frigid routines improving code locality of lukewarm or hotter parts of program.
358: The paths leading to cold functions are usually automatically marked as unlikely by the
359: compiler. It may thus be useful to mark functions used to handle unlikely conditions -- such
360: as error handlers -- as cold to improve optimization of the surrounding temperate functions.
362: Example Usage:
363: .vb
364: void my_error_handler(...) PETSC_ATTRIBUTE_COLD;
366: if (temperature < 0) {
367: return my_error_handler(...); // chilly!
368: }
369: .ve
371: .seealso: `PetscUnlikely()`, `PetscUnlikelyDebug()`, `PetscLikely()`, `PetscLikelyDebug()`,
372: `PetscUnreachable()`, `PETSC_ATTRIBUTE_FORMAT`
373: M*/
374: #if PetscHasAttribute(__cold__)
375: #define PETSC_ATTRIBUTE_COLD __attribute__((__cold__))
376: #elif PetscHasAttribute(cold) /* some implementations (old gcc) use no underscores */
377: #define PETSC_ATTRIBUTE_COLD __attribute__((cold))
378: #else
379: #define PETSC_ATTRIBUTE_COLD
380: #endif
382: /*MC
383: PETSC_ATTRIBUTE_MAY_ALIAS - Indicate to the compiler that a type is not
384: subjected to type-based alias analysis, but is instead assumed to be able to
385: alias any other type of objects
387: Example Usage:
388: .vb
389: typedef PetscScalar PetscScalarAlias PETSC_ATTRIBUTE_MAY_ALIAS;
391: PetscReal *pointer;
392: PetscScalarAlias *other_pointer = reinterpret_cast<PetscScalarAlias *>(pointer);
393: .ve
395: Level: advanced
397: .seealso: `PetscHasAttribute()`
398: M*/
399: #if PetscHasAttribute(may_alias) && !defined(PETSC_SKIP_ATTRIBUTE_MAY_ALIAS)
400: #define PETSC_ATTRIBUTE_MAY_ALIAS __attribute__((may_alias))
401: #else
402: #define PETSC_ATTRIBUTE_MAY_ALIAS
403: #endif
405: /*MC
406: PETSC_NULLPTR - Standard way of indicating a null value or pointer
408: No Fortran Support
410: Level: beginner
412: Notes:
413: Equivalent to `NULL` in C source, and `nullptr` in C++ source. Note that for the purposes of
414: interoperability between C and C++, setting a pointer to `PETSC_NULLPTR` in C++ is functonially
415: equivalent to setting the same pointer to `NULL` in C. That is to say that the following
416: expressions are equivalent\:
418: .vb
419: ptr == PETSC_NULLPTR
420: ptr == NULL
421: ptr == 0
422: !ptr
424: ptr = PETSC_NULLPTR
425: ptr = NULL
426: ptr = 0
427: .ve
429: and for completeness' sake\:
431: .vb
432: PETSC_NULLPTR == NULL
433: .ve
435: Example Usage:
436: .vb
437: // may be used in place of '\0' or other such terminators in the definition of char arrays
438: const char *const MyEnumTypes[] = {
439: "foo",
440: "bar",
441: PETSC_NULLPTR
442: };
444: // may be used to nullify objects
445: PetscObject obj = PETSC_NULLPTR;
447: // may be used in any function expecting NULL
448: PetscInfo(PETSC_NULLPTR,"Lorem Ipsum Dolor");
449: .ve
451: Developer Notes:
452: `PETSC_NULLPTR` must be used in place of `NULL` in all C++ source files. Using `NULL` in source
453: files compiled with a C++ compiler may lead to unexpected side-effects in function overload
454: resolution and/or compiler warnings.
456: .seealso: `PETSC_CONSTEXPR_14`, `PETSC_NODISCARD`
457: M*/
459: /*MC
460: PETSC_CONSTEXPR_14 - C++14 constexpr
462: No Fortran Support
464: Level: beginner
466: Notes:
467: Equivalent to `constexpr` when using a C++ compiler that supports C++14. Expands to nothing
468: if the C++ compiler does not support C++14 or when not compiling with a C++ compiler. Note
469: that this cannot be used in cases where an empty expansion would result in invalid code. It
470: is safe to use this in C source files.
472: Example Usage:
473: .vb
474: PETSC_CONSTEXPR_14 int factorial(int n)
475: {
476: int r = 1;
478: do {
479: r *= n;
480: } while (--n);
481: return r;
482: }
483: .ve
485: .seealso: `PETSC_NULLPTR`, `PETSC_NODISCARD`
486: M*/
488: /*MC
489: PETSC_NODISCARD - Mark the return value of a function as non-discardable
491: Not available in Fortran
493: Level: beginner
495: Notes:
496: Hints to the compiler that the return value of a function must be captured. A diagnostic may
497: (but is not required to) be emitted if the value is discarded. It is safe to use this in both
498: C and C++ source files.
500: In this context "captured" means assigning the return value of a function to a named
501: variable or casting it to `void`. Between the two, assigning to a named variable is the most
502: portable way of silencing any warnings, since `PETSC_NODISCARD` may expand to GCC's
503: `__attribute__((warn_unused_result))` which will still emit warnings when casting results to
504: `void`.
506: Example Usage:
507: .vb
508: class Foo
509: {
510: int x;
512: public:
513: PETSC_NODISCARD Foo(int y) : x(y) { }
514: };
516: PETSC_NODISCARD int factorial(int n)
517: {
518: return n <= 1 ? 1 : (n * factorial(n - 1));
519: }
521: factorial(10); // Warning: ignoring return value of function declared 'nodiscard'
522: auto x = factorial(10); // OK, capturing return value
523: (void)factorial(10); // Maybe OK, casting to void
524: auto y = factorial(10); // OK, capturing in y (and casting y to void to silence
525: (void)y; // set-but-not-used warnings)
527: Foo(x); // Warning: Ignoring temporary created by a constructor declared 'nodiscard'
528: auto f = Foo(x); // OK, capturing constructed object
529: (void)Foo(x); // Maybe OK, casting to void
530: auto g = Foo(x); // OK, capturing in g (and casting g to void to silence set-but-not-used
531: (void)g; // warnings)
532: .ve
534: .seealso: `PETSC_NULLPTR`, `PETSC_CONSTEXPR_14`
535: M*/
537: /* C++11 features */
538: #if defined(__cplusplus) || (PETSC_C_VERSION >= 23)
539: #define PETSC_NULLPTR nullptr
540: #else
541: #define PETSC_NULLPTR NULL
542: #endif
544: /* C++14 features */
545: #if PETSC_CPP_VERSION >= 14
546: #define PETSC_CONSTEXPR_14 constexpr
547: #else
548: #define PETSC_CONSTEXPR_14
549: #endif
551: /* C++17 features */
552: #if PETSC_CPP_VERSION >= 17
553: #define PETSC_CONSTEXPR_17 constexpr
554: #else
555: #define PETSC_CONSTEXPR_17
556: #endif
558: #if (PETSC_CPP_VERSION >= 17) || (PETSC_C_VERSION >= 23)
559: #define PETSC_NODISCARD [[nodiscard]]
560: #elif PetscHasAttribute(warn_unused_result)
561: #define PETSC_NODISCARD __attribute__((warn_unused_result))
562: #else
563: #define PETSC_NODISCARD
564: #endif
566: #include <petscversion.h>
567: #define PETSC_AUTHOR_INFO " The PETSc Team\n petsc-maint@mcs.anl.gov\n https://petsc.org/\n"
569: /* designated initializers since C99 and C++20, MSVC never supports them though */
570: #if defined(_MSC_VER) || (defined(__cplusplus) && (PETSC_CPP_VERSION < 20))
571: #define PetscDesignatedInitializer(name, ...) __VA_ARGS__
572: #else
573: #define PetscDesignatedInitializer(name, ...) .name = __VA_ARGS__
574: #endif
576: /*MC
577: PetscUnlikely - Hints the compiler that the given condition is usually false
579: Synopsis:
580: #include <petscmacros.h>
581: bool PetscUnlikely(bool cond)
583: Not Collective; No Fortran Support
585: Input Parameter:
586: . cond - Boolean expression
588: Level: advanced
590: Note:
591: This returns the same truth value, it is only a hint to compilers that the result of cond is
592: unlikely to be true.
594: Example usage:
595: .vb
596: if (PetscUnlikely(cond)) {
597: foo(); // cold path
598: } else {
599: bar(); // hot path
600: }
601: .ve
603: .seealso: `PetscLikely()`, `PetscUnlikelyDebug()`, `PetscCall()`, `PetscDefined()`, `PetscHasAttribute()`,
604: `PETSC_ATTRIBUTE_COLD`
605: M*/
606: #if defined(PETSC_HAVE_BUILTIN_EXPECT)
607: #define PetscUnlikely(cond) __builtin_expect(!!(cond), 0)
608: #else
609: #define PetscUnlikely(cond) (cond)
610: #endif
612: /*MC
613: PetscLikely - Hints the compiler that the given condition is usually true
615: Synopsis:
616: #include <petscmacros.h>
617: bool PetscLikely(bool cond)
619: Not Collective; No Fortran Support
621: Input Parameter:
622: . cond - Boolean expression
624: Level: advanced
626: Note:
627: This returns the same truth value, it is only a hint to compilers that the result of cond is
628: likely to be true.
630: Example usage:
631: .vb
632: if (PetscLikely(cond)) {
633: foo(); // hot path
634: } else {
635: bar(); // cold path
636: }
637: .ve
639: .seealso: `PetscUnlikely()`, `PetscDefined()`, `PetscHasAttribute()`, `PETSC_ATTRIBUTE_COLD`
640: M*/
641: #if defined(PETSC_HAVE_BUILTIN_EXPECT)
642: #define PetscLikely(cond) __builtin_expect(!!(cond), 1)
643: #else
644: #define PetscLikely(cond) (cond)
645: #endif
647: /*MC
648: PetscUnreachable - Indicate to the compiler that a code-path is logically unreachable
650: Synopsis:
651: #include <petscmacros.h>
652: void PetscUnreachable(void)
654: Level: advanced
656: Note:
657: Indicates to the compiler (usually via some built-in) that a particular code path is always
658: unreachable. Behavior is undefined if this function is ever executed, the user can expect an
659: unceremonious crash.
661: Example usage:
662: Useful in situations such as switches over enums where not all enumeration values are
663: explicitly covered by the switch
665: .vb
667: int foo(Color c)
668: {
669: // it is known to programmer (or checked previously) that c is either RED or GREEN
670: // but compiler may not be able to deduce this and/or emit spurious warnings
671: switch (c) {
672: case RED:
673: return bar();
674: case GREEN:
675: return baz();
676: default:
677: PetscUnreachable(); // program is ill-formed if executed
678: }
679: }
680: .ve
682: .seealso: `SETERRABORT()`, `PETSCABORT()`, `PETSC_ATTRIBUTE_COLD`, `PetscAssume()`
683: M*/
684: #if PETSC_CPP_VERSION >= 23
685: #include <utility>
686: #define PetscUnreachable() std::unreachable()
687: #elif defined(__GNUC__)
688: /* GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above) */
689: #define PetscUnreachable() __builtin_unreachable()
690: #elif defined(_MSC_VER) /* MSVC */
691: #define PetscUnreachable() __assume(0)
692: #else /* ??? */
693: #define PetscUnreachable() SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Code path explicitly marked as unreachable executed")
694: #endif
696: /*MC
697: PetscAssume - Indicate to the compiler a condition that is defined to be true
699: Synopsis:
700: #include <petscmacros.h>
701: void PetscAssume(bool cond)
703: Input Parameter:
704: . cond - Boolean expression
706: Level: advanced
708: Notes:
709: If supported by the compiler, `cond` is used to inform the optimizer of an invariant
710: truth. The argument itself is never evaluated, so any side effects of the expression will be
711: discarded. This macro is used in `PetscAssert()` to retain information gained from debug
712: checks that would be lost in optimized builds. For example\:
714: .vb
715: PetscErrorCode foo(PetscInt x) {
717: PetscAssert(x >= 0, ...);
718: }
719: .ve
721: The assertion checks that `x` is positive when debugging is enabled (and returns from `foo()`
722: if it is not). This implicitly informs the optimizer that `x` cannot be negative. However,
723: when debugging is disabled any `PetscAssert()` checks are tautologically false, and hence the
724: optimizer cannot deduce any information from them.
726: Due to compiler limitations `PetscAssume()` works best when `cond` involves
727: constants. Certain compilers do not yet propagate symbolic inequalities i.e.\:
729: .vb
730: int a, b, var_five;
732: // BEST, all supporting compilers will understand a cannot be >= 5
733: PetscAssume(a < 5);
735: // OK, some compilers may understand that a cannot be >= 5
736: PetscAssume(a <= b && b < 5);
738: // WORST, most compilers will not get the memo
739: PetscAssume(a <= b && b < var_five);
740: .ve
742: If the condition is violated at runtime then behavior is wholly undefined. If the
743: condition is violated at compile-time, the condition "supersedes" the compile-time violation
744: and the program is ill-formed, no diagnostic required. For example consider the following\:
746: .vb
747: PetscInt x = 0;
749: PetscAssume(x != 0);
750: if (x == 0) {
751: x += 10;
752: } else {
753: popen("rm -rf /", "w");
754: }
755: .ve
757: Even though `x` is demonstrably `0` the compiler may opt to\:
759: - emit an unconditional `popen("rm -rf /", "w")`
760: - ignore `PetscAssume()` altogether and emit the correct path of `x += 10`
761: - reformat the primary disk partition
763: .seealso: `PetscAssert()`
764: M*/
765: #if PETSC_CPP_VERSION >= 23
766: #define PetscAssume(...) [[assume(__VA_ARGS__)]]
767: #elif defined(_MSC_VER) // msvc
768: #define PetscAssume(...) __assume(__VA_ARGS__)
769: #elif defined(__clang__) && PetscHasBuiltin(__builtin_assume) // clang
770: #define PetscAssume(...) \
771: do { \
772: _Pragma("clang diagnostic push"); \
773: _Pragma("clang diagnostic ignored \"-Wassume\""); \
774: __builtin_assume(__VA_ARGS__); \
775: _Pragma("clang diagnostic pop"); \
776: } while (0)
777: #else // gcc (and really old clang)
778: // gcc does not have its own __builtin_assume() intrinsic. One could fake it via
779: //
780: // if (PetscUnlikely(!cond)) PetscUnreachable();
781: //
782: // but this it unsavory because the side effects of cond are not guaranteed to be
783: // discarded. Though in most circumstances gcc will optimize out the if (because any evaluation
784: // for which cond is false would be undefined results in undefined behavior anyway) it cannot
785: // always do so. This is especially the case for opaque or non-inline function calls:
786: //
787: // extern int bar(int);
788: //
789: // int foo(int x) {
790: // PetscAssume(bar(x) == 2);
791: // if (bar(x) == 2) {
792: // return 1;
793: // } else {
794: // return 0;
795: // }
796: // }
797: //
798: // Here gcc would (if just using builtin_expect()) emit 2 calls to bar(). Note we still have
799: // cond "tested" in the condition, but this is done to silence unused-but-set variable warnings
800: #define PetscAssume(...) \
801: do { \
802: if (0 && (__VA_ARGS__)) PetscUnreachable(); \
803: } while (0)
804: #endif
806: /*MC
807: PetscExpand - Expand macro argument
809: Synopsis:
810: #include <petscmacros.h>
811: <macro-expansion> PetscExpand(x)
813: Input Parameter:
814: . x - The preprocessor token to expand
816: Level: beginner
818: .seealso: `PetscStringize()`, `PetscConcat()`
819: M*/
820: #define PetscExpand_(...) __VA_ARGS__
821: #define PetscExpand(...) PetscExpand_(__VA_ARGS__)
823: /*MC
824: PetscStringize - Stringize a token
826: Synopsis:
827: #include <petscmacros.h>
828: const char* PetscStringize(x)
830: No Fortran Support
832: Input Parameter:
833: . x - The token you would like to stringize
835: Output Parameter:
836: . <return_value> - The string representation of `x`
838: Level: beginner
840: Note:
841: `PetscStringize()` expands `x` before stringizing it, if you do not wish to do so, use
842: `PetscStringize_()` instead.
844: Example Usage:
845: .vb
846: #define MY_OTHER_VAR hello there
847: #define MY_VAR MY_OTHER_VAR
849: PetscStringize(MY_VAR) -> "hello there"
850: PetscStringize_(MY_VAR) -> "MY_VAR"
852: int foo;
853: PetscStringize(foo) -> "foo"
854: PetscStringize_(foo) -> "foo"
855: .ve
857: .seealso: `PetscConcat()`, `PetscExpandToNothing()`, `PetscExpand()`
858: M*/
859: #define PetscStringize_(...) #__VA_ARGS__
860: #define PetscStringize(...) PetscStringize_(__VA_ARGS__)
862: /*MC
863: PetscConcat - Concatenate two tokens
865: Synopsis:
866: #include <petscmacros.h>
867: <macro-expansion> PetscConcat(x, y)
869: No Fortran Support
871: Input Parameters:
872: + x - First token
873: - y - Second token
875: Level: beginner
877: Note:
878: `PetscConcat()` will expand both arguments before pasting them together, use `PetscConcat_()`
879: if you don't want to expand them.
881: Example usage:
882: .vb
883: PetscConcat(hello,there) -> hellothere
885: #define HELLO hello
886: PetscConcat(HELLO,there) -> hellothere
887: PetscConcat_(HELLO,there) -> HELLOthere
888: .ve
890: .seealso: `PetscStringize()`, `PetscExpand()`
891: M*/
892: #define PetscConcat_(x, y) x##y
893: #define PetscConcat(x, y) PetscConcat_(x, y)
895: #define PETSC_INTERNAL_COMPL_0 1
896: #define PETSC_INTERNAL_COMPL_1 0
898: /*MC
899: PetscCompl - Expands to the integer complement of its argument
901: Synopsis:
902: #include <petscmacros.h>
903: int PetscCompl(b)
905: No Fortran Support
907: Input Parameter:
908: . b - Preprocessor variable, must expand to either integer literal `0` or `1`
910: Output Parameter:
911: . <return_value> - Either integer literal `0` or `1`
913: Level: beginner
915: Notes:
916: Expands to integer literal `0` if `b` expands to 1, or integer literal `1` if `b` expands to
917: `0`. Behavior is undefined if `b` expands to anything else. `PetscCompl()` will expand its
918: argument before returning the complement.
920: This macro can be useful for negating `PetscDefined()` inside macros, e.g.,
921: .vb
922: #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO))
923: .ve
925: Example usage:
926: .vb
927: #define MY_VAR 1
928: PetscCompl(MY_VAR) -> 0
930: #undef MY_VAR
931: #define MY_VAR 0
932: PetscCompl(MY_VAR) -> 1
933: .ve
935: .seealso: `PetscConcat()`, `PetscDefined()`
936: M*/
937: #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_, PetscExpand(b))
939: #define PetscDefined_arg_1 shift,
940: #define PetscDefined_arg_ shift,
941: #define PetscDefined__take_second_expanded(ignored, val, ...) val
942: #define PetscDefined__take_second_expand(args) PetscDefined__take_second_expanded args
943: #define PetscDefined__take_second(...) PetscDefined__take_second_expand((__VA_ARGS__))
944: #define PetscDefined__(arg1_or_junk) PetscDefined__take_second(arg1_or_junk 1, 0, at_)
945: #define PetscDefined_(value) PetscDefined__(PetscConcat_(PetscDefined_arg_, value))
947: /*MC
948: PetscDefined - Determine whether a Boolean macro is defined
950: Synopsis:
951: #include <petscmacros.h>
952: int PetscDefined(def)
954: No Fortran Support
956: Input Parameter:
957: . def - PETSc-style preprocessor variable (without `PETSC_` prepended!)
959: Output Parameter:
960: . <return_value> - Either integer literal `0` or `1`
962: Level: intermediate
964: Notes:
965: `PetscDefined()` returns `1` if and only if `PETSC_ ## def` is defined (but empty) or defined to
966: integer literal `1`. In all other cases, `PetscDefined()` returns integer literal `0`. Therefore
967: this macro should not be used if its argument may be defined to a non-empty value other than `1`.
969: The prefix `PETSC_` is automatically prepended to `def`, which is treated as a literal suffix
970: and is not macro-expanded. To avoid prepending `PETSC_`, say to add custom checks in user code,
971: one should use `PetscDefined_()`.
972: .vb
973: #define FooDefined(d) PetscDefined_(FOO_##d)
974: .ve
976: Developer Notes:
977: Getting something that works in C and CPP for an arg that may or may not be defined is
978: tricky. Here, if we have `#define PETSC_HAVE_BOOGER 1`, we match on the placeholder define,
979: insert the `0,` for `arg1` and generate the triplet `(0, 1, 0)`. Then, the last step cherry picks
980: the second argument (a one). When `PETSC_HAVE_BOOGER` is not defined, we generate a `(... 1, 0)` pair,
981: and when the last step cherry picks the second argument, we get a zero.
983: Our extra expansion via `PetscDefined__take_second_expand()` is needed with MSVC, which has a
984: nonconforming implementation of variadic macros. The `PETSC_` prefix must be pasted in
985: `PetscDefined()` itself so that an unprefixed macro matching `def` cannot expand before the
986: prefix is added.
988: Example Usage:
989: Suppose you would like to call either `foo()` or `bar()` depending on whether `PETSC_USE_DEBUG`
990: is defined then
992: .vb
993: #if PetscDefined(USE_DEBUG)
994: foo();
995: #else
996: bar();
997: #endif
999: // or alternatively within normal code
1000: if (PetscDefined(USE_DEBUG)) {
1001: foo();
1002: } else {
1003: bar();
1004: }
1005: .ve
1007: is equivalent to
1009: .vb
1010: #if defined(PETSC_USE_DEBUG)
1011: # if MY_DETECT_EMPTY_MACRO(PETSC_USE_DEBUG) // assuming you have such a macro
1012: foo();
1013: # elif PETSC_USE_DEBUG == 1
1014: foo();
1015: # else
1016: bar();
1017: # endif
1018: #else
1019: bar();
1020: #endif
1021: .ve
1023: .seealso: `PetscHasAttribute()`, `PetscUnlikely()`, `PetscLikely()`, `PetscConcat()`,
1024: `PetscExpandToNothing()`, `PetscCompl()`
1025: M*/
1026: #define PetscDefined(def) PetscDefined_(PETSC_##def)
1028: /*MC
1029: PetscUnlikelyDebug - Hints the compiler that the given condition is usually false, eliding
1030: the check in optimized mode
1032: Synopsis:
1033: #include <petscmacros.h>
1034: bool PetscUnlikelyDebug(bool cond)
1036: Not Collective; No Fortran Support
1038: Input Parameter:
1039: . cond - Boolean expression
1041: Level: advanced
1043: Note:
1044: This returns the same truth value, it is only a hint to compilers that the result of `cond` is
1045: likely to be false. When PETSc is compiled in optimized mode this will always return
1046: false. Additionally, `cond` is guaranteed to not be evaluated when PETSc is compiled in
1047: optimized mode.
1049: Example usage:
1050: This routine is shorthand for checking both the condition and whether `PetscDefined(USE_DEBUG)`
1051: is true. So
1053: .vb
1054: if (PetscUnlikelyDebug(cond)) {
1055: foo();
1056: } else {
1057: bar();
1058: }
1059: .ve
1061: is equivalent to
1063: .vb
1064: if (PetscDefined(USE_DEBUG)) {
1065: if (PetscUnlikely(cond)) {
1066: foo();
1067: } else {
1068: bar();
1069: }
1070: } else {
1071: bar();
1072: }
1073: .ve
1075: .seealso: `PetscUnlikely()`, `PetscLikely()`, `PetscCall()`, `SETERRQ`
1076: M*/
1077: #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond))
1079: #if defined(PETSC_CLANG_STATIC_ANALYZER)
1080: // silence compiler warnings when using -pedantic, this is only used by the linter and it cares
1081: // not what ISO C allows
1082: #define PetscMacroReturns_(retexpr, ...) \
1083: __extension__({ \
1084: __VA_ARGS__; \
1085: retexpr; \
1086: })
1087: #else
1088: #define PetscMacroReturns_(retexpr, ...) \
1089: retexpr; \
1090: do { \
1091: __VA_ARGS__; \
1092: } while (0)
1093: #endif
1095: /*MC
1096: PetscExpandToNothing - Expands to absolutely nothing
1098: Synopsis:
1099: #include <petscmacros.h>
1100: void PetscExpandToNothing(...)
1102: No Fortran Support
1104: Input Parameter:
1105: . __VA_ARGS__ - Anything at all
1107: Level: beginner
1109: Note:
1110: Must have at least 1 parameter.
1112: Example usage:
1113: .vb
1114: PetscExpandToNothing(a,b,c) -> *nothing*
1115: .ve
1117: .seealso: `PetscConcat()`, `PetscDefined()`, `PetscStringize()`, `PetscExpand()`
1118: M*/
1119: #define PetscExpandToNothing(...)
1121: /*MC
1122: PetscMacroReturns - Define a macro body that returns a value
1124: Synopsis:
1125: #include <petscmacros.h>
1126: return_type PetscMacroReturns(return_type retexpr, ...)
1128: Input Parameters:
1129: + retexpr - The value or expression that the macro should return
1130: - __VA_ARGS__ - The body of the macro
1132: Level: intermediate
1134: Notes:
1135: Due to limitations of the C-preprocessor `retexpr` cannot depend on symbols declared in the
1136: body of the macro and should not depend on values produced as a result of the expression. The
1137: user should not assume that the result of this macro is equivalent to a single logical source
1138: line. It is not portable to use macros defined using this one in conditional or loop bodies
1139: without enclosing them in curly braces\:
1141: .vb
1142: #define FOO(arg1) PetscMacroReturns(0,arg1+=10) // returns 0
1144: int err,x = 10;
1146: if (...) err = FOO(x); // ERROR, body of FOO() executed outside the if statement
1147: if (...) { err = FOO(x); } // OK
1149: for (...) err = FOO(x); // ERROR, body of FOO() executed outside the loop
1150: for (...) { err = FOO(x); } // OK
1151: .ve
1153: It is also not portable to use this macro directly inside function call, conditional, loop,
1154: or switch statements\:
1156: .vb
1157: extern void bar(int);
1159: int ret = FOO(x);
1161: bar(FOO(x)); // ERROR, may not compile
1162: bar(ret); // OK
1164: if (FOO(x)) // ERROR, may not compile
1165: if (ret) // OK
1166: .ve
1168: Example usage:
1169: .vb
1170: #define MY_SIMPLE_RETURNING_MACRO(arg1) PetscMacroReturns(0,arg1+=10)
1172: int x = 10;
1173: int err = MY_SIMPLE_RETURNING_MACRO(x); // err = 0, x = 20
1175: // multiline macros allowed, but must declare with line continuation as usual
1176: #define MY_COMPLEX_RETURNING_MACRO(arg1) PetscMacroReturns(0, \
1177: if (arg1 > 10) { \
1178: puts("big int!"); \
1179: } else { \
1180: return 7355608; \
1181: } \
1182: )
1184: // if retexpr contains commas, must enclose it with braces
1185: #define MY_COMPLEX_RETEXPR_MACRO_1() PetscMacroReturns(x+=10,0,body...)
1186: #define MY_COMPLEX_RETEXPR_MACRO_2() PetscMacroReturns((x+=10,0),body...)
1188: int x = 10;
1189: int y = MY_COMPLEX_RETEXPR_MACRO_1(); // ERROR, y = x = 20 not 0
1190: int z = MY_COMPLEX_RETEXPR_MACRO_2(); // OK, y = 0, x = 20
1191: .ve
1193: .seealso: `PetscExpand()`, `PetscConcat()`, `PetscStringize()`
1194: M*/
1195: #define PetscMacroReturns(retexpr, ...) PetscMacroReturns_(retexpr, __VA_ARGS__)
1197: #define PetscMacroReturnStandard(...) PetscMacroReturns(PETSC_SUCCESS, __VA_ARGS__)
1199: /*MC
1200: PETSC_STATIC_ARRAY_LENGTH - Return the length of a static array
1202: Synopsis:
1203: #include <petscmacros.h>
1204: size_t PETSC_STATIC_ARRAY_LENGTH(a)
1206: Input Parameter:
1207: . a - a static array of any type
1209: Output Parameter:
1210: . <return_value> - the length of the array
1212: Example:
1213: .vb
1214: PetscInt a[22];
1215: size_t sa = PETSC_STATIC_ARRAY_LENGTH(a)
1216: .ve
1217: `sa` will have a value of 22
1219: Level: intermediate
1220: M*/
1221: #if PETSC_CPP_VERSION >= 14
1222: #include <cstddef>
1223: #include <type_traits>
1225: template <typename T>
1226: static inline constexpr std::size_t PETSC_STATIC_ARRAY_LENGTH(const T &) noexcept
1227: {
1228: static_assert(std::is_array<T>::value, "");
1229: return std::extent<T, std::rank<T>::value - 1>::value;
1230: }
1231: #else
1232: #define PETSC_STATIC_ARRAY_LENGTH(...) (sizeof(__VA_ARGS__) / sizeof(__VA_ARGS__)[0])
1233: #endif
1235: /*
1236: These macros allow extracting out the first argument or all but the first argument from a macro __VAR_ARGS__ INSIDE another macro.
1238: Example usage:
1240: #define mymacro(obj,...) {
1241: PETSC_FIRST_ARG((__VA_ARGS__,unused));
1242: f(22 PETSC_REST_ARG(__VA_ARGS__));
1243: }
1245: Note you add a dummy extra argument to __VA_ARGS__ and enclose them in an extra set of () for PETSC_FIRST_ARG() and PETSC_REST_ARG(__VA_ARGS__) automatically adds a leading comma only if there are additional arguments
1247: Reference:
1248: https://stackoverflow.com/questions/5588855/standard-alternative-to-gccs-va-args-trick
1249: */
1250: #define PETSC_FIRST_ARG_(N, ...) N
1251: #define PETSC_FIRST_ARG(args) PETSC_FIRST_ARG_ args
1252: #define PETSC_SELECT_16TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, ...) a16
1253: #define PETSC_NUM(...) PETSC_SELECT_16TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway)
1254: #define PETSC_REST_HELPER_TWOORMORE(first, ...) , __VA_ARGS__
1255: #define PETSC_REST_HELPER_ONE(first)
1256: #define PETSC_REST_HELPER2(qty, ...) PETSC_REST_HELPER_##qty(__VA_ARGS__)
1257: #define PETSC_REST_HELPER(qty, ...) PETSC_REST_HELPER2(qty, __VA_ARGS__)
1258: #define PETSC_REST_ARG(...) PETSC_REST_HELPER(PETSC_NUM(__VA_ARGS__), __VA_ARGS__)
1260: #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_(name, ...) \
1261: _Pragma(PetscStringize(name diagnostic push)) \
1262: _Pragma(PetscStringize(name diagnostic ignored __VA_ARGS__))
1264: #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_(name) _Pragma(PetscStringize(name diagnostic pop))
1266: #if defined(__clang__)
1267: #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN(...) PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_(clang, __VA_ARGS__)
1268: #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END() PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_(clang)
1269: #elif defined(__GNUC__) || defined(__GNUG__)
1270: // gcc >= 4.6.0
1271: #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600
1272: #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN(...) PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_(GCC, __VA_ARGS__)
1273: #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END() PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_(GCC)
1274: #endif
1275: #endif
1277: #if !defined(PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN)
1278: #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN(...)
1279: #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END(...)
1280: // only undefine these if they are not used
1281: #undef PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_
1282: #undef PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_
1283: #endif
1285: /*MC
1286: PetscPragmaOMP - Sets an OpenMP pragma to affect the next block of code
1288: Synopsis:
1289: #include <petscmacros.h>
1290: int PetscPragmaOMP(name)
1292: No Fortran Support
1294: Input Parameter:
1295: . name - the OpenMP pragma, for example, `critical` or `parallel for`
1297: Level: intermediate
1299: Note:
1300: The pragma takes effect when PETSc was configured with `--with-openmp`. See `PetscPragmaUseOMPKernels()`
1301: for when PETSc was configured to use OpenMP in some of its numerical kernels.
1303: .seealso: `PetscPragmaUseOMPKernels()`, `PetscHasBuiltin()`, `PetscDefined()`, `PetscLikely()`, `PetscUnlikely()`,
1304: `PETSC_ATTRIBUTE_FORMAT`, `PETSC_ATTRIBUTE_MAY_ALIAS`
1305: M*/
1306: #if defined(_OPENMP)
1307: #if defined(_MSC_VER)
1308: #define PetscPragmaOMP(...) __pragma(__VA_ARGS__)
1309: #else
1310: #define PetscPragmaOMP(...) _Pragma(PetscStringize(omp __VA_ARGS__))
1311: #endif
1312: #else
1313: #define PetscPragmaOMP(...)
1314: #endif
1316: /*MC
1317: PetscPragmaUseOMPKernels - Sets an OpenMP pragma to affect the next block of code
1319: Synopsis:
1320: #include <petscmacros.h>
1321: int PetscPragmaUseOMPKernels(name)
1323: No Fortran Support
1325: Input Parameter:
1326: . name - the OpenMP pragma, for example, `critical` or `parallel for`
1328: Level: intermediate
1330: Note:
1331: The pragma takes effect when PETSc was configured with `--with-openmp-kernels`. See `PetscPragmaOMP()`
1332: for when PETSc was configured with OpenMP but not to use it in its numerical kernels
1334: .seealso: `PetscPragmaOMP()`, `PetscHasBuiltin()`, `PetscDefined()`, `PetscLikely()`, `PetscUnlikely()`,
1335: `PETSC_ATTRIBUTE_FORMAT`, `PETSC_ATTRIBUTE_MAY_ALIAS`
1336: M*/
1337: #if defined(PETSC_USE_OPENMP_KERNELS)
1338: #if defined(_MSC_VER)
1339: #define PetscPragmaUseOMPKernels(...) __pragma(__VA_ARGS__)
1340: #else
1341: #define PetscPragmaUseOMPKernels(...) _Pragma(PetscStringize(omp __VA_ARGS__))
1342: #endif
1343: #else
1344: #define PetscPragmaUseOMPKernels(...)
1345: #endif
1347: /* PetscPragmaSIMD - from CeedPragmaSIMD */
1348: #if defined(__NEC__)
1349: #define PetscPragmaSIMD _Pragma("_NEC ivdep")
1350: #elif defined(__INTEL_COMPILER) && !defined(_WIN32)
1351: #define PetscPragmaSIMD _Pragma("vector")
1352: #elif defined(__GNUC__)
1353: #if __GNUC__ >= 5 && !defined(__PGI)
1354: #define PetscPragmaSIMD _Pragma("GCC ivdep")
1355: #endif
1356: #elif defined(_OPENMP) && _OPENMP >= 201307
1357: #define PetscPragmaSIMD PetscPragmaOMP(simd)
1358: #elif defined(PETSC_HAVE_CRAY_VECTOR)
1359: #define PetscPragmaSIMD _Pragma("_CRI ivdep")
1360: #endif
1362: #if !defined(PetscPragmaSIMD)
1363: #define PetscPragmaSIMD
1364: #endif
1366: #include <petsc/private/petscadvancedmacros.h>
1368: #define PetscConcat6_(a, b, c, d, e, f) a##b##c##d##e##f
1370: /*MC
1371: PetscConcat6 - Concatenate six preprocessor tokens after expansion
1373: Synopsis:
1374: #include <petscmacros.h>
1375: <macro-expansion> PetscConcat6(a, b, c, d, e, f)
1377: No Fortran Support
1379: Input Parameters:
1380: + a - first token
1381: . b - second token
1382: . c - third token
1383: . d - fourth token
1384: . e - fifth token
1385: - f - sixth token
1387: Level: developer
1389: Note:
1390: Like `PetscConcat()` but for six arguments. Used internally to build identifier names that mix several macro arguments, for example version-stamped silence macros for deprecation warnings.
1392: .seealso: `PetscConcat()`, `PetscStringize()`, `PetscExpand()`
1393: M*/
1394: #define PetscConcat6(a, b, c, d, e, f) PetscConcat6_(a, b, c, d, e, f)
1396: #define PETSC_DEPRECATED_IDENTIFIER_(__PETSC_DEPRECATION_MACRO__, __SILENCE_MACRO__, major, minor, subminor, replacement, ...) \
1397: PetscIfPetscDefined(__SILENCE_MACRO__, PetscExpandToNothing, \
1398: __PETSC_DEPRECATION_MACRO__)(PetscStringize(Use replacement (since version major.minor.subminor) instead. Silence this warning (as well as all others for this version) by defining PetscConcat_(PETSC_, __SILENCE_MACRO__). __VA_ARGS__))
1400: #define PETSC_DEPRECATED_IDENTIFIER(__PETSC_DEPRECATION_MACRO__, major, minor, subminor, ...) \
1401: PETSC_DEPRECATED_IDENTIFIER_(__PETSC_DEPRECATION_MACRO__, PetscConcat6(SILENCE_DEPRECATION_WARNINGS_, major, _, minor, _, subminor), major, minor, subminor, __VA_ARGS__)
1403: #define PETSC_DEPRECATED_OBJECT(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_OBJECT_BASE, major, minor, subminor, replacement, __VA_ARGS__)
1404: #define PETSC_DEPRECATED_FUNCTION(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_FUNCTION_BASE, major, minor, subminor, replacement, __VA_ARGS__)
1405: #define PETSC_DEPRECATED_TYPEDEF(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_TYPEDEF_BASE, major, minor, subminor, replacement, __VA_ARGS__)
1406: #define PETSC_DEPRECATED_ENUM(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_ENUM_BASE, major, minor, subminor, replacement, __VA_ARGS__)
1407: #define PETSC_DEPRECATED_MACRO(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_MACRO_BASE, major, minor, subminor, replacement, __VA_ARGS__)