Parts of this implementation are already integrated into GCC 16. If you want to try the development version you can either install this library via:
make prefix=~/.local installor simply point your compiler's include path to this repository.
Alternatively you can also install into the compiler's standard library directory:
make install-systemThere is no support for uninstalling, since install-system overwrites the std::simd headers of libstdc++.
Build your own project with C++26 (latest GCC, PRs to support Clang are
welcome). Just include <simd> and you're good to go:
#include<simd>To build the tests there are multiple targets available. make help will list all of them.
By default all vectorizable types (including complex) are supported. More features can be enabled by defining the following macros:
| Macro | Description |
|---|---|
VIR_EXTENSIONS | Enable several optimizations and warnings on guaranteed precondition violations. |
VIR_PATCH_PERMUTE_DYNAMIC | Implements [simd.permute.dynamic]. |
VIR_PATCH_MATH | Implements [simd.math]. |
VIR_PATCH_IMPROVE_CX | Implements abs and norm for vec<complex<T>>. Three different approaches =1, =2, and =3 make different optimization/code-gen trade-offs. |
VIR_PATCH_MISSED_OPT | Enable hand-written instruction selection for optimization patterns the compiler misses. Includes ktest-based mask reductions and pshufb-based type conversions on x86. |
VIR_PATCH_TEST_STORES | Fix masked stores. |
VIR_CONSTEVAL_BROADCAST | Use consteval broadcast constructor for value-preserving conversions: Either the value doesn't change or the program is ill-formed. Peace of mind. |
| Feature | Status |
|---|---|
| P1928R15 std::simd — merge data-parallel types from the Parallelism TS 2 | ✅ done (except math) |
| P2663R7 Interleaved complex values support in std::simd | ✅ done (except math) |
| P2664R11 Proposal to extend std::simd with permutation API | 🟡 partial |
| P2876R3 Proposal to extend std::simd with more constructors and accessors | ✅ done |
| P2929R2 simd_invoke | 🔴 open (still in design phase) |
| P2933R4 Extend ⟨bit⟩ header function with overloads for std::simd | ✅ done |
P2933R4 std::simd overloads for <bit> header | ✅ done (not optimized) |
| P2964R2 Allowing user-defined types in std::simd | 🔴 open (still in design phase) |
| P3287R3 Exploration of namespaces for std::simd | ✅ done |
| P3430R3 simd issues: explicit, unsequenced, identity-element position, and members of disabled simd | ✅ done |
| P3440R2 Add n_elements named constructor to std::simd | 🔴 open (still in design phase) |
| P3441R2 Rename simd_split to simd_chunk | ✅ done |
| P3480R6 std::simd is a range | ✅ done |
| P3691R1 Reconsider naming of the namespace for 'std::simd' | ✅ done |
| P3844R4 Reword [simd.math] for consteval conversions | ✅ done |
| P3932R0 Fix LWG4470: Fix integer-from in [simd] | ✅ done |
| P3973R0 bit_cast_as: Element type reinterpretation for std::simd | 🔴 open (still in design phase) |
| P3983R0 simd object representation | 🔴 open (still in design phase) |
| P3985R0 Concepts for std::simd | 🔴 open (still in design phase) |
| P4012R1 value-preserving consteval broadcast to simd::vec | ✅ done |
P4042R0 Fix LWG4543: incorrect cast between simd::vec and simd::mask via conversion to and from impl-defined vector types | ✅ done |
| Issue | Status |
|---|---|
LWG4230simd<complex>::real/imag is overconstrained | ✅ done |
LWG4231datapar::chunk<N> should use simd-size-type instead of size_t | ✅ done |
LWG4232datapar::resize does not resize | ✅ done |
LWG4238simd_mask<complex<double>>::operator+/-/~ return a disabled simd specialization | ✅ done |
LWG4280simd::partial_load uses undefined identifier T | 🔴 unclear |
LWG4375std::simd::bit_ceil should not be noexcept | 🔴 unclear |
| LWG4376 ABI tag in return type of [simd.mask.unary] is overconstrained | ✅ done |
LWG4382 The simd::basic_mask(bool) overload needs to be more constrained | 🔴 unclear |
LWG4385 Including <simd> doesn't provide std::begin/end | ✅ done (via inclusion of <span>) |
LWG4386std::simd::select(bool c, const T& a, const U& b) is underconstrained | 🔴 unclear |
LWG4390simd::basic_vec(U&&) default template parameter | ⚪ treated as NAD |
LWG4391 Ambiguities of simd::basic_vec constructor | 🔴 unclear |
LWG4392simd::unchecked_load misses difference type casting | 🔴 unclear |
LWG4393simd::unchecked_scatter_to is underconstrained | 🔴 unclear |
LWG4394simd::unchecked_load(I first, S last) construct span maybe ill-formed | 🔴 unclear |
| LWG4402 List-initialization of iterators in [simd.mask.overview] | 🔴 unclear |
LWG4403simd::basic_vec CTAD misses difference type casting | ✅ done |
LWG4407constexpr-wrapper-like needs remove_cvref_t in simd::basic_vec constructor | ✅ done |
LWG4408 Hardening simd::vec::operator[] | 🔴 unclear |
LWG4409 Constant expression ranges::size(r) Constraints and Mandates in [simd] | 🔴 open |
LWG4412 Fix declaration of zero_element and uninit_element | ✅ done |
LWG4413 Unused/left-over simd::alignment specialization for basic_mask | ✅ done |
LWG4414 §[simd.expos.abi] deduce-abi-t is underspecified and incorrectly referenced from rebind and resize | ✅ done (P3932R0) |
LWG4420 §[simd] conversions (constructor, load, stores, gather, and scatter) are incorrectly constrained for <stdfloat> types | ✅ done |
LWG4436simd broadcast is overconstrained — std::cw<0.f> is not convertible to simd::vec<float16_t> | 🔴 unclear |
LWG4470 The use of integer-from<Bytes> all over [simd] is incorrect for Bytes=sizeof(complex<double>) | ✅ done (P3932R0) |
LWG4518simd::cat return type requires inefficient ABI tag change/conversion | ✅ done (P3932R0) |
LWG4535 Disallow user specialization of <simd> templates | ✅ done (not actionable) |
LWG4543 Incorrect cast between simd::vec and simd::mask via conversion to and from impl-defined vector types | ✅ done (P4042R0) |