77Data storage
88============
99
10- The data storage convention observed by a
11- :ref: `descriptor<onemkl_dft_descriptor> ` object depends on whether it is a real
12- or complex descriptor and, in case of complex descriptors, on the configuration
13- value associated with configuration parameter ``config_param::COMPLEX_STORAGE ``.
10+ The usage of prepended namespace specifiers ``oneapi::mkl::dft `` is
11+ omitted below for conciseness.
12+
13+ The data storage convention observed by a ``descriptor `` object depends on
14+ whether it is a real or complex descriptor and, in case of complex descriptors,
15+ on the configuration value associated with configuration parameter
16+ ``config_param::COMPLEX_STORAGE ``.
1417
1518.. _onemkl_dft_complex_storage :
1619
@@ -24,14 +27,12 @@ associated with a configuration value ``config_value::COMPLEX_COMPLEX`` (default
2427behavior), those entries are accessed and stored as ``std::complex<float> ``
2528(resp. ``std::complex<double> ``) elements of a single data container
2629(device-accessible USM allocation or ``sycl::buffer `` object) if the
27- :ref: `descriptor<onemkl_dft_descriptor> ` object is a single-precision (resp.
28- double-precision) descriptor. If the configuration value
29- ``config_value::REAL_REAL `` is used instead, the real and imaginary parts of
30- those entries are accessed and stored as ``float `` (resp. ``double ``) elements
31- of two separate, non-overlapping data containers (device-accessible USM
32- allocations or ``sycl::buffer `` objects) if the
33- :ref: `descriptor<onemkl_dft_descriptor> ` object is a single-precision (resp.
34- double-precision) descriptor.
30+ ``descriptor `` object is a single-precision (resp. double-precision) descriptor.
31+ If the configuration value ``config_value::REAL_REAL `` is used instead, the real
32+ and imaginary parts of those entries are accessed and stored as ``float `` (resp.
33+ ``double ``) elements of two separate, non-overlapping data containers
34+ (device-accessible USM allocations or ``sycl::buffer `` objects) if the
35+ ``descriptor `` object is a single-precision (resp. double-precision) descriptor.
3536
3637These two behaviors are further specified and illustrated below.
3738
@@ -45,20 +46,19 @@ sequences must belong to a single data container (device-accessible USM
4546allocation or ``sycl::buffer `` object). Any relevant entry
4647:math: `\left (\cdot \right )^{m}_{k_1 , k_2 ,\dots ,k_d}` is accessed/stored from/in
4748a data container provided at compute time at the index value expressed in eq.
48- :eq: `eq_idx_data_layout ` (from :ref: `this page<onemkl_dft_config_data_layouts> `)
49+ :eq: `eq_idx_data_layout ` (see the page dedicated to the
50+ :ref: `configuration of data layout<onemkl_dft_config_data_layouts> `)
4951of that data container, whose elementary data type is (possibly implicitly
5052re-interpreted as) ``std::complex<float> `` (resp. ``std::complex<double> ``) for
5153single-precision (resp. double-precision) descriptors.
5254
5355The same unique data container is to be used for forward- and backward-domain
54- data sequences for in-place transforms (for
55- :ref: `descriptor<onemkl_dft_descriptor> ` objects with configuration value
56- ``config_value::INPLACE `` for configuration parameter
56+ data sequences for in-place transforms (for ``descriptor `` objects with
57+ configuration value ``config_value::INPLACE `` for configuration parameter
5758``config_param::PLACEMENT ``). Two separate data containers sharing no common
58- elements are to be used for out-of-place transforms (for
59- :ref: `descriptor<onemkl_dft_descriptor> ` objects with configuration value
60- ``config_value::NOT_INPLACE `` for configuration parameter
61- ``config_param::PLACEMENT ``).
59+ elements are to be used for out-of-place transforms (for ``descriptor `` objects
60+ with configuration value ``config_value::NOT_INPLACE `` for configuration
61+ parameter ``config_param::PLACEMENT ``).
6262
6363The following snippet illustrates the usage of ``config_value::COMPLEX_COMPLEX ``
6464for configuration parameter ``config_param::COMPLEX_STORAGE ``, in the
@@ -84,8 +84,8 @@ USM allocations.
8484
8585 // initialize forward-domain data such that entry {m;k1,k2,k3}
8686 // = Z[ strides[0] + k1*strides[1] + k2*strides[2] + k3*strides[3] + m*dist ]
87- compute_forward(desc, Z); // complex-to-complex in-place DFT
88- // in backward domain: entry {m;k1,k2,k3}
87+ auto ev = compute_forward(desc, Z); // complex-to-complex in-place DFT
88+ // Upon completion of ev, in backward domain: entry {m;k1,k2,k3}
8989 // = Z[ strides[0] + k1*strides[1] + k2*strides[2] + k3*strides[3] + m*dist ]
9090
9191 .. _onemkl_dft_complex_storage_real_real :
@@ -98,21 +98,20 @@ read/stored from/in two different, non-overlapping data containers
9898(device-accessible USM allocations or ``sycl::buffer `` objects) encapsulating
9999the real and imaginary parts of the relevant entries separately. The real and
100100imaginary parts of any relevant complex entry
101- :math: `\left (\cdot \right )^{m}_{k_1 , k_2 ,\dots ,k_d}` are both stored at the index value
102- expressed in eq. :eq: `eq_idx_data_layout ` (from :ref: `this
103- page<onemkl_dft_config_data_layouts>`) of their respective data containers, whose elementary
104- data type is (possibly implicitly re-interpreted as) ``float `` (resp.
105- ``double ``) for single-precision (resp. double-precision) descriptors.
101+ :math: `\left (\cdot \right )^{m}_{k_1 , k_2 ,\dots ,k_d}` are both stored at the
102+ index value expressed in eq. :eq: `eq_idx_data_layout ` (see the page dedicated to
103+ the :ref: `configuration of data layout<onemkl_dft_config_data_layouts> `) of
104+ their respective data containers, whose elementary data type is (possibly
105+ implicitly re-interpreted as) ``float `` (resp. ``double ``) for single-precision
106+ (resp. double-precision) descriptors.
106107
107108The same two data containers are to be used for real and imaginary parts of
108109forward- and backward-domain data sequences for in-place transforms (for
109- :ref: `descriptor<onemkl_dft_descriptor> ` objects with configuration value
110- ``config_value::INPLACE `` for configuration parameter
111- ``config_param::PLACEMENT ``). Four separate data containers sharing no common
112- elements are to be used for out-of-place transforms (for
113- :ref: `descriptor<onemkl_dft_descriptor> ` objects with configuration value
114- ``config_value::NOT_INPLACE `` for configuration parameter
115- ``config_param::PLACEMENT ``).
110+ ``descriptor `` objects with configuration value ``config_value::INPLACE `` for
111+ configuration parameter ``config_param::PLACEMENT ``). Four separate data
112+ containers sharing no common elements are to be used for out-of-place transforms
113+ (for ``descriptor `` objects with configuration value ``config_value::NOT_INPLACE ``
114+ for configuration parameter ``config_param::PLACEMENT ``).
116115
117116The following snippet illustrates the usage of ``config_value::REAL_REAL ``
118117set for configuration parameter ``config_param::COMPLEX_STORAGE ``, in the
@@ -141,8 +140,8 @@ USM allocations.
141140 // = ZR[ strides[0] + k1*strides[1] + k2*strides[2] + k3*strides[3] + m*dist ]
142141 // and the imaginary part of entry {m;k1,k2,k3}
143142 // = ZI[ strides[0] + k1*strides[1] + k2*strides[2] + k3*strides[3] + m*dist ]
144- compute_forward<decltype(desc), float>(desc, ZR, ZI); // complex-to-complex in-place DFT
145- // in backward domain: the real part of entry {m;k1,k2,k3}
143+ auto ev = compute_forward<decltype(desc), float>(desc, ZR, ZI); // complex-to-complex in-place DFT
144+ // Upon completion of ev, in backward domain: the real part of entry {m;k1,k2,k3}
146145 // = ZR[ strides[0] + k1*strides[1] + k2*strides[2] + k3*strides[3] + m*dist ]
147146 // and the imaginary part of entry {m;k1,k2,k3}
148147 // = ZI[ strides[0] + k1*strides[1] + k2*strides[2] + k3*strides[3] + m*dist ]
@@ -156,14 +155,13 @@ Real descriptors observe only one type of data storage. Any relevant (real)
156155entry :math: `\left (\cdot \right )^{m}_{k_1 , k_2 ,\dots ,k_d}` of a data sequence
157156in forward domain is accessed and stored as a ``float `` (resp. ``double ``)
158157element of a single data container (device-accessible USM allocation or
159- ``sycl::buffer `` object) if the :ref: `descriptor<onemkl_dft_descriptor> ` object
160- is a single-precision (resp. double-precision) descriptor. Any relevant
161- (complex) entry :math: `\left (\cdot \right )^{m}_{k_1 , k_2 ,\dots ,k_d}` of a data
162- sequence in backward domain is accessed and stored as a ``std::complex<float> ``
163- (resp. ``std::complex<double> ``) element of a single data container
164- (device-accessible USM allocation or ``sycl::buffer `` object) if the
165- :ref: `descriptor<onemkl_dft_descriptor> ` object is a single-precision (resp.
166- double-precision) descriptor.
158+ ``sycl::buffer `` object) if the ``descriptor `` object is a single-precision
159+ (resp. double-precision) descriptor. Any relevant (complex) entry
160+ :math: `\left (\cdot \right )^{m}_{k_1 , k_2 ,\dots ,k_d}` of a data sequence in
161+ backward domain is accessed and stored as a ``std::complex<float> `` (resp.
162+ ``std::complex<double> ``) element of a single data container (device-accessible
163+ USM allocation or ``sycl::buffer `` object) if the
164+ ``descriptor `` object is a single-precision (resp. double-precision) descriptor.
167165
168166The following snippet illustrates the usage of a real, single-precision
169167descriptor (and the corresponding data storage) for the in-place,
@@ -190,12 +188,13 @@ forward and backward domains, with USM allocations.
190188
191189 // initialize forward-domain data such that real entry {m;k1,k2,k3}
192190 // = data[ fwd_strides[0] + k1*fwd_strides[1] + k2*fwd_strides[2] + k3*fwd_strides[3] + m*fwd_dist ]
193- compute_forward(desc, data); // real-to-complex in-place DFT
194- // in backward domain, the implicitly-assumed type is complex so, considering
191+ auto ev = compute_forward(desc, data); // real-to-complex in-place DFT
192+ // In backward domain, the implicitly-assumed type is complex so, consider
195193 // std::complex<float>* complex_data = static_cast<std::complex<float>*>(data);
196- // we have entry {m;k1,k2,k3}
194+ // upon completion of ev, the backward-domain entry {m;k1,k2,k3} is
197195 // = complex_data[ bwd_strides[0] + k1*bwd_strides[1] + k2*bwd_strides[2] + k3*bwd_strides[3] + m*bwd_dist ]
198196 // for 0 <= k3 <= n3/2.
199- // Note: if n3/2 < k3 < n3, entry {m;k1,k2,k3} = std::conj(entry {m;n1-k1,n2-k2,n3-k3})
197+ // Note: if n3/2 < k3 < n3, entry {m;k1,k2,k3} is not stored explicitly
198+ // since it is equal to std::conj(entry {m;n1-k1,n2-k2,n3-k3})
200199
201200 **Parent topic ** :ref: `onemkl_dft_enums `
0 commit comments