Skip to content

Commit fec42b1

Browse files
author
Vahid Tavanashad
committed
Merge branch 'master' into update-dpnp-fix
2 parents b6638eb + 05b820d commit fec42b1

File tree

9 files changed

+124
-40
lines changed

9 files changed

+124
-40
lines changed

.github/workflows/check-mkl-interfaces.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848

4949
- name: Merge conda env files
5050
run: |
51-
conda-merge ${{ env.build-with-oneapi-env }} ${{ env.dpctl-pkg-env }} ${{ env.oneapi-pkgs-env }} > ${{ env.environment-file }}
51+
conda-merge ${{ env.dpctl-pkg-env }} ${{ env.oneapi-pkgs-env }} ${{ env.build-with-oneapi-env }} > ${{ env.environment-file }}
5252
cat ${{ env.environment-file }}
5353
5454
- name: Upload artifact

.github/workflows/conda-package.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,13 @@ jobs:
9393
continue-on-error: true
9494
run: conda build --no-test --python ${{ matrix.python }} --numpy 2.0 ${{ env.channels-list }} conda-recipe
9595
env:
96-
MAX_BUILD_CMPL_MKL_VERSION: '2025.1a0'
96+
MAX_BUILD_CMPL_MKL_VERSION: '2025.2a0'
9797

9898
- name: ReBuild conda package
9999
if: steps.build_conda_pkg.outcome == 'failure'
100100
run: conda build --no-test --python ${{ matrix.python }} --numpy 2.0 ${{ env.channels-list }} conda-recipe
101101
env:
102-
MAX_BUILD_CMPL_MKL_VERSION: '2025.1a0'
102+
MAX_BUILD_CMPL_MKL_VERSION: '2025.2a0'
103103

104104
- name: Upload artifact
105105
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2

CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515

1616
### Changed
1717

