Skip to content

Commit ebe7507

Browse files
committed
P2663R7 Interleaved complex values support in std::simd
1 parent 38d1808 commit ebe7507

File tree

2 files changed

+226
-11
lines changed

2 files changed

+226
-11
lines changed

source/numerics.tex

Lines changed: 225 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16056,12 +16056,17 @@
1605616056
\end{note}
1605716057

1605816058
\pnum
16059-
The set of \defnadjx{vectorizable}{types}{type} comprises all standard integer
16060-
types, character types, and the types \tcode{float} and
16061-
\tcode{double}\iref{basic.fundamental}.
16062-
In addition, \tcode{std::float16_t}, \tcode{std::float32_t}, and
16063-
\tcode{std::float64_t} are vectorizable types if
16064-
defined\iref{basic.extended.fp}.
16059+
The set of \defnadjx{vectorizable}{types}{type} comprises
16060+
\begin{itemize}
16061+
\item
16062+
all standard integer types, character types, and the types \tcode{float} and
16063+
\tcode{double}\iref{basic.fundamental};
16064+
\item
16065+
\tcode{std::float16_t}, \tcode{std::float32_t}, and \tcode{std::float64_t}
16066+
if defined\iref{basic.extended.fp}; and
16067+
\item
16068+
\tcode{complex<T>} where \tcode{T} is a vectorizable floating-point type.
16069+
\end{itemize}
1606516070

1606616071
\pnum
1606716072
The term \defnadj{data-parallel}{type} refers to all enabled specializations of
@@ -16130,8 +16135,14 @@
1613016135

1613116136
template<class V>
1613216137
concept @\defexposconceptnc{simd-floating-point}@ = // \expos
16133-
@\libconcept{same_as}@<V, basic_simd<typename V::value_type, typename V::abi_type>> &&
16134-
is_default_constructible_v<V> && @\libconcept{floating_point}@<typename V::value_type>;
16138+
@\exposconcept{simd-type}@<V> && @\libconcept{floating_point}@<typename V::value_type>;
16139+
16140+
template<class V>
16141+
using @\exposidnc{simd-complex-value-type}@ = typename V::value_type::value_type; // \expos
16142+
16143+
template<class V>
16144+
concept @\defexposconceptnc{simd-complex}@ = // \expos
16145+
@\exposconcept{simd-type}@<V> && @\libconcept{same_as}@<typename V::value_type, complex<@\exposid{simd-complex-value-type}@<V>>>;
1613516146

1613616147
template<class... Ts>
1613716148
concept @\defexposconceptnc{math-floating-point}@ = // \expos
@@ -16778,6 +16789,47 @@
1677816789
template<@\exposconcept{simd-type}@ V>
1677916790
constexpr rebind_simd_t<make_signed_t<typename V::value_type>, V>
1678016791
popcount(const V& v) noexcept;
16792+
16793+
// \ref{simd.complex.math}, simd complex math
16794+
template<@\exposconcept{simd-complex}@ V>
16795+
constexpr rebind_simd_t<@\exposid{simd-complex-value-type<V>}@, V> real(const V&) noexcept;
16796+
16797+
template<@\exposconcept{simd-complex}@ V>
16798+
constexpr rebind_simd_t<@\exposid{simd-complex-value-type<V>}@, V> imag(const V&) noexcept;
16799+
16800+
template<@\exposconcept{simd-complex}@ V>
16801+
constexpr rebind_simd_t<@\exposid{simd-complex-value-type<V>}@, V> abs(const V&);
16802+
16803+
template<@\exposconcept{simd-complex}@ V>
16804+
constexpr rebind_simd_t<@\exposid{simd-complex-value-type<V>}@, V> arg(const V&);
16805+
16806+
template<@\exposconcept{simd-complex}@ V>
16807+
constexpr rebind_simd_t<@\exposid{simd-complex-value-type<V>}@, V> norm(const V&);
16808+
16809+
template<@\exposconcept{simd-complex}@ V> constexpr V conj(const V&);
16810+
template<@\exposconcept{simd-complex}@ V> constexpr V proj(const V&);
16811+
template<@\exposconcept{simd-complex}@ V> constexpr V exp(const V& v);
16812+
template<@\exposconcept{simd-complex}@ V> constexpr V log(const V& v);
16813+
template<@\exposconcept{simd-complex}@ V> constexpr V log10(const V& v);
16814+
16815+
template<@\exposconcept{simd-complex}@ V> constexpr V sqrt(const V& v);
16816+
template<@\exposconcept{simd-complex}@ V> constexpr V sin(const V& v);
16817+
template<@\exposconcept{simd-complex}@ V> constexpr V asin(const V& v);
16818+
template<@\exposconcept{simd-complex}@ V> constexpr V cos(const V& v);
16819+
template<@\exposconcept{simd-complex}@ V> constexpr V acos(const V& v);
16820+
template<@\exposconcept{simd-complex}@ V> constexpr V tan(const V& v);
16821+
template<@\exposconcept{simd-complex}@ V> constexpr V atan(const V& v);
16822+
template<@\exposconcept{simd-complex}@ V> constexpr V sinh(const V& v);
16823+
template<@\exposconcept{simd-complex}@ V> constexpr V asinh(const V& v);
16824+
template<@\exposconcept{simd-complex}@ V> constexpr V cosh(const V& v);
16825+
template<@\exposconcept{simd-complex}@ V> constexpr V acosh(const V& v);
16826+
template<@\exposconcept{simd-complex}@ V> constexpr V tanh(const V& v);
16827+
template<@\exposconcept{simd-complex}@ V> constexpr V atanh(const V& v);
16828+
16829+
template<@\exposconcept{simd-floating-point}@ V>
16830+
rebind_simd_t<complex<typename V::value_type>, V> polar(const V& x, const V& y = {});
16831+
16832+
template<@\exposconcept{simd-complex}@ V> constexpr V pow(const V& x, const V& y);
1678116833
}
1678216834
\end{codeblock}
1678316835

