Skip to content

Commit e809383

Browse files
authored
Merge branch 'master' into scipy-runtime
2 parents ab39f5b + de6f956 commit e809383

File tree

3 files changed

+53
-39
lines changed

3 files changed

+53
-39
lines changed

README.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,17 @@
44
[![Conda package with conda-forge channel only](https://github.com/IntelPython/mkl_fft/actions/workflows/conda-package-cf.yml/badge.svg)](https://github.com/IntelPython/mkl_fft/actions/workflows/conda-package-cf.yml)
55
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/IntelPython/mkl_fft/badge)](https://securityscorecards.dev/viewer/?uri=github.com/IntelPython/mkl_fft)
66

7+
# Introduction
78
`mkl_fft` started as a part of Intel® Distribution for Python* optimizations to NumPy, and is now being released
8-
as a stand-alone package. It can be installed into conda environment from Intel's channel using:
9+
as a stand-alone package. It offers a thin layered interface for the Intel® oneAPI Math Kernel Library (OneMKL) FFT functionality that allows efficient access to native FFT optimizations from a range of NumPy and SciPy functions. As a result, its performance is close to the performance of native C/Intel® OneMKL. The optimizations are provided for real and complex data types in both single and double precisions for in-place and out-of-place modes of operation. For analyzing the performance use [FFT benchmarks](https://github.com/intelpython/fft_benchmark).
10+
11+
Thanks to Intel® OneMKL’s flexibility in its supports for arbitrarily strided input and output arrays both one-dimensional and multi-dimensional Fast Fourier Transforms along distinct axes can be performed directly, without the need to copy the input into a contiguous array first. Furthermore, input strides can be arbitrary, including negative or zero, as long as strides remain an integer multiple of array’s item size, otherwise a copy will be made.
12+
13+
More details can be found in ["Accelerating Scientific Python with Intel Optimizations"](https://proceedings.scipy.org/articles/shinma-7f4c6e7-00f) from Proceedings of the 16th Python in Science Conference (SciPy 2017).
14+
15+
---
16+
# Installation
17+
`mkl_fft` can be installed into conda environment from Intel's channel using:
918

1019
```
1120
conda install -c https://software.repos.intel.com/python/conda mkl_fft
@@ -34,22 +43,12 @@ If command above installs NumPy package from the PyPI, please use following comm
3443
Where `<numpy_version>` should be the latest version from https://software.repos.intel.com/python/conda/
3544

3645
---
46+
# How to use?
47+
## `mkl_fft.interfaces` module
48+
The recommended way to use `mkl_fft` package is through `mkl_fft.interfaces` module. These interfaces act as drop-in replacements for equivalent functions in NumPy and SciPy. Learn more about these interfaces [here](https://github.com/IntelPython/mkl_fft/blob/master/mkl_fft/interfaces/README.md).
3749

38-
Since MKL FFT supports performing discrete Fourier transforms over non-contiguously laid out arrays, OneMKL can be directly
39-
used on any well-behaved floating point array with no internal overlaps for both in-place and not in-place transforms of
40-
arrays in single and double floating point precision.
41-
42-
This eliminates the need to copy input array contiguously into an intermediate buffer.
43-
44-
`mkl_fft` directly supports N-dimensional Fourier transforms.
45-
46-
More details can be found in [SciPy 2017 conference proceedings](https://github.com/scipy-conference/scipy_proceedings/tree/2017/papers/oleksandr_pavlyk).
47-
48-
---
49-
50-
The `mkl_fft` package offers interfaces that act as drop-in replacements for equivalent functions in NumPy and SciPy. Learn more about these interfaces [here](https://github.com/IntelPython/mkl_fft/blob/master/mkl_fft/interfaces/README.md).
51-
52-
While using these interfaces is the easiest way to leverage `mk_fft`, one can also use `mkl_fft` directly with the following FFT functions:
50+
## `mkl_fft` package
51+
While using the interfaces module is the recommended way to leverage `mk_fft`, one can also use `mkl_fft` directly with the following FFT functions:
5352

5453
### complex-to-complex (c2c) transforms:
5554

@@ -84,6 +83,7 @@ numpy.allclose(mkl_res, np_res)
8483
```
8584

8685
---
86+
# Building from source
8787

8888
To build `mkl_fft` from sources on Linux with Intel® OneMKL:
8989
- create a virtual environment: `python3 -m venv fft_env`

mkl_fft/_pydfti.pyx

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ cdef cnp.ndarray _pad_array(
203203
b_shape[axis] = n
204204

205205
# allocating temporary buffer
206-
x_arr_is_fortran = cnp.PyArray_CHKFLAGS(x_arr, cnp.NPY_F_CONTIGUOUS)
206+
x_arr_is_fortran = cnp.PyArray_CHKFLAGS(x_arr, cnp.NPY_ARRAY_F_CONTIGUOUS)
207207
b_arr = <cnp.ndarray> cnp.PyArray_EMPTY(
208208
b_ndim, b_shape, <cnp.NPY_TYPES> b_type, x_arr_is_fortran
209209
) # 0 for C-contiguous
@@ -249,9 +249,12 @@ cdef cnp.ndarray _process_arguments(
249249

250250
# convert x to ndarray, ensure that strides are multiples of itemsize
251251
x_arr = PyArray_CheckFromAny(
252-
x, NULL, 0, 0,
253-
cnp.NPY_ELEMENTSTRIDES | cnp.NPY_ENSUREARRAY | cnp.NPY_NOTSWAPPED,
254-
NULL)
252+
x, NULL, 0, 0,
253+
cnp.NPY_ARRAY_ELEMENTSTRIDES |
254+
cnp.NPY_ARRAY_ENSUREARRAY |
255+
cnp.NPY_ARRAY_NOTSWAPPED,
256+
NULL
257+
)
255258

256259
if (<void *> x_arr) is NULL:
257260
raise ValueError("An input argument x is not an array-like object")
@@ -319,7 +322,7 @@ cdef cnp.ndarray _allocate_result(
319322
f_shape[axis_] = n_
320323

321324
# allocating output buffer
322-
x_arr_is_fortran = cnp.PyArray_CHKFLAGS(x_arr, cnp.NPY_F_CONTIGUOUS)
325+
x_arr_is_fortran = cnp.PyArray_CHKFLAGS(x_arr, cnp.NPY_ARRAY_F_CONTIGUOUS)
323326
f_arr = <cnp.ndarray> cnp.PyArray_EMPTY(
324327
f_ndim, f_shape, <cnp.NPY_TYPES> f_type, x_arr_is_fortran
325328
) # 0 for C-contiguous
@@ -419,7 +422,9 @@ def _c2c_fft1d_impl(
419422
# so we cast to complex double and operate in place
420423
try:
421424
x_arr = <cnp.ndarray> cnp.PyArray_FROM_OTF(
422-
x_arr, cnp.NPY_CDOUBLE, cnp.NPY_BEHAVED | cnp.NPY_ENSURECOPY)
425+
x_arr, cnp.NPY_CDOUBLE,
426+
cnp.NPY_ARRAY_BEHAVED | cnp.NPY_ARRAY_ENSURECOPY
427+
)
423428
except:
424429
raise ValueError(
425430
"First argument must be a complex "
@@ -601,9 +606,9 @@ def _r2c_fft1d_impl(
601606
else:
602607
# we must cast the input to doubles and allocate the output,
603608
try:
604-
requirement = cnp.NPY_BEHAVED | cnp.NPY_ENSURECOPY
609+
requirement = cnp.NPY_ARRAY_BEHAVED | cnp.NPY_ARRAY_ENSURECOPY
605610
if x_type is cnp.NPY_LONGDOUBLE:
606-
requirement = requirement | cnp.NPY_FORCECAST
611+
requirement = requirement | cnp.NPY_ARRAY_FORCECAST
607612
x_arr = <cnp.ndarray> cnp.PyArray_FROM_OTF(
608613
x_arr, cnp.NPY_DOUBLE, requirement)
609614
x_type = cnp.PyArray_TYPE(x_arr)
@@ -705,11 +710,11 @@ def _c2r_fft1d_impl(
705710
# so we cast to complex double and operate in place
706711
if x_type is cnp.NPY_FLOAT:
707712
x_arr = <cnp.ndarray> cnp.PyArray_FROM_OTF(
708-
x_arr, cnp.NPY_CFLOAT, cnp.NPY_BEHAVED
713+
x_arr, cnp.NPY_CFLOAT, cnp.NPY_ARRAY_BEHAVED
709714
)
710715
else:
711716
x_arr = <cnp.ndarray> cnp.PyArray_FROM_OTF(
712-
x_arr, cnp.NPY_CDOUBLE, cnp.NPY_BEHAVED
717+
x_arr, cnp.NPY_CDOUBLE, cnp.NPY_ARRAY_BEHAVED
713718
)
714719
x_type = cnp.PyArray_TYPE(x_arr)
715720
in_place = 1
@@ -788,9 +793,12 @@ def _direct_fftnd(
788793

789794
# convert x to ndarray, ensure that strides are multiples of itemsize
790795
x_arr = PyArray_CheckFromAny(
791-
x, NULL, 0, 0,
792-
cnp.NPY_ELEMENTSTRIDES | cnp.NPY_ENSUREARRAY | cnp.NPY_NOTSWAPPED,
793-
NULL)
796+
x, NULL, 0, 0,
797+
cnp.NPY_ARRAY_ELEMENTSTRIDES |
798+
cnp.NPY_ARRAY_ENSUREARRAY |
799+
cnp.NPY_ARRAY_NOTSWAPPED,
800+
NULL
801+
)
794802

795803
if <void *> x_arr is NULL:
796804
raise ValueError("An input argument x is not an array-like object")
@@ -808,7 +816,9 @@ def _direct_fftnd(
808816
pass
809817
else:
810818
x_arr = <cnp.ndarray> cnp.PyArray_FROM_OTF(
811-
x_arr, cnp.NPY_CDOUBLE, cnp.NPY_BEHAVED | cnp.NPY_ENSURECOPY)
819+
x_arr, cnp.NPY_CDOUBLE,
820+
cnp.NPY_ARRAY_BEHAVED | cnp.NPY_ARRAY_ENSURECOPY
821+
)
812822
x_type = cnp.PyArray_TYPE(x_arr)
813823
assert x_type == cnp.NPY_CDOUBLE
814824
in_place = 1
@@ -1003,7 +1013,9 @@ def _rr_fft1d_impl(x, n=None, axis=-1, overwrite_x=False, double fsc=1.0):
10031013
else:
10041014
try:
10051015
x_arr = <cnp.ndarray> cnp.PyArray_FROM_OTF(
1006-
x_arr, cnp.NPY_DOUBLE, cnp.NPY_BEHAVED | cnp.NPY_ENSURECOPY)
1016+
x_arr, cnp.NPY_DOUBLE,
1017+
cnp.NPY_ARRAY_BEHAVED | cnp.NPY_ARRAY_ENSURECOPY
1018+
)
10071019
except:
10081020
raise TypeError("1st argument must be a real sequence")
10091021
x_type = cnp.PyArray_TYPE(x_arr)
@@ -1065,7 +1077,9 @@ def _rr_ifft1d_impl(x, n=None, axis=-1, overwrite_x=False, double fsc=1.0):
10651077
# so we cast to complex double and operate in place
10661078
try:
10671079
x_arr = <cnp.ndarray> cnp.PyArray_FROM_OTF(
1068-
x_arr, cnp.NPY_DOUBLE, cnp.NPY_BEHAVED | cnp.NPY_ENSURECOPY)
1080+
x_arr, cnp.NPY_DOUBLE,
1081+
cnp.NPY_ARRAY_BEHAVED | cnp.NPY_ARRAY_ENSURECOPY
1082+
)
10691083
except:
10701084
raise ValueError(
10711085
"First argument should be a real "

mkl_fft/interfaces/numpy_fft.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2525
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626

27-
# Added for completing the namespaces
28-
from numpy.fft import fftfreq, fftshift, ifftshift, rfftfreq
29-
3027
# pylint: disable=no-name-in-module
3128
from ._numpy_fft import (
3229
fft,
@@ -60,8 +57,11 @@
6057
"irfftn",
6158
"hfft",
6259
"ihfft",
63-
"fftshift",
64-
"ifftshift",
65-
"fftfreq",
66-
"rfftfreq",
6760
]
61+
62+
# It is important to put the following import here to avoid circular imports
63+
# when patching numpy with mkl_fft
64+
# Added for completing the namespaces
65+
from numpy.fft import fftfreq, fftshift, ifftshift, rfftfreq
66+
67+
__all__ += ["fftshift", "ifftshift", "fftfreq", "rfftfreq"]

0 commit comments

Comments
 (0)