From b60a6363f1d2c5ad3d3d48f87f8895ed6a9ae331 Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Fri, 22 Jul 2022 14:33:12 +0100 Subject: [PATCH 01/16] Add sycl marray complex proposal --- .../sycl_ext_oneapi_complex_marray.asciidoc | 543 ++++++++++++++++++ 1 file changed, 543 insertions(+) create mode 100644 sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc new file mode 100644 index 0000000000000..90f459d464000 --- /dev/null +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -0,0 +1,543 @@ += sycl_ext_oneapi_complex + +:source-highlighter: coderay +:coderay-linenums-mode: table + +// This section needs to be after the document title. +:doctype: book +:toc2: +:toc: left +:encoding: utf-8 +:lang: en +:dpcpp: pass:[DPC++] + +// Set the default source code type in this document to C++, +// for syntax highlighting purposes. This is needed because +// docbook uses c++ and html5 uses cpp. +:language: {basebackend@docbook:c++:cpp} + + +== Notice + +[%hardbreaks] +Copyright (C) 2022-2022 Codeplay Ltd. All rights reserved. + +Khronos(R) is a registered trademark and SYCL(TM) and SPIR(TM) are trademarks +of The Khronos Group Inc. OpenCL(TM) is a trademark of Apple Inc. used by +permission by Khronos. + + +== Contact + +To report problems with this extension, please open a new issue at: + +https://github.com/intel/llvm/issues + + +== Dependencies + +This extension is written against the SYCL 2020 revision 5 specification. All +references below to the "core SYCL specification" or to section numbers in the +SYCL specification refer to that revision. + +== Status + +This is a proposed extension specification, intended to gather community +feedback. Interfaces defined in this specification may not be implemented yet +or may be in a preliminary state. The specification itself may also change in +incompatible ways before it is finalized. *Shipping software products should +not rely on APIs defined in this specification.* + +[NOTE] +==== +This extension is not currently implemented in {dpcpp}. +==== + + +== Overview + +{dpcpp} has support for `sycl::ext::oneapi::complex` this allows for the +addition of new complex math features. This proposes the specialization of +`marray` to add support for complex numbers to be stored in arrays. The +proposal includes overloading the existing math functions to support complex +marrays and adding new free functions to simplify accessing, setting marray +values, and construct complex marrays. + +== Specification + +=== Feature test macro + +This extension provides a feature-test macro as described in the core SYCL +specification. An implementation supporting this extension must predefine the +macro `SYCL_EXT_ONEAPI_MARRAY_COMPLEX` to one of the values defined in the table +below. Applications can test for the existence of this macro to determine if +the implementation supports this feature, or applications can test the macro's +value to determine which of the extension's features the implementation +supports. + +[%header,cols="1,5"] +|=== +|Value +|Description + +|1 +|Initial version of this extension. +|=== + +=== Marray Complex Class Specialization + +The `marray` class is specialized for the `sycl::ext::oneapi::complex` +class. The user interface of the `marray` +class is similar to the SYCL-2020 generic `marray` interface. Some logical, +bitwise, and arithmetic operators are deleted for the complex class as there is +no equivalent. + +The marray complex specialization is trivially copyable, and the type trait +`is_device_copyable` should resolve to `std::true_type`. + +```C++ +namespace sycl { +namespace ext { +namespace oneapi { + + // Specialization of exiting `marray` class for `sycl::ext::oneapi::complex` + template + class marray , NumElements> { + private: + using DataT = sycl::ext::oneapi::complex; + public: + using value_type = DataT; + using reference = DataT&; + using const_reference = const DataT&; + using iterator = DataT*; + using const_iterator = const DataT*; + + marray(); + + explicit constexpr marray(const DataT &arg); + + template + constexpr marray(const ArgTN&... args); + + constexpr marray(const marray &rhs); + constexpr marray(marray &&rhs); + + // Available only when: NumElements == 1 + operator DataT() const; + + static constexpr std::size_t size() noexcept; + + // subscript operator + reference operator[](std::size_t index); + const_reference operator[](std::size_t index) const; + + marray &operator=(const marray &rhs); + marray &operator=(const DataT &rhs); + + // iterator functions + iterator begin(); + const_iterator begin() const; + + iterator end(); + const_iterator end() const; + + // OP is: +, -, *, / + friend marray operatorOP(const marray &lhs, const marray &rhs) { /* ... */ } + friend marray operatorOP(const marray &lhs, const DataT &rhs) { /* ... */ } + + // OP is: % + friend marray operatorOP(const marray &lhs, const DataT &rhs) = delete; + + // OP is: +=, -=, *=, /= + friend marray &operatorOP(marray &lhs, const marray &rhs) { /* ... */ } + friend marray &operatorOP(marray &lhs, const DataT &rhs) { /* ... */ } + + // OP is: %= + friend marray &operatorOP(marray &lhs, const marray &rhs) = delete; + friend marray &operatorOP(marray &lhs, const DataT &rhs) = delete; + + // OP is prefix ++, -- + friend marray &operatorOP(marray &rhs) = delete; + + // OP is postfix ++, -- + friend marray operatorOP(marray& lhs, int) = delete; + + // OP is unary +, - + friend marray operatorOP(marray &rhs) = delete; + + // OP is: &, |, ^ + friend marray operatorOP(const marray &lhs, const marray &rhs) = delete; + friend marray operatorOP(const marray &lhs, const DataT &rhs) = delete; + + // OP is: &=, |=, ^= + friend marray &operatorOP(marray &lhs, const marray &rhs) = delete; + friend marray &operatorOP(marray &lhs, const DataT &rhs) = delete; + + // OP is: &&, || + friend marray operatorOP(const marray &lhs, const marray &rhs) = delete; + friend marray operatorOP(const marray& lhs, const DataT &rhs) = delete; + + // OP is: <<, >> + friend marray operatorOP(const marray &lhs, const marray &rhs) = delete; + friend marray operatorOP(const marray &lhs, const DataT &rhs) = delete; + + // OP is: <<=, >>= + friend marray &operatorOP(marray &lhs, const marray &rhs) = delete; + friend marray &operatorOP(marray &lhs, const DataT &rhs) = delete; + + // OP is: ==, != + friend marray operatorOP(const marray &lhs, const marray &rhs) { + /* ... */ } + friend marray operatorOP(const marray &lhs, const DataT &rhs) { + /* ... */ } + + // OP is: <, >, <=, >= + friend marray operatorOP(const marray &lhs, const marray &rhs) = delete; + friend marray operatorOP(const marray &lhs, const DataT &rhs) = delete; + + friend marray operator~(const marray &v) = delete; + + // OP is: +, -, *, / + friend marray operatorOP(const DataT &lhs, const marray &rhs) { /* ... */ } + + // OP is: % + friend marray operatorOP(const DataT &lhs, const marray &rhs) = delete; + + // OP is: &, |, ^ + friend marray operatorOP(const DataT &lhs, const marray &rhs) = delete; + + // OP is: &&, || + friend marray operatorOP(const DataT &lhs, const marray &rhs) = delete; + + // OP is: <<, >> + friend marray operatorOP(const DataT &lhs, const marray &rhs) = delete; + + // OP is: ==, != + friend marray operatorOP(const DataT &lhs, const marray &rhs) { + /* ... */ } + + // OP is: <, >, <=, >= + friend marray operatorOP(const DataT &lhs, const marray &rhs) = delete; + + friend marray operator!(const marray &v) = delete; + } + +} // namespace oneapi +} // namespace ext +} // namespace sycl +``` + +The list of deleted operators are: %, %=, ++, --, +, -, &, |, ^, &=, |=, ^=, +&&, ||, <<, >>, <<=, >>=, <, >, <=, >=, ~, ! + +The `make_complex_marray` free function is added to construct complex marrays from real and +imaginary components. Additionally, the free functions `get_real` and +`get_imag` are added to access the real and imaginary components of the +`marray` class without modifying the existing `marray` interface. The usage +of free functions does cause a deviation from the `std::complex` interface. +However, it does reduce this extensions impact on the `marray` interface. + +```C++ +namespace sycl { +namespace ext { +namespace oneapi { + + // Make_complex_marray + + template + marray, NumElements> make_complex_marray(const marray &real, const marray &imag); + + template + marray, NumElements> make_complex_marray(const marray &real, const T &imag); + + template + marray, NumElements> make_complex_marray(const T &real, const marray &imag); + + template + marray, NumElements> make_complex_marray(const marray &real, const marray &imag, std::integer_sequence int_seq); + + template + marray, NumElements> make_complex_marray(const marray, NumElements> &cmplx, std::integer_sequence int_seq); + + // Get + + // return marray of component + template + marray get_real(const marray, NumElements> &input); + + template + marray get_imag(const marray, NumElements> &input); + + // return element of component + template + T get_real(const marray, NumElements> &input, std::size_t index); + + template + T get_imag(const marray, NumElements> &input, std::size_t index); + + // return sequence of elements of component + template + T get_real(const marray, NumElements> &input, std::integer_sequence int_seq); + + template + T get_imag(const marray, NumElements> &input, std::integer_sequence int_seq); + + // Set + + template + void set_real(marray, NumElements> &input, const marray &values); + + template + void set_imag(marray, NumElements> &input, const marray &values); + + template + void set_real(marray, NumElements> &input, const T value); + + template + void set_imag(marray, NumElements> &input, const T value); + + template + void set_real(marray, NumElements> &input, std::size_t index, const T value); + + template + void set_imag(marray, NumElements> &input, std::size_t index, const T value); + +} // namespace oneapi +} // namespace ext +} // namespace sycl +``` + +The class `sycl::oneapi::marray, N>`, has specializations +of `T`; `float`, `double`, and `sycl::half` defined. + +```C++ +namespace sycl { +namespace ext { +namespace oneapi { + + template + class marray; + + template + class marray; + + template + class marray; + +} // namespace oneapi +} // namespace ext +} // namespace sycl +``` + +The generic type `mgencomplex` is defined as types +`marray, {N}>`, `complex, {N}>`, +`complex, {N}>`. + +The table below shows the free functions operating on the `marray` complex +specialized class. No table is provided for the `marray` class as only +functions are removed and the underlying function defintion stays the same. + +[%header,cols="5,5"] +|=== +|Function +|Description + +|`mgencomplex make_complex_marray(const mgenfloat& x, const mgenfloat& y);` +|Constructs a marray of complex numbers with real values in marray x, and the imaginary values in marray y. +|`mgencomplex make_complex_marray(const mgenfloat& x, const genfloat& y);` +|Constructs a marray of complex numbers with real values in marray x, and the imaginary value y. +|`mgencomplex make_complex_marray(const genfloat& x, const mgenfloat& y);` +|Constructs a marray of complex numbers with real value x, and the imaginary values in marray y. +|`mgencomplex make_complex_marray(const mgenfloat& x, const mgenfloat& y, std::integer_sequence int_seq);` +|Constructs a marray of complex numbers from real values in marray x, and the imaginary values in marray y. Each element should be constructed from the corresponding index within `int_seq` and the returned marray size should be the same as the `int_seq` size. +|`mgencomplex make_complex_marray(const mgencomplex& x, std::integer_sequence int_seq);` +|Constructs a marray of complex numbers from a complex marray x. Each element should be constructed from the corresponding index within `int_seq` and the returned marray size should be the same as the `int_seq` size. +|`mgenfloat get_real(const mgencomplex& x);` +|Returns an marray of the real components for marray of complex numbers. +|`mgenfloat get_imag(const mgencomplex& x);` +|Returns an marray of the imaginary components for marray of complex numbers. +|`mgenfloat get_real(const mgencomplex& x, std::size_t idx);` +|Returns the real component of the complex number for element idx in marray x. +|`mgenfloat get_imag(const mgencomplex& x, std::size_t idx);` +|Returns the imaginary component of the complex number for element idx in marray x. +|`mgenfloat get_real(const mgencomplex& x, std::integer_sequence int_seq);` +|Returns a sequence of real components of the complex number x. Each element should be constructed from the corresponding index within `int_seq` and the returned marray size should be the same as the `int_seq` size. +|`mgenfloat get_imag(const mgencomplex& x, std::integer_sequence int_seq);` +|Returns a sequence of imaginary components of the complex number x. Each element should be constructed from the corresponding index within `int_seq` and the returned marray size should be the same as the `int_seq` size. +|`void set_real(mgencomplex& x, const mgenfloat& y);` +|Set each element of the real components in x to the corresponding element in y. +|`void set_imag(mgencomplex& x, const mgenfloat& y);` +|Set each element of the imaginary components in x to the corresponding element in y. +|`void set_real(mgencomplex& x, const genfloat& y);` +|Set each element of the real components in x to the decimal number y. +|`void set_imag(mgencomplex& x, const genfloat& y);` +|Set each element of the imaginary components in x to the decimal number y. +|`void set_real(mgencomplex& x, std::size_t idx, const genfloat& y);` +|Set the real value of element idx in x to the decimal number y. +|`void set_imag(mgencomplex& x, std::size_t idx, const genfloat& y);` +|Set the imaginary value of element idx in x to the decimal number y. + + +=== Mathematical operations + +This proposal extends `sycl::ext::oneapi` namespace math functions to accept +`mgencomplex` 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`. +For math functions with two parameters marray-scalar and scalar-marray overloads +are added. + +The functions execute as-if the math operation is performed elementwise across the +marray. The math function between each element should follow the C++ +standard for handling NaN's and Inf values. + +The proposal additionally adds overloads between marrays and scalar inputs. +Overloads with marray's and scalar parameters should execute the operation +across the marray while keeping the scalar value constant. + +```C++ +namespace sycl { +namespace ext { +namespace oneapi { + + mgenfloat abs(const mgencomplex& x); + + mgencomplex acos(const mgencomplex& x); + + mgencomplex asin(const mgencomplex& x); + + mgencomplex atan(const mgencomplex& x); + + mgencomplex acosh(const mgencomplex& x); + + mgencomplex asinh(const mgencomplex& x); + + mgencomplex atanh(const mgencomplex& x); + + mgenfloat arg(const mgencomplex& x); + + mgencomplex conj(const mgencomplex& x); + + mgencomplex cos(const mgencomplex& x); + + mgencomplex cosh(const mgencomplex& x); + + mgencomplex exp(const mgencomplex& x); + + mgencomplex log(const mgencomplex& x); + + mgencomplex log10(const mgencomplex& x); + + mgenfloat norm(const mgencomplex& x); + + mgencomplex polar(const mgenfloat& rho, const mgenfloat& theta); + mgencomplex polar(const mgenfloat& rho, const genfloat& theta = 0); + mgencomplex polar(const genfloat& rho, const mgenfloat& theta); + + mgencomplex pow(const mgencomplex& x, const mgenfloat& y); + mgencomplex pow(const mgencomplex& x, const genfloat& y); + mgencomplex pow(const gencomplex& x, const mgenfloat& y); + + mgencomplex pow(const mgencomplex& x, const mgencomplex& y); + mgencomplex pow(const mgencomplex& x, const gencomplex& y); + mgencomplex pow(const gencomplex& x, const mgencomplex& y); + + mgencomplex pow(const mgenfloat& x, const mgencomplex& y); + mgencomplex pow(const mgenfloat& x, const gencomplex& y); + mgencomplex pow(const genfloat& x, const mgencomplex& y); + + mgencomplex proj(const mgencomplex& x); + mgencomplex proj(const mgenfloat& x); + + mgencomplex sin(const mgencomplex& x); + + mgencomplex sinh(const mgencomplex& x); + + mgencomplex sqrt(const mgencomplex& x); + + mgencomplex tan(const mgencomplex& x); + + mgencomplex tanh(const mgencomplex& x); + +} // namespace oneapi +} // namespace ext +} // namespace sycl +``` + +The table below shows each function along with a description of its +mathematical operation. + +[%header,cols="5,5"] +|=== +|Function +|Description + +|`mgenfloat abs(const mgencomplex& x)` +|Compute the magnitude for each complex number in marray x. +|`mgencomplex acos(const mgencomplex& x)` +|Compute the inverse cosine for each complex number in marray x. +|`mgencomplex asin(const mgencomplex& x)` +|Compute the inverse sine for each complex number in marray x. +|`mgencomplex atan(const mgencomplex& x)` +|Compute the inverse tangent for each complex number in marray x. +|`mgencomplex acosh(const mgencomplex& x)` +|Compute the inverse hyperbolic cosine for each complex number in marray x. +|`mgencomplex asinh(const mgencomplex& x)` +|Compute the inverse hyperbolic sine for each complex number in marray x. +|`mgencomplex atanh(const mgencomplex& x)` +|Compute the inverse hyperbolic tangent for each complex number in marray x. +|`mgenfloat arg(const mgencomplex& x);` +|Compute phase angle in radians for each complex number in marray x. +|`mgencomplex conj(const mgencomplex& x)` +|Compute the conjugate for each complex number in marray x. +|`mgencomplex cos(const mgencomplex& x)` +|Compute the cosine for each complex number in marray x. +|`mgencomplex cosh(const mgencomplex& x)` +|Compute the hyperbolic cosine for each complex number in marray x. +|`mgencomplex exp(const mgencomplex& x)` +|Compute the base-e exponent for each complex number in marray x. +|`mgencomplex log(const mgencomplex& x)` +|Compute the natural log for each complex number in marray x. +|`mgencomplex log10(const mgencomplex& x)` +|Compute the base-10 log for each complex number in marray x. +|`mgenfloat norm(const mgencomplex& x)` +|Compute the squared magnitude for each complex number in marray x. +|`mgencomplex polar(const mgenfloat& rho, const mgenfloat& theta)` +|Construct an marray, elementwise, of complex numbers from each polar coordinate in marray rho and marray theta. +|`mgencomplex polar(const mgenfloat& rho, const genfloat& theta = 0)` +|Construct an marray, elementwise, of complex numbers from each polar coordinate in marray rho and scalar theta. +|`mgencomplex polar(const genfloat& rho, const mgenfloat& theta)` +|Construct an marray, elementwise, of complex numbers from each polar coordinate in scalar rho and marray theta. +|`mgencomplex pow(const mgencomplex& x, const mgenfloat& y)` +|Raise each complex element in x to the power of the corresponding decimal element in y. +|`mgencomplex pow(const mgencomplex& x, const genfloat& y)` +|Raise each complex element in x to the power of the decimal numer y. +|`mgencomplex pow(const gencomplex& x, const mgenfloat& y)` +|Raise complex number x to the power of each decimal element in y. +|`mgencomplex pow(const mgencomplex& x, const mgencomplex& y)` +|Raise each complex element in x to the power of the corresponding complex element in y. +|`mgencomplex pow(const mgencomplex& x, const gencomplex& y)` +|Raise each complex element in x to the power of the complex number y. +|`mgencomplex pow(const gencomplex& x, const mgencomplex& y)` +|Raise complex number x to the power of each complex element in y. +|`mgencomplex pow(const mgenfloat& x, const mgencomplex& y)` +|Raise each decimal element in x to the power of the corresponding complex element in y. +|`mgencomplex pow(const mgenfloat& x, const gencomplex& y)` +|Raise each decimal element in x to the power of the complex number y. +|`mgencomplex pow(const genfloat& x, const mgencomplex& y)` +|Raise decimal number x to the power of each complex element in y. +|`mgencomplex proj(const mgencomplex& x)` +|Compute the projection for each complex number in marray x. +|`mgencomplex proj(const mgenfloat& x)` +|Compute the projection for each real numer in marray x. +|`mgencomplex sin(const mgencomplex& x)` +|Compute the sine for each complex number in marray x. +|`mgencomplex sinh(const mgencomplex& x)` +|Compute the hyperbolic sine for each complex number in marray x. +|`mgencomplex sqrt(const mgencomplex& x)` +|Compute the square root for each complex number in marray x. +|`mgencomplex tan(const mgencomplex& x)` +|Compute the tangent for each complex number in marray x. +|`mgencomplex tanh(const mgencomplex& x)` +|Compute the hyperbolic tangent for each complex number in marray x. +|=== From d54a484541bb3613e1705df23ddfc7fd55b84533 Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Thu, 11 Aug 2022 11:37:15 +0100 Subject: [PATCH 02/16] Fix typo --- .../proposed/sycl_ext_oneapi_complex_marray.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index 90f459d464000..84693e81d5ad7 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -511,7 +511,7 @@ mathematical operation. |`mgencomplex pow(const mgencomplex& x, const mgenfloat& y)` |Raise each complex element in x to the power of the corresponding decimal element in y. |`mgencomplex pow(const mgencomplex& x, const genfloat& y)` -|Raise each complex element in x to the power of the decimal numer y. +|Raise each complex element in x to the power of the decimal number y. |`mgencomplex pow(const gencomplex& x, const mgenfloat& y)` |Raise complex number x to the power of each decimal element in y. |`mgencomplex pow(const mgencomplex& x, const mgencomplex& y)` @@ -529,7 +529,7 @@ mathematical operation. |`mgencomplex proj(const mgencomplex& x)` |Compute the projection for each complex number in marray x. |`mgencomplex proj(const mgenfloat& x)` -|Compute the projection for each real numer in marray x. +|Compute the projection for each real number in marray x. |`mgencomplex sin(const mgencomplex& x)` |Compute the sine for each complex number in marray x. |`mgencomplex sinh(const mgencomplex& x)` From bcb15ba96a2646650e6e50cf465f0b41fde246f8 Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Fri, 12 Aug 2022 16:52:30 +0100 Subject: [PATCH 03/16] Update based on feedback --- .../sycl_ext_oneapi_complex_marray.asciidoc | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index 84693e81d5ad7..65a1050c2a118 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -1,4 +1,4 @@ -= sycl_ext_oneapi_complex += sycl_ext_oneapi_complex_marray :source-highlighter: coderay :coderay-linenums-mode: table @@ -69,7 +69,7 @@ values, and construct complex marrays. This extension provides a feature-test macro as described in the core SYCL specification. An implementation supporting this extension must predefine the -macro `SYCL_EXT_ONEAPI_MARRAY_COMPLEX` to one of the values defined in the table +macro `SYCL_EXT_ONEAPI_COMPLEX_MARRAY` to one of the values defined in the table below. Applications can test for the existence of this macro to determine if the implementation supports this feature, or applications can test the macro's value to determine which of the extension's features the implementation @@ -90,7 +90,9 @@ The `marray` class is specialized for the `sycl::ext::oneapi::complex` class. The user interface of the `marray` class is similar to the SYCL-2020 generic `marray` interface. Some logical, bitwise, and arithmetic operators are deleted for the complex class as there is -no equivalent. +no equivalent. The marray specialization builds on the +`sycl::ext::oneapi::complex` class, therfore this extension is dependent on +link:sycl_ext_oneapi_complex.asciidoc[sycl_ext_oneapi_complex]. The marray complex specialization is trivially copyable, and the type trait `is_device_copyable` should resolve to `std::true_type`. @@ -228,7 +230,7 @@ namespace oneapi { ``` The list of deleted operators are: %, %=, ++, --, +, -, &, |, ^, &=, |=, ^=, -&&, ||, <<, >>, <<=, >>=, <, >, <=, >=, ~, ! +&&, ||, <<, >>, <<=, >>=, <, >, +<=+, >=, ~, ! The `make_complex_marray` free function is added to construct complex marrays from real and imaginary components. Additionally, the free functions `get_real` and @@ -277,10 +279,10 @@ namespace oneapi { // return sequence of elements of component template - T get_real(const marray, NumElements> &input, std::integer_sequence int_seq); + marray get_real(const marray, NumElements> &input, std::integer_sequence int_seq); template - T get_imag(const marray, NumElements> &input, std::integer_sequence int_seq); + marray get_imag(const marray, NumElements> &input, std::integer_sequence int_seq); // Set @@ -307,7 +309,7 @@ namespace oneapi { } // namespace sycl ``` -The class `sycl::oneapi::marray, N>`, has specializations +The class `sycl::ext::oneapi::marray, N>`, has specializations of `T`; `float`, `double`, and `sycl::half` defined. ```C++ @@ -316,13 +318,13 @@ namespace ext { namespace oneapi { template - class marray; + class marray, NumElements>; template - class marray; + class marray, NumElements>; template - class marray; + class marray, NumElements>; } // namespace oneapi } // namespace ext @@ -330,8 +332,9 @@ namespace oneapi { ``` The generic type `mgencomplex` is defined as types -`marray, {N}>`, `complex, {N}>`, -`complex, {N}>`. +`marray, {N}>`, +`marray, {N}>`, +`marray, {N}>`. The table below shows the free functions operating on the `marray` complex specialized class. No table is provided for the `marray` class as only @@ -376,7 +379,7 @@ functions are removed and the underlying function defintion stays the same. |Set the real value of element idx in x to the decimal number y. |`void set_imag(mgencomplex& x, std::size_t idx, const genfloat& y);` |Set the imaginary value of element idx in x to the decimal number y. - +|=== === Mathematical operations From 83b027e4783d1527696b4f3dffd8ab4e5e0f08a0 Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Mon, 15 Aug 2022 09:30:52 +0100 Subject: [PATCH 04/16] Remove redundant set/get_X overloads --- .../sycl_ext_oneapi_complex_marray.asciidoc | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index 65a1050c2a118..227b060b34e31 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -270,13 +270,6 @@ namespace oneapi { template marray get_imag(const marray, NumElements> &input); - // return element of component - template - T get_real(const marray, NumElements> &input, std::size_t index); - - template - T get_imag(const marray, NumElements> &input, std::size_t index); - // return sequence of elements of component template marray get_real(const marray, NumElements> &input, std::integer_sequence int_seq); @@ -298,12 +291,6 @@ namespace oneapi { template void set_imag(marray, NumElements> &input, const T value); - template - void set_real(marray, NumElements> &input, std::size_t index, const T value); - - template - void set_imag(marray, NumElements> &input, std::size_t index, const T value); - } // namespace oneapi } // namespace ext } // namespace sycl @@ -359,10 +346,6 @@ functions are removed and the underlying function defintion stays the same. |Returns an marray of the real components for marray of complex numbers. |`mgenfloat get_imag(const mgencomplex& x);` |Returns an marray of the imaginary components for marray of complex numbers. -|`mgenfloat get_real(const mgencomplex& x, std::size_t idx);` -|Returns the real component of the complex number for element idx in marray x. -|`mgenfloat get_imag(const mgencomplex& x, std::size_t idx);` -|Returns the imaginary component of the complex number for element idx in marray x. |`mgenfloat get_real(const mgencomplex& x, std::integer_sequence int_seq);` |Returns a sequence of real components of the complex number x. Each element should be constructed from the corresponding index within `int_seq` and the returned marray size should be the same as the `int_seq` size. |`mgenfloat get_imag(const mgencomplex& x, std::integer_sequence int_seq);` @@ -375,10 +358,6 @@ functions are removed and the underlying function defintion stays the same. |Set each element of the real components in x to the decimal number y. |`void set_imag(mgencomplex& x, const genfloat& y);` |Set each element of the imaginary components in x to the decimal number y. -|`void set_real(mgencomplex& x, std::size_t idx, const genfloat& y);` -|Set the real value of element idx in x to the decimal number y. -|`void set_imag(mgencomplex& x, std::size_t idx, const genfloat& y);` -|Set the imaginary value of element idx in x to the decimal number y. |=== === Mathematical operations From 4c93f61e2f30a5edec63e8bb5bdf04b5043e10b8 Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Mon, 15 Aug 2022 09:34:37 +0100 Subject: [PATCH 05/16] Move dependency section --- .../proposed/sycl_ext_oneapi_complex_marray.asciidoc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index 227b060b34e31..609325a39baeb 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -40,6 +40,11 @@ This extension is written against the SYCL 2020 revision 5 specification. All references below to the "core SYCL specification" or to section numbers in the SYCL specification refer to that revision. +The marray specialization builds on the `sycl::ext::oneapi::complex` class, +therefore this extension is dependent on +link:sycl_ext_oneapi_complex.asciidoc[sycl_ext_oneapi_complex]. + + == Status This is a proposed extension specification, intended to gather community @@ -90,9 +95,7 @@ The `marray` class is specialized for the `sycl::ext::oneapi::complex` class. The user interface of the `marray` class is similar to the SYCL-2020 generic `marray` interface. Some logical, bitwise, and arithmetic operators are deleted for the complex class as there is -no equivalent. The marray specialization builds on the -`sycl::ext::oneapi::complex` class, therfore this extension is dependent on -link:sycl_ext_oneapi_complex.asciidoc[sycl_ext_oneapi_complex]. +no equivalent. The marray complex specialization is trivially copyable, and the type trait `is_device_copyable` should resolve to `std::true_type`. From 0d647f739e0a8d54714c31021baa2c805e4c6ac0 Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Mon, 15 Aug 2022 13:52:47 +0100 Subject: [PATCH 06/16] Remove marray specialization --- .../sycl_ext_oneapi_complex_marray.asciidoc | 177 +++--------------- 1 file changed, 24 insertions(+), 153 deletions(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index 609325a39baeb..0afcba0f7dd2f 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -40,7 +40,7 @@ This extension is written against the SYCL 2020 revision 5 specification. All references below to the "core SYCL specification" or to section numbers in the SYCL specification refer to that revision. -The marray specialization builds on the `sycl::ext::oneapi::complex` class, +The complex marray extension builds on the `sycl::ext::oneapi::complex` class, therefore this extension is dependent on link:sycl_ext_oneapi_complex.asciidoc[sycl_ext_oneapi_complex]. @@ -62,7 +62,7 @@ This extension is not currently implemented in {dpcpp}. == Overview {dpcpp} has support for `sycl::ext::oneapi::complex` this allows for the -addition of new complex math features. This proposes the specialization of +addition of new complex math features. This proposes the instantiation of `marray` to add support for complex numbers to be stored in arrays. The proposal includes overloading the existing math functions to support complex marrays and adding new free functions to simplify accessing, setting marray @@ -91,156 +91,27 @@ supports. === Marray Complex Class Specialization -The `marray` class is specialized for the `sycl::ext::oneapi::complex` -class. The user interface of the `marray` -class is similar to the SYCL-2020 generic `marray` interface. Some logical, -bitwise, and arithmetic operators are deleted for the complex class as there is -no equivalent. +The `marray` class is extended for the `sycl::ext::oneapi::complex` class. +The user interface of the `marray` +class is not changed compared to the SYCL-2020 generic `marray` interface. -The marray complex specialization is trivially copyable, and the type trait -`is_device_copyable` should resolve to `std::true_type`. +The `marray` complex instantiation is trivially copyable, and the type +trait `is_device_copyable` should resolve to `std::true_type`. -```C++ -namespace sycl { -namespace ext { -namespace oneapi { - - // Specialization of exiting `marray` class for `sycl::ext::oneapi::complex` - template - class marray , NumElements> { - private: - using DataT = sycl::ext::oneapi::complex; - public: - using value_type = DataT; - using reference = DataT&; - using const_reference = const DataT&; - using iterator = DataT*; - using const_iterator = const DataT*; - - marray(); - - explicit constexpr marray(const DataT &arg); - - template - constexpr marray(const ArgTN&... args); - - constexpr marray(const marray &rhs); - constexpr marray(marray &&rhs); - - // Available only when: NumElements == 1 - operator DataT() const; - - static constexpr std::size_t size() noexcept; - - // subscript operator - reference operator[](std::size_t index); - const_reference operator[](std::size_t index) const; - - marray &operator=(const marray &rhs); - marray &operator=(const DataT &rhs); - - // iterator functions - iterator begin(); - const_iterator begin() const; - - iterator end(); - const_iterator end() const; - - // OP is: +, -, *, / - friend marray operatorOP(const marray &lhs, const marray &rhs) { /* ... */ } - friend marray operatorOP(const marray &lhs, const DataT &rhs) { /* ... */ } - - // OP is: % - friend marray operatorOP(const marray &lhs, const DataT &rhs) = delete; - - // OP is: +=, -=, *=, /= - friend marray &operatorOP(marray &lhs, const marray &rhs) { /* ... */ } - friend marray &operatorOP(marray &lhs, const DataT &rhs) { /* ... */ } - - // OP is: %= - friend marray &operatorOP(marray &lhs, const marray &rhs) = delete; - friend marray &operatorOP(marray &lhs, const DataT &rhs) = delete; - - // OP is prefix ++, -- - friend marray &operatorOP(marray &rhs) = delete; - - // OP is postfix ++, -- - friend marray operatorOP(marray& lhs, int) = delete; - - // OP is unary +, - - friend marray operatorOP(marray &rhs) = delete; - - // OP is: &, |, ^ - friend marray operatorOP(const marray &lhs, const marray &rhs) = delete; - friend marray operatorOP(const marray &lhs, const DataT &rhs) = delete; - - // OP is: &=, |=, ^= - friend marray &operatorOP(marray &lhs, const marray &rhs) = delete; - friend marray &operatorOP(marray &lhs, const DataT &rhs) = delete; - - // OP is: &&, || - friend marray operatorOP(const marray &lhs, const marray &rhs) = delete; - friend marray operatorOP(const marray& lhs, const DataT &rhs) = delete; - - // OP is: <<, >> - friend marray operatorOP(const marray &lhs, const marray &rhs) = delete; - friend marray operatorOP(const marray &lhs, const DataT &rhs) = delete; - - // OP is: <<=, >>= - friend marray &operatorOP(marray &lhs, const marray &rhs) = delete; - friend marray &operatorOP(marray &lhs, const DataT &rhs) = delete; - - // OP is: ==, != - friend marray operatorOP(const marray &lhs, const marray &rhs) { - /* ... */ } - friend marray operatorOP(const marray &lhs, const DataT &rhs) { - /* ... */ } - - // OP is: <, >, <=, >= - friend marray operatorOP(const marray &lhs, const marray &rhs) = delete; - friend marray operatorOP(const marray &lhs, const DataT &rhs) = delete; - - friend marray operator~(const marray &v) = delete; - - // OP is: +, -, *, / - friend marray operatorOP(const DataT &lhs, const marray &rhs) { /* ... */ } - - // OP is: % - friend marray operatorOP(const DataT &lhs, const marray &rhs) = delete; - - // OP is: &, |, ^ - friend marray operatorOP(const DataT &lhs, const marray &rhs) = delete; - - // OP is: &&, || - friend marray operatorOP(const DataT &lhs, const marray &rhs) = delete; - - // OP is: <<, >> - friend marray operatorOP(const DataT &lhs, const marray &rhs) = delete; - - // OP is: ==, != - friend marray operatorOP(const DataT &lhs, const marray &rhs) { - /* ... */ } - - // OP is: <, >, <=, >= - friend marray operatorOP(const DataT &lhs, const marray &rhs) = delete; - - friend marray operator!(const marray &v) = delete; - } - -} // namespace oneapi -} // namespace ext -} // namespace sycl -``` - -The list of deleted operators are: %, %=, ++, --, +, -, &, |, ^, &=, |=, ^=, -&&, ||, <<, >>, <<=, >>=, <, >, +<=+, >=, ~, ! +As the `marray` class is not specialized in this proposal. The `marray` +definition used within this proposal assumes that any operator the `marray` +class defines is only implemented if the marray's value type also +implements the operator. So, for example, `marray` does not +implement the modulus operator as float does not support it. As the +`marray` class is not changed in this proposal, it is not redefined below. -The `make_complex_marray` free function is added to construct complex marrays from real and -imaginary components. Additionally, the free functions `get_real` and -`get_imag` are added to access the real and imaginary components of the -`marray` class without modifying the existing `marray` interface. The usage -of free functions does cause a deviation from the `std::complex` interface. -However, it does reduce this extensions impact on the `marray` interface. +The `make_complex_marray` free function is added to construct complex +marrays from real and imaginary components. Additionally, the free +functions `get_real` and `get_imag` are added to access the real and +imaginary components of the `marray` class without modifying the existing +`marray` interface. The usage of free functions does cause a deviation +from the `std::complex` interface. However, it does reduce this extensions +impact on the `marray` interface. ```C++ namespace sycl { @@ -299,8 +170,8 @@ namespace oneapi { } // namespace sycl ``` -The class `sycl::ext::oneapi::marray, N>`, has specializations -of `T`; `float`, `double`, and `sycl::half` defined. +The class `sycl::ext::oneapi::marray, N>`, +has instantiations of `T`; `float`, `double`, and `sycl::half` declared. ```C++ namespace sycl { @@ -327,8 +198,8 @@ The generic type `mgencomplex` is defined as types `marray, {N}>`. The table below shows the free functions operating on the `marray` complex -specialized class. No table is provided for the `marray` class as only -functions are removed and the underlying function defintion stays the same. +class. No table is provided for the `marray` class as no changes to it are +proposed. [%header,cols="5,5"] |=== From 0fe241835d8ea3fb3a8d1534c3320a24b3aef4ad Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Tue, 16 Aug 2022 10:03:13 +0100 Subject: [PATCH 07/16] Clarify mgencomplex --- .../sycl_ext_oneapi_complex_marray.asciidoc | 38 +++++-------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index 0afcba0f7dd2f..7d0b1188b640a 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -170,35 +170,15 @@ namespace oneapi { } // namespace sycl ``` -The class `sycl::ext::oneapi::marray, N>`, -has instantiations of `T`; `float`, `double`, and `sycl::half` declared. - -```C++ -namespace sycl { -namespace ext { -namespace oneapi { - - template - class marray, NumElements>; - - template - class marray, NumElements>; - - template - class marray, NumElements>; - -} // namespace oneapi -} // namespace ext -} // namespace sycl -``` - -The generic type `mgencomplex` is defined as types -`marray, {N}>`, -`marray, {N}>`, -`marray, {N}>`. - -The table below shows the free functions operating on the `marray` complex -class. No table is provided for the `marray` class as no changes to it are +The table below shows the free functions operating on the `marray` type +when it is instantiated with `sycl::ext::oneapi::complex`, +`sycl::ext::oneapi::complex`, and +`sycl::ext::oneapi::complex`. For the purposes of this +specification, we use the generic type name `mgencomplex` to represent +these three instantiations. However, there is no C++ type actually named +`mgencomplex`. + +No table is provided for the `marray` class as no changes to it are proposed. [%header,cols="5,5"] From c11762cb1895f1e0d4d252b8ddcab80ff2db2409 Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Tue, 16 Aug 2022 10:06:38 +0100 Subject: [PATCH 08/16] Remove genfloat pass by reference --- .../proposed/sycl_ext_oneapi_complex_marray.asciidoc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index 7d0b1188b640a..09ad8ef4fb242 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -124,10 +124,10 @@ namespace oneapi { marray, NumElements> make_complex_marray(const marray &real, const marray &imag); template - marray, NumElements> make_complex_marray(const marray &real, const T &imag); + marray, NumElements> make_complex_marray(const marray &real, const T imag); template - marray, NumElements> make_complex_marray(const T &real, const marray &imag); + marray, NumElements> make_complex_marray(const T real, const marray &imag); template marray, NumElements> make_complex_marray(const marray &real, const marray &imag, std::integer_sequence int_seq); @@ -188,9 +188,9 @@ proposed. |`mgencomplex make_complex_marray(const mgenfloat& x, const mgenfloat& y);` |Constructs a marray of complex numbers with real values in marray x, and the imaginary values in marray y. -|`mgencomplex make_complex_marray(const mgenfloat& x, const genfloat& y);` +|`mgencomplex make_complex_marray(const mgenfloat& x, const genfloat y);` |Constructs a marray of complex numbers with real values in marray x, and the imaginary value y. -|`mgencomplex make_complex_marray(const genfloat& x, const mgenfloat& y);` +|`mgencomplex make_complex_marray(const genfloat x, const mgenfloat& y);` |Constructs a marray of complex numbers with real value x, and the imaginary values in marray y. |`mgencomplex make_complex_marray(const mgenfloat& x, const mgenfloat& y, std::integer_sequence int_seq);` |Constructs a marray of complex numbers from real values in marray x, and the imaginary values in marray y. Each element should be constructed from the corresponding index within `int_seq` and the returned marray size should be the same as the `int_seq` size. @@ -208,9 +208,9 @@ proposed. |Set each element of the real components in x to the corresponding element in y. |`void set_imag(mgencomplex& x, const mgenfloat& y);` |Set each element of the imaginary components in x to the corresponding element in y. -|`void set_real(mgencomplex& x, const genfloat& y);` +|`void set_real(mgencomplex& x, const genfloat y);` |Set each element of the real components in x to the decimal number y. -|`void set_imag(mgencomplex& x, const genfloat& y);` +|`void set_imag(mgencomplex& x, const genfloat y);` |Set each element of the imaginary components in x to the decimal number y. |=== From 7800fd4dd588208fdaae7929c1204a2a6a1a6fbb Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Tue, 16 Aug 2022 15:23:55 +0100 Subject: [PATCH 09/16] Remove const --- .../sycl_ext_oneapi_complex_marray.asciidoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index 09ad8ef4fb242..47eb80d3d0066 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -124,10 +124,10 @@ namespace oneapi { marray, NumElements> make_complex_marray(const marray &real, const marray &imag); template - marray, NumElements> make_complex_marray(const marray &real, const T imag); + marray, NumElements> make_complex_marray(const marray &real, T imag); template - marray, NumElements> make_complex_marray(const T real, const marray &imag); + marray, NumElements> make_complex_marray(T real, const marray &imag); template marray, NumElements> make_complex_marray(const marray &real, const marray &imag, std::integer_sequence int_seq); @@ -160,10 +160,10 @@ namespace oneapi { void set_imag(marray, NumElements> &input, const marray &values); template - void set_real(marray, NumElements> &input, const T value); + void set_real(marray, NumElements> &input, T value); template - void set_imag(marray, NumElements> &input, const T value); + void set_imag(marray, NumElements> &input, T value); } // namespace oneapi } // namespace ext @@ -188,9 +188,9 @@ proposed. |`mgencomplex make_complex_marray(const mgenfloat& x, const mgenfloat& y);` |Constructs a marray of complex numbers with real values in marray x, and the imaginary values in marray y. -|`mgencomplex make_complex_marray(const mgenfloat& x, const genfloat y);` +|`mgencomplex make_complex_marray(const mgenfloat& x, genfloat y);` |Constructs a marray of complex numbers with real values in marray x, and the imaginary value y. -|`mgencomplex make_complex_marray(const genfloat x, const mgenfloat& y);` +|`mgencomplex make_complex_marray(genfloat x, const mgenfloat& y);` |Constructs a marray of complex numbers with real value x, and the imaginary values in marray y. |`mgencomplex make_complex_marray(const mgenfloat& x, const mgenfloat& y, std::integer_sequence int_seq);` |Constructs a marray of complex numbers from real values in marray x, and the imaginary values in marray y. Each element should be constructed from the corresponding index within `int_seq` and the returned marray size should be the same as the `int_seq` size. @@ -208,9 +208,9 @@ proposed. |Set each element of the real components in x to the corresponding element in y. |`void set_imag(mgencomplex& x, const mgenfloat& y);` |Set each element of the imaginary components in x to the corresponding element in y. -|`void set_real(mgencomplex& x, const genfloat y);` +|`void set_real(mgencomplex& x, genfloat y);` |Set each element of the real components in x to the decimal number y. -|`void set_imag(mgencomplex& x, const genfloat y);` +|`void set_imag(mgencomplex& x, genfloat y);` |Set each element of the imaginary components in x to the decimal number y. |=== From dad26bd85eaaa9f3dea4428b912c77352a573a4e Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Tue, 16 Aug 2022 15:26:13 +0100 Subject: [PATCH 10/16] Extend change to math functions --- .../sycl_ext_oneapi_complex_marray.asciidoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index 47eb80d3d0066..21d324ebbd629 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -267,11 +267,11 @@ namespace oneapi { mgenfloat norm(const mgencomplex& x); mgencomplex polar(const mgenfloat& rho, const mgenfloat& theta); - mgencomplex polar(const mgenfloat& rho, const genfloat& theta = 0); - mgencomplex polar(const genfloat& rho, const mgenfloat& theta); + mgencomplex polar(const mgenfloat& rho, genfloat theta = 0); + mgencomplex polar(genfloat rho, const mgenfloat& theta); mgencomplex pow(const mgencomplex& x, const mgenfloat& y); - mgencomplex pow(const mgencomplex& x, const genfloat& y); + mgencomplex pow(const mgencomplex& x, genfloat y); mgencomplex pow(const gencomplex& x, const mgenfloat& y); mgencomplex pow(const mgencomplex& x, const mgencomplex& y); @@ -280,7 +280,7 @@ namespace oneapi { mgencomplex pow(const mgenfloat& x, const mgencomplex& y); mgencomplex pow(const mgenfloat& x, const gencomplex& y); - mgencomplex pow(const genfloat& x, const mgencomplex& y); + mgencomplex pow(genfloat x, const mgencomplex& y); mgencomplex proj(const mgencomplex& x); mgencomplex proj(const mgenfloat& x); @@ -340,13 +340,13 @@ mathematical operation. |Compute the squared magnitude for each complex number in marray x. |`mgencomplex polar(const mgenfloat& rho, const mgenfloat& theta)` |Construct an marray, elementwise, of complex numbers from each polar coordinate in marray rho and marray theta. -|`mgencomplex polar(const mgenfloat& rho, const genfloat& theta = 0)` +|`mgencomplex polar(const mgenfloat& rho, genfloat theta = 0)` |Construct an marray, elementwise, of complex numbers from each polar coordinate in marray rho and scalar theta. -|`mgencomplex polar(const genfloat& rho, const mgenfloat& theta)` +|`mgencomplex polar(genfloat rho, const mgenfloat& theta)` |Construct an marray, elementwise, of complex numbers from each polar coordinate in scalar rho and marray theta. |`mgencomplex pow(const mgencomplex& x, const mgenfloat& y)` |Raise each complex element in x to the power of the corresponding decimal element in y. -|`mgencomplex pow(const mgencomplex& x, const genfloat& y)` +|`mgencomplex pow(const mgencomplex& x, genfloat y)` |Raise each complex element in x to the power of the decimal number y. |`mgencomplex pow(const gencomplex& x, const mgenfloat& y)` |Raise complex number x to the power of each decimal element in y. @@ -360,7 +360,7 @@ mathematical operation. |Raise each decimal element in x to the power of the corresponding complex element in y. |`mgencomplex pow(const mgenfloat& x, const gencomplex& y)` |Raise each decimal element in x to the power of the complex number y. -|`mgencomplex pow(const genfloat& x, const mgencomplex& y)` +|`mgencomplex pow(genfloat x, const mgencomplex& y)` |Raise decimal number x to the power of each complex element in y. |`mgencomplex proj(const mgencomplex& x)` |Compute the projection for each complex number in marray x. From 18cca203358b0d644d2003440271fa52f05fd395 Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Wed, 24 Aug 2022 10:13:55 +0100 Subject: [PATCH 11/16] Update title --- .../extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index 21d324ebbd629..cf4f02d2c4d40 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -89,7 +89,7 @@ supports. |Initial version of this extension. |=== -=== Marray Complex Class Specialization +=== Marray Complex Class Instantiation The `marray` class is extended for the `sycl::ext::oneapi::complex` class. The user interface of the `marray` From 0f9996448c158c968661252c08a67fd719392929 Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Wed, 24 Aug 2022 15:10:11 +0100 Subject: [PATCH 12/16] remove unneded line --- .../extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc | 1 - 1 file changed, 1 deletion(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index cf4f02d2c4d40..daa759d0861db 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -91,7 +91,6 @@ supports. === Marray Complex Class Instantiation -The `marray` class is extended for the `sycl::ext::oneapi::complex` class. The user interface of the `marray` class is not changed compared to the SYCL-2020 generic `marray` interface. From d6ebad6acb7dc002bcc11f8e3778e7f2ea8c4eca Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Wed, 31 Aug 2022 15:37:38 +0100 Subject: [PATCH 13/16] Make free functions member functions --- .../sycl_ext_oneapi_complex_marray.asciidoc | 260 ++++++++++++------ 1 file changed, 183 insertions(+), 77 deletions(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index daa759d0861db..f3cc8e4c1b4b8 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -62,10 +62,10 @@ This extension is not currently implemented in {dpcpp}. == Overview {dpcpp} has support for `sycl::ext::oneapi::complex` this allows for the -addition of new complex math features. This proposes the instantiation of +addition of new complex math features. This proposes the specialization of `marray` to add support for complex numbers to be stored in arrays. The proposal includes overloading the existing math functions to support complex -marrays and adding new free functions to simplify accessing, setting marray +marrays and adding member functions to simplify accessing, setting marray values, and construct complex marrays. == Specification @@ -89,128 +89,234 @@ supports. |Initial version of this extension. |=== -=== Marray Complex Class Instantiation +=== Marray Complex Class Specialization The user interface of the `marray` -class is not changed compared to the SYCL-2020 generic `marray` interface. +class is changed compared to the SYCL-2020 generic `marray` interface. +It adds new constructors, `real()`, and `imag()`. This changes the +`marray` interface when specialized for the `sycl::ext::oneapi::complex` +type. -The `marray` complex instantiation is trivially copyable, and the type +The `marray` complex specialization is trivially copyable, and the type trait `is_device_copyable` should resolve to `std::true_type`. -As the `marray` class is not specialized in this proposal. The `marray` -definition used within this proposal assumes that any operator the `marray` -class defines is only implemented if the marray's value type also -implements the operator. So, for example, `marray` does not -implement the modulus operator as float does not support it. As the -`marray` class is not changed in this proposal, it is not redefined below. - -The `make_complex_marray` free function is added to construct complex -marrays from real and imaginary components. Additionally, the free -functions `get_real` and `get_imag` are added to access the real and -imaginary components of the `marray` class without modifying the existing -`marray` interface. The usage of free functions does cause a deviation -from the `std::complex` interface. However, it does reduce this extensions -impact on the `marray` interface. +The `marray` definition used within this proposal assumes that any +operator the `marray` class defines is only implemented if the marray's +value type also implements the operator. So, for example, +`marray` does not implement the modulus operator as float does +not support it. The specialized marray class is shown below. ```C++ namespace sycl { namespace ext { namespace oneapi { - // Make_complex_marray + // Specialization of exiting `marray` class for `sycl::ext::oneapi::complex` + template + class marray , NumElements> { + private: + using DataT = sycl::ext::oneapi::complex; + public: + using value_type = DataT; + using reference = DataT&; + using const_reference = const DataT&; + using iterator = DataT*; + using const_iterator = const DataT*; - template - marray, NumElements> make_complex_marray(const marray &real, const marray &imag); + marray(); - template - marray, NumElements> make_complex_marray(const marray &real, T imag); + explicit constexpr marray(const DataT &arg); - template - marray, NumElements> make_complex_marray(T real, const marray &imag); + template + constexpr marray(const ArgTN&... args); - template - marray, NumElements> make_complex_marray(const marray &real, const marray &imag, std::integer_sequence int_seq); + constexpr marray(const marray &rhs); + constexpr marray(marray &&rhs); - template - marray, NumElements> make_complex_marray(const marray, NumElements> &cmplx, std::integer_sequence int_seq); + // Additional constructors + template + constexpr marray(const marray &real, const marray &imag); - // Get + template + constexpr marray(const marray &real, T imag); - // return marray of component - template - marray get_real(const marray, NumElements> &input); + template + constexpr marray(T real, const marray &imag); - template - marray get_imag(const marray, NumElements> &input); + template + constexpr marray(const marray &real, const marray &imag, std::integer_sequence int_seq); - // return sequence of elements of component - template - marray get_real(const marray, NumElements> &input, std::integer_sequence int_seq); + template + constexpr marray(const marray &cmplx, std::integer_sequence int_seq); - template - marray get_imag(const marray, NumElements> &input, std::integer_sequence int_seq); + // Available only when: NumElements == 1 + operator DataT() const; - // Set + static constexpr std::size_t size() noexcept; - template - void set_real(marray, NumElements> &input, const marray &values); + // real and imag + template + marray real(); - template - void set_imag(marray, NumElements> &input, const marray &values); + template + marray imag(); - template - void set_real(marray, NumElements> &input, T value); + template + marray real(std::integer_sequence int_seq); - template - void set_imag(marray, NumElements> &input, T value); + template + marray imag(std::integer_sequence int_seq); + + template + void real(const marray &values); + + template + void imag(const marray &values); + + template + void real(T value); + + template + void imag(T value); + + // subscript operator + reference operator[](std::size_t index); + const_reference operator[](std::size_t index) const; + + marray &operator=(const marray &rhs); + marray &operator=(const DataT &rhs); + + // iterator functions + iterator begin(); + const_iterator begin() const; + + iterator end(); + const_iterator end() const; + + // OP is: +, -, *, / + friend marray operatorOP(const marray &lhs, const marray &rhs) { /* ... */ } + friend marray operatorOP(const marray &lhs, const DataT &rhs) { /* ... */ } + + // OP is: % + friend marray operatorOP(const marray &lhs, const DataT &rhs) { /* ... */ } + + // OP is: +=, -=, *=, /= + friend marray &operatorOP(marray &lhs, const marray &rhs) { /* ... */ } + friend marray &operatorOP(marray &lhs, const DataT &rhs) { /* ... */ } + + // OP is: %= + friend marray &operatorOP(marray &lhs, const marray &rhs) { /* ... */ } + friend marray &operatorOP(marray &lhs, const DataT &rhs) { /* ... */ } + + // OP is prefix ++, -- + friend marray &operatorOP(marray &rhs) { /* ... */ } + + // OP is postfix ++, -- + friend marray operatorOP(marray& lhs, int) { /* ... */ } + + // OP is unary +, - + friend marray operatorOP(marray &rhs) { /* ... */ } + + // OP is: &, |, ^ + friend marray operatorOP(const marray &lhs, const marray &rhs) { /* ... */ } + friend marray operatorOP(const marray &lhs, const DataT &rhs) { /* ... */ } + + // OP is: &=, |=, ^= + friend marray &operatorOP(marray &lhs, const marray &rhs) { /* ... */ } + friend marray &operatorOP(marray &lhs, const DataT &rhs) { /* ... */ } + + // OP is: &&, || + friend marray operatorOP(const marray &lhs, const marray &rhs) { /* ... */ } + friend marray operatorOP(const marray& lhs, const DataT &rhs) { /* ... */ } + + // OP is: <<, >> + friend marray operatorOP(const marray &lhs, const marray &rhs) { /* ... */ } + friend marray operatorOP(const marray &lhs, const DataT &rhs) { /* ... */ } + + // OP is: <<=, >>= + friend marray &operatorOP(marray &lhs, const marray &rhs) { /* ... */ } + friend marray &operatorOP(marray &lhs, const DataT &rhs) { /* ... */ } + + // OP is: ==, != + friend marray operatorOP(const marray &lhs, const marray &rhs) { + /* ... */ } + friend marray operatorOP(const marray &lhs, const DataT &rhs) { + /* ... */ } + + // OP is: <, >, <=, >= + friend marray operatorOP(const marray &lhs, const marray &rhs) { /* ... */ } + friend marray operatorOP(const marray &lhs, const DataT &rhs) { /* ... */ } + + friend marray operator~(const marray &v) { /* ... */ } + // OP is: +, -, *, / + friend marray operatorOP(const DataT &lhs, const marray &rhs) { /* ... */ } + + // OP is: % + friend marray operatorOP(const DataT &lhs, const marray &rhs) { /* ... */ } + + // OP is: &, |, ^ + friend marray operatorOP(const DataT &lhs, const marray &rhs) { /* ... */ } + + // OP is: &&, || + friend marray operatorOP(const DataT &lhs, const marray &rhs) { /* ... */ } + + // OP is: <<, >> + friend marray operatorOP(const DataT &lhs, const marray &rhs) { /* ... */ } + + // OP is: ==, != + friend marray operatorOP(const DataT &lhs, const marray &rhs) { + /* ... */ } + + // OP is: <, >, <=, >= + friend marray operatorOP(const DataT &lhs, const marray &rhs) { /* ... */ } + + friend marray operator!(const marray &v) { /* ... */ } + } } // namespace oneapi } // namespace ext } // namespace sycl ``` -The table below shows the free functions operating on the `marray` type -when it is instantiated with `sycl::ext::oneapi::complex`, +The table below shows the new member functions added to the `marray` type +when it is specialized with `sycl::ext::oneapi::complex`, `sycl::ext::oneapi::complex`, and `sycl::ext::oneapi::complex`. For the purposes of this specification, we use the generic type name `mgencomplex` to represent -these three instantiations. However, there is no C++ type actually named +these three specializations. However, there is no C++ type actually named `mgencomplex`. -No table is provided for the `marray` class as no changes to it are -proposed. - [%header,cols="5,5"] |=== |Function |Description -|`mgencomplex make_complex_marray(const mgenfloat& x, const mgenfloat& y);` +|`marray(const mgenfloat& x, const mgenfloat& y);` |Constructs a marray of complex numbers with real values in marray x, and the imaginary values in marray y. -|`mgencomplex make_complex_marray(const mgenfloat& x, genfloat y);` +|`marray(const mgenfloat& x, genfloat y);` |Constructs a marray of complex numbers with real values in marray x, and the imaginary value y. -|`mgencomplex make_complex_marray(genfloat x, const mgenfloat& y);` +|`marray(genfloat x, const mgenfloat& y);` |Constructs a marray of complex numbers with real value x, and the imaginary values in marray y. -|`mgencomplex make_complex_marray(const mgenfloat& x, const mgenfloat& y, std::integer_sequence int_seq);` +|`marray(const mgenfloat& x, const mgenfloat& y, std::integer_sequence int_seq);` |Constructs a marray of complex numbers from real values in marray x, and the imaginary values in marray y. Each element should be constructed from the corresponding index within `int_seq` and the returned marray size should be the same as the `int_seq` size. -|`mgencomplex make_complex_marray(const mgencomplex& x, std::integer_sequence int_seq);` +|`marray(const mgencomplex& x, std::integer_sequence int_seq);` |Constructs a marray of complex numbers from a complex marray x. Each element should be constructed from the corresponding index within `int_seq` and the returned marray size should be the same as the `int_seq` size. -|`mgenfloat get_real(const mgencomplex& x);` -|Returns an marray of the real components for marray of complex numbers. -|`mgenfloat get_imag(const mgencomplex& x);` -|Returns an marray of the imaginary components for marray of complex numbers. -|`mgenfloat get_real(const mgencomplex& x, std::integer_sequence int_seq);` -|Returns a sequence of real components of the complex number x. Each element should be constructed from the corresponding index within `int_seq` and the returned marray size should be the same as the `int_seq` size. -|`mgenfloat get_imag(const mgencomplex& x, std::integer_sequence int_seq);` -|Returns a sequence of imaginary components of the complex number x. Each element should be constructed from the corresponding index within `int_seq` and the returned marray size should be the same as the `int_seq` size. -|`void set_real(mgencomplex& x, const mgenfloat& y);` -|Set each element of the real components in x to the corresponding element in y. -|`void set_imag(mgencomplex& x, const mgenfloat& y);` -|Set each element of the imaginary components in x to the corresponding element in y. -|`void set_real(mgencomplex& x, genfloat y);` -|Set each element of the real components in x to the decimal number y. -|`void set_imag(mgencomplex& x, genfloat y);` -|Set each element of the imaginary components in x to the decimal number y. +|`mgenfloat real();` +|Returns a marray of the real components for marray of complex numbers held by this `marray`. +|`mgenfloat imag();` +|Returns a marray of the imaginary components for marray of complex numbers held by this `marray`. +|`mgenfloat real(std::integer_sequence int_seq);` +|Returns a marray of real components of the complex number held by this `marray`. Each element should be constructed from the corresponding index within `int_seq` and the returned marray size should be the same as the `int_seq` size. +|`mgenfloat imag(std::integer_sequence int_seq);` +|Returns a marray of imaginary components of the complex number held by this `marray`. Each element should be constructed from the corresponding index within `int_seq` and the returned marray size should be the same as the `int_seq` size. +|`void real(const mgenfloat& y);` +|Set each element of the real components held by this `marray` to the corresponding element in y. +|`void imag(const mgenfloat& y);` +|Set each element of the imaginary components held by this `marray` to the corresponding element in y. +|`void real(genfloat y);` +|Set each element of the real components held by this `marray` to the decimal number y. +|`void imag(genfloat y);` +|Set each element of the imaginary components held by this `marray` to the decimal number y. |=== === Mathematical operations From 6ba06a0bc6a3992bb2ddad4f6694b9d50cd9c509 Mon Sep 17 00:00:00 2001 From: "aidan.belton" Date: Mon, 12 Sep 2022 09:48:30 +0100 Subject: [PATCH 14/16] Update real/imag keywords --- .../proposed/sycl_ext_oneapi_complex_marray.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index f3cc8e4c1b4b8..c6db2522f02f6 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -156,10 +156,10 @@ namespace oneapi { // real and imag template - marray real(); + constexpr marray real() const; template - marray imag(); + constexpr marray imag() const; template marray real(std::integer_sequence int_seq); From db5cbcc95a505c0303171b05768755bef8faa780 Mon Sep 17 00:00:00 2001 From: jle-quel Date: Thu, 17 Nov 2022 11:01:31 +0100 Subject: [PATCH 15/16] make sure the marray's complex proposal does compile --- .../sycl_ext_oneapi_complex_marray.asciidoc | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index c6db2522f02f6..2815008ab806a 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -134,19 +134,16 @@ namespace oneapi { constexpr marray(marray &&rhs); // Additional constructors - template constexpr marray(const marray &real, const marray &imag); - template constexpr marray(const marray &real, T imag); - template constexpr marray(T real, const marray &imag); - template + template constexpr marray(const marray &real, const marray &imag, std::integer_sequence int_seq); - template + template constexpr marray(const marray &cmplx, std::integer_sequence int_seq); // Available only when: NumElements == 1 @@ -155,28 +152,22 @@ namespace oneapi { static constexpr std::size_t size() noexcept; // real and imag - template constexpr marray real() const; - template constexpr marray imag() const; - template - marray real(std::integer_sequence int_seq); + template + constexpr auto real(std::integer_sequence int_seq); - template - marray imag(std::integer_sequence int_seq); + template + constexpr auto imag(std::integer_sequence int_seq); - template void real(const marray &values); - template void imag(const marray &values); - template void real(T value); - template void imag(T value); // subscript operator @@ -271,7 +262,7 @@ namespace oneapi { friend marray operatorOP(const DataT &lhs, const marray &rhs) { /* ... */ } friend marray operator!(const marray &v) { /* ... */ } - } + }; } // namespace oneapi } // namespace ext From 1164402de7331ed4b883cfa54b281af266b16aef Mon Sep 17 00:00:00 2001 From: jle-quel Date: Thu, 17 Nov 2022 11:02:51 +0100 Subject: [PATCH 16/16] add const keyword to integer_sequence getters --- .../proposed/sycl_ext_oneapi_complex_marray.asciidoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc index 2815008ab806a..cadbe399179c8 100644 --- a/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc +++ b/sycl/doc/extensions/proposed/sycl_ext_oneapi_complex_marray.asciidoc @@ -157,10 +157,10 @@ namespace oneapi { constexpr marray imag() const; template - constexpr auto real(std::integer_sequence int_seq); + constexpr auto real(std::integer_sequence int_seq) const; template - constexpr auto imag(std::integer_sequence int_seq); + constexpr auto imag(std::integer_sequence int_seq) const; void real(const marray &values);