Skip to content

Commit 21a52c4

Browse files
committed
Merge branch 'master' into impl-bitwise_count
2 parents 371319a + 1eb1592 commit 21a52c4

File tree

11 files changed

+872
-1766
lines changed

11 files changed

+872
-1766
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
* @antonwolfy @AlexanderKalistratov @vlad-perevezentsev @vtavana
1+
* @antonwolfy @AlexanderKalistratov @vlad-perevezentsev @vtavana @ndgrigorian

conda-recipe/meta.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ about:
6969
7070
extra:
7171
recipe-maintainers:
72-
- oleksandr-pavlyk
7372
- antonwolfy
7473
- AlexanderKalistratov
7574
- vtavana
7675
- vlad-perevezentsev
76+
- ndgrigorian

dpnp/dpnp_iface_histograms.py

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -225,17 +225,23 @@ def _get_bin_edges(a, bins, range, usm_type):
225225

226226

227227
def _bincount_validate(x, weights, minlength):
228+
dpnp.check_supported_arrays_type(x)
228229
if x.ndim > 1:
229230
raise ValueError("object too deep for desired array")
231+
230232
if x.ndim < 1:
231233
raise ValueError("object of too small depth for desired array")
234+
232235
if not dpnp.issubdtype(x.dtype, dpnp.integer) and not dpnp.issubdtype(
233236
x.dtype, dpnp.bool
234237
):
235238
raise TypeError("x must be an integer array")
239+
236240
if weights is not None:
241+
dpnp.check_supported_arrays_type(weights)
237242
if x.shape != weights.shape:
238243
raise ValueError("The weights and x don't have the same length.")
244+
239245
if not (
240246
dpnp.issubdtype(weights.dtype, dpnp.integer)
241247
or dpnp.issubdtype(weights.dtype, dpnp.floating)
@@ -245,10 +251,12 @@ def _bincount_validate(x, weights, minlength):
245251
f"Weights must be integer or float. Got {weights.dtype}"
246252
)
247253

248-
if minlength is not None:
249-
minlength = int(minlength)
250-
if minlength < 0:
251-
raise ValueError("minlength must be non-negative")
254+
if minlength is None:
255+
raise TypeError("use 0 instead of None for minlength")
256+
257+
minlength = int(minlength)
258+
if minlength < 0:
259+
raise ValueError("minlength must be non-negative")
252260

253261