18-
* Extended `dpnp.fft.fftfreq` and `dpnp.fft.rfftfreq` functions to support `dtype` keyword per Python Array API spec 2024.12 [#2384](https://github.com/IntelPython/dpnp/pull/2384)
18+
* Improved performance of `dpnp.nansum`, `dpnp.nanprod`, `dpnp.nancumsum`, and `dpnp.nancumprod` by reusing `dpnp.nan_to_num` function in implementation of the functions [#2339](https://github.com/IntelPython/dpnp/pull/2339)
1919
* Allowed input array of `uint64` dtype in `dpnp.bincount` [#2361](https://github.com/IntelPython/dpnp/pull/2361)
2020
* The vector norms `ord={None, 1, 2, inf}` and the matrix norms `ord={None, 1, 2, inf, "fro", "nuc"}` now consistently return zero for empty arrays, which are arrays with at least one axis of size zero. This change affects `dpnp.linalg.norm`, `dpnp.linalg.vector_norm`, and `dpnp.linalg.matrix_norm`. Previously, dpnp would either raise errors or return zero depending on the parameters provided [#2371](https://github.com/IntelPython/dpnp/pull/2371)
21-
* Improved performance of `dpnp.nansum`, `dpnp.nanprod`, `dpnp.nancumsum`, and `dpnp.nancumprod` by reusing `dpnp.nan_to_num` function in implementation of the functions [#2339](https://github.com/IntelPython/dpnp/pull/2339)
21+
* Extended `dpnp.fft.fftfreq` and `dpnp.fft.rfftfreq` functions to support `dtype` keyword per Python Array API spec 2024.12 [#2384](https://github.com/IntelPython/dpnp/pull/2384)
2222
* Updated `dpnp.fix` to return output with the same data-type of input [#2392](https://github.com/IntelPython/dpnp/pull/2392)
2323

2424
### Fixed
2525

2626
* Resolved an issue with an incorrect result returned due to missing dependency from the strided kernel on a copy event in `dpnp.erf` [#2378](https://github.com/IntelPython/dpnp/pull/2378)
27+
* Updated `conda create` commands build and install instructions of `Quick start guide` to avoid a compilation error [#2395](https://github.com/IntelPython/dpnp/pull/2395)
2728

2829

2930
## [0.17.0] - 02/26/2025

doc/quick_start_guide.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,18 @@ On Linux:
8888

8989
.. code-block:: bash
9090
91-
conda create -n build-env dpctl cython dpcpp_linux-64 mkl-devel-dpcpp tbb-devel onedpl-devel cmake scikit-build ninja pytest -c https://software.repos.intel.com/python/conda/ -c conda-forge
91+
conda create -n build-env dpctl cython dpcpp_linux-64 mkl-devel-dpcpp tbb-devel \
92+
onedpl-devel cmake scikit-build ninja pytest intel-gpu-ocl-icd-system \
93+
-c dppy/label/dev -c https://software.repos.intel.com/python/conda/ -c conda-forge
9294
conda activate build-env
9395
9496
On Windows:
9597

9698
.. code-block:: bash
9799
98-
conda create -n build-env dpctl cython dpcpp_win-64 mkl-devel-dpcpp tbb-devel onedpl-devel cmake scikit-build ninja pytest -c https://software.repos.intel.com/python/conda/ -c conda-forge
100+
conda create -n build-env dpctl cython dpcpp_win-64 mkl-devel-dpcpp tbb-devel \
101+
onedpl-devel cmake scikit-build ninja pytest intel-gpu-ocl-icd-system \
102+
-c dppy/label/dev -c https://software.repos.intel.com/python/conda/ -c conda-forge
99103
conda activate build-env
100104
101105
To build and install the package on Linux OS, run:

dpnp/dpnp_iface_types.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,25 @@
3232
This module provides public type interface file for the library
3333
"""
3434

35+
import functools
36+
37+
import dpctl
3538
import dpctl.tensor as dpt
3639
import numpy
3740

41+
import dpnp
42+
3843
from .dpnp_array import dpnp_array
3944

45+
# pylint: disable=no-name-in-module
46+
from .dpnp_utils import get_usm_allocations
47+
4048
__all__ = [
4149
"bool",
4250
"bool_",
4351
"byte",
4452
"cdouble",
53+
"common_type",
4554
"complex128",
4655
"complex64",
4756
"complexfloating",
@@ -145,6 +154,67 @@
145154
pi = numpy.pi
146155

147156

157+
def common_type(*arrays):
158+
"""
159+
Return a scalar type which is common to the input arrays.
160+
161+
The return type will always be an inexact (i.e. floating point or complex)
162+
scalar type, even if all the arrays are integer arrays.
163+
If one of the inputs is an integer array, the minimum precision type
164+
that is returned is the default floating point data type for the device
165+
where the input arrays are allocated.
166+
167+
For full documentation refer to :obj:`numpy.common_type`.
168+
169+
Parameters
170+
----------
171+
arrays: {dpnp.ndarray, usm_ndarray}
172+
Input arrays.
173+
174+
Returns
175+
-------
176+
out: data type
177+
Data type object.
178+
179+
See Also
180+
--------
181+
:obj:`dpnp.dtype` : Create a data type object.
182+
183+
Examples
184+
--------
185+
>>> import dpnp as np
186+
>>> np.common_type(np.arange(2, dtype=np.float32))
187+
numpy.float32
188+
>>> np.common_type(np.arange(2, dtype=np.float32), np.arange(2))
189+
numpy.float64 # may vary
190+
>>> np.common_type(np.arange(4), np.array([45, 6.j]), np.array([45.0]))
191+
numpy.complex128 # may vary
192+
193+
"""
194+
195+
if len(arrays) == 0:
196+
return (
197+
dpnp.float16
198+
if dpctl.select_default_device().has_aspect_fp16
199+
else dpnp.float32
200+
)
201+
202+
dpnp.check_supported_arrays_type(*arrays)
203+
204+
_, exec_q = get_usm_allocations(arrays)
205+
default_float_dtype = dpnp.default_float_type(sycl_queue=exec_q)
206+
dtypes = []
207+
for a in arrays:
208+
if not dpnp.issubdtype(a.dtype, dpnp.number):
209+
raise TypeError("can't get common type for non-numeric array")
210+
if dpnp.issubdtype(a.dtype, dpnp.integer):
211+
dtypes.append(default_float_dtype)
212+
else:
213+
dtypes.append(a.dtype)
214+
215+
return functools.reduce(numpy.promote_types, dtypes).type
216+
217+
148218
# pylint: disable=redefined-outer-name
149219
def finfo(dtype):
150220
"""

dpnp/fft/dpnp_iface_fft.py

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,7 @@
3838

3939
import dpnp
4040

41-
from .dpnp_utils_fft import (
42-
dpnp_fft,
43-
dpnp_fftn,
44-
dpnp_fillfreq,
45-
)
41+
from .dpnp_utils_fft import dpnp_fft, dpnp_fftn, dpnp_fillfreq, swap_direction
4642

4743
__all__ = [
4844
"fft",
@@ -66,24 +62,6 @@
6662
]
6763

6864

69-
_SWAP_DIRECTION_MAP = {
70-
"backward": "forward",
71-
None: "forward",
72-
"ortho": "ortho",
73-
"forward": "backward",
74-
}
75-
76-
77-
def _swap_direction(norm):
78-
try:
79-
return _SWAP_DIRECTION_MAP[norm]
80-
except KeyError:
81-
raise ValueError(
82-
f'Invalid norm value {norm}; should be None, "backward", '
83-
'"ortho" or "forward".'
84-
) from None
85-
86-
8765
def fft(a, n=None, axis=-1, norm=None, out=None):
8866
"""
8967
Compute the one-dimensional discrete Fourier Transform.
@@ -644,7 +622,7 @@ def hfft(a, n=None, axis=-1, norm=None, out=None):
644622
645623
"""
646624

647-
new_norm = _swap_direction(norm)
625+
new_norm = swap_direction(norm)
648626
return irfft(dpnp.conjugate(a), n=n, axis=axis, norm=new_norm, out=out)
649627

650628

@@ -1073,7 +1051,7 @@ def ihfft(a, n=None, axis=-1, norm=None, out=None):
10731051
10741052
"""
10751053

1076-
new_norm = _swap_direction(norm)
1054+
new_norm = swap_direction(norm)
10771055
res = rfft(a, n=n, axis=axis, norm=new_norm, out=out)
10781056
return dpnp.conjugate(res, out=out)
10791057

dpnp/fft/dpnp_utils_fft.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,7 @@
5757
_standardize_strides_to_nonzero,
5858
)
5959

60-
__all__ = [
61-
"dpnp_fft",
62-
"dpnp_fftn",
63-
"dpnp_fillfreq",
64-
]
60+
__all__ = ["dpnp_fft", "dpnp_fftn", "dpnp_fillfreq", "swap_direction"]
6561

6662

6763
def _check_norm(norm):
@@ -584,7 +580,6 @@ def dpnp_fft(a, forward, real, n=None, axis=-1, norm=None, out=None):
584580
if n < 1:
585581
raise ValueError(f"Invalid number of FFT data points ({n}) specified")
586582

587-
_check_norm(norm)
588583
a = _truncate_or_pad(a, (n,), (axis,))
589584
_validate_out_keyword(a, out, (n,), (axis,), c2c, c2r, r2c)
590585
# if input array is copied, in-place FFT can be used
@@ -714,3 +709,17 @@ def dpnp_fillfreq(a, m, n, val):
714709
ht_lin_ev, lin_ev = ti._linspace_step(m - n, 1, a[m:].get_array(), exec_q)
715710
_manager.add_event_pair(ht_lin_ev, lin_ev)
716711
return a * val
712+
713+
714+
def swap_direction(norm):
715+
"""Swap the direction of the FFT."""
716+
717+
_check_norm(norm)
718+
_swap_direction_map = {
719+
"backward": "forward",
720+
None: "forward",
721+
"ortho": "ortho",
722+
"forward": "backward",
723+
}
724+
725+
return _swap_direction_map[norm]

dpnp/tests/test_fft.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
get_all_dtypes,
1515
get_complex_dtypes,
1616
get_float_dtypes,
17+
has_support_aspect16,
1718
)
1819

1920

@@ -926,6 +927,16 @@ def test_rfft_1D_on_2D_array_out(self, dtype, n, axis, norm, order):
926927
expected = numpy.fft.rfft(a_np, n=n, axis=axis, norm=norm)
927928
assert_dtype_allclose(result, expected, check_only_type_kind=True)
928929

930+
@pytest.mark.skipif(not has_support_aspect16(), reason="no fp16 support")
931+
def test_float16(self):
932+
a = numpy.arange(10, dtype=numpy.float16)
933+
ia = dpnp.array(a)
934+
935+
expected = numpy.fft.rfft(a)
936+
result = dpnp.fft.rfft(ia)
937+
# check_only_type_kind=True since Intel NumPy returns complex128
938+
assert_dtype_allclose(result, expected, check_only_type_kind=True)
939+
929940
@pytest.mark.parametrize("xp", [numpy, dpnp])
930941
def test_rfft_error(self, xp):
931942
a = xp.ones((4, 3), dtype=xp.complex64)

dpnp/tests/third_party/cupy/test_type_routines.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import pytest
55

66
import dpnp as cupy
7-
from dpnp.tests.helper import has_support_aspect64
7+
from dpnp.tests.helper import has_support_aspect16, has_support_aspect64
88
from dpnp.tests.third_party.cupy import testing
99

1010

@@ -47,13 +47,17 @@ def test_can_cast(self, xp, from_dtype, to_dtype):
4747
return ret
4848

4949

50-
@pytest.mark.skip("dpnp.common_type() is not implemented yet")
5150
class TestCommonType(unittest.TestCase):
5251

5352
@testing.numpy_cupy_equal()
5453
def test_common_type_empty(self, xp):
5554
ret = xp.common_type()
5655
assert type(ret) is type
56+
# NumPy always returns float16 for empty input,
57+
# but dpnp returns float32 if the device does not support
58+
# 16-bit precision floating point operations
59+
if xp is numpy and not has_support_aspect16():
60+
return xp.float32
5761
return ret
5862

5963
@testing.for_all_dtypes(no_bool=True)
@@ -62,6 +66,11 @@ def test_common_type_single_argument(self, xp, dtype):
6266
array = _generate_type_routines_input(xp, dtype, "array")
6367
ret = xp.common_type(array)
6468
assert type(ret) is type
69+
# NumPy promotes integer types to float64,
70+
# but dpnp may return float32 if the device does not support
71+
# 64-bit precision floating point operations.
72+
if xp is numpy and not has_support_aspect64():
73+
return xp.float32
6574
return ret
6675

6776
@testing.for_all_dtypes_combination(
@@ -73,6 +82,8 @@ def test_common_type_two_arguments(self, xp, dtype1, dtype2):
7382
array2 = _generate_type_routines_input(xp, dtype2, "array")
7483
ret = xp.common_type(array1, array2)
7584
assert type(ret) is type
85+
if xp is numpy and not has_support_aspect64():
86+
return xp.float32
7687
return ret
7788

7889
@testing.for_all_dtypes()

0 commit comments

Comments
 (0)