Skip to content

Commit bd315df

Browse files
authored
SIMD: Portable Masks, C++20 (#4607)
## Summary Ensure we can use any producing type's `simd_mask`, e.g., `double`, when setting (in)valid particles, by manipulating our `uint64` in `idcpu`. This currently requires a conversion/cast in C++. Make this conversion portable, so far it only worked on GCC/Linux. This helper needs C++20. Thus, build AMReX conditionally always with C++20 or newer when SIMD is requested (non-default). Eventually, we will require C++26 once this becomes standard, and C++29 will have even more updates. ## Additional background Portability to macOS/Windows: - conda-forge/impactx-feedstock#54 - mattkretz/vir-simd#45 ## Checklist The proposed changes: - [x] fix a bug or incorrect behavior in AMReX - [ ] 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
1 parent f4640f1 commit bd315df

File tree

3 files changed

+18
-4
lines changed

3 files changed

+18
-4
lines changed

Src/Base/AMReX_SIMD.H

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#ifdef AMREX_USE_SIMD
99
// TODO make SIMD provider configurable: VIR (C++17 TS2) or C++26 (later)
1010
# include <vir/simd.h> // includes SIMD TS2 header <experimental/simd>
11+
# if __cplusplus >= 202002L
12+
# include <vir/simd_cvt.h>
13+
# endif
1114
#endif
1215

1316
#include <cstdint>
@@ -21,6 +24,9 @@ namespace amrex::simd
2124
namespace stdx {
2225
#ifdef AMREX_USE_SIMD
2326
using namespace vir::stdx;
27+
# if __cplusplus >= 202002L
28+
using vir::cvt;
29+
# endif
2430
#else
2531
// fallback implementations for functions that are commonly used in portable code paths
2632

Src/Particle/AMReX_Particle.H

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,9 @@ namespace amrex {
106106
#ifdef AMREX_USE_SIMD
107107
// SIMD
108108
static_assert(!std::is_same_v<T_SIMD, uint64_t>, "make_invalid: forgot template on wrapper?");
109-
// .__cvt() because of: https://github.com/VcDevel/std-simd/issues/41
110-
simd::stdx::where(mask.__cvt(), idcpu) &= ~(T_SIMD{1} << 63);
109+
// cvt / .__cvt() because of: https://github.com/VcDevel/std-simd/issues/41#issuecomment-3185164952
110+
// see also https://github.com/mattkretz/vir-simd/issues/45
111+
simd::stdx::where(simd::stdx::cvt(mask), idcpu) &= ~(T_SIMD{1} << 63);
111112
#else
112113
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(false, "make_invalid: AMReX_SIMD was not enabled!");
113114
#endif
@@ -132,8 +133,9 @@ namespace amrex {
132133
#ifdef AMREX_USE_SIMD
133134
// SIMD
134135
static_assert(!std::is_same_v<T_SIMD, uint64_t>, "make_valid: forgot template on wrapper?");
135-
// .__cvt() because of: https://github.com/VcDevel/std-simd/issues/41
136-
simd::stdx::where(mask.__cvt(), idcpu) |= T_SIMD{1} << 63;
136+
// cvt / .__cvt() because of: https://github.com/VcDevel/std-simd/issues/41#issuecomment-3185164952
137+
// see also https://github.com/mattkretz/vir-simd/issues/45
138+
simd::stdx::where(simd::stdx::cvt(mask), idcpu) |= T_SIMD{1} << 63;
137139
#else
138140
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(false, "make_valid: AMReX_SIMD was not enabled!");
139141
#endif

Tools/CMake/AMReX_Config.cmake

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ function (configure_amrex AMREX_TARGET)
4747
# minimum: C++17
4848
target_compile_features(${AMREX_TARGET} PUBLIC cxx_std_17)
4949

50+
# vir::cvt
51+
# https://github.com/mattkretz/vir-simd/issues/45
52+
if (AMReX_SIMD)
53+
target_compile_features(${AMREX_TARGET} PUBLIC cxx_std_20)
54+
endif()
55+
5056
if (AMReX_CUDA)
5157
set_target_properties(${AMREX_TARGET} PROPERTIES CUDA_EXTENSIONS OFF)
5258
# minimum: C++17

0 commit comments

Comments
 (0)