Skip to content

Commit 24fb8d2

Browse files
authored
Merge 57ff795 into 0b7c230
2 parents 0b7c230 + 57ff795 commit 24fb8d2

20 files changed

+1779
-234
lines changed

doc/known_words.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
al
12
backend
23
bitwise
34
boolean
@@ -9,7 +10,9 @@ combinatorially
910
conda
1011
cubically
1112
Decompositions
13+
diag
1214
dimensionality
15+
discretized
1316
docstring
1417
dpctl
1518
dpnp
@@ -19,9 +22,11 @@ einsum
1922
endian
2023
eps
2124
epsneg
25+
et
2226
Extrema
2327
finfo
2428
finiteness
29+
Flannery
2530
Fortran
2631
Frobenius
2732
Hadamard
@@ -41,10 +46,12 @@ ndarray
4146
ndarrays
4247
ndim
4348
normed
49+
Nyquist
4450
oneAPI
4551
orthonormal
4652
Penrose
4753
Polyutils
54+
pre
4855
prepend
4956
prepending
5057
representable
@@ -58,14 +65,21 @@ subclasses
5865
subtype
5966
SyclDevice
6067
SyclQueue
68+
tensordot
69+
Teukolsky
6170
th
71+
tril
72+
triu
73+
Tukey
6274
ufunc
6375
ufuncs
6476
Unary
77+
unscaled
6578
unicode
6679
usm
6780
Vandermonde
6881
vectorized
82+
Vetterline
6983
von
7084
Weibull
7185
whitespace

doc/reference/fft.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,5 @@ Helper routines
6363
.. dpnp.fft.config.set_cufft_gpus
6464
.. dpnp.fft.config.get_plan_cache
6565
.. dpnp.fft.config.show_plan_cache_info
66+
67+
.. automodule:: dpnp.fft

