[simd.expos] # 29 Numerics library [[numerics]](./#numerics) ## 29.10 Data-parallel types [[simd]](simd#expos) ### 29.10.2 Exposition-only types, variables, and concepts [simd.expos] using *simd-size-type* = *see below*; // *exposition only*template using *integer-from* = *see below*; // *exposition only*templateconstexpr *simd-size-type* *simd-size-v* = *see below*; // *exposition only*template constexpr size_t *mask-element-size* = *see below*; // *exposition only*templateconcept [*constexpr-wrapper-like*](#concept:constexpr-wrapper-like "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") = // *exposition only*[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]") &&[equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4 Concept equality_­comparable [concept.equalitycomparable]") && bool_constant::value && bool_constant(T()) == T::value>::value; template using *deduced-vec-t* = *see below*; // *exposition only*template using *make-compatible-simd-t* = *see below*; // *exposition only*templateconcept [*simd-vec-type*](#concept:simd-vec-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") = // *exposition only*[same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")> && is_default_constructible_v; templateconcept [*simd-mask-type*](#concept:simd-mask-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") = // *exposition only*[same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]"), typename V::abi_type>> && is_default_constructible_v; templateconcept [*simd-floating-point*](#concept:simd-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") = // *exposition only*[*simd-vec-type*](#concept:simd-vec-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") && [floating_point](concepts.arithmetic#concept:floating_point "18.4.7 Arithmetic concepts [concepts.arithmetic]"); templateconcept [*simd-integral*](#concept:simd-integral "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") = // *exposition only*[*simd-vec-type*](#concept:simd-vec-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") && [integral](concepts.arithmetic#concept:integral "18.4.7 Arithmetic concepts [concepts.arithmetic]"); templateusing *simd-complex-value-type* = typename V::value_type::value_type; // *exposition only*templateconcept [*simd-complex*](#concept:simd-complex "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") = // *exposition only*[*simd-vec-type*](#concept:simd-vec-type "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") && [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")>>; templateconcept [*math-floating-point*](#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") = // *exposition only*([*simd-floating-point*](#concept:simd-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]")<*deduced-vec-t*> || ...); templaterequires [*math-floating-point*](#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]")using *math-common-simd-t* = *see below*; // *exposition only*templateconcept [*reduction-binary-operation*](#concept:reduction-binary-operation "29.10.2.1 Exposition-only helpers [simd.expos.defn]") = *see below*; // *exposition only*// [[simd.expos.abi]](#abi "29.10.2.2 simd ABI tags"), simd ABI tagstemplate using *native-abi* = *see below*; // *exposition only*template using *deduce-abi-t* = *see below*; // *exposition only*// [[simd.flags]](simd.flags "29.10.5 Load and store flags"), Load and store flagsstruct *convert-flag*; // *exposition only*struct *aligned-flag*; // *exposition only*template struct *overaligned-flag*; // *exposition only* #### [29.10.2.1](#defn) Exposition-only helpers [[simd.expos.defn]](simd.expos.defn) [🔗](#defn-itemdecl:1) `using simd-size-type = see below; ` [1](#defn-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16280) *simd-size-type* is an alias for a signed integer type[.](#defn-1.sentence-1) [🔗](#defn-itemdecl:2) `template using integer-from = see below; ` [2](#defn-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16289) *integer-from* is an alias for a signed integer typeT such that sizeof(T) equals Bytes[.](#defn-2.sentence-1) [🔗](#defn-itemdecl:3) `template constexpr simd-size-type simd-size-v = see below; ` [3](#defn-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16300) *simd-size-v* denotes the width of basic_vec if the specialization basic_vec is enabled, or 0 otherwise[.](#defn-3.sentence-1) [🔗](#defn-itemdecl:4) `template constexpr size_t mask-element-size = see below; ` [4](#defn-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16311) *mask-element-size*> has the valueBytes[.](#defn-4.sentence-1) [🔗](#defn-itemdecl:5) `template using deduced-vec-t = see below; ` [5](#defn-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16321) Let x denote an lvalue of type const T[.](#defn-5.sentence-1) [6](#defn-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16324) *deduced-vec-t* is an alias for - [(6.1)](#defn-6.1) decltype(x + x), if the type of x + x is an enabled specialization of basic_vec; otherwise - [(6.2)](#defn-6.2) void[.](#defn-6.sentence-1) [🔗](#defn-itemdecl:6) `template using make-compatible-simd-t = see below; ` [7](#defn-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16340) Let x denote an lvalue of type const T[.](#defn-7.sentence-1) [8](#defn-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16343) *make-compatible-simd-t* is an alias for - [(8.1)](#defn-8.1) *deduced-vec-t*, if that type is not void, otherwise - [(8.2)](#defn-8.2) vec[.](#defn-8.sentence-1) [🔗](#defn-itemdecl:7) `template requires [math-floating-point](#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") using math-common-simd-t = see below; ` [9](#defn-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16361) Let T0 denote Ts...[0][.](#defn-9.sentence-1) Let T1 denote Ts...[1][.](#defn-9.sentence-2) Let TRest denote a pack such that T0, T1, TRest... is equivalent to Ts...[.](#defn-9.sentence-3) [10](#defn-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16367) Let *math-common-simd-t* be an alias for - [(10.1)](#defn-10.1) *deduced-vec-t*, if sizeof...(Ts) equals 1; otherwise - [(10.2)](#defn-10.2) common_type_t<*deduced-vec-t*, *deduced-vec-t*>, if sizeof...(Ts) equals 2 and [*math-floating-point*](#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") &&[*math-floating-point*](#concept:math-floating-point "29.10.2 Exposition-only types, variables, and concepts [simd.expos]") is true; otherwise - [(10.3)](#defn-10.3) common_type_t<*deduced-vec-t*, T1>, if sizeof...(Ts) equals 2 and *math-floating-​point*<​T0> is true; otherwise - [(10.4)](#defn-10.4) common_type_t>, if sizeof...(Ts) equals 2; otherwise - [(10.5)](#defn-10.5) common_type_t<*math-common-simd-t*, TRest...>, if *math-common-simd-t* is valid and denotes a type; otherwise - [(10.6)](#defn-10.6) common_type_t<*math-common-simd-t*, T0, T1>[.](#defn-10.sentence-1) [🔗](#concept:reduction-binary-operation) `template concept [reduction-binary-operation](#concept:reduction-binary-operation "29.10.2.1 Exposition-only helpers [simd.expos.defn]") = requires (const BinaryOperation binary_op, const vec v) { { binary_op(v, v) } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")>; }; ` [11](#defn-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16404) Types BinaryOperation and T model[*reduction-binary-operation*](#concept:reduction-binary-operation "29.10.2.1 Exposition-only helpers [simd.expos.defn]") only if: - [(11.1)](#defn-11.1) BinaryOperation is a binary element-wise operation and the operation is commutative[.](#defn-11.1.sentence-1) - [(11.2)](#defn-11.2) An object of type BinaryOperation can be invoked with two arguments of type basic_vec, with unspecified ABI tagAbi, returning a basic_vec[.](#defn-11.2.sentence-1) #### [29.10.2.2](#abi) simd ABI tags [[simd.expos.abi]](simd.expos.abi) [🔗](#abi-itemdecl:1) `template using native-abi = see below; template using deduce-abi-t = see below; ` [1](#abi-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16425) An [*ABI tag*](#def:ABI_tag "29.10.2.2 simd ABI tags [simd.expos.abi]") is a type that indicates a choice of size and binary representation for objects of data-parallel type[.](#abi-1.sentence-1) [*Note [1](#abi-note-1)*: The intent is for the size and binary representation to depend on the target architecture and compiler flags[.](#abi-1.sentence-2) The ABI tag, together with a given element type, implies the width[.](#abi-1.sentence-3) — *end note*] [2](#abi-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16434) [*Note [2](#abi-note-2)*: The ABI tag is orthogonal to selecting the machine instruction set[.](#abi-2.sentence-1) The selected machine instruction set limits the usable ABI tag types, though (see [[simd.overview]](simd.overview "29.10.7.1 Class template basic_­vec overview"))[.](#abi-2.sentence-2) The ABI tags enable users to safely pass objects of data-parallel type between translation unit boundaries (e.g., function calls or I/O)[.](#abi-2.sentence-3) — *end note*] [3](#abi-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16443) An implementation defines ABI tag types as necessary for the following aliases[.](#abi-3.sentence-1) [4](#abi-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16446) *deduce-abi-t* is defined if - [(4.1)](#abi-4.1) T is a vectorizable type, - [(4.2)](#abi-4.2) N is greater than zero, and - [(4.3)](#abi-4.3) N is not larger than an implementation-defined maximum[.](#abi-4.sentence-1) The implementation-defined maximum forN is not smaller than 64 and can differ depending on T[.](#abi-4.sentence-2) [5](#abi-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16456) Where present, *deduce-abi-t* names an ABI tag type such that - [(5.1)](#abi-5.1) *simd-size-v*> equals N, - [(5.2)](#abi-5.2) basic_vec> is enabled ([[simd.overview]](simd.overview "29.10.7.1 Class template basic_­vec overview")), and - [(5.3)](#abi-5.3) basic_mask, N>> is enabled[.](#abi-5.sentence-1) [6](#abi-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16469) *native-abi* is an implementation-defined alias for an ABI tag[.](#abi-6.sentence-1) basic_vec> is an enabled specialization[.](#abi-6.sentence-2) [*Note [3](#abi-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[.](#abi-6.sentence-3) For target architectures with ISA extensions, compiler flags can change the type of the *native-abi* alias[.](#abi-6.sentence-4) — *end note*] [*Example [1](#abi-example-1)*: Consider a target architecture supporting the ABI tags __simd128 and__simd256, where hardware support for __simd256 exists only for floating-point types[.](#abi-6.sentence-5) The implementation therefore defines *native-abi* as an alias for - [(6.1)](#abi-6.1) __simd256 if T is a floating-point type, and - [(6.2)](#abi-6.2) __simd128 otherwise[.](#abi-6.sentence-6) — *end example*]