@@ -16951,6 +17003,8 @@
1695117003
constexpr basic_simd(R&& range, simd_flags<Flags...> = {});
1695217004
template<class R, class... Flags>
1695317005
constexpr basic_simd(R&& range, const mask_type& mask, simd_flags<Flags...> = {});
17006+
template<@\exposid{simd-floating-point}@ V>
17007+
constexpr explicit(@\seebelow@) basic_simd(const V& reals, const V& imags = {}) noexcept;
1695417008

1695517009
// \ref{simd.subscr}, \tcode{basic_simd} subscript operators
1695617010
constexpr value_type operator[](@\exposid{simd-size-type}@) const;
@@ -17001,6 +17055,14 @@
1700117055
friend constexpr mask_type operator>(const basic_simd&, const basic_simd&) noexcept;
1700217056
friend constexpr mask_type operator<(const basic_simd&, const basic_simd&) noexcept;
1700317057

17058+
// \ref{simd.complex.access}, \tcode{basic_simd} complex-value accessors
17059+
constexpr auto real() const noexcept;
17060+
constexpr auto imag() const noexcept;
17061+
template<@\exposid{simd-floating-point}@ V>
17062+
constexpr void real(const V& v) noexcept;
17063+
template<@\exposid{simd-floating-point}@ V>
17064+
constexpr void imag(const V& v) noexcept;
17065+
1700417066
// \ref{simd.cond}, \tcode{basic_simd} exposition only conditional operators
1700517067
friend constexpr basic_simd @\exposid{simd-select-impl}@( // \expos
1700617068
const mask_type&, const basic_simd&, const basic_simd&) noexcept;
@@ -17026,14 +17088,16 @@
1702617088
specializations} if such a specialization is enabled.
1702717089
\end{itemize}
1702817090

17029-
If \tcode{basic_simd<T, Abi>} is disabled, the specialization has a
17091+
If \tcode{basic_simd<T, Abi>} is disabled, then the specialization has a
1703017092
deleted default constructor, deleted destructor, deleted copy constructor, and
1703117093
deleted copy assignment.
1703217094
In addition only the \tcode{value_type}, \tcode{abi_type}, and
1703317095
\tcode{mask_type} members are present.
1703417096

17035-
If \tcode{basic_simd<T, Abi>} is enabled, \tcode{basic_simd<T, Abi>} is
17036-
trivially copyable.
17097+
If \tcode{basic_simd<T, Abi>} is enabled, then \tcode{basic_simd<T, Abi>} is
17098+
trivially copyable, default-initialization of an object of such a type
17099+
default-initializes all elements, and value-initialization value-initializes
17100+
all elements\iref{dcl.init.general}.
1703717101

1703817102
\pnum
1703917103
\recommended
@@ -17214,6 +17278,34 @@
1721417278
ranges::size(r)>}.
1721517279
\end{itemdescr}
1721617280