dpnp/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ endfunction()
5757
build_dpnp_cython_ext_with_backend(dparray ${CMAKE_CURRENT_SOURCE_DIR}/dparray.pyx dpnp)
5858
add_subdirectory(backend)
5959
add_subdirectory(backend/extensions/blas)
60+
add_subdirectory(backend/extensions/fft)
6061
add_subdirectory(backend/extensions/lapack)
6162
add_subdirectory(backend/extensions/vm)
6263
add_subdirectory(backend/extensions/sycl_ext)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# *****************************************************************************
2+
# Copyright (c) 2024, Intel Corporation
3+
# All rights reserved.
4+
#
5+
# Redistribution and use in source and binary forms, with or without
6+
# modification, are permitted provided that the following conditions are met:
7+
# - Redistributions of source code must retain the above copyright notice,
8+
# this list of conditions and the following disclaimer.
9+
# - Redistributions in binary form must reproduce the above copyright notice,
10+
# this list of conditions and the following disclaimer in the documentation
11+
# and/or other materials provided with the distribution.
12+
#
13+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
17+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23+
# THE POSSIBILITY OF SUCH DAMAGE.
24+
# *****************************************************************************
25+
26+
27+
set(python_module_name _fft_impl)
28+
set(_module_src
29+
${CMAKE_CURRENT_SOURCE_DIR}/fft_py.cpp
30+
${CMAKE_CURRENT_SOURCE_DIR}/c2c_in.cpp
31+
${CMAKE_CURRENT_SOURCE_DIR}/c2c_out.cpp
32+
)
33+
34+
pybind11_add_module(${python_module_name} MODULE ${_module_src})
35+
add_sycl_to_target(TARGET ${python_module_name} SOURCES ${_module_src})
36+
37+
if (WIN32)
38+
if (${CMAKE_VERSION} VERSION_LESS "3.27")
39+
# this is a work-around for target_link_options inserting option after -link option, cause
40+
# linker to ignore it.
41+
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -fsycl-device-code-split=per_kernel")
42+
endif()
43+
endif()
44+
45+
set_target_properties(${python_module_name} PROPERTIES CMAKE_POSITION_INDEPENDENT_CODE ON)
46+
47+
target_include_directories(${python_module_name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../include)
48+
target_include_directories(${python_module_name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../src)
49+
50+
target_include_directories(${python_module_name} PUBLIC ${Dpctl_INCLUDE_DIRS})
51+
target_include_directories(${python_module_name} PUBLIC ${Dpctl_TENSOR_INCLUDE_DIR})
52+
53+
if (WIN32)
54+
target_compile_options(${python_module_name} PRIVATE
55+
/clang:-fno-approx-func
56+
/clang:-fno-finite-math-only
57+
)
58+
else()
59+
target_compile_options(${python_module_name} PRIVATE
60+
-fno-approx-func
61+
-fno-finite-math-only
62+
)
63+
endif()
64+
65+
target_link_options(${python_module_name} PUBLIC -fsycl-device-code-split=per_kernel)
66+
67+
if (DPNP_GENERATE_COVERAGE)
68+
target_link_options(${python_module_name} PRIVATE -fprofile-instr-generate -fcoverage-mapping)
69+
endif()
70+
71+
target_link_libraries(${python_module_name} PUBLIC MKL::MKL_SYCL::DFT)
72+
73+
install(TARGETS ${python_module_name}
74+
DESTINATION "dpnp/backend/extensions/fft"
75+
)

dpnp/backend/extensions/fft/c2c.hpp

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
//*****************************************************************************
2+
// Copyright (c) 2024, Intel Corporation
3+
// All rights reserved.
4+
//
5+
// Redistribution and use in source and binary forms, with or without
6+
// modification, are permitted provided that the following conditions are met:
7+
// - Redistributions of source code must retain the above copyright notice,
8+
// this list of conditions and the following disclaimer.
9+
// - Redistributions in binary form must reproduce the above copyright notice,
10+
// this list of conditions and the following disclaimer in the documentation
11+
// and/or other materials provided with the distribution.
12+
//
13+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
17+
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23+
// THE POSSIBILITY OF SUCH DAMAGE.
24+
//*****************************************************************************
25+
26+
#pragma once
27+
28+
#include <oneapi/mkl.hpp>
29+
#include <sycl/sycl.hpp>
30+
31+
#include <dpctl4pybind11.hpp>
32+
33+
namespace dpnp::extensions::fft
34+
{
35+
namespace mkl_dft = oneapi::mkl::dft;
36+
namespace py = pybind11;
37+
38+
template <mkl_dft::precision prec>
39+
class ComplexDescriptorWrapper
40+
{
41+
public:
42+
using descr_type = mkl_dft::descriptor<prec, mkl_dft::domain::COMPLEX>;
43+
44+
ComplexDescriptorWrapper(std::int64_t n) : descr_(n), queue_ptr_{} {}
45+
ComplexDescriptorWrapper(std::vector<std::int64_t> dimensions)
46+
: descr_(dimensions), queue_ptr_{}
47+
{
48+
}
49+
~ComplexDescriptorWrapper() {}
50+
51+
void commit(sycl::queue &q)
52+
{
53+
mkl_dft::precision fft_prec = get_precision();
54+
if (fft_prec == mkl_dft::precision::DOUBLE &&
55+
!q.get_device().has(sycl::aspect::fp64))
56+
{
57+
throw py::value_error("Descriptor is double precision but the "
58+
"device does not support double precision.");
59+
}
60+
61+
descr_.commit(q);
62+
queue_ptr_ = std::make_unique<sycl::queue>(q);
63+
}
64+
65+
descr_type &get_descriptor() { return descr_; }
66+
67+
const sycl::queue &get_queue() const
68+
{
69+
if (queue_ptr_) {
70+
return *queue_ptr_;
71+
}
72+
else {
73+
throw std::runtime_error(
74+
"Attempt to get queue when it is not yet set");
75+
}
76+
}
77+
78+
// config_param::DIMENSION
79+
template <typename valT = std::int64_t>
80+
valT get_dim()
81+
{
82+
valT dim = -1;
83+
descr_.get_value(mkl_dft::config_param::DIMENSION, &dim);
84+
85+
return dim;
86+
}
87+
88+
// config_param::NUMBER_OF_TRANSFORMS
89+
template <typename valT = std::int64_t>
90+
valT get_number_of_transforms()
91+
{
92+
valT transforms_count{};
93+
94+
descr_.get_value(mkl_dft::config_param::NUMBER_OF_TRANSFORMS,
95+
&transforms_count);
96+
return transforms_count;
97+
}
98+
99+
template <typename valT = std::int64_t>
100+
void set_number_of_transforms(const valT num)
101+
{
102+
descr_.set_value(mkl_dft::config_param::NUMBER_OF_TRANSFORMS, num);
103+
}
104+
105+
// config_param::FWD_STRIDES
106+
template <typename valT = std::vector<std::int64_t>>
107+
valT get_fwd_strides()
108+
{
109+
const typename valT::value_type dim = get_dim();
110+
111+
valT fwd_strides(dim + 1);
112+
descr_.get_value(mkl_dft::config_param::FWD_STRIDES,
113+
fwd_strides.data());
114+
return fwd_strides;
115+
}
116+
117+
template <typename valT = std::vector<std::int64_t>>
118+
void set_fwd_strides(const valT &strides)
119+
{
120+
const typename valT::value_type dim = get_dim();
121+
122+
if (static_cast<size_t>(dim + 1) != strides.size()) {
123+
throw py::value_error(
124+
"Strides length does not match descriptor's dimension");
125+
}
126+
descr_.set_value(mkl_dft::config_param::FWD_STRIDES, strides.data());
127+
}
128+
129+
// config_param::BWD_STRIDES
130+
template <typename valT = std::vector<std::int64_t>>
131+
valT get_bwd_strides()
132+
{
133+
const typename valT::value_type dim = get_dim();
134+
135+
valT bwd_strides(dim + 1);
136+
descr_.get_value(mkl_dft::config_param::BWD_STRIDES,
137+
bwd_strides.data());
138+
return bwd_strides;
139+
}
140+
141+
template <typename valT = std::vector<std::int64_t>>
142+
void set_bwd_strides(const valT &strides)
143+
{
144+
const typename valT::value_type dim = get_dim();
145+
146+
if (static_cast<size_t>(dim + 1) != strides.size()) {
147+
throw py::value_error(
148+
"Strides length does not match descriptor's dimension");
149+
}
150+
descr_.set_value(mkl_dft::config_param::BWD_STRIDES, strides.data());
151+
}
152+
153+
// config_param::FWD_DISTANCE
154+
template <typename valT = std::int64_t>
155+
valT get_fwd_distance()
156+
{
157+
valT dist = 0;
158+
159+
descr_.get_value(mkl_dft::config_param::FWD_DISTANCE, &dist);
160+
return dist;
161+
}
162+
163+
template <typename valT = std::int64_t>
164+
void set_fwd_distance(const valT dist)
165+
{
166+
descr_.set_value(mkl_dft::config_param::FWD_DISTANCE, dist);
167+
}
168+
169+
// config_param::BWD_DISTANCE
170+
template <typename valT = std::int64_t>
171+
valT get_bwd_distance()
172+
{
173+
valT dist = 0;
174+
175+
descr_.get_value(mkl_dft::config_param::BWD_DISTANCE, &dist);
176+
return dist;
177+
}
178+
179+
template <typename valT = std::int64_t>
180+
void set_bwd_distance(const valT dist)
181+
{
182+
descr_.set_value(mkl_dft::config_param::BWD_DISTANCE, dist);
183+
}
184+
185+
// config_param::PLACEMENT
186+
bool get_in_place()
187+
{
188+
DFTI_CONFIG_VALUE placement;
189+
190+
descr_.get_value(mkl_dft::config_param::PLACEMENT, &placement);
191+
return (placement == DFTI_CONFIG_VALUE::DFTI_INPLACE);
192+
}
193+
194+
void set_in_place(const bool in_place_request)
195+
{
196+
descr_.set_value(mkl_dft::config_param::PLACEMENT,
197+
(in_place_request)
198+
? DFTI_CONFIG_VALUE::DFTI_INPLACE
199+
: DFTI_CONFIG_VALUE::DFTI_NOT_INPLACE);
200+
}
201+
202+
// config_param::PRECISION
203+
mkl_dft::precision get_precision()
204+
{
205+
mkl_dft::precision fft_prec;
206+
207+
descr_.get_value(mkl_dft::config_param::PRECISION, &fft_prec);
208+
return fft_prec;
209+
}
210+
211+
// config_param::COMMIT_STATUS
212+
bool is_committed()
213+
{
214+
DFTI_CONFIG_VALUE committed;
215+
216+
descr_.get_value(mkl_dft::config_param::COMMIT_STATUS, &committed);
217+
return (committed == DFTI_CONFIG_VALUE::DFTI_COMMITTED);
218+
}
219+
220+
private:
221+
mkl_dft::descriptor<prec, mkl_dft::domain::COMPLEX> descr_;
222+
std::unique_ptr<sycl::queue> queue_ptr_;
223+
};
224+
225+
// forward declaration
226+
template <mkl_dft::precision prec>
227+
std::pair<sycl::event, sycl::event>
228+
compute_fft_out_of_place(ComplexDescriptorWrapper<prec> &descr,
229+
const dpctl::tensor::usm_ndarray &in,
230+
const dpctl::tensor::usm_ndarray &out,
231+
const bool is_forward,
232+
const std::vector<sycl::event> &depends);
233+
234+
template <mkl_dft::precision prec>
235+
std::pair<sycl::event, sycl::event>
236+
compute_fft_in_place(ComplexDescriptorWrapper<prec> &descr,
237+
const dpctl::tensor::usm_ndarray &in_out,
238+
const bool is_forward,
239+
const std::vector<sycl::event> &depends);
240+
241+
} // namespace dpnp::extensions::fft

0 commit comments

Comments
 (0)