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