From 261c6389254d61642f8738009299e3d02132f12c Mon Sep 17 00:00:00 2001 From: Jefferson Le Quellec Date: Mon, 6 Nov 2023 15:38:54 +0100 Subject: [PATCH 1/5] Expand complex extension with complex support for sycl::marray --- .../sycl_ext_oneapi_complex.asciidoc | 259 +++++++++++++++++- 1 file changed, 247 insertions(+), 12 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc index d17e5b3576273..48a9ea3f3a563 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc @@ -54,10 +54,20 @@ specification.* While {dpcpp} has support for `std::complex` in device code, it limits the complex interface and operations to the existing C++ standard. This proposal defines a SYCL complex extension based on but independent of the `std::complex` -interface. This framework would allow for further development of complex math -within oneAPI. Possible areas for deviation with `std::complex` include adding -complex support for `marray` and `vec` and overloading mathematical -functions to handle the element-wise operations. +interface. + +The proposed framework not only encompasses complex support for traditional use +cases but also accommodate for advanced mathematical features and data +structures. + +Specifically, we propose to incorporate complex support for `sycl::marray`. +This addition will empower developers to store complex numbers seamlessly +within arrays, opening up new possibilities for data manipulation and +computation. + +Furthermore, this extension involves overloading existing mathematical +functions to facilitate scalar operation on complex numbers as well as +element-wise operations on complex marrays. == Specification @@ -211,17 +221,125 @@ namespace sycl::ext::oneapi::experimental { } // namespace sycl::ext::oneapi::experimental ``` -=== Mathematical operations +=== Marray Complex Class Specialization + +This proposal also introduces the specialization of the marray class to +support SYCL complex. The marray class undergoes slight modification for this +specialization, primarily involving the removal of operators that are +inapplicable. No new functions or operators are introduced to the marray class. + +The marray complex specialization maintains the principles of trivial +copyability (as seen in the Complex class description), with the +`is_device_copyable` type trait resolving to `std::true_type`. + +The marray definition used within this proposal assumes that any operator the +`sycl::marray` class defines is only implemented if the marray's value type +also implements the operator. + +For instance, +`sycl::marray, NumElements>` does +not implement the modulus operator since +`sycl::ext::oneapi::experimental::complex` does not support it. + +```C++ +namespace sycl { + +// Specialization of exiting `marray` class for `sycl::ext::oneapi::experimental::complex` +template +class marray, NumElements> { +public: + + /* ... */ + + friend marray operator %(const marray &lhs, const marray &rhs) = delete; + friend marray operator %(const marray &lhs, const value_type &rhs) = delete; + friend marray operator %(const value_type &lhs, const marray &rhs) = delete; + + friend marray &operator %=(marray &lhs, const marray &rhs) = delete; + friend marray &operator %=(marray &lhs, const value_type &rhs) = delete; + friend marray &operator %=(value_type &lhs, const marray &rhs) = delete; + + friend marray operator ++(marray &lhs, int) = delete; + friend marray &operator ++(marray & rhs) = delete; + + friend marray operator --(marray &lhs, int) = delete; + friend marray &operator --(marray & rhs) = delete; + + friend marray operator &(const marray &lhs, const marray &rhs) = delete; + friend marray operator &(const marray &lhs, const value_type &rhs) = delete; + + friend marray operator |(const marray &lhs, const marray &rhs) = delete; + friend marray operator |(const marray &lhs, const value_type &rhs) = delete; + + friend marray operator ^(const marray &lhs, const marray &rhs) = delete; + friend marray operator ^(const marray &lhs, const value_type &rhs) = delete; + + friend marray &operator &=(marray & lhs, const marray & rhs) = delete; + friend marray &operator &=(marray & lhs, const value_type & rhs) = delete; + friend marray &operator &=(value_type & lhs, const marray & rhs) = delete; + + friend marray &operator |=(marray & lhs, const marray & rhs) = delete; + friend marray &operator |=(marray & lhs, const value_type & rhs) = delete; + friend marray &operator |=(value_type & lhs, const marray & rhs) = delete; + + friend marray &operator ^=(marray & lhs, const marray & rhs) = delete; + friend marray &operator ^=(marray & lhs, const value_type & rhs) = delete; + friend marray &operator ^=(value_type & lhs, const marray & rhs) = delete; + + friend marray operator <<(const marray & lhs, const marray & rhs) = delete; + friend marray operator <<(const marray & lhs, const value_type & rhs) = delete; + friend marray operator <<(const value_type & lhs, const marray & rhs) = delete; + + friend marray operator >>(const marray & lhs, const marray & rhs) = delete; + friend marray operator >>(const marray & lhs, const value_type & rhs) = delete; + friend marray operator >>(const value_type & lhs, const marray & rhs) = delete; + + friend marray &operator <<=(marray & lhs, const marray & rhs) = delete; + friend marray &operator <<=(marray & lhs, const value_type & rhs) = delete; + + friend marray &operator >>=(marray & lhs, const marray & rhs) = delete; + friend marray &operator >>=(marray & lhs, const value_type & rhs) = delete; -This proposal adds to the `sycl::ext::oneapi::experimental` namespace, math -functions accepting the complex types `complex`, `complex`, -`complex` as well as the scalar types `sycl::half`, `float` and `double` -for the SYCL math functions, `abs`, `acos`, `asin`, `atan`, `acosh`, `asinh`, -`atanh`, `arg`, `conj`, `cos`, `cosh`, `exp`, `log`, `log10`, `norm`, `polar`, -`pow`, `proj`, `sin`, `sinh`, `sqrt`, `tan`, and `tanh`. + friend marray operator <(const marray & lhs, const marray & rhs) = delete; + friend marray operator <(const marray & lhs, const value_type & rhs) = delete; + friend marray operator <(const value_type & lhs, const marray & rhs) = delete; + + friend marray operator >(const marray & lhs, const marray & rhs) = delete; + friend marray operator >(const marray & lhs, const value_type & rhs) = delete; + friend marray operator >(const value_type & lhs, const marray & rhs) = delete; + + friend marray operator <=(const marray & lhs, const marray & rhs) = delete; + friend marray operator <=(const marray & lhs, const value_type & rhs) = delete; + friend marray operator <=(const value_type & lhs, const marray & rhs) = delete; + + friend marray operator >=(const marray & lhs, const marray & rhs) = delete; + friend marray operator >=(const marray & lhs, const value_type & rhs) = delete; + friend marray operator >=(const value_type & lhs, const marray & rhs) = delete; + + friend marray operator ~(const marray &v) = delete; + + friend marray operator !(const marray &v) = delete; +}; + +} // namespace sycl +``` + +=== Scalar Mathematical operations + +This proposal extends the `sycl::ext::oneapi::experimental` namespace math +functions to accept `complex`, `complex`, `complex` +as well as the scalar types `sycl::half`, `float` and `double` for a range of +SYCL math functions. + +Specifically, it adds support for `abs`, `acos`, `asin`, `atan`, `acosh`, +`asinh`, `atanh`, `arg`, `conj`, `cos`, `cosh`, `exp`, `log`, `log10`, `norm`, +`polar`, `pow`, `proj`, `sin`, `sinh`, `sqrt`, `tan`, and `tanh`. + +Additionally, this extension introduces support for the `real` and `imag` free +functions, which the real and imaginary component, respectively. These functions are available in both host and device code, and each math -function should follow the C++ standard for handling NaN's and Inf values. +function should follow the C++ standard for handling `NaN` and `Inf` values. Note: In the case of the `pow` function, additional overloads have been added to ensure that for their first argument `base` and second argument `exponent`: @@ -319,6 +437,123 @@ namespace sycl::ext::oneapi::experimental { } // namespace sycl::ext::oneapi::experimental ``` +=== Element-Wise Mathematical operations + +In harmony with the complex scalar operations, this proposal extends +furthermore the `sycl::ext::oneapi::experimental`` namespace math functions +to accept `sycl::marray>` for a range of SYCL math functions. + +Specifically, it adds support for `abs`, `acos`, `asin`, `atan`, `acosh`, +`asinh`, `atanh`, `arg`, `conj`, `cos`, `cosh`, `exp`, `log`, `log10`, `norm`, +`polar`, `pow`, `proj`, `sin`, `sinh`, `sqrt`, `tan`, and `tanh`. + +Additionally, this extension introduces support for the `real` and `imag` free +functions, which return marrays of scalar values representing the real and +imaginary components, respectively. + +In scenarios where mathematical functions involve both marray and scalar +parameters, two sets of overloads are introduced marray-scalar and +scalar-marray. + +These mathematical operations are designed to execute element-wise across the +marray, ensuring that each operation is applied to every element within the +marray. + +Moreover, this proposal includes overloads for mathematical functions between +marrays and scalar inputs. In these cases, the operations are executed across +the entire marray, with the scalar value held constant. + +For consistency, these functions are available in both host and device code, +and each math function should follow the C++ standard for handling `NaN` and +`Inf` values. + +```C++ +namespace sycl/ext/oneapi/experimental { + +/// VALUES: +/// Returns an marray of real components from the marray x. +template +sycl::marray real(const marray, NumElements> &x); +/// Returns an marray of imaginary components from the marray x. +template +sycl::marray imag(const marray, NumElements> &x); + +/// Compute the magnitude for each complex number in marray x. +template marray abs(const marray, NumElements> &x); +/// Compute phase angle in radians for each complex number in marray x. +template marray arg(const marray, NumElements> &x); +/// Compute the squared magnitude for each complex number in marray x. +template marray norm(const marray, NumElements> &x); +/// Compute the conjugate for each complex number in marray x. +template marray, NumElements> conj(const marray, NumElements> &x); +/// Compute the projection for each complex number in marray x. +template marray, NumElements> proj(const marray, NumElements> &x); +/// Compute the projection for each real number in marray x. +template marray, NumElements> proj(const marray &x); +/// Construct an marray, elementwise, of complex numbers from each polar coordinate in marray rho and scalar theta. +template marray, NumElements> polar(const marray &rho, T theta = 0); +/// Construct an marray, elementwise, of complex numbers from each polar coordinate in marray rho and marray theta. +template marray, NumElements> polar(const marray &rho, const marray &theta); +/// Construct an marray, elementwise, of complex numbers from each polar coordinate in scalar rho and marray theta. +template marray, NumElements> polar(T rho, const marray &theta); + +/// TRANSCENDENTALS: +/// Compute the natural log for each complex number in marray x. +template marray, NumElements> log(const marray, NumElements> &x); +/// Compute the base-10 log for each complex number in marray x. +template marray, NumElements> log10(const marray, NumElements> &x); +/// Compute the square root for each complex number in marray x. +template marray, NumElements> sqrt(const marray, NumElements> &x); +/// Compute the base-e exponent for each complex number in marray x. +template marray, NumElements> exp(const marray, NumElements> &x); + +/// Raise each complex element in x to the power of the corresponding decimal element in y. +template marray, NumElements> pow(const marray, NumElements> &x, const marray &y); +/// Raise each complex element in x to the power of the decimal number y. +template marray, NumElements> pow(const marray, NumElements> &x, T y); +/// Raise complex number x to the power of each decimal element in y. +template marray, NumElements> pow(const marray, NumElements> &x, const marray &y); +/// Raise each complex element in x to the power of the corresponding complex element in y. +template marray, NumElements> pow(const marray, NumElements> &x, const marray, NumElements> &y); +/// Raise each complex element in x to the power of the complex number y. +template marray, NumElements> pow(const marray, NumElements> &x, const marray, NumElements> &y); +/// Raise complex number x to the power of each complex element in y. +template marray, NumElements> pow(const marray, NumElements> &x, const marray, NumElements> &y); +/// Raise each decimal element in x to the power of the corresponding complex element in y. +template marray, NumElements> pow(const marray &x, const marray, NumElements> &y); +/// Raise each decimal element in x to the power of the complex number y. +template marray, NumElements> pow(const marray &x, const marray, NumElements> &y); +/// Raise decimal number x to the power of each complex element in y. +template marray, NumElements> pow(T x, const marray, NumElements> &y); + +/// Compute the inverse hyperbolic sine for each complex number in marray x. +template marray, NumElements> asinh(const marray, NumElements> &x); +/// Compute the inverse hyperbolic cosine for each complex number in marray x. +template marray, NumElements> acosh(const marray, NumElements> &x); +/// Compute the inverse hyperbolic tangent for each complex number in marray x. +template marray, NumElements> atanh(const marray, NumElements> &x); +/// Compute the hyperbolic sine for each complex number in marray x. +template marray, NumElements> sinh(const marray, NumElements> &x); +/// Compute the hyperbolic cosine for each complex number in marray x. +template marray, NumElements> cosh(const marray, NumElements> &x); +/// Compute the hyperbolic tangent for each complex number in marray x. +template marray, NumElements> tanh(const marray, NumElements> &x); +/// Compute the inverse sine for each complex number in marray x. +template marray, NumElements> asin(const marray, NumElements> &x); +/// Compute the inverse cosine for each complex number in marray x. +template marray, NumElements> acos(const marray, NumElements> &x); +/// Compute the inverse tangent for each complex number in marray x. +template marray, NumElements> atan(const marray, NumElements> &x); +/// Compute the sine for each complex number in marray x. +template marray, NumElements> sin(const marray, NumElements> &x); +/// Compute the cosine for each complex number in marray x. +template marray, NumElements> cos(const marray, NumElements> &x); +/// Compute the tangent for each complex number in marray x. +template marray, NumElements> tan(const marray, NumElements> &x); + +} // namespace sycl::ext::oneapi::experimental +``` + == Implementation notes The complex mathematical operations can all be defined using SYCL built-ins. From 7b132a91813dd1f8c2262b5d1d0f9535186f4b6c Mon Sep 17 00:00:00 2001 From: Jefferson Le Quellec Date: Thu, 11 Jan 2024 11:32:53 +0100 Subject: [PATCH 2/5] Add missing closing brace --- .../doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc index 48a9ea3f3a563..ceb460a9b4286 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc @@ -217,6 +217,7 @@ namespace sycl::ext::oneapi::experimental { template friend std::basic_ostream &operator<<(std::basic_ostream &os, const complex &); /// Streams the complex number z in the format "(real,imaginary)" into `sycl::stream` x and return the result. friend const sycl::stream &operator<<(const sycl::stream &x, const complex &z); + }; } // namespace sycl::ext::oneapi::experimental ``` From b17e53abc7169300f4b3f4e7236f47d2922f39c2 Mon Sep 17 00:00:00 2001 From: Jefferson Le Quellec Date: Thu, 11 Jan 2024 11:36:06 +0100 Subject: [PATCH 3/5] Format c++ code --- .../sycl_ext_oneapi_complex.asciidoc | 362 +++++++++--------- 1 file changed, 181 insertions(+), 181 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc index ceb460a9b4286..2f350dfd60989 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc @@ -111,113 +111,113 @@ the decimal and an imaginary component equal to 0. ```C++ namespace sycl::ext::oneapi::experimental { - template - class complex { - public: - using value_type = T; - - /// Constructs the complex number from real and imaginary parts. - constexpr complex(value_type __re = value_type(), value_type __im = value_type()); - - /// Converting constructor. Constructs the object from a complex number of a different type. - template - constexpr complex(const complex &); - - /// Converting constructor. Constructs the object from a std::complex number. - template - constexpr complex(const std::complex &); - - /// Constructs a std::complex number from a sycl::complex. - template - constexpr operator std::complex() const; - - /// Returns the real part. - constexpr value_type real() const; - /// Returns the imaginary part. - constexpr value_type imag() const; - - /// Sets the real part from value. - void real(value_type value); - /// Sets the imaginary part from value. - void imag(value_type value); - - /// Assigns x to the real part of the complex number. Imaginary part is set to zero. - complex &operator=(value_type x); - /// Adds and assigns real number y to complex number z. - friend complex &operator+=(complex &z, value_type y); - /// Subtracts and assigns real number y to complex number z. - friend complex &operator-=(complex &z, value_type y); - /// Multiplies and assigns real number y to complex number z. - friend complex &operator*=(complex &z, value_type y); - /// Divides and assigns real number y to complex number z. - friend complex &operator/=(complex &z, value_type y); - - /// Assigns cx.real() and cx.imag() to the real and the imaginary parts of the complex number respectively. - complex &operator=(const complex &cx); - /// Adds and assigns complex number w to complex number z. - template friend complex &operator+=(complex &z, const complex &w); - /// Subtracts and assigns complex number w to complex number z. - template friend complex &operator-=(complex &z, const complex &w); - /// Multiplies and assigns complex number w to complex number z. - template friend complex &operator*=(complex &z, const complex &w); - /// Divides and assigns complex number w to complex number z. - template friend complex &operator/=(complex &z, const complex &w); - - /// Adds complex numbers z and w and returns the value. - friend complex operator+(const complex &z, const complex &w); - /// Adds complex number z and real y and returns the value. - friend complex operator+(const complex &z, value_type y); - /// Adds real x and complex number w and returns the value. - friend complex operator+(value_type x, const complex &w); - /// Returns the value of its argument. - friend complex operator+(const complex &); - - /// Subtracts complex numbers z and w and returns the value. - friend complex operator-(const complex &z, const complex &w); - /// Subtracts complex number z and real y and returns the value. - friend complex operator-(const complex &z, value_type y); - /// Subtracts real x and complex number w and returns the value. - friend complex operator-(value_type x, const complex &w); - /// Negates the argument. - friend complex operator-(const complex &); - - /// Multiplies complex numbers z and w and returns the value. - friend complex operator*(const complex &z, const complex &w); - /// Multiplies complex number z and real y and returns the value. - friend complex operator*(const complex &z, value_type y); - /// Multiplies real x and complex number w and returns the value. - friend complex operator*(value_type x, const complex &w); - - /// Divides complex numbers z and w and returns the value. - friend complex operator/(const complex &z, const complex &w); - /// Divides complex number z and real y and returns the value. - friend complex operator/(const complex &z, value_type y); - /// Divides real x and complex number w and returns the value. - friend complex operator/(value_type x, const complex &w); - - /// Compares complex numbers z and w and returns true if they are the same, otherwise false. - friend constexpr bool operator==(const complex &z, const complex &w); - /// Compares complex number z and real y and returns true if they are the same, otherwise false. - friend constexpr bool operator==(const complex &z, value_type y); - /// Compares real x and complex number w and returns true if they are the same, otherwise false. - friend constexpr bool operator==(value_type x, const complex &w); - - /// Compares complex numbers z and w and returns true if they are different, otherwise false. - friend constexpr bool operator!=(const complex &z, const complex &w); - ///Compares complex number z and real y and returns true if they are different, otherwise false. - friend constexpr bool operator!=(const complex &z, value_type y); - /// Compares real x and complex number w and returns true if they are different, otherwise false. - friend constexpr bool operator!=(value_type x, const complex &w); - - /// Reads a complex number from is. - /// Not allowed in device code. - template friend std::basic_istream &operator>>(std::basic_istream &is, complex &); - /// Writes to os the complex number z in the form (real,imaginary). - /// Not allowed in device code. - template friend std::basic_ostream &operator<<(std::basic_ostream &os, const complex &); - /// Streams the complex number z in the format "(real,imaginary)" into `sycl::stream` x and return the result. - friend const sycl::stream &operator<<(const sycl::stream &x, const complex &z); - }; +template +class complex { +public: + using value_type = T; + + /// Constructs the complex number from real and imaginary parts. + constexpr complex(value_type __re = value_type(), value_type __im = value_type()); + + /// Converting constructor. Constructs the object from a complex number of a different type. + template + constexpr complex(const complex &); + + /// Converting constructor. Constructs the object from a std::complex number. + template + constexpr complex(const std::complex &); + + /// Constructs a std::complex number from a sycl::complex. + template + constexpr operator std::complex() const; + + /// Returns the real part. + constexpr value_type real() const; + /// Returns the imaginary part. + constexpr value_type imag() const; + + /// Sets the real part from value. + void real(value_type value); + /// Sets the imaginary part from value. + void imag(value_type value); + + /// Assigns x to the real part of the complex number. Imaginary part is set to zero. + complex &operator=(value_type x); + /// Adds and assigns real number y to complex number z. + friend complex &operator+=(complex &z, value_type y); + /// Subtracts and assigns real number y to complex number z. + friend complex &operator-=(complex &z, value_type y); + /// Multiplies and assigns real number y to complex number z. + friend complex &operator*=(complex &z, value_type y); + /// Divides and assigns real number y to complex number z. + friend complex &operator/=(complex &z, value_type y); + + /// Assigns cx.real() and cx.imag() to the real and the imaginary parts of the complex number respectively. + complex &operator=(const complex &cx); + /// Adds and assigns complex number w to complex number z. + template friend complex &operator+=(complex &z, const complex &w); + /// Subtracts and assigns complex number w to complex number z. + template friend complex &operator-=(complex &z, const complex &w); + /// Multiplies and assigns complex number w to complex number z. + template friend complex &operator*=(complex &z, const complex &w); + /// Divides and assigns complex number w to complex number z. + template friend complex &operator/=(complex &z, const complex &w); + + /// Adds complex numbers z and w and returns the value. + friend complex operator+(const complex &z, const complex &w); + /// Adds complex number z and real y and returns the value. + friend complex operator+(const complex &z, value_type y); + /// Adds real x and complex number w and returns the value. + friend complex operator+(value_type x, const complex &w); + /// Returns the value of its argument. + friend complex operator+(const complex &); + + /// Subtracts complex numbers z and w and returns the value. + friend complex operator-(const complex &z, const complex &w); + /// Subtracts complex number z and real y and returns the value. + friend complex operator-(const complex &z, value_type y); + /// Subtracts real x and complex number w and returns the value. + friend complex operator-(value_type x, const complex &w); + /// Negates the argument. + friend complex operator-(const complex &); + + /// Multiplies complex numbers z and w and returns the value. + friend complex operator*(const complex &z, const complex &w); + /// Multiplies complex number z and real y and returns the value. + friend complex operator*(const complex &z, value_type y); + /// Multiplies real x and complex number w and returns the value. + friend complex operator*(value_type x, const complex &w); + + /// Divides complex numbers z and w and returns the value. + friend complex operator/(const complex &z, const complex &w); + /// Divides complex number z and real y and returns the value. + friend complex operator/(const complex &z, value_type y); + /// Divides real x and complex number w and returns the value. + friend complex operator/(value_type x, const complex &w); + + /// Compares complex numbers z and w and returns true if they are the same, otherwise false. + friend constexpr bool operator==(const complex &z, const complex &w); + /// Compares complex number z and real y and returns true if they are the same, otherwise false. + friend constexpr bool operator==(const complex &z, value_type y); + /// Compares real x and complex number w and returns true if they are the same, otherwise false. + friend constexpr bool operator==(value_type x, const complex &w); + + /// Compares complex numbers z and w and returns true if they are different, otherwise false. + friend constexpr bool operator!=(const complex &z, const complex &w); + ///Compares complex number z and real y and returns true if they are different, otherwise false. + friend constexpr bool operator!=(const complex &z, value_type y); + /// Compares real x and complex number w and returns true if they are different, otherwise false. + friend constexpr bool operator!=(value_type x, const complex &w); + + /// Reads a complex number from is. + /// Not allowed in device code. + template friend std::basic_istream &operator>>(std::basic_istream &is, complex &); + /// Writes to os the complex number z in the form (real,imaginary). + /// Not allowed in device code. + template friend std::basic_ostream &operator<<(std::basic_ostream &os, const complex &); + /// Streams the complex number z in the format "(real,imaginary)" into `sycl::stream` x and return the result. + friend const sycl::stream &operator<<(const sycl::stream &x, const complex &z); +}; } // namespace sycl::ext::oneapi::experimental ``` @@ -360,80 +360,80 @@ to ensure that for their first argument `base` and second argument `exponent`: ```C++ namespace sycl::ext::oneapi::experimental { - /// VALUES: - /// Returns the real component of the complex number z. - template constexpr T real(const complex &); - /// Returns the real component of the number y, treated as complex numbers with zero imaginary component. - template constexpr T real(T); - /// Returns the imaginary component of the complex number z. - template constexpr T imag(const complex &); - /// Returns the imaginary component of the number y, treated as complex numbers with zero imaginary component. - template constexpr T imag(T); - - /// Compute the magnitude of complex number x. - template T abs(const complex &); - /// Compute phase angle in radians of complex number x. - template T arg(const complex &); - /// Compute phase angle in radians of complex number x, treated as complex number with positive zero imaginary component. - template T arg(T); - /// Compute the squared magnitude of complex number x. - template T norm(const complex &); - /// Compute the squared magnitude of number x, treated as complex number with positive zero imaginary component. - template T norm(T); - /// Compute the conjugate of complex number x. - template complex conj(const complex &); - /// Compute the conjugate of number y, treated as complex number with positive zero imaginary component. - template complex conj(T); - /// Compute the projection of complex number x. - template complex proj(const complex &); - /// Compute the projection of number y, treated as complex number with positive zero imaginary component. - template complex proj(T); - /// Construct a complex number from polar coordinates with mangitude rho and angle theta. - template complex polar(const T &rho, const T &theta = T()); - - /// TRANSCENDENTALS: - /// Compute the natural log of complex number x. - template complex log(const complex &); - /// Compute the base-10 log of complex number x. - template complex log10(const complex &); - /// Compute the square root of complex number x. - template complex sqrt(const complex &); - /// Compute the base-e exponent of complex number x. - template complex exp(const complex &); - - /// Compute complex number z raised to the power of complex number y. - template complex pow(const complex &, const complex &); - /// Compute complex number z raised to the power of complex number y. - template complex pow(const complex &, const complex &); - /// Compute complex number z raised to the power of real number y. - template complex pow(const complex &, const U &); - /// Compute real number x raised to the power of complex number y. - template complex pow(const T &, const complex &); - - /// Compute the inverse hyperbolic sine of complex number x. - template complex asinh(const complex &); - /// Compute the inverse hyperbolic cosine of complex number x. - template complex acosh(const complex &); - /// Compute the inverse hyperbolic tangent of complex number x. - template complex atanh(const complex &); - /// Compute the hyperbolic sine of complex number x. - template complex sinh(const complex &); - /// Compute the hyperbolic cosine of complex number x. - template complex cosh(const complex &); - /// Compute the hyperbolic tangent of complex number x. - template complex tanh(const complex &); - /// Compute the inverse sine of complex number x. - template complex asin(const complex &); - /// Compute the inverse cosine of complex number x. - template complex acos(const complex &); - /// Compute the inverse tangent of complex number x. - template complex atan(const complex &); - /// Compute the sine of complex number x. - template complex sin(const complex &); - /// Compute the cosine of complex number x. - template complex cos(const complex &); - // Compute the tangent of complex number x. - template complex tan(const complex &); +/// VALUES: +/// Returns the real component of the complex number z. +template constexpr T real(const complex &); +/// Returns the real component of the number y, treated as complex numbers with zero imaginary component. +template constexpr T real(T); +/// Returns the imaginary component of the complex number z. +template constexpr T imag(const complex &); +/// Returns the imaginary component of the number y, treated as complex numbers with zero imaginary component. +template constexpr T imag(T); + +/// Compute the magnitude of complex number x. +template T abs(const complex &); +/// Compute phase angle in radians of complex number x. +template T arg(const complex &); +/// Compute phase angle in radians of complex number x, treated as complex number with positive zero imaginary component. +template T arg(T); +/// Compute the squared magnitude of complex number x. +template T norm(const complex &); +/// Compute the squared magnitude of number x, treated as complex number with positive zero imaginary component. +template T norm(T); +/// Compute the conjugate of complex number x. +template complex conj(const complex &); +/// Compute the conjugate of number y, treated as complex number with positive zero imaginary component. +template complex conj(T); +/// Compute the projection of complex number x. +template complex proj(const complex &); +/// Compute the projection of number y, treated as complex number with positive zero imaginary component. +template complex proj(T); +/// Construct a complex number from polar coordinates with mangitude rho and angle theta. +template complex polar(const T &rho, const T &theta = T()); + +/// TRANSCENDENTALS: +/// Compute the natural log of complex number x. +template complex log(const complex &); +/// Compute the base-10 log of complex number x. +template complex log10(const complex &); +/// Compute the square root of complex number x. +template complex sqrt(const complex &); +/// Compute the base-e exponent of complex number x. +template complex exp(const complex &); + +/// Compute complex number z raised to the power of complex number y. +template complex pow(const complex &, const complex &); +/// Compute complex number z raised to the power of complex number y. +template complex pow(const complex &, const complex &); +/// Compute complex number z raised to the power of real number y. +template complex pow(const complex &, const U &); +/// Compute real number x raised to the power of complex number y. +template complex pow(const T &, const complex &); + +/// Compute the inverse hyperbolic sine of complex number x. +template complex asinh(const complex &); +/// Compute the inverse hyperbolic cosine of complex number x. +template complex acosh(const complex &); +/// Compute the inverse hyperbolic tangent of complex number x. +template complex atanh(const complex &); +/// Compute the hyperbolic sine of complex number x. +template complex sinh(const complex &); +/// Compute the hyperbolic cosine of complex number x. +template complex cosh(const complex &); +/// Compute the hyperbolic tangent of complex number x. +template complex tanh(const complex &); +/// Compute the inverse sine of complex number x. +template complex asin(const complex &); +/// Compute the inverse cosine of complex number x. +template complex acos(const complex &); +/// Compute the inverse tangent of complex number x. +template complex atan(const complex &); +/// Compute the sine of complex number x. +template complex sin(const complex &); +/// Compute the cosine of complex number x. +template complex cos(const complex &); +// Compute the tangent of complex number x. +template complex tan(const complex &); } // namespace sycl::ext::oneapi::experimental ``` From 8a2cb5c043c5d2e6b9aae2988e8b528eaeb7dae3 Mon Sep 17 00:00:00 2001 From: Jefferson Le Quellec Date: Thu, 11 Jan 2024 11:42:30 +0100 Subject: [PATCH 4/5] Add link to complex implementation --- .../extensions/experimental/sycl_ext_oneapi_complex.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc index 2f350dfd60989..2fa7ff62f4cab 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc @@ -230,8 +230,8 @@ specialization, primarily involving the removal of operators that are inapplicable. No new functions or operators are introduced to the marray class. The marray complex specialization maintains the principles of trivial -copyability (as seen in the Complex class description), with the -`is_device_copyable` type trait resolving to `std::true_type`. +copyability (as seen in the <>), +with the `is_device_copyable` type trait resolving to `std::true_type`. The marray definition used within this proposal assumes that any operator the `sycl::marray` class defines is only implemented if the marray's value type From 65c0ac7f8de9c51f5f135d5de86acf138d8c12b7 Mon Sep 17 00:00:00 2001 From: Jefferson Le Quellec Date: Fri, 26 Jan 2024 11:06:31 +0100 Subject: [PATCH 5/5] Apply reviewer's feedbacks --- .../sycl_ext_oneapi_complex.asciidoc | 48 +++++++++---------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc b/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc index 2fa7ff62f4cab..41700a898fecb 100644 --- a/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc +++ b/sycl/doc/extensions/experimental/sycl_ext_oneapi_complex.asciidoc @@ -57,12 +57,12 @@ defines a SYCL complex extension based on but independent of the `std::complex` interface. The proposed framework not only encompasses complex support for traditional use -cases but also accommodate for advanced mathematical features and data +cases but also accommodates for advanced mathematical features and data structures. Specifically, we propose to incorporate complex support for `sycl::marray`. This addition will empower developers to store complex numbers seamlessly -within arrays, opening up new possibilities for data manipulation and +within a `sycl::marray`, opening up new possibilities for data manipulation and computation. Furthermore, this extension involves overloading existing mathematical @@ -224,28 +224,23 @@ public: === Marray Complex Class Specialization -This proposal also introduces the specialization of the marray class to -support SYCL complex. The marray class undergoes slight modification for this -specialization, primarily involving the removal of operators that are -inapplicable. No new functions or operators are introduced to the marray class. +This proposal also introduces the specialization of the `sycl::marray` class to +support SYCL `complex`. The `marray` class undergoes slight modification for +this specialization, primarily involving the removal of operators that are +inapplicable. No new functions or operators are introduced to the `marray` +class. -The marray complex specialization maintains the principles of trivial +The `complex`'s `marray` specialization maintains the principles of trivial copyability (as seen in the <>), with the `is_device_copyable` type trait resolving to `std::true_type`. -The marray definition used within this proposal assumes that any operator the -`sycl::marray` class defines is only implemented if the marray's value type -also implements the operator. - -For instance, -`sycl::marray, NumElements>` does -not implement the modulus operator since -`sycl::ext::oneapi::experimental::complex` does not support it. +The `marray` specialization for `complex` deletes any operator that is not +supported by `complex`. ```C++ namespace sycl { -// Specialization of exiting `marray` class for `sycl::ext::oneapi::experimental::complex` +// Specialization of the existing `marray` class for `sycl::ext::oneapi::experimental::complex` template class marray, NumElements> { public: @@ -337,7 +332,8 @@ Specifically, it adds support for `abs`, `acos`, `asin`, `atan`, `acosh`, `polar`, `pow`, `proj`, `sin`, `sinh`, `sqrt`, `tan`, and `tanh`. Additionally, this extension introduces support for the `real` and `imag` free -functions, which the real and imaginary component, respectively. +functions, which returns the real and imaginary component of a number, +respectively. These functions are available in both host and device code, and each math function should follow the C++ standard for handling `NaN` and `Inf` values. @@ -440,8 +436,8 @@ template complex tan(const complex &); === Element-Wise Mathematical operations -In harmony with the complex scalar operations, this proposal extends -furthermore the `sycl::ext::oneapi::experimental`` namespace math functions +In harmony with the `complex` scalar operations, this proposal extends +furthermore the `sycl::ext::oneapi::experimental` namespace math functions to accept `sycl::marray>` for a range of SYCL math functions. Specifically, it adds support for `abs`, `acos`, `asin`, `atan`, `acosh`, @@ -449,20 +445,20 @@ Specifically, it adds support for `abs`, `acos`, `asin`, `atan`, `acosh`, `polar`, `pow`, `proj`, `sin`, `sinh`, `sqrt`, `tan`, and `tanh`. Additionally, this extension introduces support for the `real` and `imag` free -functions, which return marrays of scalar values representing the real and -imaginary components, respectively. +functions, which return a `sycl::marray` of scalar values representing the real +and imaginary components, respectively. -In scenarios where mathematical functions involve both marray and scalar +In scenarios where mathematical functions involve both `marray` and scalar parameters, two sets of overloads are introduced marray-scalar and scalar-marray. These mathematical operations are designed to execute element-wise across the -marray, ensuring that each operation is applied to every element within the -marray. +`marray`, ensuring that each operation is applied to every element within the +`sycl::marray`. Moreover, this proposal includes overloads for mathematical functions between -marrays and scalar inputs. In these cases, the operations are executed across -the entire marray, with the scalar value held constant. +`marray` and scalar inputs. In these cases, the operations are executed across +the entire `marray`, with the scalar value held constant. For consistency, these functions are available in both host and device code, and each math function should follow the C++ standard for handling `NaN` and