29 Numerics library [numerics]

29.10 Data-parallel types [simd]

29.10.2 Exposition-only types, variables, and concepts [simd.expos]


29.10.2.1 Exposition-only helpers [simd.expos.defn]

29.10.2.2 simd ABI tags [simd.expos.abi]


using simd-size-type = see below; // exposition only template<size_t Bytes> using integer-from = see below; // exposition only template<class T, class Abi> constexpr simd-size-type simd-size-v = see below; // exposition only template<size_t Bytes, class Abi> constexpr simd-size-type mask-size-v = see below; // exposition only template<class T> constexpr size_t mask-element-size = see below; // exposition only template<class From, class To> concept explicitly-convertible-to = // exposition only requires { static_cast<To>(declval<From>()); }; template<class T> using deduced-vec-t = see below; // exposition only template<class V> concept simd-vec-type = // exposition only same_as<V, basic_vec<typename V::value_type, typename V::abi_type>> && is_default_constructible_v<V>; template<class V> concept simd-mask-type = // exposition only same_as<V, basic_mask<mask-element-size<V>, typename V::abi_type>> && is_default_constructible_v<V>; template<class V> concept simd-floating-point = // exposition only simd-vec-type<V> && floating_point<typename V::value_type>; template<class V> concept simd-integral = // exposition only simd-vec-type<V> && integral<typename V::value_type>; template<class V> using simd-complex-value-type = V::value_type::value_type; // exposition only template<class V> concept simd-complex = // exposition only simd-vec-type<V> && same_as<typename V::value_type, complex<simd-complex-value-type<V>>>; template<class T> concept math-floating-point = // exposition only simd-floating-point<deduced-vec-t<T>>; template<class BinaryOperation, class T> concept reduction-binary-operation = see below; // exposition only // [simd.expos.abi], simd ABI tags template<class T> using native-abi = see below; // exposition only template<class T, simd-size-type N> using deduce-abi-t = see below; // exposition only // [simd.flags], load and store flags struct convert-flag; // exposition only struct aligned-flag; // exposition only template<size_t N> struct overaligned-flag; // exposition only

29.10.2.1 Exposition-only helpers [simd.expos.defn]

using simd-size-type = see below;
simd-size-type is an alias for a signed integer type.
template<size_t Bytes> using integer-from = see below;
integer-from<Bytes> is an alias for a signed integer type T such that sizeof(T) equals Bytes.
template<class T, class Abi> constexpr simd-size-type simd-size-v = see below;
simd-size-v<T, Abi> denotes the width of basic_vec<T, Abi> if the specialization basic_vec<T, Abi> is enabled, or 0 otherwise.
template<size_t Bytes, class Abi> constexpr simd-size-type mask-size-v = see below;
mask-size-v<Bytes, Abi> denotes the width of basic_mask<Bytes, Abi> if the specialization basic_mask<Bytes, Abi> is enabled, or 0 otherwise.
template<class T> constexpr size_t mask-element-size = see below;
mask-element-size<basic_mask<Bytes, Abi>> has the value Bytes.
template<class T> using deduced-vec-t = see below;
Let x denote an lvalue of type const T.
deduced-vec-t<T> is an alias for decltype(x + x).
template<class BinaryOperation, class T> concept reduction-binary-operation = requires (const BinaryOperation binary_op, const vec<T, 1> v) { { binary_op(v, v) } -> same_as<vec<T, 1>>; };
Types BinaryOperation and T model reduction-binary-operation<BinaryOperation, T> only if:
  • BinaryOperation is a binary element-wise operation and the operation is commutative.
  • An object of type BinaryOperation can be invoked with two arguments of type basic_vec<T, Abi>, with unspecified ABI tag Abi, returning a basic_vec<T, Abi>.

29.10.2.2 simd ABI tags [simd.expos.abi]

template<class T> using native-abi = see below; template<class T, simd-size-type N> using deduce-abi-t = see below;
An ABI tag is a type that indicates a choice of size and binary representation for objects of data-parallel type.
[Note 1: 
The intent is for the size and binary representation to depend on the target architecture and compiler flags.
The ABI tag, together with a given element type, implies the width.
— end note]
[Note 2: 
The ABI tag is orthogonal to selecting the machine instruction set.
The selected machine instruction set limits the usable ABI tag types, though (see [simd.overview]).
The ABI tags enable users to safely pass objects of data-parallel type between translation unit boundaries (e.g., function calls or I/O).
— end note]
An implementation defines ABI tag types as necessary for the following aliases.
deduce-abi-t<T, N> names an ABI tag type if and only if
  • T is a vectorizable type,
  • N is greater than zero, and
  • N is not larger than an implementation-defined maximum.
Otherwise, deduce-abi-t<T, N> names an unspecified type.
The implementation-defined maximum for N is not smaller than 64 and can differ depending on T.
If deduce-abi-t<T, N> names an ABI tag type, the following is true:
native-abi<T> is an implementation-defined alias for an ABI tag.
basic_vec<T, native-abi<T>> is an enabled specialization.
[Note 3: 
The intent is to use the ABI tag producing the most efficient data-parallel execution for the element type T on the currently targeted system.
For target architectures with ISA extensions, compiler flags can change the type of the native-abi<T> alias.
— end note]
[Example 1: 
Consider a target architecture supporting the ABI tags __simd128 and __simd256, where hardware support for __simd256 exists only for floating-point types.
The implementation therefore defines native-abi<T> as an alias for
  • __simd256 if T is a floating-point type, and
  • __simd128 otherwise.
— end example]