Skip to content

Commit 0eb5914

Browse files
Merge pull request #80 from IntelPython/fix-clongdouble-input-win32
Fix unexpected behavior of fft call on clongdouble type on win32
2 parents 01e9cf9 + 1dc1c37 commit 0eb5914

File tree

3 files changed

+31
-16
lines changed

3 files changed

+31
-16
lines changed

conda-recipe/meta.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ requirements:
3030

3131
test:
3232
commands:
33-
- pytest -v --args mkl_fft
33+
- pytest -v --pyargs mkl_fft
3434
requires:
3535
- pytest
3636
imports:
3737
- mkl_fft
38-
- mkl_fft.interface
39-
- mkl_fft.interface.numpy_fft
40-
- mkl_fft.interface.scipy_fft
38+
- mkl_fft.interfaces
39+
- mkl_fft.interfaces.numpy_fft
40+
- mkl_fft.interfaces.scipy_fft
4141

4242
about:
4343
home: http://github.com/IntelPython/mkl_fft

mkl_fft/_pydfti.pyx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ def _fft1d_impl(x, n=None, axis=-1, overwrite_arg=False, direction=+1, double fs
321321
# so we cast to complex double and operate in place
322322
try:
323323
x_arr = <cnp.ndarray> cnp.PyArray_FROM_OTF(
324-
x_arr, cnp.NPY_CDOUBLE, cnp.NPY_BEHAVED)
324+
x_arr, cnp.NPY_CDOUBLE, cnp.NPY_BEHAVED | cnp.NPY_ENSURECOPY)
325325
except:
326326
raise ValueError("First argument must be a complex or real sequence of single or double precision")
327327
x_type = cnp.PyArray_TYPE(x_arr)
@@ -545,7 +545,7 @@ def _rr_fft1d_impl2(x, n=None, axis=-1, overwrite_arg=False, double fsc=1.0):
545545
else:
546546
try:
547547
x_arr = <cnp.ndarray> cnp.PyArray_FROM_OTF(
548-
x_arr, cnp.NPY_DOUBLE, cnp.NPY_BEHAVED)
548+
x_arr, cnp.NPY_DOUBLE, cnp.NPY_BEHAVED | cnp.NPY_ENSURECOPY)
549549
except:
550550
raise TypeError("1st argument must be a real sequence")
551551
x_type = cnp.PyArray_TYPE(x_arr)
@@ -601,7 +601,7 @@ def _rr_ifft1d_impl2(x, n=None, axis=-1, overwrite_arg=False, double fsc=1.0):
601601
# so we cast to complex double and operate in place
602602
try:
603603
x_arr = <cnp.ndarray> cnp.PyArray_FROM_OTF(
604-
x_arr, cnp.NPY_DOUBLE, cnp.NPY_BEHAVED)
604+
x_arr, cnp.NPY_DOUBLE, cnp.NPY_BEHAVED | cnp.NPY_ENSURECOPY)
605605
except:
606606
raise ValueError("First argument should be a real or a complex sequence of single or double precision")
607607
x_type = cnp.PyArray_TYPE(x_arr)
@@ -669,7 +669,7 @@ def _rc_fft1d_impl(x, n=None, axis=-1, overwrite_arg=False, double fsc=1.0):
669669
else:
670670
# we must cast the input to doubles and allocate the output,
671671
try:
672-
requirement = cnp.NPY_BEHAVED
672+
requirement = cnp.NPY_BEHAVED | cnp.NPY_ENSURECOPY
673673
if x_type is cnp.NPY_LONGDOUBLE:
674674
requirement = requirement | cnp.NPY_FORCECAST
675675
x_arr = <cnp.ndarray> cnp.PyArray_FROM_OTF(
@@ -981,7 +981,14 @@ def _direct_fftnd(x, overwrite_arg=False, direction=+1, double fsc=1.0):
981981
in_place = 1 # a copy was made, so we can work in place.
982982

983983
x_type = cnp.PyArray_TYPE(x_arr)
984-
assert( x_type == cnp.NPY_CDOUBLE or x_type == cnp.NPY_CFLOAT or x_type == cnp.NPY_DOUBLE or x_type == cnp.NPY_FLOAT);
984+
if (x_type == cnp.NPY_CDOUBLE or x_type == cnp.NPY_CFLOAT or x_type == cnp.NPY_DOUBLE or x_type == cnp.NPY_FLOAT):
985+
pass
986+
else:
987+
x_arr = <cnp.ndarray> cnp.PyArray_FROM_OTF(
988+
x_arr, cnp.NPY_CDOUBLE, cnp.NPY_BEHAVED | cnp.NPY_ENSURECOPY)
989+
x_type = cnp.PyArray_TYPE(x_arr)
990+
assert x_type == cnp.NPY_CDOUBLE
991+
in_place = 1
985992

986993
if in_place:
987994
in_place = 1 if x_type == cnp.NPY_CDOUBLE or x_type == cnp.NPY_CFLOAT else 0
@@ -1076,7 +1083,7 @@ def _fftnd_impl(x, shape=None, axes=None, overwrite_x=False, direction=+1, doubl
10761083
if _direct:
10771084
return _direct_fftnd(x, overwrite_arg=overwrite_x, direction=direction, fsc=fsc)
10781085
else:
1079-
if (shape is None and x.dtype in [np.complex64, np.complex128, np.float32, np.float64]):
1086+
if (shape is None and x.dtype in [np.csingle, np.cdouble, np.single, np.double]):
10801087
x = np.asarray(x)
10811088
res = np.empty(x.shape, dtype=_output_dtype(x.dtype))
10821089
return iter_complementary(

mkl_fft/_scipy_fft_backend.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030

3131
from numpy.core import (take, sqrt, prod)
3232
import contextvars
33+
import contextlib
3334
import operator
35+
import os
3436

3537

3638
__doc__ = """
@@ -89,14 +91,20 @@ def get_workers():
8991
return _workers_global_settings.get().workers
9092

9193

94+
@contextlib.contextmanager
9295
def set_workers(n_workers):
9396
"Set the value of workers used by default, returns the previous value"
9497
nw = operator.index(n_workers)
95-
wd = _workers_global_settings.get()
96-
saved_nw = wd.workers
97-
wd.workers = nw
98-
_workers_global_settings.set(wd)
99-
return saved_nw
98+
token = None
99+
try:
100+
new_wd = _workers_data(nw)
101+
token = _workers_global_settings.set(new_wd)
102+
yield
103+
finally:
104+
if token:
105+
_workers_global_settings.reset(token)
106+
else:
107+
raise ValueError
100108

101109

102110
__all__ = ['fft', 'ifft', 'fft2', 'ifft2', 'fftn', 'ifftn',
@@ -153,7 +161,7 @@ def _workers_to_num_threads(w):
153161
if (_w == 0):
154162
raise ValueError("Number of workers must not be zero")
155163
if (_w < 0):
156-
ub = _cpu_max_threads_count().get_cpu_count()
164+
ub = os.cpu_count()
157165
_w += ub + 1
158166
if _w <= 0:
159167
raise ValueError("workers value out of range; got {}, must not be"

0 commit comments

Comments
 (0)