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 #ifndef 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 #ifndef 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 #ifndef PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE 242 #define PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE(bufno, typeno) 243 #endif 244 245 #ifndef PETSC_ATTRIBUTE_MPI_TYPE_TAG 246 #define PETSC_ATTRIBUTE_MPI_TYPE_TAG(type) 247 #endif 248 249 #ifndef 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> 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 #ifndef 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 #ifndef 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