Skip to content

Commit be88a7c

Browse files
authored
Merge branch 'master' into impl_vecdot
2 parents 2576446 + 257ee51 commit be88a7c

18 files changed

+365
-68
lines changed

.github/workflows/build-sphinx.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ jobs:
7676
7777
- name: Install Intel OneAPI
7878
run: |
79-
sudo apt-get install intel-oneapi-mkl \
80-
intel-oneapi-mkl-devel \
81-
intel-oneapi-tbb-devel \
82-
intel-oneapi-libdpstd-devel \
83-
intel-oneapi-compiler-dpcpp-cpp
79+
sudo apt-get install intel-oneapi-mkl-2024.2* \
80+
intel-oneapi-mkl-devel-2024.2* \
81+
intel-oneapi-tbb-devel-2021.13* \
82+
intel-oneapi-libdpstd-devel-2022.6* \
83+
intel-oneapi-compiler-dpcpp-cpp-2024.2*
8484
8585
# required by sphinxcontrib-spelling extension
8686
- name: Install enchant package

.github/workflows/conda-package.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ env:
2929
test_copy.py
3030
test_counting.py
3131
test_fft.py
32+
test_fill.py
3233
test_flat.py
3334
test_histogram.py
3435
test_indexing.py
@@ -63,6 +64,7 @@ env:
6364
third_party/cupy/statistics_tests/test_histogram.py
6465
third_party/cupy/statistics_tests/test_meanvar.py
6566
third_party/cupy/test_ndim.py
67+
third_party/cupy/test_type_routines.py
6668
VER_JSON_NAME: 'version.json'
6769
VER_SCRIPT1: "import json; f = open('version.json', 'r'); j = json.load(f); f.close(); "
6870
VER_SCRIPT2: "d = j['dpnp'][0]; print('='.join((d[s] for s in ('version', 'build'))))"
@@ -142,6 +144,8 @@ jobs:
142144
143145
- name: Build conda package
144146
run: conda build --no-test --python ${{ matrix.python }} --numpy 2.0 ${{ env.CHANNELS }} conda-recipe
147+
env:
148+
MAX_BUILD_CMPL_MKL_VERSION: '2024.3a0'
145149

146150
- name: Upload artifact
147151
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3

.github/workflows/generate_coverage.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ jobs:
4949
- name: Install latest Intel OneAPI
5050
if: env.INSTALL_ONE_API == 'yes'
5151
run: |
52-
sudo apt-get install intel-oneapi-mkl \
53-
intel-oneapi-mkl-devel \
54-
intel-oneapi-tbb-devel \
55-
intel-oneapi-libdpstd-devel \
56-
intel-oneapi-compiler-dpcpp-cpp
52+
sudo apt-get install intel-oneapi-mkl-2024.2* \
53+
intel-oneapi-mkl-devel-2024.2* \
54+
intel-oneapi-tbb-devel-2021.13* \
55+
intel-oneapi-libdpstd-devel-2022.6* \
56+
intel-oneapi-compiler-dpcpp-cpp-2024.2*
5757
5858
- name: Install Lcov
5959
run: |

.github/workflows/pre-commit.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
3030

3131
- name: Set up python
32-
uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
32+
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
3333
with:
3434
python-version: '3.12'
3535

conda-recipe/meta.yaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
{% set max_compiler_and_mkl_version = environ.get("MAX_BUILD_CMPL_MKL_VERSION", "2026.0a0") %}
12
{% set required_compiler_and_mkl_version = "2024.2" %}
2-
{% set required_dpctl_version = "0.18.0*" %}
3+
{% set required_dpctl_version = "0.18.1" %}
34

45
package:
56
name: dpnp
@@ -17,14 +18,14 @@ requirements:
1718
- ninja
1819
- git
1920
- dpctl >={{ required_dpctl_version }}
20-
- mkl-devel-dpcpp >={{ required_compiler_and_mkl_version }}
21+
- mkl-devel-dpcpp >={{ required_compiler_and_mkl_version }},<{{ max_compiler_and_mkl_version }}
2122
- onedpl-devel
2223
- tbb-devel
2324
- wheel
2425
- scikit-build
2526
build:
2627
- {{ compiler('cxx') }}
27-
- {{ compiler('dpcpp') }} >={{ required_compiler_and_mkl_version }}
28+
- {{ compiler('dpcpp') }} >={{ required_compiler_and_mkl_version }},<{{ max_compiler_and_mkl_version }}
2829
- sysroot_linux-64 >=2.28 # [linux]
2930
run:
3031
- python