254262
def _bincount_run_native(
@@ -262,9 +270,7 @@ def _bincount_run_native(
262270
if min_v < 0:
263271
raise ValueError("x argument must have no negative arguments")
264272

265-
size = int(dpnp.max(max_v)) + 1
266-
if minlength is not None:
267-
size = max(size, minlength)
273+
size = max(int(max_v) + 1, minlength)
268274

269275
# bincount implementation uses atomics, but atomics doesn't work with
270276
# host usm memory
@@ -299,9 +305,9 @@ def _bincount_run_native(
299305
return n_casted
300306

301307

302-
def bincount(x, weights=None, minlength=None):
308+
def bincount(x, weights=None, minlength=0):
303309
"""
304-
bincount(x, /, weights=None, minlength=None)
310+
bincount(x, /, weights=None, minlength=0)
305311
306312
Count number of occurrences of each value in array of non-negative ints.
307313
@@ -313,10 +319,12 @@ def bincount(x, weights=None, minlength=None):
313319
Input 1-dimensional array with non-negative integer values.
314320
weights : {None, dpnp.ndarray, usm_ndarray}, optional
315321
Weights, array of the same shape as `x`.
322+
316323
Default: ``None``
317-
minlength : {None, int}, optional
324+
minlength : int, optional
318325
A minimum number of bins for the output array.
319-
Default: ``None``
326+
327+
Default: ``0``
320328
321329
Returns
322330
-------
@@ -416,6 +424,7 @@ def digitize(x, bins, right=False):
416424
increasing or decreasing.
417425
right : bool, optional
418426
Indicates whether the intervals include the right or the left bin edge.
427+
419428
Default: ``False``.
420429
421430
Returns
@@ -675,6 +684,7 @@ def histogram_bin_edges(a, bins=10, range=None, weights=None):
675684
given range.
676685
If `bins` is a sequence, it defines the bin edges, including the
677686
rightmost edge, allowing for non-uniform bin widths.
687+
678688
Default: ``10``.
679689
range : {None, 2-tuple of float}, optional
680690
The lower and upper range of the bins. If not provided, range is simply
@@ -683,12 +693,14 @@ def histogram_bin_edges(a, bins=10, range=None, weights=None):
683693
affects the automatic bin computation as well. While bin width is
684694
computed to be optimal based on the actual data within `range`, the bin
685695
count will fill the entire range including portions containing no data.
696+
686697
Default: ``None``.
687698
weights : {None, dpnp.ndarray, usm_ndarray}, optional
688699
An array of weights, of the same shape as `a`. Each value in `a` only
689700
contributes its associated weight towards the bin count (instead of 1).
690701
This is currently not used by any of the bin estimators, but may be in
691702
the future.
703+
692704
Default: ``None``.
693705
694706
Returns

dpnp/linalg/dpnp_utils_linalg.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,13 +449,15 @@ def _batched_qr(a, mode="reduced"):
449449
a_t,
450450
shape=(batch_size, m, m),
451451
dtype=res_type,
452+
order="C",
452453
)
453454
else:
454455
mc = k
455456
q = dpnp.empty_like(
456457
a_t,
457458
shape=(batch_size, n, m),
458459
dtype=res_type,
460+
order="C",
459461
)
460462

461463
# use DPCTL tensor function to fill the matrix array `q[..., :n, :]`
@@ -2532,13 +2534,15 @@ def dpnp_qr(a, mode="reduced"):
25322534
a_t,
25332535
shape=(m, m),
25342536
dtype=res_type,
2537+
order="C",
25352538
)
25362539
else:
25372540
mc = k
25382541
q = dpnp.empty_like(
25392542
a_t,
25402543
shape=(n, m),
25412544
dtype=res_type,
2545+
order="C",
25422546
)
25432547

25442548
# use DPCTL tensor function to fill the matrix array `q[:n]`

dpnp/tests/helper.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
from numpy.testing import assert_allclose, assert_array_equal
77

88
import dpnp
9-
from dpnp.tests import config
9+
10+
from . import config
1011

1112

1213
def assert_dtype_allclose(
@@ -86,14 +87,14 @@ def assert_dtype_allclose(
8687
assert dpnp_arr.dtype == numpy_arr.dtype
8788

8889

89-
def get_integer_dtypes(no_unsigned=False):
90+
def get_integer_dtypes(all_int_types=False, no_unsigned=False):
9091
"""
9192
Build a list of integer types supported by DPNP.
9293
"""
9394

9495
dtypes = [dpnp.int32, dpnp.int64]
9596

96-
if config.all_int_types:
97+
if config.all_int_types or all_int_types:
9798
dtypes += [dpnp.int8, dpnp.int16]
9899
if not no_unsigned:
99100
dtypes += [dpnp.uint8, dpnp.uint16, dpnp.uint32, dpnp.uint64]

dpnp/tests/test_histogram.py

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
assert_array_equal,
88
assert_raises,
99
assert_raises_regex,
10-
suppress_warnings,
1110
)
1211

1312
import dpnp
@@ -19,6 +18,7 @@
1918
get_float_dtypes,
2019
get_integer_dtypes,
2120
has_support_aspect64,
21+
numpy_version,
2222
)
2323

2424

@@ -282,9 +282,10 @@ def test_weights(self, density):
282282
assert_dtype_allclose(result_hist, expected_hist)
283283
assert_dtype_allclose(result_edges, expected_edges)
284284

285-
def test_integer_weights(self):
285+
@pytest.mark.parametrize("dt", get_integer_dtypes(all_int_types=True))
286+
def test_integer_weights(self, dt):
286287
v = numpy.array([1, 2, 2, 4])
287-
w = numpy.array([4, 3, 2, 1])
288+
w = numpy.array([4, 3, 2, 1], dtype=dt)
288289

289290
iv = dpnp.array(v)
290291
iw = dpnp.array(w)
@@ -602,19 +603,42 @@ def test_different_bins_amount(self, bins_count):
602603
@pytest.mark.parametrize(
603604
"array",
604605
[[1, 2, 3], [1, 2, 2, 1, 2, 4], [2, 2, 2, 2]],
605-
ids=["[1, 2, 3]", "[1, 2, 2, 1, 2, 4]", "[2, 2, 2, 2]"],
606+
ids=["size=3", "size=6", "size=4"],
606607
)
607-
@pytest.mark.parametrize(
608-
"minlength", [0, 1, 3, 5], ids=["0", "1", "3", "5"]
609-
)
610-
def test_bincount_minlength(self, array, minlength):
608+
@pytest.mark.parametrize("minlength", [0, 1, 3, 5])
609+
def test_minlength(self, array, minlength):
611610
np_a = numpy.array(array)
612611
dpnp_a = dpnp.array(array)
613612

614613
expected = numpy.bincount(np_a, minlength=minlength)
615614
result = dpnp.bincount(dpnp_a, minlength=minlength)
616615
assert_allclose(expected, result)
617616

617+
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
618+
@pytest.mark.parametrize(
619+
"xp",
620+
[
621+
dpnp,
622+
pytest.param(
623+
numpy,
624+
marks=pytest.mark.xfail(
625+
numpy_version() < "2.3.0",
626+
reason="numpy deprecates but accepts that",
627+
strict=True,
628+
),
629+
),
630+
],
631+
)
632+
def test_minlength_none(self, xp):
633+
a = xp.array([1, 2, 3])
634+
assert_raises_regex(
635+
TypeError,
636+
"use 0 instead of None for minlength",
637+
xp.bincount,
638+
a,
639+
minlength=None,
640+
)
641+
618642
@pytest.mark.parametrize(
619643
"array", [[1, 2, 2, 1, 2, 4]], ids=["[1, 2, 2, 1, 2, 4]"]
620644
)
@@ -623,7 +647,7 @@ def test_bincount_minlength(self, array, minlength):
623647
[None, [0.3, 0.5, 0.2, 0.7, 1.0, -0.6], [2, 2, 2, 2, 2, 2]],
624648
ids=["None", "[0.3, 0.5, 0.2, 0.7, 1., -0.6]", "[2, 2, 2, 2, 2, 2]"],
625649
)
626-
def test_bincount_weights(self, array, weights):
650+
def test_weights(self, array, weights):
627651
np_a = numpy.array(array)
628652
np_weights = numpy.array(weights) if weights is not None else weights
629653
dpnp_a = dpnp.array(array)
@@ -633,6 +657,20 @@ def test_bincount_weights(self, array, weights):
633657
result = dpnp.bincount(dpnp_a, weights=dpnp_weights)
634658
assert_allclose(expected, result)
635659

660+
@pytest.mark.parametrize(
661+
"data",
662+
[numpy.arange(5), 3, [2, 1]],
663+
ids=["numpy.ndarray", "scalar", "list"],
664+
)
665+
def test_unsupported_data_weights(self, data):
666+
# check input array
667+
msg = "An array must be any of supported type"
668+
assert_raises_regex(TypeError, msg, dpnp.bincount, data)
669+
670+
# check array of weights
671+
a = dpnp.ones(5, dtype=dpnp.int32)
672+
assert_raises_regex(TypeError, msg, dpnp.bincount, a, weights=data)
673+
636674

637675
class TestHistogramDd:
638676
@pytest.mark.usefixtures("suppress_complex_warning")

dpnp/tests/test_linalg.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2372,12 +2372,24 @@ class TestQr:
23722372
@pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True))
23732373
@pytest.mark.parametrize(
23742374
"shape",
2375-
[(2, 2), (3, 4), (5, 3), (16, 16), (2, 2, 2), (2, 4, 2), (2, 2, 4)],
2375+
[
2376+
(2, 1),
2377+
(2, 2),
2378+
(3, 4),
2379+
(5, 3),
2380+
(16, 16),
2381+
(3, 3, 1),
2382+
(2, 2, 2),
2383+
(2, 4, 2),
2384+
(2, 2, 4),
2385+
],
23762386
ids=[
2387+
"(2, 1)",
23772388
"(2, 2)",
23782389
"(3, 4)",
23792390
"(5, 3)",
23802391
"(16, 16)",
2392+
"(3, 3, 1)",
23812393
"(2, 2, 2)",
23822394
"(2, 4, 2)",
23832395
"(2, 2, 4)",

dpnp/tests/test_mathematical.py

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2309,35 +2309,27 @@ def test_float_remainder_fmod_nans_inf(func, dtype, lhs, rhs):
23092309
assert_equal(result, expected)
23102310

23112311

2312+
@testing.with_requires("numpy>=2.0.0")
23122313
@pytest.mark.parametrize(
2313-
"data",
2314-
[[2, 0, -2], [1.1, -1.1]],
2315-
ids=["[2, 0, -2]", "[1.1, -1.1]"],
2316-
)
2317-
@pytest.mark.parametrize(
2318-
"dtype", get_all_dtypes(no_bool=True, no_unsigned=True)
2314+
"dtype", get_all_dtypes(no_none=True, no_unsigned=True)
23192315
)
2320-
def test_sign(data, dtype):
2321-
np_a = numpy.array(data, dtype=dtype)
2322-
dpnp_a = dpnp.array(data, dtype=dtype)
2316+
def test_sign(dtype):
2317+
a = generate_random_numpy_array((2, 3), dtype=dtype)
2318+
ia = dpnp.array(a, dtype=dtype)
23232319

2324-
result = dpnp.sign(dpnp_a)
2325-
expected = numpy.sign(np_a)
2326-
assert_dtype_allclose(result, expected)
2327-
2328-
# out keyword
2329-
if dtype is not None:
2330-
dp_out = dpnp.empty(expected.shape, dtype=expected.dtype)
2331-
result = dpnp.sign(dpnp_a, out=dp_out)
2332-
assert dp_out is result
2320+
if dtype == dpnp.bool:
2321+
assert_raises(TypeError, dpnp.sign, ia)
2322+
assert_raises(TypeError, numpy.sign, a)
2323+
else:
2324+
result = dpnp.sign(ia)
2325+
expected = numpy.sign(a)
23332326
assert_dtype_allclose(result, expected)
23342327

2335-
2336-
def test_sign_boolean():
2337-
dpnp_a = dpnp.array([True, False])
2338-
2339-
with pytest.raises(TypeError):
2340-
dpnp.sign(dpnp_a)
2328+
# out keyword
2329+
iout = dpnp.empty(expected.shape, dtype=expected.dtype)
2330+
result = dpnp.sign(ia, out=iout)
2331+
assert iout is result
2332+
assert_dtype_allclose(result, expected)
23412333

23422334

23432335
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)