-
Notifications
You must be signed in to change notification settings - Fork 801
[SYCL][Doc] Add SYCL marray complex extension proposal #6550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
b60a636
d54a484
bcb15ba
83b027e
4c93f61
0d647f7
0fe2418
c11762c
7800fd4
dad26bd
18cca20
0f99964
d6ebad6
6ba06a0
db5cbcc
1164402
7aedfc9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,399 @@ | ||
| = sycl_ext_oneapi_complex_marray | ||
|
|
||
| :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. | ||
|
|
||
| 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]. | ||
|
|
||
|
|
||
| == 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 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 | ||
| 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_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 | ||
| supports. | ||
|
|
||
| [%header,cols="1,5"] | ||
| |=== | ||
| |Value | ||
| |Description | ||
|
|
||
| |1 | ||
| |Initial version of this extension. | ||
| |=== | ||
|
|
||
| === Marray Complex Class Specialization | ||
jle-quel marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| The `marray` class is extended for the `sycl::ext::oneapi::complex` class. | ||
jle-quel marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| The user interface of the `marray<sycl::ext::oneapi::complex, {N}>` | ||
| class is not changed compared to the SYCL-2020 generic `marray` interface. | ||
|
|
||
| The `marray` complex instantiation 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<float, N>` 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. | ||
|
|
||
| ```C++ | ||
| namespace sycl { | ||
| namespace ext { | ||
| namespace oneapi { | ||
|
|
||
| // Make_complex_marray | ||
|
||
|
|
||
| template <class T, std::size_t NumElements> | ||
| marray<sycl::ext::oneapi::complex<T>, NumElements> make_complex_marray(const marray<T, NumElements> &real, const marray<T, NumElements> &imag); | ||
|
|
||
| template <class T, std::size_t NumElements> | ||
| marray<sycl::ext::oneapi::complex<T>, NumElements> make_complex_marray(const marray<T, NumElements> &real, const T &imag); | ||
|
|
||
| template <class T, std::size_t NumElements> | ||
| marray<sycl::ext::oneapi::complex<T>, NumElements> make_complex_marray(const T &real, const marray<T, NumElements> &imag); | ||
|
|
||
| template <class T, std::size_t NumElements, std::size_t... I> | ||
| marray<sycl::ext::oneapi::complex<T>, NumElements> make_complex_marray(const marray<T, NumElements> &real, const marray<T, NumElements> &imag, std::integer_sequence<std::size_t, I...> int_seq); | ||
|
|
||
| template <class T, std::size_t NumElements, std::size_t... I> | ||
| marray<sycl::ext::oneapi::complex<T>, NumElements> make_complex_marray(const marray<sycl::ext::oneapi::complex<T>, NumElements> &cmplx, std::integer_sequence<std::size_t, I...> int_seq); | ||
|
|
||
| // Get | ||
|
|
||
| // return marray of component | ||
| template <class T, std::size_t NumElements> | ||
| marray<T, NumElements> get_real(const marray<sycl::ext::oneapi::complex<T>, NumElements> &input); | ||
|
||
|
|
||
| template <class T, std::size_t NumElements> | ||
| marray<T, NumElements> get_imag(const marray<sycl::ext::oneapi::complex<T>, NumElements> &input); | ||
|
|
||
| // return sequence of elements of component | ||
| template <class T, std::size_t NumElements, std::size_t... I> | ||
| marray<T, int_seq::size()> get_real(const marray<sycl::ext::oneapi::complex<T>, NumElements> &input, std::integer_sequence<std::size_t, I...> int_seq); | ||
|
|
||
| template <class T, std::size_t NumElements, std::size_t... I> | ||
| marray<T, int_seq::size()> get_imag(const marray<sycl::ext::oneapi::complex<T>, NumElements> &input, std::integer_sequence<std::size_t, I...> int_seq); | ||
|
|
||
| // Set | ||
|
|
||
| template <class T, std::size_t NumElements> | ||
| void set_real(marray<sycl::ext::oneapi::complex<T>, NumElements> &input, const marray<T, NumElements> &values); | ||
|
|
||
| template <class T, std::size_t NumElements> | ||
| void set_imag(marray<sycl::ext::oneapi::complex<T>, NumElements> &input, const marray<T, NumElements> &values); | ||
|
|
||
| template <class T, std::size_t NumElements> | ||
| void set_real(marray<sycl::ext::oneapi::complex<T>, NumElements> &input, const T value); | ||
|
|
||
| template <class T, std::size_t NumElements> | ||
| void set_imag(marray<sycl::ext::oneapi::complex<T>, NumElements> &input, const T value); | ||
|
|
||
| } // namespace oneapi | ||
| } // namespace ext | ||
| } // namespace sycl | ||
| ``` | ||
|
|
||
| The class `sycl::ext::oneapi::marray<sycl::ext::oneapi::complex<T>, N>`, | ||
| has instantiations of `T`; `float`, `double`, and `sycl::half` declared. | ||
gmlueck marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ```C++ | ||
| namespace sycl { | ||
| namespace ext { | ||
| namespace oneapi { | ||
|
|
||
| template <std::size_t NumElements> | ||
| class marray<sycl::ext::oneapi::complex<double>, NumElements>; | ||
|
|
||
| template <std::size_t NumElements> | ||
| class marray<sycl::ext::oneapi::complex<float>, NumElements>; | ||
|
|
||
| template <std::size_t NumElements> | ||
| class marray<sycl::ext::oneapi::complex<sycl::half>, NumElements>; | ||
|
|
||
| } // namespace oneapi | ||
| } // namespace ext | ||
| } // namespace sycl | ||
| ``` | ||
|
|
||
| The generic type `mgencomplex` is defined as types | ||
| `marray<sycl::ext::oneapi::complex<double>, {N}>`, | ||
| `marray<sycl::ext::oneapi::complex<float>, {N}>`, | ||
| `marray<sycl::ext::oneapi::complex<sycl::half>, {N}>`. | ||
gmlueck marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| 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 | ||
| proposed. | ||
|
|
||
| [%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);` | ||
gmlueck marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| |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::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. | ||
| |=== | ||
|
|
||
| === 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); | ||
gmlueck marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| 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 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)` | ||
| |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 number 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. | ||
| |=== | ||
Uh oh!
There was an error while loading. Please reload this page.