dpnp/dpnp_algo/dpnp_arraycreation.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
1+
# -*- coding: utf-8 -*-
2+
# *****************************************************************************
3+
# Copyright (c) 2016-2024, Intel Corporation
4+
# All rights reserved.
5+
#
6+
# Redistribution and use in source and binary forms, with or without
7+
# modification, are permitted provided that the following conditions are met:
8+
# - Redistributions of source code must retain the above copyright notice,
9+
# this list of conditions and the following disclaimer.
10+
# - Redistributions in binary form must reproduce the above copyright notice,
11+
# this list of conditions and the following disclaimer in the documentation
12+
# and/or other materials provided with the distribution.
13+
#
14+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24+
# THE POSSIBILITY OF SUCH DAMAGE.
25+
# *****************************************************************************
26+
127
import math
228
import operator
329

dpnp/dpnp_algo/dpnp_fill.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# -*- coding: utf-8 -*-
2+
# *****************************************************************************
3+
# Copyright (c) 2016-2024, Intel Corporation
4+
# All rights reserved.
5+
#
6+
# Redistribution and use in source and binary forms, with or without
7+
# modification, are permitted provided that the following conditions are met:
8+
# - Redistributions of source code must retain the above copyright notice,
9+
# this list of conditions and the following disclaimer.
10+
# - Redistributions in binary form must reproduce the above copyright notice,
11+
# this list of conditions and the following disclaimer in the documentation
12+
# and/or other materials provided with the distribution.
13+
#
14+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24+
# THE POSSIBILITY OF SUCH DAMAGE.
25+
# *****************************************************************************
26+
27+
from numbers import Number
28+
29+
import dpctl.tensor as dpt
30+
import dpctl.utils as dpu
31+
from dpctl.tensor._ctors import _cast_fill_val
32+
from dpctl.tensor._tensor_impl import (
33+
_copy_usm_ndarray_into_usm_ndarray,
34+
_full_usm_ndarray,
35+
_zeros_usm_ndarray,
36+
)
37+
38+
import dpnp
39+
40+
41+
def dpnp_fill(arr, val):
42+
arr = dpnp.get_usm_ndarray(arr)
43+
exec_q = arr.sycl_queue
44+
45+
# if val is an array, process it
46+
if dpnp.is_supported_array_type(val):
47+
val = dpnp.get_usm_ndarray(val)
48+
if val.shape != ():
49+
raise ValueError("`val` must be a scalar or 0D-array")
50+
if dpu.get_execution_queue((exec_q, val.sycl_queue)) is None:
51+
raise dpu.ExecutionPlacementError(
52+
"Input arrays have incompatible queues."
53+
)
54+
a_val = dpt.astype(val, arr.dtype)
55+
a_val = dpt.broadcast_to(a_val, arr.shape)
56+
_manager = dpu.SequentialOrderManager[exec_q]
57+
dep_evs = _manager.submitted_events
58+
h_ev, c_ev = _copy_usm_ndarray_into_usm_ndarray(
59+
src=a_val, dst=arr, sycl_queue=exec_q, depends=dep_evs
60+
)
61+
_manager.add_event_pair(h_ev, c_ev)
62+
return
63+
elif not isinstance(val, (Number, dpnp.bool)):
64+
raise TypeError(
65+
f"array cannot be filled with `val` of type {type(val)}"
66+
)
67+
val = _cast_fill_val(val, arr.dtype)
68+
69+
_manager = dpu.SequentialOrderManager[exec_q]
70+
dep_evs = _manager.submitted_events
71+
72+
# can leverage efficient memset when val is 0
73+
if arr.flags["FORC"] and val == 0:
74+
h_ev, zeros_ev = _zeros_usm_ndarray(arr, exec_q, depends=dep_evs)
75+
_manager.add_event_pair(h_ev, zeros_ev)
76+
else:
77+
h_ev, fill_ev = _full_usm_ndarray(val, arr, exec_q, depends=dep_evs)
78+
_manager.add_event_pair(h_ev, fill_ev)

dpnp/dpnp_array.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -928,13 +928,16 @@ def fill(self, value):
928928
"""
929929
Fill the array with a scalar value.
930930
931+
For full documentation refer to :obj:`numpy.ndarray.fill`.
932+
931933
Parameters
932934
----------
933-
value : scalar
935+
value : {dpnp.ndarray, usm_ndarray, scalar}
934936
All elements of `a` will be assigned this value.
935937
936938
Examples
937939
--------
940+
>>> import dpnp as np
938941
>>> a = np.array([1, 2])
939942
>>> a.fill(0)
940943
>>> a
@@ -946,8 +949,10 @@ def fill(self, value):
946949
947950
"""
948951

949-
for i in range(self.size):
950-
self.flat[i] = value
952+
# lazy import avoids circular imports
953+
from .dpnp_algo.dpnp_fill import dpnp_fill
954+
955+
dpnp_fill(self, value)
951956

952957
@property
953958
def flags(self):

dpnp/dpnp_iface_logic.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"iscomplex",
6565
"iscomplexobj",
6666
"isfinite",
67+
"isfortran",
6768
"isinf",
6869
"isnan",
6970
"isneginf",
@@ -991,6 +992,76 @@ def iscomplexobj(x):
991992
)
992993

