1a4963045SJacob Faibussowitsch #pragma once 2bde483f2SJacob Faibussowitsch 3bde483f2SJacob Faibussowitsch #include <petscconf.h> 4bde483f2SJacob Faibussowitsch #include <petscconf_poison.h> /* for PetscDefined() error checking */ 5bde483f2SJacob Faibussowitsch 6ac09b921SBarry Smith /* SUBMANSEC = Sys */ 7ac09b921SBarry Smith 80e6b6b59SJacob Faibussowitsch #if defined(__cplusplus) 90e6b6b59SJacob Faibussowitsch #if __cplusplus <= 201103L 100e6b6b59SJacob Faibussowitsch #define PETSC_CPP_VERSION 11 110e6b6b59SJacob Faibussowitsch #elif __cplusplus <= 201402L 120e6b6b59SJacob Faibussowitsch #define PETSC_CPP_VERSION 14 130e6b6b59SJacob Faibussowitsch #elif __cplusplus <= 201703L 140e6b6b59SJacob Faibussowitsch #define PETSC_CPP_VERSION 17 150e6b6b59SJacob Faibussowitsch #elif __cplusplus <= 202002L 160e6b6b59SJacob Faibussowitsch #define PETSC_CPP_VERSION 20 170e6b6b59SJacob Faibussowitsch #else 180e6b6b59SJacob Faibussowitsch #define PETSC_CPP_VERSION 22 // current year, or date of c++2b ratification 190e6b6b59SJacob Faibussowitsch #endif 200e6b6b59SJacob Faibussowitsch #endif // __cplusplus 210e6b6b59SJacob Faibussowitsch 22*beceaeb6SBarry Smith #if !defined(PETSC_CPP_VERSION) 230e6b6b59SJacob Faibussowitsch #define PETSC_CPP_VERSION 0 240e6b6b59SJacob Faibussowitsch #endif 250e6b6b59SJacob Faibussowitsch 266797ed33SJacob Faibussowitsch #if defined(__STDC_VERSION__) 276797ed33SJacob Faibussowitsch #if __STDC_VERSION__ <= 199901L 286797ed33SJacob Faibussowitsch // C99 except that 99 is >= 11 or 17 so we shorten it to 9 instead 296797ed33SJacob Faibussowitsch #define PETSC_C_VERSION 9 306797ed33SJacob Faibussowitsch #elif __STDC_VERSION__ <= 201112L 316797ed33SJacob Faibussowitsch #define PETSC_C_VERSION 11 326797ed33SJacob Faibussowitsch #elif __STDC_VERSION__ <= 201710L 336797ed33SJacob Faibussowitsch #define PETSC_C_VERSION 17 346797ed33SJacob Faibussowitsch #else 356797ed33SJacob Faibussowitsch #define PETSC_C_VERSION 22 // current year, or date of c2b ratification 366797ed33SJacob Faibussowitsch #endif 376797ed33SJacob Faibussowitsch #endif // __STDC_VERSION__ 386797ed33SJacob Faibussowitsch 39*beceaeb6SBarry Smith #if !defined(PETSC_C_VERSION) 406797ed33SJacob Faibussowitsch #define PETSC_C_VERSION 0 416797ed33SJacob Faibussowitsch #endif 426797ed33SJacob Faibussowitsch 43bde483f2SJacob Faibussowitsch /* ========================================================================== */ 44bde483f2SJacob Faibussowitsch /* This facilitates using the C version of PETSc from C++ and the C++ version from C. */ 45bde483f2SJacob Faibussowitsch #if defined(__cplusplus) 46bde483f2SJacob Faibussowitsch #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_CXX 47bde483f2SJacob Faibussowitsch #else 48bde483f2SJacob Faibussowitsch #define PETSC_FUNCTION_NAME PETSC_FUNCTION_NAME_C 49bde483f2SJacob Faibussowitsch #endif 50bde483f2SJacob Faibussowitsch 51bde483f2SJacob Faibussowitsch /* ========================================================================== */ 52bde483f2SJacob Faibussowitsch /* Since PETSc manages its own extern "C" handling users should never include PETSc include 53bde483f2SJacob Faibussowitsch * files within extern "C". This will generate a compiler error if a user does put the include 54bde483f2SJacob Faibussowitsch * file within an extern "C". 55bde483f2SJacob Faibussowitsch */ 56bde483f2SJacob Faibussowitsch #if defined(__cplusplus) 579371c9d4SSatish Balay void assert_never_put_petsc_headers_inside_an_extern_c(int); 589371c9d4SSatish Balay void assert_never_put_petsc_headers_inside_an_extern_c(double); 59bde483f2SJacob Faibussowitsch #endif 60bde483f2SJacob Faibussowitsch 61bde483f2SJacob Faibussowitsch #if defined(__cplusplus) 62bde483f2SJacob Faibussowitsch #define PETSC_RESTRICT PETSC_CXX_RESTRICT 63bde483f2SJacob Faibussowitsch #else 646ee8c794SJacob Faibussowitsch #define PETSC_RESTRICT restrict 65bde483f2SJacob Faibussowitsch #endif 66bde483f2SJacob Faibussowitsch 67edd03b47SJacob Faibussowitsch #define PETSC_INLINE PETSC_DEPRECATED_MACRO(3, 17, 0, "inline", ) inline 68edd03b47SJacob Faibussowitsch #define PETSC_STATIC_INLINE PETSC_DEPRECATED_MACRO(3, 17, 0, "static inline", ) static inline 69bde483f2SJacob Faibussowitsch 70bde483f2SJacob Faibussowitsch #if defined(_WIN32) && defined(PETSC_USE_SHARED_LIBRARIES) /* For Win32 shared libraries */ 71bde483f2SJacob Faibussowitsch #define PETSC_DLLEXPORT __declspec(dllexport) 72bde483f2SJacob Faibussowitsch #define PETSC_DLLIMPORT __declspec(dllimport) 73bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_INTERNAL 74bde483f2SJacob Faibussowitsch #elif defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_CXX) 75bde483f2SJacob Faibussowitsch #define PETSC_DLLEXPORT __attribute__((visibility("default"))) 76bde483f2SJacob Faibussowitsch #define PETSC_DLLIMPORT __attribute__((visibility("default"))) 77bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden"))) 78bde483f2SJacob Faibussowitsch #elif !defined(__cplusplus) && defined(PETSC_USE_VISIBILITY_C) 79bde483f2SJacob Faibussowitsch #define PETSC_DLLEXPORT __attribute__((visibility("default"))) 80bde483f2SJacob Faibussowitsch #define PETSC_DLLIMPORT __attribute__((visibility("default"))) 81bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_INTERNAL __attribute__((visibility("hidden"))) 82bde483f2SJacob Faibussowitsch #else 83bde483f2SJacob Faibussowitsch #define PETSC_DLLEXPORT 84bde483f2SJacob Faibussowitsch #define PETSC_DLLIMPORT 85bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_INTERNAL 86bde483f2SJacob Faibussowitsch #endif 87bde483f2SJacob Faibussowitsch 88bde483f2SJacob Faibussowitsch #if defined(petsc_EXPORTS) /* CMake defines this when building the shared library */ 89bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_PUBLIC PETSC_DLLEXPORT 90bde483f2SJacob Faibussowitsch #else /* Win32 users need this to import symbols from petsc.dll */ 91bde483f2SJacob Faibussowitsch #define PETSC_VISIBILITY_PUBLIC PETSC_DLLIMPORT 92bde483f2SJacob Faibussowitsch #endif 93bde483f2SJacob Faibussowitsch 94bde483f2SJacob Faibussowitsch /* Functions tagged with PETSC_EXTERN in the header files are always defined as extern "C" when 95bde483f2SJacob Faibussowitsch * compiled with C++ so they may be used from C and are always visible in the shared libraries 96bde483f2SJacob Faibussowitsch */ 97bde483f2SJacob Faibussowitsch #if defined(__cplusplus) 98bde483f2SJacob Faibussowitsch #define PETSC_EXTERN extern "C" PETSC_VISIBILITY_PUBLIC 99bde483f2SJacob Faibussowitsch #define PETSC_EXTERN_TYPEDEF extern "C" 100bde483f2SJacob Faibussowitsch #define PETSC_INTERN extern "C" PETSC_VISIBILITY_INTERNAL 101bde483f2SJacob Faibussowitsch #else 102bde483f2SJacob Faibussowitsch #define PETSC_EXTERN extern PETSC_VISIBILITY_PUBLIC 103bde483f2SJacob Faibussowitsch #define PETSC_EXTERN_TYPEDEF 104bde483f2SJacob Faibussowitsch #define PETSC_INTERN extern PETSC_VISIBILITY_INTERNAL 105bde483f2SJacob Faibussowitsch #endif 106bde483f2SJacob Faibussowitsch 107bde483f2SJacob Faibussowitsch #if defined(PETSC_USE_SINGLE_LIBRARY) 10847f8145dSJacob Faibussowitsch #define PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL PETSC_VISIBILITY_INTERNAL 109bde483f2SJacob Faibussowitsch #define PETSC_SINGLE_LIBRARY_INTERN PETSC_INTERN 110bde483f2SJacob Faibussowitsch #else 11147f8145dSJacob Faibussowitsch #define PETSC_SINGLE_LIBRARY_VISIBILITY_INTERNAL PETSC_VISIBILITY_PUBLIC 112bde483f2SJacob Faibussowitsch #define PETSC_SINGLE_LIBRARY_INTERN PETSC_EXTERN 113bde483f2SJacob Faibussowitsch #endif 114bde483f2SJacob Faibussowitsch 1151cf396e4SJacob Faibussowitsch #if !defined(__has_feature) 1161cf396e4SJacob Faibussowitsch #define __has_feature(x) 0 1171cf396e4SJacob Faibussowitsch #endif 1181cf396e4SJacob Faibussowitsch 119bde483f2SJacob Faibussowitsch /*MC 120bde483f2SJacob Faibussowitsch PetscHasAttribute - Determine whether a particular __attribute__ is supported by the compiler 121bde483f2SJacob Faibussowitsch 122bde483f2SJacob Faibussowitsch Synopsis: 123bde483f2SJacob Faibussowitsch #include <petscmacros.h> 124c7481402SJacob Faibussowitsch int PetscHasAttribute(name) 125bde483f2SJacob Faibussowitsch 126bde483f2SJacob Faibussowitsch Input Parameter: 127bde483f2SJacob Faibussowitsch . name - The name of the attribute to test 128bde483f2SJacob Faibussowitsch 12995bd0b28SBarry Smith Level: intermediate 13095bd0b28SBarry Smith 131bde483f2SJacob Faibussowitsch Notes: 132bde483f2SJacob Faibussowitsch name should be identical to what you might pass to the __attribute__ declaration itself -- 133bde483f2SJacob Faibussowitsch plain, unbroken text. 134bde483f2SJacob Faibussowitsch 135c7481402SJacob Faibussowitsch As `PetscHasAttribute()` is wrapper over the function-like macro `__has_attribute()`, the 136c7481402SJacob Faibussowitsch exact type and value returned is implementation defined. In practice however, it usually 137c7481402SJacob Faibussowitsch returns `1` if the attribute is supported and `0` if the attribute is not supported. 138bde483f2SJacob Faibussowitsch 139bde483f2SJacob Faibussowitsch Example Usage: 140bde483f2SJacob Faibussowitsch Typical usage is using the preprocessor 141bde483f2SJacob Faibussowitsch 142bde483f2SJacob Faibussowitsch .vb 143bde483f2SJacob Faibussowitsch #if PetscHasAttribute(always_inline) 144bde483f2SJacob Faibussowitsch # define MY_ALWAYS_INLINE __attribute__((always_inline)) 145bde483f2SJacob Faibussowitsch #else 146bde483f2SJacob Faibussowitsch # define MY_ALWAYS_INLINE 147bde483f2SJacob Faibussowitsch #endif 148bde483f2SJacob Faibussowitsch 149bde483f2SJacob Faibussowitsch void foo(void) MY_ALWAYS_INLINE; 150bde483f2SJacob Faibussowitsch .ve 151bde483f2SJacob Faibussowitsch 152bde483f2SJacob Faibussowitsch but it can also be used in regular code 153bde483f2SJacob Faibussowitsch 154bde483f2SJacob Faibussowitsch .vb 155bde483f2SJacob Faibussowitsch if (PetscHasAttribute(some_attribute)) { 156bde483f2SJacob Faibussowitsch foo(); 157bde483f2SJacob Faibussowitsch } else { 158bde483f2SJacob Faibussowitsch bar(); 159bde483f2SJacob Faibussowitsch } 160bde483f2SJacob Faibussowitsch .ve 161bde483f2SJacob Faibussowitsch 162c7481402SJacob Faibussowitsch .seealso: `PetscHasBuiltin()`, `PetscDefined()`, `PetscLikely()`, `PetscUnlikely()`, 163f7b5d04fSPierre Jolivet `PETSC_ATTRIBUTE_FORMAT`, `PETSC_ATTRIBUTE_MAY_ALIAS` 164bde483f2SJacob Faibussowitsch M*/ 165bde483f2SJacob Faibussowitsch #if !defined(__has_attribute) 166bde483f2SJacob Faibussowitsch #define __has_attribute(x) 0 167bde483f2SJacob Faibussowitsch #endif 168bde483f2SJacob Faibussowitsch #define PetscHasAttribute(name) __has_attribute(name) 169bde483f2SJacob Faibussowitsch 170c7481402SJacob Faibussowitsch /*MC 171c7481402SJacob Faibussowitsch PetscHasBuiltin - Determine whether a particular builtin method is supported by the compiler 172c7481402SJacob Faibussowitsch 173c7481402SJacob Faibussowitsch Synopsis: 174c7481402SJacob Faibussowitsch #include <petscmacros.h> 175c7481402SJacob Faibussowitsch int PetscHasBuiltin(name) 176c7481402SJacob Faibussowitsch 177c7481402SJacob Faibussowitsch Input Parameter: 178c7481402SJacob Faibussowitsch . name - the name of the builtin routine 179c7481402SJacob Faibussowitsch 18095bd0b28SBarry Smith Level: intermediate 18195bd0b28SBarry Smith 182c7481402SJacob Faibussowitsch Notes: 183d5b43468SJose E. Roman Evaluates to `1` if the builtin is supported and `0` otherwise. Note the term "evaluates" 184c7481402SJacob Faibussowitsch (vs "expands") is deliberate; even though `PetscHasBuiltin()` is a macro the underlying 185c7481402SJacob Faibussowitsch detector is itself is a compiler extension with implementation-defined return type and 186c7481402SJacob Faibussowitsch semantics. Some compilers implement it as a macro, others as a compiler function. In practice 187c7481402SJacob Faibussowitsch however, all supporting compilers return an integer boolean as described. 188c7481402SJacob Faibussowitsch 189c7481402SJacob Faibussowitsch Example Usage: 190c7481402SJacob Faibussowitsch Typical usage is in preprocessor directives 191c7481402SJacob Faibussowitsch 192c7481402SJacob Faibussowitsch .vb 193c7481402SJacob Faibussowitsch #if PetscHasBuiltin(__builtin_trap) 194c7481402SJacob Faibussowitsch __builtin_trap(); 195c7481402SJacob Faibussowitsch #else 196c7481402SJacob Faibussowitsch abort(); 197c7481402SJacob Faibussowitsch #endif 198c7481402SJacob Faibussowitsch .ve 199c7481402SJacob Faibussowitsch 200c7481402SJacob Faibussowitsch But it may also be used in regular code 201c7481402SJacob Faibussowitsch 202c7481402SJacob Faibussowitsch .vb 203c7481402SJacob Faibussowitsch if (PetscHasBuiltin(__builtin_alloca)) { 204c7481402SJacob Faibussowitsch foo(); 205c7481402SJacob Faibussowitsch } else { 206c7481402SJacob Faibussowitsch bar(); 207c7481402SJacob Faibussowitsch } 208c7481402SJacob Faibussowitsch .ve 209c7481402SJacob Faibussowitsch 210c7481402SJacob Faibussowitsch .seealso: `PetscHasAttribute()`, `PetscAssume()` 211c7481402SJacob Faibussowitsch M*/ 212c7481402SJacob Faibussowitsch #if !defined(__has_builtin) 213c7481402SJacob Faibussowitsch #define __has_builtin(x) 0 214c7481402SJacob Faibussowitsch #endif 215c7481402SJacob Faibussowitsch // clangs __has_builtin prior to clang 10 did not properly handle non-function builtins such as 216c7481402SJacob Faibussowitsch // __builtin_types_compatible_p which take types or other non-functiony things as 217c7481402SJacob Faibussowitsch // arguments. The correct way to detect these then is to use __is_identifier (also a clang 218c7481402SJacob Faibussowitsch // extension). GCC has always worked as expected. see https://stackoverflow.com/a/45043153 219c7481402SJacob Faibussowitsch #if defined(__clang__) && defined(__clang_major__) && (__clang_major__ < 10) && defined(__is_identifier) 220c7481402SJacob Faibussowitsch #define PetscHasBuiltin(name) __is_identifier(name) 221c7481402SJacob Faibussowitsch #else 222c7481402SJacob Faibussowitsch #define PetscHasBuiltin(name) __has_builtin(name) 223c7481402SJacob Faibussowitsch #endif 224c7481402SJacob Faibussowitsch 22593d501b3SJacob Faibussowitsch #if !defined(PETSC_SKIP_ATTRIBUTE_MPI_TYPE_TAG) 22693d501b3SJacob Faibussowitsch /* 22793d501b3SJacob Faibussowitsch Support for Clang (>=3.2) matching type tag arguments with void* buffer types. 22893d501b3SJacob Faibussowitsch This allows the compiler to detect cases where the MPI datatype argument passed to a MPI routine 22993d501b3SJacob Faibussowitsch does not match the actual type of the argument being passed in 23093d501b3SJacob Faibussowitsch */ 23193d501b3SJacob Faibussowitsch #if PetscHasAttribute(pointer_with_type_tag) 23293d501b3SJacob Faibussowitsch #define PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE(bufno, typeno) __attribute__((pointer_with_type_tag(MPI, bufno, typeno))) 23393d501b3SJacob Faibussowitsch #endif 23493d501b3SJacob Faibussowitsch 23593d501b3SJacob Faibussowitsch #if PetscHasAttribute(type_tag_for_datatype) 23693d501b3SJacob Faibussowitsch #define PETSC_ATTRIBUTE_MPI_TYPE_TAG(type) __attribute__((type_tag_for_datatype(MPI, type))) 23793d501b3SJacob Faibussowitsch #define PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(type) __attribute__((type_tag_for_datatype(MPI, type, layout_compatible))) 23893d501b3SJacob Faibussowitsch #endif 23993d501b3SJacob Faibussowitsch #endif // PETSC_SKIP_ATTRIBUTE_MPI_TYPE_TAG 24093d501b3SJacob Faibussowitsch 241*beceaeb6SBarry Smith #if !defined(PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE) 24293d501b3SJacob Faibussowitsch #define PETSC_ATTRIBUTE_MPI_POINTER_WITH_TYPE(bufno, typeno) 24393d501b3SJacob Faibussowitsch #endif 24493d501b3SJacob Faibussowitsch 245*beceaeb6SBarry Smith #if !defined(PETSC_ATTRIBUTE_MPI_TYPE_TAG) 24693d501b3SJacob Faibussowitsch #define PETSC_ATTRIBUTE_MPI_TYPE_TAG(type) 24793d501b3SJacob Faibussowitsch #endif 24893d501b3SJacob Faibussowitsch 249*beceaeb6SBarry Smith #if !defined(PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE) 25093d501b3SJacob Faibussowitsch #define PETSC_ATTRIBUTE_MPI_TYPE_TAG_LAYOUT_COMPATIBLE(type) 25193d501b3SJacob Faibussowitsch #endif 25293d501b3SJacob Faibussowitsch 253bde483f2SJacob Faibussowitsch /*MC 25463a3b9bcSJacob Faibussowitsch PETSC_ATTRIBUTE_FORMAT - Indicate to the compiler that specified arguments should be treated 25563a3b9bcSJacob Faibussowitsch as format specifiers and checked for validity 25663a3b9bcSJacob Faibussowitsch 25763a3b9bcSJacob Faibussowitsch Synopsis: 25863a3b9bcSJacob Faibussowitsch #include <petscmacros.h> 25963a3b9bcSJacob Faibussowitsch <attribute declaration> PETSC_ATTRIBUTE_FORMAT(int strIdx, int vaArgIdx) 26063a3b9bcSJacob Faibussowitsch 26163a3b9bcSJacob Faibussowitsch Input Parameters: 26263a3b9bcSJacob Faibussowitsch + strIdx - The (1-indexed) location of the format string in the argument list 26363a3b9bcSJacob Faibussowitsch - vaArgIdx - The (1-indexed) location of the first formattable argument in the argument list 26463a3b9bcSJacob Faibussowitsch 26516a05f60SBarry Smith Level: developer 26616a05f60SBarry Smith 26763a3b9bcSJacob Faibussowitsch Notes: 26863a3b9bcSJacob Faibussowitsch This function attribute causes the compiler to issue warnings when the format specifier does 26963a3b9bcSJacob Faibussowitsch not match the type of the variable that will be formatted, or when there exists a mismatch 27063a3b9bcSJacob Faibussowitsch between the number of format specifiers and variables to be formatted. It is safe to use this 27163a3b9bcSJacob Faibussowitsch macro if your compiler does not support format specifier checking (though this is 27263a3b9bcSJacob Faibussowitsch exceeedingly rare). 27363a3b9bcSJacob Faibussowitsch 27416a05f60SBarry Smith Both `strIdx` and `vaArgIdx` must be compile-time constant integer literals and cannot have the 27563a3b9bcSJacob Faibussowitsch same value. 27663a3b9bcSJacob Faibussowitsch 27763a3b9bcSJacob Faibussowitsch The arguments to be formatted (and therefore checked by the compiler) must be "contiguous" in 27863a3b9bcSJacob Faibussowitsch the argument list, that is, there is no way to indicate gaps which should not be checked. 27963a3b9bcSJacob Faibussowitsch 28087497f52SBarry Smith Definition is suppressed by defining `PETSC_SKIP_ATTRIBUTE_FORMAT` prior to including PETSc 28163a3b9bcSJacob Faibussowitsch header files. In this case the macro will expand empty. 28263a3b9bcSJacob Faibussowitsch 28363a3b9bcSJacob Faibussowitsch Example Usage: 28463a3b9bcSJacob Faibussowitsch .vb 28563a3b9bcSJacob Faibussowitsch // format string is 2nd argument, variable argument list containing args is 3rd argument 28663a3b9bcSJacob Faibussowitsch void my_printf(void *obj, const char *fmt_string, ...) PETSC_ATTRIBUTE_FORMAT(2,3) 28763a3b9bcSJacob Faibussowitsch 28863a3b9bcSJacob Faibussowitsch int x = 1; 28963a3b9bcSJacob Faibussowitsch double y = 50.0; 29063a3b9bcSJacob Faibussowitsch 29163a3b9bcSJacob Faibussowitsch my_printf(NULL,"%g",x); // WARNING, format specifier does not match for 'int'! 29263a3b9bcSJacob Faibussowitsch my_printf(NULL,"%d",x,y); // WARNING, more arguments than format specifiers! 29363a3b9bcSJacob Faibussowitsch my_printf(NULL,"%d %g",x,y); // OK 29463a3b9bcSJacob Faibussowitsch .ve 29563a3b9bcSJacob Faibussowitsch 296db781477SPatrick Sanan .seealso: `PETSC_ATTRIBUTE_COLD`, `PetscHasAttribute()` 29763a3b9bcSJacob Faibussowitsch M*/ 29863a3b9bcSJacob Faibussowitsch #if PetscHasAttribute(format) && !defined(PETSC_SKIP_ATTRIBUTE_FORMAT) 29963a3b9bcSJacob Faibussowitsch #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx) __attribute__((format(printf, strIdx, vaArgIdx))) 30063a3b9bcSJacob Faibussowitsch #else 30163a3b9bcSJacob Faibussowitsch #define PETSC_ATTRIBUTE_FORMAT(strIdx, vaArgIdx) 30263a3b9bcSJacob Faibussowitsch #endif 30363a3b9bcSJacob Faibussowitsch 30463a3b9bcSJacob Faibussowitsch /*MC 305d8e4614bSJacob Faibussowitsch PETSC_ATTRIBUTE_COLD - Indicate to the compiler that a function is very unlikely to be 306d8e4614bSJacob Faibussowitsch executed 307d8e4614bSJacob Faibussowitsch 30816a05f60SBarry Smith Level: intermediate 30916a05f60SBarry Smith 310d8e4614bSJacob Faibussowitsch Notes: 311d8e4614bSJacob Faibussowitsch The marked function is often optimized for size rather than speed and may be grouped alongside 312d8e4614bSJacob Faibussowitsch other equally frigid routines improving code locality of lukewarm or hotter parts of program. 313d8e4614bSJacob Faibussowitsch 314d8e4614bSJacob Faibussowitsch The paths leading to cold functions are usually automatically marked as unlikely by the 315d8e4614bSJacob Faibussowitsch compiler. It may thus be useful to mark functions used to handle unlikely conditions -- such 316d8e4614bSJacob Faibussowitsch as error handlers -- as cold to improve optimization of the surrounding temperate functions. 317d8e4614bSJacob Faibussowitsch 318d8e4614bSJacob Faibussowitsch Example Usage: 319d8e4614bSJacob Faibussowitsch .vb 320d8e4614bSJacob Faibussowitsch void my_error_handler(...) PETSC_ATTRIBUTE_COLD; 321d8e4614bSJacob Faibussowitsch 322d8e4614bSJacob Faibussowitsch if (temperature < 0) { 323d8e4614bSJacob Faibussowitsch return my_error_handler(...); // chilly! 324d8e4614bSJacob Faibussowitsch } 325d8e4614bSJacob Faibussowitsch .ve 326d8e4614bSJacob Faibussowitsch 327db781477SPatrick Sanan .seealso: `PetscUnlikely()`, `PetscUnlikelyDebug()`, `PetscLikely()`, `PetscLikelyDebug()`, 328db781477SPatrick Sanan `PetscUnreachable()`, `PETSC_ATTRIBUTE_FORMAT` 329d8e4614bSJacob Faibussowitsch M*/ 330d8e4614bSJacob Faibussowitsch #if PetscHasAttribute(__cold__) 331d8e4614bSJacob Faibussowitsch #define PETSC_ATTRIBUTE_COLD __attribute__((__cold__)) 332d8e4614bSJacob Faibussowitsch #elif PetscHasAttribute(cold) /* some implementations (old gcc) use no underscores */ 333d8e4614bSJacob Faibussowitsch #define PETSC_ATTRIBUTE_COLD __attribute__((cold)) 334d8e4614bSJacob Faibussowitsch #else 335d8e4614bSJacob Faibussowitsch #define PETSC_ATTRIBUTE_COLD 336d8e4614bSJacob Faibussowitsch #endif 337d8e4614bSJacob Faibussowitsch 338d8e4614bSJacob Faibussowitsch /*MC 339f7b5d04fSPierre Jolivet PETSC_ATTRIBUTE_MAY_ALIAS - Indicate to the compiler that a type is not 340f7b5d04fSPierre Jolivet subjected to type-based alias analysis, but is instead assumed to be able to 341f7b5d04fSPierre Jolivet alias any other type of objects 342f7b5d04fSPierre Jolivet 343752b9880SPierre Jolivet Example Usage: 344752b9880SPierre Jolivet .vb 345752b9880SPierre Jolivet typedef PetscScalar PetscScalarAlias PETSC_ATTRIBUTE_MAY_ALIAS; 346752b9880SPierre Jolivet 347752b9880SPierre Jolivet PetscReal *pointer; 348752b9880SPierre Jolivet PetscScalarAlias *other_pointer = reinterpret_cast<PetscScalarAlias *>(pointer); 349752b9880SPierre Jolivet .ve 350752b9880SPierre Jolivet 351f7b5d04fSPierre Jolivet Level: advanced 352f7b5d04fSPierre Jolivet 353f7b5d04fSPierre Jolivet .seealso: `PetscHasAttribute()` 354f7b5d04fSPierre Jolivet M*/ 355f7b5d04fSPierre Jolivet #if PetscHasAttribute(may_alias) && !defined(PETSC_SKIP_ATTRIBUTE_MAY_ALIAS) 356f7b5d04fSPierre Jolivet #define PETSC_ATTRIBUTE_MAY_ALIAS __attribute__((may_alias)) 357f7b5d04fSPierre Jolivet #else 358f7b5d04fSPierre Jolivet #define PETSC_ATTRIBUTE_MAY_ALIAS 359f7b5d04fSPierre Jolivet #endif 360f7b5d04fSPierre Jolivet 361f7b5d04fSPierre Jolivet /*MC 362bde483f2SJacob Faibussowitsch PETSC_NULLPTR - Standard way of indicating a null value or pointer 363bde483f2SJacob Faibussowitsch 36420f4b53cSBarry Smith No Fortran Support 36520f4b53cSBarry Smith 36620f4b53cSBarry Smith Level: beginner 36720f4b53cSBarry Smith 368bde483f2SJacob Faibussowitsch Notes: 36916a05f60SBarry Smith Equivalent to `NULL` in C source, and `nullptr` in C++ source. Note that for the purposes of 37016a05f60SBarry Smith interoperability between C and C++, setting a pointer to `PETSC_NULLPTR` in C++ is functonially 37120f4b53cSBarry Smith equivalent to setting the same pointer to `NULL` in C. That is to say that the following 372bde483f2SJacob Faibussowitsch expressions are equivalent\: 373bde483f2SJacob Faibussowitsch 374bde483f2SJacob Faibussowitsch .vb 375bde483f2SJacob Faibussowitsch ptr == PETSC_NULLPTR 376bde483f2SJacob Faibussowitsch ptr == NULL 377bde483f2SJacob Faibussowitsch ptr == 0 378bde483f2SJacob Faibussowitsch !ptr 379bde483f2SJacob Faibussowitsch 380bde483f2SJacob Faibussowitsch ptr = PETSC_NULLPTR 381bde483f2SJacob Faibussowitsch ptr = NULL 382bde483f2SJacob Faibussowitsch ptr = 0 383bde483f2SJacob Faibussowitsch .ve 384bde483f2SJacob Faibussowitsch 385bde483f2SJacob Faibussowitsch and for completeness' sake\: 386bde483f2SJacob Faibussowitsch 387bde483f2SJacob Faibussowitsch .vb 388bde483f2SJacob Faibussowitsch PETSC_NULLPTR == NULL 389bde483f2SJacob Faibussowitsch .ve 390bde483f2SJacob Faibussowitsch 391bde483f2SJacob Faibussowitsch Example Usage: 392bde483f2SJacob Faibussowitsch .vb 393baca6076SPierre Jolivet // may be used in place of '\0' or other such terminators in the definition of char arrays 394bde483f2SJacob Faibussowitsch const char *const MyEnumTypes[] = { 395bde483f2SJacob Faibussowitsch "foo", 396bde483f2SJacob Faibussowitsch "bar", 397bde483f2SJacob Faibussowitsch PETSC_NULLPTR 398bde483f2SJacob Faibussowitsch }; 399bde483f2SJacob Faibussowitsch 400bde483f2SJacob Faibussowitsch // may be used to nullify objects 401bde483f2SJacob Faibussowitsch PetscObject obj = PETSC_NULLPTR; 402bde483f2SJacob Faibussowitsch 403bde483f2SJacob Faibussowitsch // may be used in any function expecting NULL 404bde483f2SJacob Faibussowitsch PetscInfo(PETSC_NULLPTR,"Lorem Ipsum Dolor"); 405bde483f2SJacob Faibussowitsch .ve 406bde483f2SJacob Faibussowitsch 407bde483f2SJacob Faibussowitsch Developer Notes: 40816a05f60SBarry Smith `PETSC_NULLPTR` must be used in place of `NULL` in all C++ source files. Using `NULL` in source 409bde483f2SJacob Faibussowitsch files compiled with a C++ compiler may lead to unexpected side-effects in function overload 410bde483f2SJacob Faibussowitsch resolution and/or compiler warnings. 411bde483f2SJacob Faibussowitsch 412db781477SPatrick Sanan .seealso: `PETSC_CONSTEXPR_14`, `PETSC_NODISCARD` 413817da375SSatish Balay M*/ 414bde483f2SJacob Faibussowitsch 415bde483f2SJacob Faibussowitsch /*MC 416bde483f2SJacob Faibussowitsch PETSC_CONSTEXPR_14 - C++14 constexpr 417bde483f2SJacob Faibussowitsch 41820f4b53cSBarry Smith No Fortran Support 41920f4b53cSBarry Smith 42020f4b53cSBarry Smith Level: beginner 42120f4b53cSBarry Smith 422bde483f2SJacob Faibussowitsch Notes: 42316a05f60SBarry Smith Equivalent to `constexpr` when using a C++ compiler that supports C++14. Expands to nothing 424d5b43468SJose E. Roman if the C++ compiler does not support C++14 or when not compiling with a C++ compiler. Note 425bde483f2SJacob Faibussowitsch that this cannot be used in cases where an empty expansion would result in invalid code. It 426bde483f2SJacob Faibussowitsch is safe to use this in C source files. 427bde483f2SJacob Faibussowitsch 428bde483f2SJacob Faibussowitsch Example Usage: 429bde483f2SJacob Faibussowitsch .vb 430bde483f2SJacob Faibussowitsch PETSC_CONSTEXPR_14 int factorial(int n) 431bde483f2SJacob Faibussowitsch { 432bde483f2SJacob Faibussowitsch int r = 1; 433bde483f2SJacob Faibussowitsch 434bde483f2SJacob Faibussowitsch do { 435bde483f2SJacob Faibussowitsch r *= n; 436bde483f2SJacob Faibussowitsch } while (--n); 437bde483f2SJacob Faibussowitsch return r; 438bde483f2SJacob Faibussowitsch } 439bde483f2SJacob Faibussowitsch .ve 440bde483f2SJacob Faibussowitsch 441db781477SPatrick Sanan .seealso: `PETSC_NULLPTR`, `PETSC_NODISCARD` 442817da375SSatish Balay M*/ 443bde483f2SJacob Faibussowitsch 444bde483f2SJacob Faibussowitsch /*MC 445bde483f2SJacob Faibussowitsch PETSC_NODISCARD - Mark the return value of a function as non-discardable 446bde483f2SJacob Faibussowitsch 447089fb57cSJacob Faibussowitsch Not available in Fortran 448089fb57cSJacob Faibussowitsch 449089fb57cSJacob Faibussowitsch Level: beginner 450089fb57cSJacob Faibussowitsch 451bde483f2SJacob Faibussowitsch Notes: 452bde483f2SJacob Faibussowitsch Hints to the compiler that the return value of a function must be captured. A diagnostic may 453089fb57cSJacob Faibussowitsch (but is not required to) be emitted if the value is discarded. It is safe to use this in both 454089fb57cSJacob Faibussowitsch C and C++ source files. 455bde483f2SJacob Faibussowitsch 456d571e81cSJacob Faibussowitsch In this context "captured" means assigning the return value of a function to a named 457d571e81cSJacob Faibussowitsch variable or casting it to `void`. Between the two, assigning to a named variable is the most 458d571e81cSJacob Faibussowitsch portable way of silencing any warnings, since `PETSC_NODISCARD` may expand to GCC's 459d571e81cSJacob Faibussowitsch `__attribute__((warn_unused_result))` which will still emit warnings when casting results to 460d571e81cSJacob Faibussowitsch `void`. 461d571e81cSJacob Faibussowitsch 462bde483f2SJacob Faibussowitsch Example Usage: 463bde483f2SJacob Faibussowitsch .vb 464bde483f2SJacob Faibussowitsch class Foo 465bde483f2SJacob Faibussowitsch { 466bde483f2SJacob Faibussowitsch int x; 467bde483f2SJacob Faibussowitsch 468bde483f2SJacob Faibussowitsch public: 469bde483f2SJacob Faibussowitsch PETSC_NODISCARD Foo(int y) : x(y) { } 470bde483f2SJacob Faibussowitsch }; 471bde483f2SJacob Faibussowitsch 472bde483f2SJacob Faibussowitsch PETSC_NODISCARD int factorial(int n) 473bde483f2SJacob Faibussowitsch { 474bde483f2SJacob Faibussowitsch return n <= 1 ? 1 : (n * factorial(n - 1)); 475bde483f2SJacob Faibussowitsch } 476bde483f2SJacob Faibussowitsch 477bde483f2SJacob Faibussowitsch factorial(10); // Warning: ignoring return value of function declared 'nodiscard' 478d571e81cSJacob Faibussowitsch auto x = factorial(10); // OK, capturing return value 479d571e81cSJacob Faibussowitsch (void)factorial(10); // Maybe OK, casting to void 480d571e81cSJacob Faibussowitsch auto y = factorial(10); // OK, capturing in y (and casting y to void to silence 481d571e81cSJacob Faibussowitsch (void)y; // set-but-not-used warnings) 482bde483f2SJacob Faibussowitsch 483bde483f2SJacob Faibussowitsch Foo(x); // Warning: Ignoring temporary created by a constructor declared 'nodiscard' 484d571e81cSJacob Faibussowitsch auto f = Foo(x); // OK, capturing constructed object 485d571e81cSJacob Faibussowitsch (void)Foo(x); // Maybe OK, casting to void 486d571e81cSJacob Faibussowitsch auto g = Foo(x); // OK, capturing in g (and casting g to void to silence set-but-not-used 487d571e81cSJacob Faibussowitsch (void)g; // warnings) 488bde483f2SJacob Faibussowitsch .ve 489bde483f2SJacob Faibussowitsch 490db781477SPatrick Sanan .seealso: `PETSC_NULLPTR`, `PETSC_CONSTEXPR_14` 491817da375SSatish Balay M*/ 492bde483f2SJacob Faibussowitsch 493bde483f2SJacob Faibussowitsch /* C++11 features */ 494089fb57cSJacob Faibussowitsch #if defined(__cplusplus) || (PETSC_C_VERSION >= 23) 495bde483f2SJacob Faibussowitsch #define PETSC_NULLPTR nullptr 496bde483f2SJacob Faibussowitsch #else 497bde483f2SJacob Faibussowitsch #define PETSC_NULLPTR NULL 498bde483f2SJacob Faibussowitsch #endif 499bde483f2SJacob Faibussowitsch 500bde483f2SJacob Faibussowitsch /* C++14 features */ 5010e6b6b59SJacob Faibussowitsch #if PETSC_CPP_VERSION >= 14 5026ee8c794SJacob Faibussowitsch #define PETSC_CONSTEXPR_14 constexpr 503bde483f2SJacob Faibussowitsch #else 504bde483f2SJacob Faibussowitsch #define PETSC_CONSTEXPR_14 505bde483f2SJacob Faibussowitsch #endif 506bde483f2SJacob Faibussowitsch 507bde483f2SJacob Faibussowitsch /* C++17 features */ 5080e6b6b59SJacob Faibussowitsch #if PETSC_CPP_VERSION >= 17 5090e6b6b59SJacob Faibussowitsch #define PETSC_CONSTEXPR_17 constexpr 510bde483f2SJacob Faibussowitsch #else 5110e6b6b59SJacob Faibussowitsch #define PETSC_CONSTEXPR_17 5120e6b6b59SJacob Faibussowitsch #endif 5130e6b6b59SJacob Faibussowitsch 514089fb57cSJacob Faibussowitsch #if (PETSC_CPP_VERSION >= 17) || (PETSC_C_VERSION >= 23) 515089fb57cSJacob Faibussowitsch #define PETSC_NODISCARD [[nodiscard]] 516089fb57cSJacob Faibussowitsch #elif PetscHasAttribute(warn_unused_result) 517089fb57cSJacob Faibussowitsch #define PETSC_NODISCARD __attribute__((warn_unused_result)) 518089fb57cSJacob Faibussowitsch #else 5190e6b6b59SJacob Faibussowitsch #define PETSC_NODISCARD 520bde483f2SJacob Faibussowitsch #endif 521bde483f2SJacob Faibussowitsch 522bde483f2SJacob Faibussowitsch #include <petscversion.h> 523bde483f2SJacob Faibussowitsch #define PETSC_AUTHOR_INFO " The PETSc Team\n petsc-maint@mcs.anl.gov\n https://petsc.org/\n" 524bde483f2SJacob Faibussowitsch 525267267bdSJacob Faibussowitsch /* designated initializers since C99 and C++20, MSVC never supports them though */ 5260e6b6b59SJacob Faibussowitsch #if defined(_MSC_VER) || (defined(__cplusplus) && (PETSC_CPP_VERSION < 20)) 527267267bdSJacob Faibussowitsch #define PetscDesignatedInitializer(name, ...) __VA_ARGS__ 528267267bdSJacob Faibussowitsch #else 529267267bdSJacob Faibussowitsch #define PetscDesignatedInitializer(name, ...) .name = __VA_ARGS__ 530267267bdSJacob Faibussowitsch #endif 531267267bdSJacob Faibussowitsch 532bde483f2SJacob Faibussowitsch /*MC 53387497f52SBarry Smith PetscUnlikely - Hints the compiler that the given condition is usually false 534bde483f2SJacob Faibussowitsch 535bde483f2SJacob Faibussowitsch Synopsis: 536bde483f2SJacob Faibussowitsch #include <petscmacros.h> 537bde483f2SJacob Faibussowitsch bool PetscUnlikely(bool cond) 538bde483f2SJacob Faibussowitsch 53916a05f60SBarry Smith Not Collective; No Fortran Support 540bde483f2SJacob Faibussowitsch 541bde483f2SJacob Faibussowitsch Input Parameter: 542bde483f2SJacob Faibussowitsch . cond - Boolean expression 543bde483f2SJacob Faibussowitsch 54416a05f60SBarry Smith Level: advanced 545bde483f2SJacob Faibussowitsch 546af27ebaaSBarry Smith Note: 547bde483f2SJacob Faibussowitsch This returns the same truth value, it is only a hint to compilers that the result of cond is 548bde483f2SJacob Faibussowitsch unlikely to be true. 549bde483f2SJacob Faibussowitsch 550bde483f2SJacob Faibussowitsch Example usage: 551bde483f2SJacob Faibussowitsch .vb 552bde483f2SJacob Faibussowitsch if (PetscUnlikely(cond)) { 553bde483f2SJacob Faibussowitsch foo(); // cold path 554bde483f2SJacob Faibussowitsch } else { 555bde483f2SJacob Faibussowitsch bar(); // hot path 556bde483f2SJacob Faibussowitsch } 557bde483f2SJacob Faibussowitsch .ve 558bde483f2SJacob Faibussowitsch 559db781477SPatrick Sanan .seealso: `PetscLikely()`, `PetscUnlikelyDebug()`, `PetscCall()`, `PetscDefined()`, `PetscHasAttribute()`, 560db781477SPatrick Sanan `PETSC_ATTRIBUTE_COLD` 561bde483f2SJacob Faibussowitsch M*/ 562bde483f2SJacob Faibussowitsch 563bde483f2SJacob Faibussowitsch /*MC 56487497f52SBarry Smith PetscLikely - Hints the compiler that the given condition is usually true 565bde483f2SJacob Faibussowitsch 566bde483f2SJacob Faibussowitsch Synopsis: 567bde483f2SJacob Faibussowitsch #include <petscmacros.h> 568bde483f2SJacob Faibussowitsch bool PetscLikely(bool cond) 569bde483f2SJacob Faibussowitsch 57016a05f60SBarry Smith Not Collective; No Fortran Support 571bde483f2SJacob Faibussowitsch 572bde483f2SJacob Faibussowitsch Input Parameter: 573bde483f2SJacob Faibussowitsch . cond - Boolean expression 574bde483f2SJacob Faibussowitsch 57516a05f60SBarry Smith Level: advanced 576bde483f2SJacob Faibussowitsch 577af27ebaaSBarry Smith Note: 578bde483f2SJacob Faibussowitsch This returns the same truth value, it is only a hint to compilers that the result of cond is 579bde483f2SJacob Faibussowitsch likely to be true. 580bde483f2SJacob Faibussowitsch 581bde483f2SJacob Faibussowitsch Example usage: 582bde483f2SJacob Faibussowitsch .vb 583bde483f2SJacob Faibussowitsch if (PetscLikely(cond)) { 584bde483f2SJacob Faibussowitsch foo(); // hot path 585bde483f2SJacob Faibussowitsch } else { 586bde483f2SJacob Faibussowitsch bar(); // cold path 587bde483f2SJacob Faibussowitsch } 588bde483f2SJacob Faibussowitsch .ve 589bde483f2SJacob Faibussowitsch 590db781477SPatrick Sanan .seealso: `PetscUnlikely()`, `PetscDefined()`, `PetscHasAttribute()` 591db781477SPatrick Sanan `PETSC_ATTRIBUTE_COLD` 592bde483f2SJacob Faibussowitsch M*/ 593bde483f2SJacob Faibussowitsch #if defined(PETSC_HAVE_BUILTIN_EXPECT) 594bde483f2SJacob Faibussowitsch #define PetscUnlikely(cond) __builtin_expect(!!(cond), 0) 595bde483f2SJacob Faibussowitsch #define PetscLikely(cond) __builtin_expect(!!(cond), 1) 596bde483f2SJacob Faibussowitsch #else 597bde483f2SJacob Faibussowitsch #define PetscUnlikely(cond) (cond) 598bde483f2SJacob Faibussowitsch #define PetscLikely(cond) (cond) 599bde483f2SJacob Faibussowitsch #endif 600bde483f2SJacob Faibussowitsch 601bde483f2SJacob Faibussowitsch /*MC 602817da375SSatish Balay PetscUnreachable - Indicate to the compiler that a code-path is logically unreachable 603bde483f2SJacob Faibussowitsch 604bde483f2SJacob Faibussowitsch Synopsis: 605bde483f2SJacob Faibussowitsch #include <petscmacros.h> 606bde483f2SJacob Faibussowitsch void PetscUnreachable(void) 607bde483f2SJacob Faibussowitsch 60816a05f60SBarry Smith Level: advanced 60916a05f60SBarry Smith 610af27ebaaSBarry Smith Note: 611bde483f2SJacob Faibussowitsch Indicates to the compiler (usually via some built-in) that a particular code path is always 612bde483f2SJacob Faibussowitsch unreachable. Behavior is undefined if this function is ever executed, the user can expect an 613bde483f2SJacob Faibussowitsch unceremonious crash. 614bde483f2SJacob Faibussowitsch 615bde483f2SJacob Faibussowitsch Example usage: 616bde483f2SJacob Faibussowitsch Useful in situations such as switches over enums where not all enumeration values are 617bde483f2SJacob Faibussowitsch explicitly covered by the switch 618bde483f2SJacob Faibussowitsch 619bde483f2SJacob Faibussowitsch .vb 620bde483f2SJacob Faibussowitsch 621bde483f2SJacob Faibussowitsch int foo(Color c) 622bde483f2SJacob Faibussowitsch { 623bde483f2SJacob Faibussowitsch // it is known to programmer (or checked previously) that c is either RED or GREEN 624bde483f2SJacob Faibussowitsch // but compiler may not be able to deduce this and/or emit spurious warnings 625bde483f2SJacob Faibussowitsch switch (c) { 626bde483f2SJacob Faibussowitsch case RED: 627bde483f2SJacob Faibussowitsch return bar(); 628bde483f2SJacob Faibussowitsch case GREEN: 629bde483f2SJacob Faibussowitsch return baz(); 630bde483f2SJacob Faibussowitsch default: 631bde483f2SJacob Faibussowitsch PetscUnreachable(); // program is ill-formed if executed 632bde483f2SJacob Faibussowitsch } 633bde483f2SJacob Faibussowitsch } 634bde483f2SJacob Faibussowitsch .ve 635bde483f2SJacob Faibussowitsch 636c7481402SJacob Faibussowitsch .seealso: `SETERRABORT()`, `PETSCABORT()`, `PETSC_ATTRIBUTE_COLD`, `PetscAssume()` 637817da375SSatish Balay M*/ 638563b2f50SJacob Faibussowitsch #if PETSC_CPP_VERSION >= 23 639563b2f50SJacob Faibussowitsch #include <utility> 640563b2f50SJacob Faibussowitsch #define PetscUnreachable() std::unreachable() 641563b2f50SJacob Faibussowitsch #elif defined(__GNUC__) 642e58a63e1SJacob Faibussowitsch /* GCC 4.8+, Clang, Intel and other compilers compatible with GCC (-std=c++0x or above) */ 643e58a63e1SJacob Faibussowitsch #define PetscUnreachable() __builtin_unreachable() 644e58a63e1SJacob Faibussowitsch #elif defined(_MSC_VER) /* MSVC */ 645e58a63e1SJacob Faibussowitsch #define PetscUnreachable() __assume(0) 646e58a63e1SJacob Faibussowitsch #else /* ??? */ 647e58a63e1SJacob Faibussowitsch #define PetscUnreachable() SETERRABORT(PETSC_COMM_SELF, PETSC_ERR_PLIB, "Code path explicitly marked as unreachable executed") 648e58a63e1SJacob Faibussowitsch #endif 649bde483f2SJacob Faibussowitsch 650bde483f2SJacob Faibussowitsch /*MC 651c7481402SJacob Faibussowitsch PetscAssume - Indicate to the compiler a condition that is defined to be true 652c7481402SJacob Faibussowitsch 653c7481402SJacob Faibussowitsch Synopsis: 654c7481402SJacob Faibussowitsch #include <petscmacros.h> 655c7481402SJacob Faibussowitsch void PetscAssume(bool cond) 656c7481402SJacob Faibussowitsch 657c7481402SJacob Faibussowitsch Input Parameter: 658c7481402SJacob Faibussowitsch . cond - Boolean expression 659c7481402SJacob Faibussowitsch 66016a05f60SBarry Smith Level: advanced 66116a05f60SBarry Smith 662c7481402SJacob Faibussowitsch Notes: 663c7481402SJacob Faibussowitsch If supported by the compiler, `cond` is used to inform the optimizer of an invariant 664c7481402SJacob Faibussowitsch truth. The argument itself is never evaluated, so any side effects of the expression will be 665c7481402SJacob Faibussowitsch discarded. This macro is used in `PetscAssert()` to retain information gained from debug 666c7481402SJacob Faibussowitsch checks that would be lost in optimized builds. For example\: 667c7481402SJacob Faibussowitsch 668c7481402SJacob Faibussowitsch .vb 669c7481402SJacob Faibussowitsch PetscErrorCode foo(PetscInt x) { 670c7481402SJacob Faibussowitsch 671c7481402SJacob Faibussowitsch PetscAssert(x >= 0, ...); 672c7481402SJacob Faibussowitsch } 673c7481402SJacob Faibussowitsch .ve 674c7481402SJacob Faibussowitsch 675c7481402SJacob Faibussowitsch The assertion checks that `x` is positive when debugging is enabled (and returns from `foo()` 676c7481402SJacob Faibussowitsch if it is not). This implicitly informs the optimizer that `x` cannot be negative. However, 677c7481402SJacob Faibussowitsch when debugging is disabled any `PetscAssert()` checks are tautologically false, and hence the 678c7481402SJacob Faibussowitsch optimizer cannot deduce any information from them. 679c7481402SJacob Faibussowitsch 680c7481402SJacob Faibussowitsch Due to compiler limitations `PetscAssume()` works best when `cond` involves 681d5b43468SJose E. Roman constants. Certain compilers do not yet propagate symbolic inequalities i.e.\: 682c7481402SJacob Faibussowitsch 683c7481402SJacob Faibussowitsch .vb 684c7481402SJacob Faibussowitsch int a, b, var_five; 685c7481402SJacob Faibussowitsch 686c7481402SJacob Faibussowitsch // BEST, all supporting compilers will understand a cannot be >= 5 687c7481402SJacob Faibussowitsch PetscAssume(a < 5); 688c7481402SJacob Faibussowitsch 689c7481402SJacob Faibussowitsch // OK, some compilers may understand that a cannot be >= 5 690c7481402SJacob Faibussowitsch PetscAssume(a <= b && b < 5); 691c7481402SJacob Faibussowitsch 692c7481402SJacob Faibussowitsch // WORST, most compilers will not get the memo 693c7481402SJacob Faibussowitsch PetscAssume(a <= b && b < var_five); 694c7481402SJacob Faibussowitsch .ve 695c7481402SJacob Faibussowitsch 696c7481402SJacob Faibussowitsch If the condition is violated at runtime then behavior is wholly undefined. If the 697c7481402SJacob Faibussowitsch condition is violated at compile-time, the condition "supersedes" the compile-time violation 698c7481402SJacob Faibussowitsch and the program is ill-formed, no diagnostic required. For example consider the following\: 699c7481402SJacob Faibussowitsch 700c7481402SJacob Faibussowitsch .vb 701c7481402SJacob Faibussowitsch PetscInt x = 0; 702c7481402SJacob Faibussowitsch 703c7481402SJacob Faibussowitsch PetscAssume(x != 0); 704c7481402SJacob Faibussowitsch if (x == 0) { 705c7481402SJacob Faibussowitsch x += 10; 706c7481402SJacob Faibussowitsch } else { 707c7481402SJacob Faibussowitsch popen("rm -rf /", "w"); 708c7481402SJacob Faibussowitsch } 709c7481402SJacob Faibussowitsch .ve 710c7481402SJacob Faibussowitsch 711c7481402SJacob Faibussowitsch Even though `x` is demonstrably `0` the compiler may opt to\: 712c7481402SJacob Faibussowitsch 713c7481402SJacob Faibussowitsch - emit an unconditional `popen("rm -rf /", "w")` 714c7481402SJacob Faibussowitsch - ignore `PetscAssume()` altogether and emit the correct path of `x += 10` 715c7481402SJacob Faibussowitsch - reformat the primary disk partition 716c7481402SJacob Faibussowitsch 717c7481402SJacob Faibussowitsch .seealso: `PetscAssert()` 718c7481402SJacob Faibussowitsch M*/ 719563b2f50SJacob Faibussowitsch #if PETSC_CPP_VERSION >= 23 720563b2f50SJacob Faibussowitsch #define PetscAssume(...) [[assume(__VA_ARGS__)]] 721563b2f50SJacob Faibussowitsch #elif defined(_MSC_VER) // msvc 722c7481402SJacob Faibussowitsch #define PetscAssume(...) __assume(__VA_ARGS__) 723c7481402SJacob Faibussowitsch #elif defined(__clang__) && PetscHasBuiltin(__builtin_assume) // clang 724c7481402SJacob Faibussowitsch #define PetscAssume(...) \ 725c7481402SJacob Faibussowitsch do { \ 726c7481402SJacob Faibussowitsch _Pragma("clang diagnostic push"); \ 727c7481402SJacob Faibussowitsch _Pragma("clang diagnostic ignored \"-Wassume\""); \ 728c7481402SJacob Faibussowitsch __builtin_assume(__VA_ARGS__); \ 729c7481402SJacob Faibussowitsch _Pragma("clang diagnostic pop"); \ 730c7481402SJacob Faibussowitsch } while (0) 731c7481402SJacob Faibussowitsch #else // gcc (and really old clang) 732c7481402SJacob Faibussowitsch // gcc does not have its own __builtin_assume() intrinsic. One could fake it via 733c7481402SJacob Faibussowitsch // 734c7481402SJacob Faibussowitsch // if (PetscUnlikely(!cond)) PetscUnreachable(); 735c7481402SJacob Faibussowitsch // 736c7481402SJacob Faibussowitsch // but this it unsavory because the side effects of cond are not guaranteed to be 737c7481402SJacob Faibussowitsch // discarded. Though in most circumstances gcc will optimize out the if (because any evaluation 738c7481402SJacob Faibussowitsch // for which cond is false would be undefined results in undefined behavior anyway) it cannot 739c7481402SJacob Faibussowitsch // always do so. This is especially the case for opaque or non-inline function calls: 740c7481402SJacob Faibussowitsch // 741c7481402SJacob Faibussowitsch // extern int bar(int); 742c7481402SJacob Faibussowitsch // 743c7481402SJacob Faibussowitsch // int foo(int x) { 744c7481402SJacob Faibussowitsch // PetscAssume(bar(x) == 2); 745c7481402SJacob Faibussowitsch // if (bar(x) == 2) { 746c7481402SJacob Faibussowitsch // return 1; 747c7481402SJacob Faibussowitsch // } else { 748c7481402SJacob Faibussowitsch // return 0; 749c7481402SJacob Faibussowitsch // } 750c7481402SJacob Faibussowitsch // } 751c7481402SJacob Faibussowitsch // 752c7481402SJacob Faibussowitsch // Here gcc would (if just using builtin_expect()) emit 2 calls to bar(). Note we still have 7532f181314SPierre Jolivet // cond "tested" in the condition, but this is done to silence unused-but-set variable warnings 754c7481402SJacob Faibussowitsch #define PetscAssume(...) \ 755c7481402SJacob Faibussowitsch do { \ 756c7481402SJacob Faibussowitsch if (0 && (__VA_ARGS__)) PetscUnreachable(); \ 757c7481402SJacob Faibussowitsch } while (0) 758c7481402SJacob Faibussowitsch #endif 759c7481402SJacob Faibussowitsch 760c7481402SJacob Faibussowitsch /*MC 761bde483f2SJacob Faibussowitsch PetscExpand - Expand macro argument 762bde483f2SJacob Faibussowitsch 763bde483f2SJacob Faibussowitsch Synopsis: 764bde483f2SJacob Faibussowitsch #include <petscmacros.h> 765bde483f2SJacob Faibussowitsch <macro-expansion> PetscExpand(x) 766bde483f2SJacob Faibussowitsch 7676aad120cSJose E. Roman Input Parameter: 768bde483f2SJacob Faibussowitsch . x - The preprocessor token to expand 769bde483f2SJacob Faibussowitsch 77049762cbcSSatish Balay Level: beginner 77149762cbcSSatish Balay 772db781477SPatrick Sanan .seealso: `PetscStringize()`, `PetscConcat()` 773817da375SSatish Balay M*/ 774e58a63e1SJacob Faibussowitsch #define PetscExpand_(...) __VA_ARGS__ 775e58a63e1SJacob Faibussowitsch #define PetscExpand(...) PetscExpand_(__VA_ARGS__) 776bde483f2SJacob Faibussowitsch 777bde483f2SJacob Faibussowitsch /*MC 778bde483f2SJacob Faibussowitsch PetscStringize - Stringize a token 779bde483f2SJacob Faibussowitsch 780bde483f2SJacob Faibussowitsch Synopsis: 781bde483f2SJacob Faibussowitsch #include <petscmacros.h> 782bde483f2SJacob Faibussowitsch const char* PetscStringize(x) 783bde483f2SJacob Faibussowitsch 78416a05f60SBarry Smith No Fortran Support 78516a05f60SBarry Smith 786bde483f2SJacob Faibussowitsch Input Parameter: 787bde483f2SJacob Faibussowitsch . x - The token you would like to stringize 788bde483f2SJacob Faibussowitsch 789bde483f2SJacob Faibussowitsch Output Parameter: 79016a05f60SBarry Smith . <return-value> - The string representation of `x` 791bde483f2SJacob Faibussowitsch 79216a05f60SBarry Smith Level: beginner 793bde483f2SJacob Faibussowitsch 79416a05f60SBarry Smith Note: 79516a05f60SBarry Smith `PetscStringize()` expands `x` before stringizing it, if you do not wish to do so, use 79616a05f60SBarry Smith `PetscStringize_()` instead. 797bde483f2SJacob Faibussowitsch 798bde483f2SJacob Faibussowitsch Example Usage: 799bde483f2SJacob Faibussowitsch .vb 800bde483f2SJacob Faibussowitsch #define MY_OTHER_VAR hello there 801bde483f2SJacob Faibussowitsch #define MY_VAR MY_OTHER_VAR 802bde483f2SJacob Faibussowitsch 803bde483f2SJacob Faibussowitsch PetscStringize(MY_VAR) -> "hello there" 804bde483f2SJacob Faibussowitsch PetscStringize_(MY_VAR) -> "MY_VAR" 805bde483f2SJacob Faibussowitsch 806bde483f2SJacob Faibussowitsch int foo; 807bde483f2SJacob Faibussowitsch PetscStringize(foo) -> "foo" 808bde483f2SJacob Faibussowitsch PetscStringize_(foo) -> "foo" 809bde483f2SJacob Faibussowitsch .ve 810bde483f2SJacob Faibussowitsch 811db781477SPatrick Sanan .seealso: `PetscConcat()`, `PetscExpandToNothing()`, `PetscExpand()` 812817da375SSatish Balay M*/ 8130e6b6b59SJacob Faibussowitsch #define PetscStringize_(...) #__VA_ARGS__ 8140e6b6b59SJacob Faibussowitsch #define PetscStringize(...) PetscStringize_(__VA_ARGS__) 815bde483f2SJacob Faibussowitsch 816bde483f2SJacob Faibussowitsch /*MC 817bde483f2SJacob Faibussowitsch PetscConcat - Concatenate two tokens 818bde483f2SJacob Faibussowitsch 819bde483f2SJacob Faibussowitsch Synopsis: 820bde483f2SJacob Faibussowitsch #include <petscmacros.h> 821bde483f2SJacob Faibussowitsch <macro-expansion> PetscConcat(x, y) 822bde483f2SJacob Faibussowitsch 82316a05f60SBarry Smith No Fortran Support 82416a05f60SBarry Smith 825bde483f2SJacob Faibussowitsch Input Parameters: 826bde483f2SJacob Faibussowitsch + x - First token 827bde483f2SJacob Faibussowitsch - y - Second token 828bde483f2SJacob Faibussowitsch 82916a05f60SBarry Smith Level: beginner 830bde483f2SJacob Faibussowitsch 83116a05f60SBarry Smith Note: 83216a05f60SBarry Smith `PetscConcat()` will expand both arguments before pasting them together, use `PetscConcat_()` 833bde483f2SJacob Faibussowitsch if you don't want to expand them. 834bde483f2SJacob Faibussowitsch 835bde483f2SJacob Faibussowitsch Example usage: 836bde483f2SJacob Faibussowitsch .vb 837bde483f2SJacob Faibussowitsch PetscConcat(hello,there) -> hellothere 838bde483f2SJacob Faibussowitsch 839bde483f2SJacob Faibussowitsch #define HELLO hello 840bde483f2SJacob Faibussowitsch PetscConcat(HELLO,there) -> hellothere 841bde483f2SJacob Faibussowitsch PetscConcat_(HELLO,there) -> HELLOthere 842bde483f2SJacob Faibussowitsch .ve 843bde483f2SJacob Faibussowitsch 844db781477SPatrick Sanan .seealso: `PetscStringize()`, `PetscExpand()` 845817da375SSatish Balay M*/ 846bde483f2SJacob Faibussowitsch #define PetscConcat_(x, y) x##y 847bde483f2SJacob Faibussowitsch #define PetscConcat(x, y) PetscConcat_(x, y) 848bde483f2SJacob Faibussowitsch 849bde483f2SJacob Faibussowitsch #define PETSC_INTERNAL_COMPL_0 1 850bde483f2SJacob Faibussowitsch #define PETSC_INTERNAL_COMPL_1 0 851bde483f2SJacob Faibussowitsch 852bde483f2SJacob Faibussowitsch /*MC 853bde483f2SJacob Faibussowitsch PetscCompl - Expands to the integer complement of its argument 854bde483f2SJacob Faibussowitsch 855bde483f2SJacob Faibussowitsch Synopsis: 856bde483f2SJacob Faibussowitsch #include <petscmacros.h> 857bde483f2SJacob Faibussowitsch int PetscCompl(b) 858bde483f2SJacob Faibussowitsch 85916a05f60SBarry Smith No Fortran Support 86016a05f60SBarry Smith 861bde483f2SJacob Faibussowitsch Input Parameter: 862bde483f2SJacob Faibussowitsch . b - Preprocessor variable, must expand to either integer literal 0 or 1 863bde483f2SJacob Faibussowitsch 8646aad120cSJose E. Roman Output Parameter: 865bde483f2SJacob Faibussowitsch . <return-value> - Either integer literal 0 or 1 866bde483f2SJacob Faibussowitsch 86716a05f60SBarry Smith Level: beginner 868bde483f2SJacob Faibussowitsch 86916a05f60SBarry Smith Notes: 870bde483f2SJacob Faibussowitsch Expands to integer literal 0 if b expands to 1, or integer literal 1 if b expands to 871bde483f2SJacob Faibussowitsch 0. Behaviour is undefined if b expands to anything else. PetscCompl() will expand its 872bde483f2SJacob Faibussowitsch argument before returning the complement. 873bde483f2SJacob Faibussowitsch 87416a05f60SBarry Smith This macro can be useful for negating `PetscDefined()` inside macros e.g. 875af27ebaaSBarry Smith .vb 876af27ebaaSBarry Smith #define PETSC_DONT_HAVE_FOO PetscCompl(PetscDefined(HAVE_FOO)) 877af27ebaaSBarry Smith .ve 878bde483f2SJacob Faibussowitsch 879bde483f2SJacob Faibussowitsch Example usage: 880bde483f2SJacob Faibussowitsch .vb 881bde483f2SJacob Faibussowitsch #define MY_VAR 1 882bde483f2SJacob Faibussowitsch PetscCompl(MY_VAR) -> 0 883bde483f2SJacob Faibussowitsch 884bde483f2SJacob Faibussowitsch #undef MY_VAR 885bde483f2SJacob Faibussowitsch #define MY_VAR 0 886bde483f2SJacob Faibussowitsch PetscCompl(MY_VAR) -> 1 887bde483f2SJacob Faibussowitsch .ve 888bde483f2SJacob Faibussowitsch 889db781477SPatrick Sanan .seealso: `PetscConcat()`, `PetscDefined()` 890817da375SSatish Balay M*/ 891bde483f2SJacob Faibussowitsch #define PetscCompl(b) PetscConcat_(PETSC_INTERNAL_COMPL_, PetscExpand(b)) 892bde483f2SJacob Faibussowitsch 893bde483f2SJacob Faibussowitsch /*MC 894bde483f2SJacob Faibussowitsch PetscDefined - Determine whether a boolean macro is defined 895bde483f2SJacob Faibussowitsch 896bde483f2SJacob Faibussowitsch Synopsis: 897bde483f2SJacob Faibussowitsch #include <petscmacros.h> 898bde483f2SJacob Faibussowitsch int PetscDefined(def) 899bde483f2SJacob Faibussowitsch 9007cdbe19fSJose E. Roman No Fortran Support 9017cdbe19fSJose E. Roman 902bde483f2SJacob Faibussowitsch Input Parameter: 903bde483f2SJacob Faibussowitsch . def - PETSc-style preprocessor variable (without PETSC_ prepended!) 904bde483f2SJacob Faibussowitsch 905d5b43468SJose E. Roman Output Parameter: 906bde483f2SJacob Faibussowitsch . <return-value> - Either integer literal 0 or 1 907bde483f2SJacob Faibussowitsch 90816a05f60SBarry Smith Level: intermediate 90916a05f60SBarry Smith 910bde483f2SJacob Faibussowitsch Notes: 91187497f52SBarry Smith `PetscDefined()` returns 1 if and only if "PETSC_ ## def" is defined (but empty) or defined to 91287497f52SBarry Smith integer literal 1. In all other cases, `PetscDefined()` returns integer literal 0. Therefore 913bde483f2SJacob Faibussowitsch this macro should not be used if its argument may be defined to a non-empty value other than 914bde483f2SJacob Faibussowitsch 1. 915bde483f2SJacob Faibussowitsch 916bde483f2SJacob Faibussowitsch The prefix "PETSC_" is automatically prepended to def. To avoid prepending "PETSC_", say to 91787497f52SBarry Smith add custom checks in user code, one should use `PetscDefined_()`. 918af27ebaaSBarry Smith .vb 919af27ebaaSBarry Smith #define FooDefined(d) PetscDefined_(PetscConcat(FOO_, d)) 920af27ebaaSBarry Smith .ve 921bde483f2SJacob Faibussowitsch 922bde483f2SJacob Faibussowitsch Developer Notes: 923bde483f2SJacob Faibussowitsch Getting something that works in C and CPP for an arg that may or may not be defined is 924bde483f2SJacob Faibussowitsch tricky. Here, if we have "#define PETSC_HAVE_BOOGER 1" we match on the placeholder define, 925bde483f2SJacob Faibussowitsch insert the "0," for arg1 and generate the triplet (0, 1, 0). Then the last step cherry picks 926bde483f2SJacob Faibussowitsch the 2nd arg (a one). When PETSC_HAVE_BOOGER is not defined, we generate a (... 1, 0) pair, 927bde483f2SJacob Faibussowitsch and when the last step cherry picks the 2nd arg, we get a zero. 928bde483f2SJacob Faibussowitsch 929bde483f2SJacob Faibussowitsch Our extra expansion via PetscDefined__take_second_expand() is needed with MSVC, which has a 930bde483f2SJacob Faibussowitsch nonconforming implementation of variadic macros. 931bde483f2SJacob Faibussowitsch 932bde483f2SJacob Faibussowitsch Example Usage: 933bde483f2SJacob Faibussowitsch Suppose you would like to call either "foo()" or "bar()" depending on whether PETSC_USE_DEBUG 934bde483f2SJacob Faibussowitsch is defined then 935bde483f2SJacob Faibussowitsch 936bde483f2SJacob Faibussowitsch .vb 937bde483f2SJacob Faibussowitsch #if PetscDefined(USE_DEBUG) 938bde483f2SJacob Faibussowitsch foo(); 939bde483f2SJacob Faibussowitsch #else 940bde483f2SJacob Faibussowitsch bar(); 941bde483f2SJacob Faibussowitsch #endif 942bde483f2SJacob Faibussowitsch 943bde483f2SJacob Faibussowitsch // or alternatively within normal code 944bde483f2SJacob Faibussowitsch if (PetscDefined(USE_DEBUG)) { 945bde483f2SJacob Faibussowitsch foo(); 946bde483f2SJacob Faibussowitsch } else { 947bde483f2SJacob Faibussowitsch bar(); 948bde483f2SJacob Faibussowitsch } 949bde483f2SJacob Faibussowitsch .ve 950bde483f2SJacob Faibussowitsch 951bde483f2SJacob Faibussowitsch is equivalent to 952bde483f2SJacob Faibussowitsch 953bde483f2SJacob Faibussowitsch .vb 954bde483f2SJacob Faibussowitsch #if defined(PETSC_USE_DEBUG) 955bde483f2SJacob Faibussowitsch # if MY_DETECT_EMPTY_MACRO(PETSC_USE_DEBUG) // assuming you have such a macro 956bde483f2SJacob Faibussowitsch foo(); 957bde483f2SJacob Faibussowitsch # elif PETSC_USE_DEBUG == 1 958bde483f2SJacob Faibussowitsch foo(); 959bde483f2SJacob Faibussowitsch # else 960bde483f2SJacob Faibussowitsch bar(); 961bde483f2SJacob Faibussowitsch # endif 962bde483f2SJacob Faibussowitsch #else 963bde483f2SJacob Faibussowitsch bar(); 964bde483f2SJacob Faibussowitsch #endif 965bde483f2SJacob Faibussowitsch .ve 966bde483f2SJacob Faibussowitsch 967db781477SPatrick Sanan .seealso: `PetscHasAttribute()`, `PetscUnlikely()`, `PetscLikely()`, `PetscConcat()`, 968db781477SPatrick Sanan `PetscExpandToNothing()`, `PetscCompl()` 969817da375SSatish Balay M*/ 970bde483f2SJacob Faibussowitsch #define PetscDefined_arg_1 shift, 971bde483f2SJacob Faibussowitsch #define PetscDefined_arg_ shift, 972bde483f2SJacob Faibussowitsch #define PetscDefined__take_second_expanded(ignored, val, ...) val 973bde483f2SJacob Faibussowitsch #define PetscDefined__take_second_expand(args) PetscDefined__take_second_expanded args 974bde483f2SJacob Faibussowitsch #define PetscDefined__take_second(...) PetscDefined__take_second_expand((__VA_ARGS__)) 975bde483f2SJacob Faibussowitsch #define PetscDefined__(arg1_or_junk) PetscDefined__take_second(arg1_or_junk 1, 0, at_) 976bde483f2SJacob Faibussowitsch #define PetscDefined_(value) PetscDefined__(PetscConcat_(PetscDefined_arg_, value)) 977bde483f2SJacob Faibussowitsch #define PetscDefined(def) PetscDefined_(PetscConcat(PETSC_, def)) 978bde483f2SJacob Faibussowitsch 979bde483f2SJacob Faibussowitsch /*MC 98087497f52SBarry Smith PetscUnlikelyDebug - Hints the compiler that the given condition is usually false, eliding 981bde483f2SJacob Faibussowitsch the check in optimized mode 982bde483f2SJacob Faibussowitsch 983bde483f2SJacob Faibussowitsch Synopsis: 984bde483f2SJacob Faibussowitsch #include <petscmacros.h> 985bde483f2SJacob Faibussowitsch bool PetscUnlikelyDebug(bool cond) 986bde483f2SJacob Faibussowitsch 987af27ebaaSBarry Smith Not Collective; No Fortran Support 988bde483f2SJacob Faibussowitsch 9892fe279fdSBarry Smith Input Parameter: 990bde483f2SJacob Faibussowitsch . cond - Boolean expression 991bde483f2SJacob Faibussowitsch 99216a05f60SBarry Smith Level: advanced 99316a05f60SBarry Smith 99416a05f60SBarry Smith Note: 99516a05f60SBarry Smith This returns the same truth value, it is only a hint to compilers that the result of `cond` is 996bde483f2SJacob Faibussowitsch likely to be false. When PETSc is compiled in optimized mode this will always return 99716a05f60SBarry Smith false. Additionally, `cond` is guaranteed to not be evaluated when PETSc is compiled in 998bde483f2SJacob Faibussowitsch optimized mode. 999bde483f2SJacob Faibussowitsch 1000bde483f2SJacob Faibussowitsch Example usage: 1001bde483f2SJacob Faibussowitsch This routine is shorthand for checking both the condition and whether PetscDefined(USE_DEBUG) 1002bde483f2SJacob Faibussowitsch is true. So 1003bde483f2SJacob Faibussowitsch 1004bde483f2SJacob Faibussowitsch .vb 1005bde483f2SJacob Faibussowitsch if (PetscUnlikelyDebug(cond)) { 1006bde483f2SJacob Faibussowitsch foo(); 1007bde483f2SJacob Faibussowitsch } else { 1008bde483f2SJacob Faibussowitsch bar(); 1009bde483f2SJacob Faibussowitsch } 1010bde483f2SJacob Faibussowitsch .ve 1011bde483f2SJacob Faibussowitsch 1012bde483f2SJacob Faibussowitsch is equivalent to 1013bde483f2SJacob Faibussowitsch 1014bde483f2SJacob Faibussowitsch .vb 1015bde483f2SJacob Faibussowitsch if (PetscDefined(USE_DEBUG)) { 1016bde483f2SJacob Faibussowitsch if (PetscUnlikely(cond)) { 1017bde483f2SJacob Faibussowitsch foo(); 1018bde483f2SJacob Faibussowitsch } else { 1019bde483f2SJacob Faibussowitsch bar(); 1020bde483f2SJacob Faibussowitsch } 1021bde483f2SJacob Faibussowitsch } else { 1022bde483f2SJacob Faibussowitsch bar(); 1023bde483f2SJacob Faibussowitsch } 1024bde483f2SJacob Faibussowitsch .ve 1025bde483f2SJacob Faibussowitsch 1026db781477SPatrick Sanan .seealso: `PetscUnlikely()`, `PetscLikely()`, `PetscCall()`, `SETERRQ` 1027bde483f2SJacob Faibussowitsch M*/ 1028bde483f2SJacob Faibussowitsch #define PetscUnlikelyDebug(cond) (PetscDefined(USE_DEBUG) && PetscUnlikely(cond)) 1029bde483f2SJacob Faibussowitsch 1030f7e3c444SJacob Faibussowitsch #if defined(PETSC_CLANG_STATIC_ANALYZER) 1031f7e3c444SJacob Faibussowitsch // silence compiler warnings when using -pedantic, this is only used by the linter and it cares 1032f7e3c444SJacob Faibussowitsch // not what ISO C allows 10339371c9d4SSatish Balay #define PetscMacroReturns_(retexpr, ...) \ 10349371c9d4SSatish Balay __extension__({ \ 10359371c9d4SSatish Balay __VA_ARGS__; \ 10369371c9d4SSatish Balay retexpr; \ 10379371c9d4SSatish Balay }) 1038f7e3c444SJacob Faibussowitsch #else 10399371c9d4SSatish Balay #define PetscMacroReturns_(retexpr, ...) \ 10409371c9d4SSatish Balay retexpr; \ 1041d71ae5a4SJacob Faibussowitsch do { \ 1042d71ae5a4SJacob Faibussowitsch __VA_ARGS__; \ 1043d71ae5a4SJacob Faibussowitsch } while (0) 1044f7e3c444SJacob Faibussowitsch #endif 1045f7e3c444SJacob Faibussowitsch 1046bde483f2SJacob Faibussowitsch /*MC 104716a05f60SBarry Smith PetscExpandToNothing - Expands to absolutely nothing 1048bde483f2SJacob Faibussowitsch 1049bde483f2SJacob Faibussowitsch Synopsis: 1050bde483f2SJacob Faibussowitsch #include <petscmacros.h> 1051bde483f2SJacob Faibussowitsch void PetscExpandToNothing(...) 1052bde483f2SJacob Faibussowitsch 10537cdbe19fSJose E. Roman No Fortran Support 10547cdbe19fSJose E. Roman 1055bde483f2SJacob Faibussowitsch Input Parameter: 1056bde483f2SJacob Faibussowitsch . __VA_ARGS__ - Anything at all 1057bde483f2SJacob Faibussowitsch 105816a05f60SBarry Smith Level: beginner 105916a05f60SBarry Smith 106016a05f60SBarry Smith Note: 1061bde483f2SJacob Faibussowitsch Must have at least 1 parameter. 1062bde483f2SJacob Faibussowitsch 1063bde483f2SJacob Faibussowitsch Example usage: 1064bde483f2SJacob Faibussowitsch .vb 1065bde483f2SJacob Faibussowitsch PetscExpandToNothing(a,b,c) -> *nothing* 1066bde483f2SJacob Faibussowitsch .ve 1067bde483f2SJacob Faibussowitsch 1068db781477SPatrick Sanan .seealso: `PetscConcat()`, `PetscDefined()`, `PetscStringize()`, `PetscExpand()` 1069817da375SSatish Balay M*/ 1070bde483f2SJacob Faibussowitsch #define PetscExpandToNothing(...) 1071f7e3c444SJacob Faibussowitsch 1072f7e3c444SJacob Faibussowitsch /*MC 1073f7e3c444SJacob Faibussowitsch PetscMacroReturns - Define a macro body that returns a value 1074f7e3c444SJacob Faibussowitsch 1075f7e3c444SJacob Faibussowitsch Synopsis: 1076f7e3c444SJacob Faibussowitsch #include <petscmacros.h> 1077f7e3c444SJacob Faibussowitsch return_type PetscMacroReturns(return_type retexpr, ...) 1078f7e3c444SJacob Faibussowitsch 1079f7e3c444SJacob Faibussowitsch Input Parameters: 1080f7e3c444SJacob Faibussowitsch + retexpr - The value or expression that the macro should return 1081f7e3c444SJacob Faibussowitsch - __VA_ARGS__ - The body of the macro 1082f7e3c444SJacob Faibussowitsch 108316a05f60SBarry Smith Level: intermediate 108416a05f60SBarry Smith 1085f7e3c444SJacob Faibussowitsch Notes: 1086f7e3c444SJacob Faibussowitsch Due to limitations of the C-preprocessor retexpr cannot depend on symbols declared in the 1087f7e3c444SJacob Faibussowitsch body of the macro and should not depend on values produced as a result of the expression. The 1088f7e3c444SJacob Faibussowitsch user should not assume that the result of this macro is equivalent to a single logical source 1089f7e3c444SJacob Faibussowitsch line. It is not portable to use macros defined using this one in conditional or loop bodies 1090f7e3c444SJacob Faibussowitsch without enclosing them in curly braces\: 1091f7e3c444SJacob Faibussowitsch 1092f7e3c444SJacob Faibussowitsch .vb 1093f7e3c444SJacob Faibussowitsch #define FOO(arg1) PetscMacroReturns(0,arg1+=10) // returns 0 1094f7e3c444SJacob Faibussowitsch 1095f7e3c444SJacob Faibussowitsch int err,x = 10; 1096f7e3c444SJacob Faibussowitsch 1097f7e3c444SJacob Faibussowitsch if (...) err = FOO(x); // ERROR, body of FOO() executed outside the if statement 1098f7e3c444SJacob Faibussowitsch if (...) { err = FOO(x); } // OK 1099f7e3c444SJacob Faibussowitsch 1100f7e3c444SJacob Faibussowitsch for (...) err = FOO(x); // ERROR, body of FOO() executed outside the loop 1101f7e3c444SJacob Faibussowitsch for (...) { err = FOO(x); } // OK 1102f7e3c444SJacob Faibussowitsch .ve 1103f7e3c444SJacob Faibussowitsch 1104f7e3c444SJacob Faibussowitsch It is also not portable to use this macro directly inside function call, conditional, loop, 1105f7e3c444SJacob Faibussowitsch or switch statements\: 1106f7e3c444SJacob Faibussowitsch 1107f7e3c444SJacob Faibussowitsch .vb 1108f7e3c444SJacob Faibussowitsch extern void bar(int); 1109f7e3c444SJacob Faibussowitsch 1110f7e3c444SJacob Faibussowitsch int ret = FOO(x); 1111f7e3c444SJacob Faibussowitsch 1112f7e3c444SJacob Faibussowitsch bar(FOO(x)); // ERROR, may not compile 1113f7e3c444SJacob Faibussowitsch bar(ret); // OK 1114f7e3c444SJacob Faibussowitsch 1115f7e3c444SJacob Faibussowitsch if (FOO(x)) // ERROR, may not compile 1116f7e3c444SJacob Faibussowitsch if (ret) // OK 1117f7e3c444SJacob Faibussowitsch .ve 1118f7e3c444SJacob Faibussowitsch 1119f7e3c444SJacob Faibussowitsch Example usage: 1120f7e3c444SJacob Faibussowitsch .vb 1121f7e3c444SJacob Faibussowitsch #define MY_SIMPLE_RETURNING_MACRO(arg1) PetscMacroReturns(0,arg1+=10) 1122f7e3c444SJacob Faibussowitsch 1123f7e3c444SJacob Faibussowitsch int x = 10; 1124f7e3c444SJacob Faibussowitsch int err = MY_SIMPLE_RETURNING_MACRO(x); // err = 0, x = 20 1125f7e3c444SJacob Faibussowitsch 1126f7e3c444SJacob Faibussowitsch // multiline macros allowed, but must declare with line continuation as usual 1127f7e3c444SJacob Faibussowitsch #define MY_COMPLEX_RETURNING_MACRO(arg1) PetscMacroReturns(0, \ 1128f7e3c444SJacob Faibussowitsch if (arg1 > 10) { \ 1129f7e3c444SJacob Faibussowitsch puts("big int!"); \ 1130f7e3c444SJacob Faibussowitsch } else { \ 1131f7e3c444SJacob Faibussowitsch return 7355608; \ 1132f7e3c444SJacob Faibussowitsch } \ 1133f7e3c444SJacob Faibussowitsch ) 1134f7e3c444SJacob Faibussowitsch 1135f7e3c444SJacob Faibussowitsch // if retexpr contains commas, must enclose it with braces 1136f7e3c444SJacob Faibussowitsch #define MY_COMPLEX_RETEXPR_MACRO_1() PetscMacroReturns(x+=10,0,body...) 1137f7e3c444SJacob Faibussowitsch #define MY_COMPLEX_RETEXPR_MACRO_2() PetscMacroReturns((x+=10,0),body...) 1138f7e3c444SJacob Faibussowitsch 1139f7e3c444SJacob Faibussowitsch int x = 10; 1140f7e3c444SJacob Faibussowitsch int y = MY_COMPLEX_RETEXPR_MACRO_1(); // ERROR, y = x = 20 not 0 1141f7e3c444SJacob Faibussowitsch int z = MY_COMPLEX_RETEXPR_MACRO_2(); // OK, y = 0, x = 20 1142f7e3c444SJacob Faibussowitsch .ve 1143f7e3c444SJacob Faibussowitsch 1144db781477SPatrick Sanan .seealso: `PetscExpand()`, `PetscConcat()`, `PetscStringize()` 1145f7e3c444SJacob Faibussowitsch M*/ 1146f7e3c444SJacob Faibussowitsch #define PetscMacroReturns(retexpr, ...) PetscMacroReturns_(retexpr, __VA_ARGS__) 1147f7e3c444SJacob Faibussowitsch 11483ba16761SJacob Faibussowitsch #define PetscMacroReturnStandard(...) PetscMacroReturns(PETSC_SUCCESS, __VA_ARGS__) 1149f7e3c444SJacob Faibussowitsch 1150dd39110bSPierre Jolivet /*MC 1151dd39110bSPierre Jolivet PETSC_STATIC_ARRAY_LENGTH - Return the length of a static array 1152dd39110bSPierre Jolivet 115316a05f60SBarry Smith Synopsis: 115416a05f60SBarry Smith #include <petscmacros.h> 115516a05f60SBarry Smith size_t PETSC_STATIC_ARRAY_LENGTH(a) 115616a05f60SBarry Smith 115716a05f60SBarry Smith Input Parameter: 115816a05f60SBarry Smith . a - a static array of any type 115916a05f60SBarry Smith 116016a05f60SBarry Smith Output Parameter: 116116a05f60SBarry Smith . <return-value> - the length of the array 116216a05f60SBarry Smith 116316a05f60SBarry Smith Example: 116416a05f60SBarry Smith .vb 116516a05f60SBarry Smith PetscInt a[22]; 116616a05f60SBarry Smith size_t sa = PETSC_STATIC_ARRAY_LENGTH(a) 116716a05f60SBarry Smith .ve 116816a05f60SBarry Smith `sa` will have a value of 22 116916a05f60SBarry Smith 1170dd39110bSPierre Jolivet Level: intermediate 1171dd39110bSPierre Jolivet M*/ 117291c5ff90SBarry Smith #if PETSC_CPP_VERSION >= 14 117391c5ff90SBarry Smith #include <cstddef> 117491c5ff90SBarry Smith #include <type_traits> 117591c5ff90SBarry Smith 117691c5ff90SBarry Smith template <typename T> 117791c5ff90SBarry Smith static inline constexpr std::size_t PETSC_STATIC_ARRAY_LENGTH(const T &) noexcept 117891c5ff90SBarry Smith { 117991c5ff90SBarry Smith static_assert(std::is_array<T>::value, ""); 118091c5ff90SBarry Smith return std::extent<T, std::rank<T>::value - 1>::value; 118191c5ff90SBarry Smith } 118291c5ff90SBarry Smith #else 118391c5ff90SBarry Smith #define PETSC_STATIC_ARRAY_LENGTH(...) (sizeof(__VA_ARGS__) / sizeof(__VA_ARGS__)[0]) 118491c5ff90SBarry Smith #endif 1185dd39110bSPierre Jolivet 1186296d8154SBarry Smith /* 1187296d8154SBarry Smith These macros allow extracting out the first argument or all but the first argument from a macro __VAR_ARGS__ INSIDE another macro. 1188296d8154SBarry Smith 1189296d8154SBarry Smith Example usage: 1190296d8154SBarry Smith 1191296d8154SBarry Smith #define mymacro(obj,...) { 1192296d8154SBarry Smith PETSC_FIRST_ARG((__VA_ARGS__,unused)); 1193296d8154SBarry Smith f(22 PETSC_REST_ARG(__VA_ARGS__)); 1194296d8154SBarry Smith } 1195296d8154SBarry Smith 1196296d8154SBarry Smith 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 1197296d8154SBarry Smith 1198296d8154SBarry Smith Reference: 1199296d8154SBarry Smith https://stackoverflow.com/questions/5588855/standard-alternative-to-gccs-va-args-trick 1200296d8154SBarry Smith */ 1201296d8154SBarry Smith #define PETSC_FIRST_ARG_(N, ...) N 1202296d8154SBarry Smith #define PETSC_FIRST_ARG(args) PETSC_FIRST_ARG_ args 1203296d8154SBarry Smith #define PETSC_SELECT_16TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, ...) a16 1204296d8154SBarry Smith #define PETSC_NUM(...) PETSC_SELECT_16TH(__VA_ARGS__, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway) 1205296d8154SBarry Smith #define PETSC_REST_HELPER_TWOORMORE(first, ...) , __VA_ARGS__ 1206296d8154SBarry Smith #define PETSC_REST_HELPER_ONE(first) 1207296d8154SBarry Smith #define PETSC_REST_HELPER2(qty, ...) PETSC_REST_HELPER_##qty(__VA_ARGS__) 1208296d8154SBarry Smith #define PETSC_REST_HELPER(qty, ...) PETSC_REST_HELPER2(qty, __VA_ARGS__) 1209296d8154SBarry Smith #define PETSC_REST_ARG(...) PETSC_REST_HELPER(PETSC_NUM(__VA_ARGS__), __VA_ARGS__) 1210296d8154SBarry Smith 12111c7e414eSJacob Faibussowitsch #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_(name, ...) \ 12121c7e414eSJacob Faibussowitsch _Pragma(PetscStringize(name diagnostic push)) \ 12131c7e414eSJacob Faibussowitsch _Pragma(PetscStringize(name diagnostic ignored __VA_ARGS__)) 12141c7e414eSJacob Faibussowitsch 12151c7e414eSJacob Faibussowitsch #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_(name) _Pragma(PetscStringize(name diagnostic pop)) 12161c7e414eSJacob Faibussowitsch 12171c7e414eSJacob Faibussowitsch #if defined(__clang__) 12181c7e414eSJacob Faibussowitsch #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN(...) PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_(clang, __VA_ARGS__) 12191c7e414eSJacob Faibussowitsch #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END() PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_(clang) 12201c7e414eSJacob Faibussowitsch #elif defined(__GNUC__) || defined(__GNUG__) 12219bab7813SJacob Faibussowitsch // gcc >= 4.6.0 12229bab7813SJacob Faibussowitsch #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600 12231c7e414eSJacob Faibussowitsch #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN(...) PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_(GCC, __VA_ARGS__) 12241c7e414eSJacob Faibussowitsch #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END() PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_(GCC) 12251c7e414eSJacob Faibussowitsch #endif 12269bab7813SJacob Faibussowitsch #endif 12271c7e414eSJacob Faibussowitsch 1228*beceaeb6SBarry Smith #if !defined(PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN) 12291c7e414eSJacob Faibussowitsch #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN(...) 12301c7e414eSJacob Faibussowitsch #define PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END(...) 12311c7e414eSJacob Faibussowitsch // only undefine these if they are not used 12321c7e414eSJacob Faibussowitsch #undef PETSC_PRAGMA_DIAGNOSTIC_IGNORED_BEGIN_ 12331c7e414eSJacob Faibussowitsch #undef PETSC_PRAGMA_DIAGNOSTIC_IGNORED_END_ 12341c7e414eSJacob Faibussowitsch #endif 12351c7e414eSJacob Faibussowitsch 12368d031ccaSJunchao Zhang /*MC 12378d031ccaSJunchao Zhang PetscPragmaOMP - Sets an OpenMP pragma to affect the next block of code 12388d031ccaSJunchao Zhang 12398d031ccaSJunchao Zhang Synopsis: 12408d031ccaSJunchao Zhang #include <petscmacros.h> 12418d031ccaSJunchao Zhang int PetscPragmaOMP(name) 12428d031ccaSJunchao Zhang 12438d031ccaSJunchao Zhang No Fortran Support 12448d031ccaSJunchao Zhang 12458d031ccaSJunchao Zhang Input Parameter: 12468d031ccaSJunchao Zhang . name - the OpenMP pragma, for example, `critical` or `parallel for` 12478d031ccaSJunchao Zhang 12488d031ccaSJunchao Zhang Level: intermediate 12498d031ccaSJunchao Zhang 12508d031ccaSJunchao Zhang Note: 12518d031ccaSJunchao Zhang The pragma takes effect when PETSc was configured with `--with-openmp`. See `PetscPragmaUseOMPKernels()` 1252d7c1f440SPierre Jolivet for when PETSc was configured to use OpenMP in some of its numerical kernels. 12538d031ccaSJunchao Zhang 12548d031ccaSJunchao Zhang .seealso: `PetscPragmaUseOMPKernels()`, `PetscHasBuiltin()`, `PetscDefined()`, `PetscLikely()`, `PetscUnlikely()`, 12558d031ccaSJunchao Zhang `PETSC_ATTRIBUTE_FORMAT`, `PETSC_ATTRIBUTE_MAY_ALIAS` 12568d031ccaSJunchao Zhang M*/ 12572e327cfbSJacob Faibussowitsch #if defined(_OPENMP) 12582e327cfbSJacob Faibussowitsch #if defined(_MSC_VER) 12592e327cfbSJacob Faibussowitsch #define PetscPragmaOMP(...) __pragma(__VA_ARGS__) 12602e327cfbSJacob Faibussowitsch #else 12612e327cfbSJacob Faibussowitsch #define PetscPragmaOMP(...) _Pragma(PetscStringize(omp __VA_ARGS__)) 12622e327cfbSJacob Faibussowitsch #endif 12638d031ccaSJunchao Zhang #else 12648d031ccaSJunchao Zhang #define PetscPragmaOMP(...) 12652e327cfbSJacob Faibussowitsch #endif 12662e327cfbSJacob Faibussowitsch 12678d031ccaSJunchao Zhang /*MC 12688d031ccaSJunchao Zhang PetscPragmaUseOMPKernels - Sets an OpenMP pragma to affect the next block of code 12698d031ccaSJunchao Zhang 12708d031ccaSJunchao Zhang Synopsis: 12718d031ccaSJunchao Zhang #include <petscmacros.h> 12728d031ccaSJunchao Zhang int PetscPragmaUseOMPKernels(name) 12738d031ccaSJunchao Zhang 12748d031ccaSJunchao Zhang No Fortran Support 12758d031ccaSJunchao Zhang 12768d031ccaSJunchao Zhang Input Parameter: 12778d031ccaSJunchao Zhang . name - the OpenMP pragma, for example, `critical` or `parallel for` 12788d031ccaSJunchao Zhang 12798d031ccaSJunchao Zhang Level: intermediate 12808d031ccaSJunchao Zhang 12818d031ccaSJunchao Zhang Note: 12828d031ccaSJunchao Zhang The pragma takes effect when PETSc was configured with `--with-openmp-kernels`. See `PetscPragmaOMP()` 12838d031ccaSJunchao Zhang for when PETSc was configured with OpenMP but not to use it in its numerical kernels 12848d031ccaSJunchao Zhang 12858d031ccaSJunchao Zhang .seealso: `PetscPragmaOMP()`, `PetscHasBuiltin()`, `PetscDefined()`, `PetscLikely()`, `PetscUnlikely()`, 12868d031ccaSJunchao Zhang `PETSC_ATTRIBUTE_FORMAT`, `PETSC_ATTRIBUTE_MAY_ALIAS` 12878d031ccaSJunchao Zhang M*/ 12888d031ccaSJunchao Zhang #if defined(PETSC_USE_OPENMP_KERNELS) 12898d031ccaSJunchao Zhang #if defined(_MSC_VER) 12908d031ccaSJunchao Zhang #define PetscPragmaUseOMPKernels(...) __pragma(__VA_ARGS__) 12918d031ccaSJunchao Zhang #else 12928d031ccaSJunchao Zhang #define PetscPragmaUseOMPKernels(...) _Pragma(PetscStringize(omp __VA_ARGS__)) 12938d031ccaSJunchao Zhang #endif 12948d031ccaSJunchao Zhang #else 12958d031ccaSJunchao Zhang #define PetscPragmaUseOMPKernels(...) 12962e327cfbSJacob Faibussowitsch #endif 12972e327cfbSJacob Faibussowitsch 12982e327cfbSJacob Faibussowitsch /* PetscPragmaSIMD - from CeedPragmaSIMD */ 12992e327cfbSJacob Faibussowitsch #if defined(__NEC__) 13002e327cfbSJacob Faibussowitsch #define PetscPragmaSIMD _Pragma("_NEC ivdep") 13012e327cfbSJacob Faibussowitsch #elif defined(__INTEL_COMPILER) && !defined(_WIN32) 13022e327cfbSJacob Faibussowitsch #define PetscPragmaSIMD _Pragma("vector") 13032e327cfbSJacob Faibussowitsch #elif defined(__GNUC__) 13042e327cfbSJacob Faibussowitsch #if __GNUC__ >= 5 && !defined(__PGI) 13052e327cfbSJacob Faibussowitsch #define PetscPragmaSIMD _Pragma("GCC ivdep") 13062e327cfbSJacob Faibussowitsch #endif 13072e327cfbSJacob Faibussowitsch #elif defined(_OPENMP) && _OPENMP >= 201307 13082e327cfbSJacob Faibussowitsch #define PetscPragmaSIMD PetscPragmaOMP(simd) 13092e327cfbSJacob Faibussowitsch #elif defined(PETSC_HAVE_CRAY_VECTOR) 13102e327cfbSJacob Faibussowitsch #define PetscPragmaSIMD _Pragma("_CRI ivdep") 13112e327cfbSJacob Faibussowitsch #endif 13122e327cfbSJacob Faibussowitsch 1313*beceaeb6SBarry Smith #if !defined(PetscPragmaSIMD) 13142e327cfbSJacob Faibussowitsch #define PetscPragmaSIMD 13152e327cfbSJacob Faibussowitsch #endif 13162e327cfbSJacob Faibussowitsch 13175029be03SJacob Faibussowitsch #include <petsc/private/petscadvancedmacros.h> 13185029be03SJacob Faibussowitsch 13195029be03SJacob Faibussowitsch #define PetscConcat6_(a, b, c, d, e, f) a##b##c##d##e##f 13205029be03SJacob Faibussowitsch #define PetscConcat6(a, b, c, d, e, f) PetscConcat6_(a, b, c, d, e, f) 13215029be03SJacob Faibussowitsch 13225029be03SJacob Faibussowitsch #define PETSC_DEPRECATED_IDENTIFIER_(__PETSC_DEPRECATION_MACRO__, __SILENCE_MACRO__, major, minor, subminor, replacement, ...) \ 13235029be03SJacob Faibussowitsch PetscIfPetscDefined(__SILENCE_MACRO__, PetscExpandToNothing, \ 132458cbeaadSJacob Faibussowitsch __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__)) 13255029be03SJacob Faibussowitsch 13265029be03SJacob Faibussowitsch #define PETSC_DEPRECATED_IDENTIFIER(__PETSC_DEPRECATION_MACRO__, major, minor, subminor, ...) \ 13275029be03SJacob Faibussowitsch PETSC_DEPRECATED_IDENTIFIER_(__PETSC_DEPRECATION_MACRO__, PetscConcat6(SILENCE_DEPRECATION_WARNINGS_, major, _, minor, _, subminor), major, minor, subminor, __VA_ARGS__) 13285029be03SJacob Faibussowitsch 1329a14d4ff0SToby Isaac #define PETSC_DEPRECATED_OBJECT(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_OBJECT_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1330edd03b47SJacob Faibussowitsch #define PETSC_DEPRECATED_FUNCTION(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_FUNCTION_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1331edd03b47SJacob Faibussowitsch #define PETSC_DEPRECATED_TYPEDEF(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_TYPEDEF_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1332edd03b47SJacob Faibussowitsch #define PETSC_DEPRECATED_ENUM(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_ENUM_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1333edd03b47SJacob Faibussowitsch #define PETSC_DEPRECATED_MACRO(major, minor, subminor, replacement, ...) PETSC_DEPRECATED_IDENTIFIER(PETSC_DEPRECATED_MACRO_BASE, major, minor, subminor, replacement, __VA_ARGS__) 1334