17281+
\begin{itemdecl}
17282+
template<@\exposconcept{simd-floating-point}@ V>
17283+
constexpr explicit(@\seebelow@)
17284+
basic_simd(const V& reals, const V& imags = {}) noexcept;
17285+
\end{itemdecl}
17286+
17287+
\begin{itemdescr}
17288+
\pnum
17289+
\constraints
17290+
\begin{itemize}
17291+
\item
17292+
\tcode{\exposconcept{simd-complex}<basic_simd>} is modeled, and
17293+
\item
17294+
\tcode{V::size() == size()} is \tcode{true}.
17295+
\end{itemize}
17296+
17297+
\pnum
17298+
\effects
17299+
Initializes the $i^\text{th}$ element with \tcode{value_type(reals[$i$],
17300+
imags[$i$])} for all $i$ in the range \range{0}{size()}.
17301+
17302+
\pnum
17303+
\remarks
17304+
The expression inside \tcode{explicit} evaluates to \tcode{false} if and only
17305+
if the floating-point conversion rank of \tcode{T::value_type} is greater than
17306+
or equal to the floating-point conversion rank of \tcode{V::value_type}.
17307+
\end{itemdescr}
17308+
1721717309
\rSec3[simd.subscr]{\tcode{basic_simd} subscript operator}
1721817310

1721917311
\begin{itemdecl}
@@ -17504,6 +17596,55 @@
1750417596
operation.
1750517597
\end{itemdescr}
1750617598

17599+
\rSec3[simd.complex.access]{\tcode{simd} complex accessors}
17600+
17601+
\begin{itemdecl}
17602+
constexpr auto real() const noexcept;
17603+
constexpr auto imag() const noexcept;
17604+
\end{itemdecl}
17605+
17606+
\begin{itemdescr}
17607+
\pnum
17608+
\constraints
17609+
\tcode{\exposconcept{simd-complex}<basic_simd>} is modeled.
17610+
17611+
\pnum
17612+
\returns
17613+
An object of type \tcode{rebind_simd_t<typename T::value_type, basic_simd>}
17614+
where the $i^\text{th}$ element is initialized to the result of
17615+
\tcode{\placeholder{cmplx-func}(operator[]($i$))} for all $i$ in the range
17616+
\range{0}{size()}, where \placeholder{cmplx-func} is the corresponding function
17617+
from \tcode{<complex>}.
17618+
\end{itemdescr}
17619+
17620+
\begin{itemdecl}
17621+
template<@\exposconcept{simd-floating-point}@ V>
17622+
constexpr void real(const V& v) noexcept;
17623+
template<@\exposconcept{simd-floating-point}@ V>
17624+
constexpr void imag(const V& v) noexcept;
17625+
\end{itemdecl}
17626+
17627+
\begin{itemdescr}
17628+
\pnum
17629+
\constraints
17630+
\begin{itemize}
17631+
\item
17632+
\tcode{\exposconcept{simd-complex}<basic_simd>} is modeled,
17633+
\item
17634+
\tcode{\libconcept{same_as}<typename V::value_type, typename T::value_type>}
17635+
is modeled, and
17636+
\item
17637+
\tcode{V::size() == size()} is \tcode{true}.
17638+
\end{itemize}
17639+
17640+
\pnum
17641+
\effects
17642+
Replaces each element of the \tcode{basic_simd} object such that the
17643+
$i^\text{th}$ element is replaced with \tcode{value_type(v[$i$],
17644+
operator[]($i$).imag())} or \tcode{value_type(operator[]($i$).real(), v[$i$])}
17645+
for \tcode{real} and \tcode{imag} respectively, for all $i$ in the range \range{0}{size()}.
17646+
\end{itemdescr}
17647+
1750717648
\rSec3[simd.cond]{\tcode{basic_simd} exposition only conditional operators}
1750817649

1750917650
\begin{itemdecl}
@@ -18638,6 +18779,79 @@
1863818779
function from \tcode{<bit>}.
1863918780
\end{itemdescr}
1864018781

