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

321 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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<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<class T> constexpr size_t *mask-element-size* = *see below*; // *exposition only*template<class T>concept [*constexpr-wrapper-like*](#concept:constexpr-wrapper-like "29.10.2Exposition-only types, variables, and concepts[simd.expos]") = // *exposition only*[convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<T, decltype(T::value)> &&[equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<T, decltype(T::value)> && bool_constant<T() == T::value>::value && bool_constant<static_cast<decltype(T::value)>(T()) == T::value>::value;
template<class T> using *deduced-vec-t* = *see below*; // *exposition only*template<class V, class T> using *make-compatible-simd-t* = *see below*; // *exposition only*template<class V>concept [*simd-vec-type*](#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") = // *exposition only*[same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<V, basic_vec<typename V::value_type, typename V::abi_type>> && is_default_constructible_v<V>;
template<class V>concept [*simd-mask-type*](#concept:simd-mask-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]") = // *exposition only*[same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<V, basic_mask<*mask-element-size*<V>, typename V::abi_type>> && is_default_constructible_v<V>;
template<class V>concept [*simd-floating-point*](#concept:simd-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") = // *exposition only*[*simd-vec-type*](#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]")<V> && [floating_point](concepts.arithmetic#concept:floating_point "18.4.7Arithmetic concepts[concepts.arithmetic]")<typename V::value_type>;
template<class V>concept [*simd-integral*](#concept:simd-integral "29.10.2Exposition-only types, variables, and concepts[simd.expos]") = // *exposition only*[*simd-vec-type*](#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]")<V> && [integral](concepts.arithmetic#concept:integral "18.4.7Arithmetic concepts[concepts.arithmetic]")<typename V::value_type>;
template<class V>using *simd-complex-value-type* = typename V::value_type::value_type; // *exposition only*template<class V>concept [*simd-complex*](#concept:simd-complex "29.10.2Exposition-only types, variables, and concepts[simd.expos]") = // *exposition only*[*simd-vec-type*](#concept:simd-vec-type "29.10.2Exposition-only types, variables, and concepts[simd.expos]")<V> && [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<typename V::value_type, complex<*simd-complex-value-type*<V>>>;
template<class... Ts>concept [*math-floating-point*](#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]") = // *exposition only*([*simd-floating-point*](#concept:simd-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]")<*deduced-vec-t*<Ts>> || ...);
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*; // *exposition only*template<class BinaryOperation, class T>concept [*reduction-binary-operation*](#concept:reduction-binary-operation "29.10.2.1Exposition-only helpers[simd.expos.defn]") = *see below*; // *exposition only*// [[simd.expos.abi]](#abi "29.10.2.2simd ABI tags"), simd ABI tagstemplate<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]](simd.flags "29.10.5Load and store flags"), Load and store flagsstruct *convert-flag*; // *exposition only*struct *aligned-flag*; // *exposition only*template<size_t N> 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<size_t Bytes> using integer-from = see below;
`
[2](#defn-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16289)
*integer-from*<Bytes> is an alias for a signed integer typeT such that sizeof(T) equals Bytes[.](#defn-2.sentence-1)
[🔗](#defn-itemdecl:3)
`template<class T, class Abi>
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*<T, Abi> denotes the width of basic_vec<T,
Abi> if the specialization basic_vec<T, Abi> is enabled, or 0 otherwise[.](#defn-3.sentence-1)
[🔗](#defn-itemdecl:4)
`template<class T> 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*<basic_mask<Bytes, Abi>> has the valueBytes[.](#defn-4.sentence-1)
[🔗](#defn-itemdecl:5)
`template<class T> 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*<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<class V, class T> 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*<V, T> is an alias for
- [(8.1)](#defn-8.1)
*deduced-vec-t*<T>, if that type is not void,
otherwise
- [(8.2)](#defn-8.2)
vec<decltype(x + x), V::size()>[.](#defn-8.sentence-1)
[🔗](#defn-itemdecl:7)
`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](#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*<Ts...> be an alias for
- [(10.1)](#defn-10.1)
*deduced-vec-t*<T0>, if sizeof...(Ts) equals 1;
otherwise
- [(10.2)](#defn-10.2)
common_type_t<*deduced-vec-t*<T0>, *deduced-vec-t*<T1>>, if sizeof...(Ts) equals 2 and [*math-floating-point*](#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]")<T0> &&[*math-floating-point*](#concept:math-floating-point "29.10.2Exposition-only types, variables, and concepts[simd.expos]")<T1> is true; otherwise
- [(10.3)](#defn-10.3)
common_type_t<*deduced-vec-t*<T0>, T1>, if sizeof...(Ts) equals 2 and *math-floating-point*<T0> is true; otherwise
- [(10.4)](#defn-10.4)
common_type_t<T0, *deduced-vec-t*<T1>>, if sizeof...(Ts) equals 2; otherwise
- [(10.5)](#defn-10.5)
common_type_t<*math-common-simd-t*<T0, T1>, TRest...>, if *math-common-simd-t*<T0, T1> is valid and denotes a type;
otherwise
- [(10.6)](#defn-10.6)
common_type_t<*math-common-simd-t*<TRest...>, T0, T1>[.](#defn-10.sentence-1)
[🔗](#concept:reduction-binary-operation)
`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](#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.1Exposition-only helpers[simd.expos.defn]")<BinaryOperation, T> 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<T, Abi>, with unspecified ABI tagAbi, returning a basic_vec<T, Abi>[.](#defn-11.2.sentence-1)
#### [29.10.2.2](#abi) simd ABI tags [[simd.expos.abi]](simd.expos.abi)
[🔗](#abi-itemdecl:1)
`template<class T> using native-abi = see below;
template<class T, simd-size-type N> 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.2simd 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.1Class 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*<T, N> 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*<T, N> names an ABI tag type such
that
- [(5.1)](#abi-5.1)
*simd-size-v*<T, *deduce-abi-t*<T, N>> equals N,
- [(5.2)](#abi-5.2)
basic_vec<T, *deduce-abi-t*<T, N>> is
enabled ([[simd.overview]](simd.overview "29.10.7.1Class template basic_­vec overview")), and
- [(5.3)](#abi-5.3)
basic_mask<sizeof(T), *deduce-abi-t*<*integer-from*<sizeof(T)>, N>> is enabled[.](#abi-5.sentence-1)
[6](#abi-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/numerics.tex#L16469)
*native-abi*<T> is an implementation-defined alias for an ABI tag[.](#abi-6.sentence-1)
basic_vec<T, *native-abi*<T>> 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*<T> 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*<T> 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*]