Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

### Fixed
* Zero-padding (`n` larger than the input length along the axis) of input that is both C- and F-contiguous, such as shape `(m, 1)` padded along axis 1, now gives a C-contiguous result as NumPy does instead of a Fortran-contiguous one, so a C-ordered `out` is also written directly without a temporary copy [gh-397](https://github.com/IntelPython/mkl_fft/pull/397)

## [2.4.0] - 2026-10-16

Expand Down
6 changes: 3 additions & 3 deletions mkl_fft/_pydfti.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -229,9 +229,9 @@ cdef cnp.ndarray _pad_array(
b_shape[axis] = n

# allocating temporary buffer
x_arr_is_fortran = cnp.PyArray_CHKFLAGS(
x_arr, cnp.NPY_ARRAY_F_CONTIGUOUS
)
# F order only if x_arr is not also C-contiguous (e.g. shape (m, 1)),
# as NumPy does, otherwise padding along a unit axis gives an F array
x_arr_is_fortran = cnp.PyArray_ISFORTRAN(x_arr)
b_arr = <cnp.ndarray> cnp.PyArray_EMPTY(
b_ndim, b_shape, <cnp.NPY_TYPES> b_type, x_arr_is_fortran
) # 0 for C-contiguous
Expand Down
22 changes: 22 additions & 0 deletions mkl_fft/tests/test_fft1d.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,28 @@ def test_irfft_dtype(dt):
assert_allclose(result, expected, rtol=1e-7, atol=1e-7, strict=True)


@pytest.mark.parametrize(
"shape, axis", [((5, 1), 1), ((1, 5), 0), ((4, 1, 1), 2), ((1, 1, 4), 0)]
)
@pytest.mark.parametrize("func", ["fft", "ifft", "rfft", "irfft"])
def test_pad_both_contiguous_input(func, shape, axis):
# x is both C- and F-contiguous and is zero-padded along a unit axis,
# the padded copy and so the result are C-contiguous as in NumPy
x = rnd.random(shape)
if func == "irfft":
x = x + 1j * rnd.random(shape)
expected = getattr(np.fft, func)(x, n=8, axis=axis)

result = getattr(mkl_fft, func)(x, n=8, axis=axis)
assert result.flags.c_contiguous
assert_allclose(result, expected, atol=1e-12)

out = np.full_like(expected, -1, order="C")
result = getattr(mkl_fft, func)(x, n=8, axis=axis, out=out)
assert result is out
assert_allclose(result, expected, atol=1e-12)


@pytest.mark.parametrize("step", [2, -1, -3])
@pytest.mark.parametrize("func", ["fft", "ifft"])
def test_fft_real_input_out_strided_1d(func, step):
Expand Down
Loading