18782+
\rSec3[simd.complex.math]{\tcode{simd} complex math}
18783+
18784+
\begin{itemdecl}
18785+
template<@\exposconcept{simd-complex}@ V>
18786+
constexpr rebind_simd_t<@\exposid{simd-complex-value-type<V>}@, V> real(const V&) noexcept;
18787+
template<@\exposconcept{simd-complex}@ V>
18788+
constexpr rebind_simd_t<@\exposid{simd-complex-value-type<V>}@, V> imag(const V&) noexcept;
18789+
18790+
template<@\exposconcept{simd-complex}@ V>
18791+
constexpr rebind_simd_t<@\exposid{simd-complex-value-type<V>}@, V> abs(const V&);
18792+
template<@\exposconcept{simd-complex}@ V>
18793+
constexpr rebind_simd_t<@\exposid{simd-complex-value-type<V>}@, V> arg(const V&);
18794+
template<@\exposconcept{simd-complex}@ V>
18795+
constexpr rebind_simd_t<@\exposid{simd-complex-value-type<V>}@, V> norm(const V&);
18796+
template<@\exposconcept{simd-complex}@ V> constexpr V conj(const V&);
18797+
template<@\exposconcept{simd-complex}@ V> constexpr V proj(const V&);
18798+
18799+
template<@\exposconcept{simd-complex}@ V> constexpr V exp(const V& v);
18800+
template<@\exposconcept{simd-complex}@ V> constexpr V log(const V& v);
18801+
template<@\exposconcept{simd-complex}@ V> constexpr V log10(const V& v);
18802+
18803+
template<@\exposconcept{simd-complex}@ V> constexpr V sqrt(const V& v);
18804+
template<@\exposconcept{simd-complex}@ V> constexpr V sin(const V& v);
18805+
template<@\exposconcept{simd-complex}@ V> constexpr V asin(const V& v);
18806+
template<@\exposconcept{simd-complex}@ V> constexpr V cos(const V& v);
18807+
template<@\exposconcept{simd-complex}@ V> constexpr V acos(const V& v);
18808+
template<@\exposconcept{simd-complex}@ V> constexpr V tan(const V& v);
18809+
template<@\exposconcept{simd-complex}@ V> constexpr V atan(const V& v);
18810+
template<@\exposconcept{simd-complex}@ V> constexpr V sinh(const V& v);
18811+
template<@\exposconcept{simd-complex}@ V> constexpr V asinh(const V& v);
18812+
template<@\exposconcept{simd-complex}@ V> constexpr V cosh(const V& v);
18813+
template<@\exposconcept{simd-complex}@ V> constexpr V acosh(const V& v);
18814+
template<@\exposconcept{simd-complex}@ V> constexpr V tanh(const V& v);
18815+
template<@\exposconcept{simd-complex}@ V> constexpr V atanh(const V& v);
18816+
\end{itemdecl}
18817+
18818+
\begin{itemdescr}
18819+
\pnum
18820+
\returns
18821+
A \tcode{basic_simd} object \tcode{ret} where the $i^\text{th}$ element is
18822+
initialized to the result of \tcode{\placeholder{cmplx-func}(v[$i$])} for all
18823+
$i$ in the range \range{0}{V::size()}, where \placeholder{cmplx-func} is the
18824+
corresponding function from \tcode{<complex>}. If in an invocation of
18825+
\placeholder{cmplx-func} for index $i$ a domain, pole, or range error would
18826+
occur, the value of \tcode{ret[$i$]} is unspecified.
18827+
18828+
\pnum
18829+
\remarks
18830+
It is unspecified whether \tcode{errno}\iref{errno} is accessed.
18831+
\end{itemdescr}
18832+
18833+
\begin{itemdecl}
18834+
template<@\exposconcept{simd-floating-point}@ V>
18835+
rebind_simd_t<complex<typename V::value_type>, V> polar(const V& x, const V& y = {});
18836+
18837+
template<@\exposconcept{simd-complex}@ V> constexpr V pow(const V& x, const V& y);
18838+
\end{itemdecl}
18839+
18840+
\begin{itemdescr}
18841+
\pnum
18842+
\returns
18843+
A \tcode{basic_simd} object \tcode{ret} where the $i^\text{th}$ element is
18844+
initialized to the result of \tcode{\placeholder{cmplx-func}(x[$i$], y[$i$])}
18845+
for all $i$ in the range \range{0}{V::size()}, where \placeholder{cmplx-func}
18846+
is the corresponding function from \tcode{<complex>}. If in an invocation of
18847+
\placeholder{cmplx-func} for index $i$ a domain, pole, or range error would
18848+
occur, the value of \tcode{ret[$i$]} is unspecified.
18849+
18850+
\pnum
18851+
\remarks
18852+
It is unspecified whether \tcode{errno}\iref{errno} is accessed.
18853+
\end{itemdescr}
18854+
1864118855
\rSec2[simd.mask.class]{Class template \tcode{basic_simd_mask}}
1864218856

1864318857
\rSec3[simd.mask.overview]{Class template \tcode{basic_simd_mask} overview}

source/support.tex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,7 @@
783783
#define @\defnlibxname{cpp_lib_shared_timed_mutex}@ 201402L // also in \libheader{shared_mutex}
784784
#define @\defnlibxname{cpp_lib_shift}@ 202202L // also in \libheader{algorithm}
785785
#define @\defnlibxname{cpp_lib_simd}@ 202502L // also in \libheader{simd}
786+
#define @\defnlibxname{cpp_lib_simd_complex}@ 202502L // also in \libheader{simd}
786787
#define @\defnlibxname{cpp_lib_smart_ptr_for_overwrite}@ 202002L // also in \libheader{memory}
787788
#define @\defnlibxname{cpp_lib_smart_ptr_owner_equality}@ 202306L // also in \libheader{memory}
788789
#define @\defnlibxname{cpp_lib_source_location}@ 201907L // freestanding, also in \libheader{source_location}

0 commit comments

Comments
 (0)