Files
2025-10-25 03:02:53 +03:00

14 KiB
Raw Permalink Blame History

[simd.expos]

29 Numerics library [numerics]

29.10 Data-parallel types [simd]

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

using simd-size-type = see below; // exposition onlytemplate<size_t Bytes> using integer-from = see below; // exposition onlytemplate<class T, class Abi>constexpr simd-size-type simd-size-v = see below; // exposition onlytemplate constexpr size_t mask-element-size = see below; // exposition onlytemplateconcept constexpr-wrapper-like = // exposition onlyconvertible_to<T, decltype(T::value)> &&equality_comparable_with<T, decltype(T::value)> && bool_constant<T() == T::value>::value && bool_constant<static_cast<decltype(T::value)>(T()) == T::value>::value;

template using deduced-vec-t = see below; // exposition onlytemplate<class V, class T> using make-compatible-simd-t = see below; // exposition onlytemplateconcept simd-vec-type = // exposition onlysame_as<V, basic_vec<typename V::value_type, typename V::abi_type>> && is_default_constructible_v;

templateconcept simd-mask-type = // exposition onlysame_as<V, basic_mask<mask-element-size, typename V::abi_type>> && is_default_constructible_v;

templateconcept simd-floating-point = // exposition onlysimd-vec-type && floating_point;

templateconcept simd-integral = // exposition onlysimd-vec-type && integral;

templateusing simd-complex-value-type = typename V::value_type::value_type; // exposition onlytemplateconcept simd-complex = // exposition onlysimd-vec-type && same_as<typename V::value_type, complex<simd-complex-value-type>>;

template<class... Ts>concept math-floating-point = // exposition only(simd-floating-point<deduced-vec-t> || ...);

template<class... Ts>requires math-floating-point<Ts...>using math-common-simd-t = see below; // exposition onlytemplate<class BinaryOperation, class T>concept reduction-binary-operation = see below; // exposition only// [simd.expos.abi], simd ABI tagstemplate using native-abi = see below; // exposition onlytemplate<class T, simd-size-type N> using deduce-abi-t = see below; // exposition only// [simd.flags], Load and store flagsstruct convert-flag; // exposition onlystruct aligned-flag; // exposition onlytemplate<size_t N> struct overaligned-flag; // exposition only

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

🔗

using simd-size-type = see below;

1

#

simd-size-type is an alias for a signed integer type.

🔗

template<size_t Bytes> using integer-from = see below;

2

#

integer-from is an alias for a signed integer typeT such that sizeof(T) equals Bytes.

🔗

template<class T, class Abi> constexpr simd-size-type simd-size-v = see below;

3

#

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<class T> constexpr size_t mask-element-size = see below;

4

#

mask-element-size<basic_mask<Bytes, Abi>> has the valueBytes.

🔗

template<class T> using deduced-vec-t = see below;

5

#

Let x denote an lvalue of type const T.

6

#

deduced-vec-t is an alias for

decltype(x + x), if the type of x + x is an enabled specialization of basic_vec; otherwise

void.

🔗

template<class V, class T> using make-compatible-simd-t = see below;

7

#

Let x denote an lvalue of type const T.

8

#

make-compatible-simd-t<V, T> is an alias for

deduced-vec-t, if that type is not void, otherwise

vec<decltype(x + x), V::size()>.

🔗

template<class... Ts> requires [math-floating-point](#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]")<Ts...> using math-common-simd-t = see below;

9

#

Let T0 denote Ts...[0].

Let T1 denote Ts...[1].

Let TRest denote a pack such that T0, T1, TRest... is equivalent to Ts....

10

#

Let math-common-simd-t<Ts...> be an alias for

deduced-vec-t, if sizeof...(Ts) equals 1; otherwise

common_type_t<deduced-vec-t, deduced-vec-t>, if sizeof...(Ts) equals 2 and math-floating-point &&math-floating-point is true; otherwise

common_type_t<deduced-vec-t, T1>, if sizeof...(Ts) equals 2 and math-floating-point<T0> is true; otherwise

common_type_t<T0, deduced-vec-t>, if sizeof...(Ts) equals 2; otherwise

common_type_t<math-common-simd-t<T0, T1>, TRest...>, if math-common-simd-t<T0, T1> is valid and denotes a type; otherwise

common_type_t<math-common-simd-t<TRest...>, T0, T1>.

🔗

template<class BinaryOperation, class T> concept [reduction-binary-operation](#concept:reduction-binary-operation "29.10.2.1Exposition-only helpers[simd.expos.defn]") = requires (const BinaryOperation binary_op, const vec<T, 1> v) { { binary_op(v, v) } -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<vec<T, 1>>; };

11

#

Types BinaryOperation and T modelreduction-binary-operation<BinaryOperation, T> only if:

  • (11.1)

    BinaryOperation is a binary element-wise operation and the operation is commutative.

  • (11.2)

    An object of type BinaryOperation can be invoked with two arguments of type basic_vec<T, Abi>, with unspecified ABI tagAbi, 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;

1

#

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]

2

#

[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]

3

#

An implementation defines ABI tag types as necessary for the following aliases.

4

#

deduce-abi-t<T, N> is defined if

T is a vectorizable type,

N is greater than zero, and

N is not larger than an implementation-defined maximum.

The implementation-defined maximum forN is not smaller than 64 and can differ depending on T.

5

#

Where present, deduce-abi-t<T, N> names an ABI tag type such that

simd-size-v<T, deduce-abi-t<T, N>> equals N,

basic_vec<T, deduce-abi-t<T, N>> is enabled ([simd.overview]), and

basic_mask<sizeof(T), deduce-abi-t<integer-from<sizeof(T)>, N>> is enabled.

6

#

native-abi is an implementation-defined alias for an ABI tag.

basic_vec<T, native-abi> 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 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 as an alias for

__simd256 if T is a floating-point type, and

__simd128 otherwise.

— end example]