7
7
Data storage
8
8
============
9
9
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 ``.
14
17
15
18
.. _onemkl_dft_complex_storage :
16
19
@@ -24,14 +27,12 @@ associated with a configuration value ``config_value::COMPLEX_COMPLEX`` (default
24
27
behavior), those entries are accessed and stored as ``std::complex<float> ``
25
28
(resp. ``std::complex<double> ``) elements of a single data container
26
29
(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.
35
36
36
37
These two behaviors are further specified and illustrated below.
37
38
@@ -45,20 +46,19 @@ sequences must belong to a single data container (device-accessible USM
45
46
allocation or ``sycl::buffer `` object). Any relevant entry
46
47
:math: `\left (\cdot \right )^{m}_{k_1 , k_2 ,\dots ,k_d}` is accessed/stored from/in
47
48
a 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> `)
49
51
of that data container, whose elementary data type is (possibly implicitly
50
52
re-interpreted as) ``std::complex<float> `` (resp. ``std::complex<double> ``) for
51
53
single-precision (resp. double-precision) descriptors.
52
54
53
55
The 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
57
58
``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 ``).
62
62
63
63
The following snippet illustrates the usage of ``config_value::COMPLEX_COMPLEX ``
64
64
for configuration parameter ``config_param::COMPLEX_STORAGE ``, in the
@@ -84,8 +84,8 @@ USM allocations.
84
84
85
85
// initialize forward-domain data such that entry {m;k1,k2,k3}
86
86
// = 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}
89
89
// = Z[ strides[0] + k1*strides[1] + k2*strides[2] + k3*strides[3] + m*dist ]
90
90
91
91
.. _onemkl_dft_complex_storage_real_real :
@@ -98,21 +98,20 @@ read/stored from/in two different, non-overlapping data containers
98
98
(device-accessible USM allocations or ``sycl::buffer `` objects) encapsulating
99
99
the real and imaginary parts of the relevant entries separately. The real and
100
100
imaginary 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.
106
107
107
108
The same two data containers are to be used for real and imaginary parts of
108
109
forward- 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 ``).
116
115
117
116
The following snippet illustrates the usage of ``config_value::REAL_REAL ``
118
117
set for configuration parameter ``config_param::COMPLEX_STORAGE ``, in the
@@ -141,8 +140,8 @@ USM allocations.
141
140
// = ZR[ strides[0] + k1*strides[1] + k2*strides[2] + k3*strides[3] + m*dist ]
142
141
// and the imaginary part of entry {m;k1,k2,k3}
143
142
// = 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}
146
145
// = ZR[ strides[0] + k1*strides[1] + k2*strides[2] + k3*strides[3] + m*dist ]
147
146
// and the imaginary part of entry {m;k1,k2,k3}
148
147
// = 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)
156
155
entry :math: `\left (\cdot \right )^{m}_{k_1 , k_2 ,\dots ,k_d}` of a data sequence
157
156
in forward domain is accessed and stored as a ``float `` (resp. ``double ``)
158
157
element 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.
167
165
168
166
The following snippet illustrates the usage of a real, single-precision
169
167
descriptor (and the corresponding data storage) for the in-place,
@@ -190,12 +188,13 @@ forward and backward domains, with USM allocations.
190
188
191
189
// initialize forward-domain data such that real entry {m;k1,k2,k3}
192
190
// = 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
195
193
// 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
197
195
// = complex_data[ bwd_strides[0] + k1*bwd_strides[1] + k2*bwd_strides[2] + k3*bwd_strides[3] + m*bwd_dist ]
198
196
// 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})
200
199
201
200
**Parent topic ** :ref: `onemkl_dft_enums `
0 commit comments