Skip to content

Commit

Permalink
Implement portable assumptions with AMREX_ASSUME (#3770)
Browse files Browse the repository at this point in the history
## Summary
This PR implements portable assumptions by defining a new
`AMREX_ASSUME(assumption)` macro.

In case the C++23 attribute
[`[[assume(ASSUMPTION)]]`](https://en.cppreference.com/w/cpp/language/attributes/assume)
is available, the macro simply becomes this attribute. Otherwise it
becomes a builtin function, depending on the compiler.

The macro is intended to be used as follows:
```
float f_test(float p)
{
    AMREX_ASSUME(p >= 0);
    return std::clamp(p, 0.0f, 1.0f);
}
```

## Additional background

Please use this link to test this implementation with the Compiler
Explorer: https://godbolt.org/z/1Tz7v7v45

## Checklist

The proposed changes:
- [ ] fix a bug or incorrect behavior in AMReX
- [X] add new capabilities to AMReX
- [ ] changes answers in the test suite to more than roundoff level
- [ ] are likely to significantly affect the results of downstream AMReX
users
- [ ] include documentation in the code and/or rst files, if appropriate
  • Loading branch information
lucafedeli88 authored Feb 20, 2024
1 parent 99b47cb commit 398b20b
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions Src/Base/AMReX_Extension.H
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,28 @@
# define AMREX_UNLIKELY
#endif

// Note: following compilers support assumptions, at least using builtin functions:
// - Clang >= 3.7
// - GCC >= 5.1
// - MSVC >= 19.20
// - nvcc >= 11.1.0
// - icx >= 2021.1.2
#if defined(__has_cpp_attribute) && __has_cpp_attribute(assume)
# define AMREX_ASSUME(ASSUMPTION) [[assume(ASSUMPTION)]]
#else
# if defined(__CUDACC__) && ( (__CUDACC_VER_MAJOR__ > 11) || ((__CUDACC_VER_MAJOR__ == 11) && (__CUDACC_VER_MINOR__ >= 1)) )
# define AMREX_ASSUME(ASSUMPTION) __builtin_assume(ASSUMPTION)
# elif defined(AMREX_CXX_INTEL) || defined(__clang__)
# define AMREX_ASSUME(ASSUMPTION) __builtin_assume(ASSUMPTION)
# elif defined(_MSC_VER)
# define AMREX_ASSUME(ASSUMPTION) __assume(ASSUMPTION)
# elif defined(__GNUC__)
# define AMREX_ASSUME(ASSUMPTION) if (ASSUMPTION) {} else { __builtin_unreachable(); }
# else
# define AMREX_ASSUME(ASSUMPTION)
# endif
#endif

// CI uses -Werror -Wc++17-extension, thus we need to add the __cplusplus clause
#if !defined(AMREX_NO_NODISCARD) && defined(__has_cpp_attribute) && __has_cpp_attribute(nodiscard) >= 201603L
# define AMREX_NODISCARD [[nodiscard]]
Expand Down

0 comments on commit 398b20b

Please sign in to comment.