993994

995+
def isfortran(a):
996+
"""
997+
Check if the array is Fortran contiguous but *not* C contiguous.
998+
999+
This function is obsolete. If you only want to check if an array is Fortran
1000+
contiguous use ``a.flags.f_contiguous`` instead.
1001+
1002+
For full documentation refer to :obj:`numpy.isfortran`.
1003+
1004+
Parameters
1005+
----------
1006+
a : {dpnp.ndarray, usm_ndarray}
1007+
Input array.
1008+
1009+
Returns
1010+
-------
1011+
isfortran : bool
1012+
Returns ``True`` if the array is Fortran contiguous
1013+
but *not* C contiguous.
1014+
1015+
Examples
1016+
--------
1017+
:obj:`dpnp.array` allows to specify whether the array is written in
1018+
C-contiguous order (last index varies the fastest), or FORTRAN-contiguous
1019+
order in memory (first index varies the fastest).
1020+
1021+
>>> import dpnp as np
1022+
>>> a = np.array([[1, 2, 3], [4, 5, 6]], order='C')
1023+
>>> a
1024+
array([[1, 2, 3],
1025+
[4, 5, 6]])
1026+
>>> np.isfortran(a)
1027+
False
1028+
1029+
>>> b = np.array([[1, 2, 3], [4, 5, 6]], order='F')
1030+
>>> b
1031+
array([[1, 2, 3],
1032+
[4, 5, 6]])
1033+
>>> np.isfortran(b)
1034+
True
1035+
1036+
The transpose of a C-ordered array is a FORTRAN-ordered array.
1037+
1038+
>>> a = np.array([[1, 2, 3], [4, 5, 6]], order='C')
1039+
>>> a
1040+
array([[1, 2, 3],
1041+
[4, 5, 6]])
1042+
>>> np.isfortran(a)
1043+
False
1044+
>>> b = a.T
1045+
>>> b
1046+
array([[1, 4],
1047+
[2, 5],
1048+
[3, 6]])
1049+
>>> np.isfortran(b)
1050+
True
1051+
1052+
C-ordered arrays evaluate as ``False`` even if they are also
1053+
FORTRAN-ordered.
1054+
1055+
>>> np.isfortran(np.array([1, 2], order='F'))
1056+
False
1057+
1058+
"""
1059+
1060+
dpnp.check_supported_arrays_type(a)
1061+
1062+
return a.flags.fnc
1063+
1064+
9941065
_ISINF_DOCSTRING = """
9951066
Test if each element of input array is an infinity.
9961067

dpnp/dpnp_iface_statistics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ def correlate(x1, x2, mode="valid"):
370370
-----------
371371
Input arrays are supported as :obj:`dpnp.ndarray`.
372372
Size and shape of input arrays are supported to be equal.
373-
Parameter `mode` is supported only with default value ``"valid``.
373+
Parameter `mode` is supported only with default value ``"valid"``.
374374
Otherwise the function will be executed sequentially on CPU.
375375
Input array data types are limited by supported DPNP :ref:`Data types`.
376376

dpnp/dpnp_utils/dpnp_utils_einsum.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,8 @@
3333
from dpctl.utils import ExecutionPlacementError
3434

3535
import dpnp
36-
from dpnp.dpnp_utils import get_usm_allocations
37-
38-
from ..dpnp_array import dpnp_array
36+
from dpnp.dpnp_array import dpnp_array
37+
from dpnp.dpnp_utils import get_usm_allocations, map_dtype_to_device
3938

4039
_einsum_symbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
4140

@@ -1027,17 +1026,16 @@ def dpnp_einsum(
10271026
"Input and output allocation queues are not compatible"
10281027
)
10291028

1030-
result_dtype = dpnp.result_type(*arrays) if dtype is None else dtype
10311029
for id, a in enumerate(operands):
10321030
if dpnp.isscalar(a):
1031+
scalar_dtype = map_dtype_to_device(type(a), exec_q.sycl_device)
10331032
operands[id] = dpnp.array(
1034-
a, dtype=result_dtype, usm_type=res_usm_type, sycl_queue=exec_q
1033+
a, dtype=scalar_dtype, usm_type=res_usm_type, sycl_queue=exec_q
10351034
)
1035+
arrays.append(operands[id])
10361036
result_dtype = dpnp.result_type(*arrays) if dtype is None else dtype
1037-
if order in ["a", "A"]:
1038-
order = (
1039-
"F" if not any(arr.flags.c_contiguous for arr in arrays) else "C"
1040-
)
1037+
if order in "aA":
1038+
order = "F" if all(arr.flags.fnc for arr in arrays) else "C"
10411039

10421040
input_subscripts = [
10431041
_parse_ellipsis_subscript(sub, idx, ndim=arr.ndim)

0 commit comments

Comments
 (0)