Skip to content
Merged
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 @@ -57,6 +57,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Fixed `dpnp.unique` with 1d input array and `axis=0`, `equal_nan=True` keywords passed where the produced result doesn't collapse the NaNs [#2530](https://github.com/IntelPython/dpnp/pull/2530)
* Resolved issue when `dpnp.ndarray` constructor is called with `dpnp.ndarray.data` as `buffer` keyword [#2533](https://github.com/IntelPython/dpnp/pull/2533)
* Fixed `dpnp.linalg.cond` to always return a real dtype [#2547](https://github.com/IntelPython/dpnp/pull/2547)
* Resolved the issue in `dpnp.random` functions to allow any value of `size` where each element is castable to `Py_ssize_t` type [#2578](https://github.com/IntelPython/dpnp/pull/2578)

### Security

Expand Down
20 changes: 18 additions & 2 deletions dpnp/dpnp_utils/dpnp_algo_utils.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -390,10 +390,26 @@ cpdef inline tuple _object_to_tuple(object obj):
if obj is None:
return ()

if cpython.PySequence_Check(obj):
return tuple(obj)
# dpnp.ndarray unconditionally succeeds in PySequence_Check as it implements __getitem__
if cpython.PySequence_Check(obj) and not dpnp.is_supported_array_type(obj):
if isinstance(obj, numpy.ndarray):
obj = numpy.atleast_1d(obj)

nd = len(obj)
shape = []

for i in range(0, nd):
if cpython.PyBool_Check(obj[i]):
raise TypeError("DPNP object_to_tuple(): no item in size can be bool")

# Assumes each item is castable to Py_ssize_t,
# otherwise TypeError will be raised
shape.append(<Py_ssize_t> obj[i])
return tuple(shape)

if dpnp.isscalar(obj):
if cpython.PyBool_Check(obj):
raise TypeError("DPNP object_to_tuple(): 'obj' can't be bool")
return (obj, )

raise ValueError("DPNP object_to_tuple(): 'obj' should be 'None', collections.abc.Sequence, or 'int'")
Expand Down
29 changes: 29 additions & 0 deletions dpnp/tests/test_random_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
is_cpu_device,
is_gpu_device,
)
from .third_party.cupy import testing

# aspects of default device:
_def_device = dpctl.SyclQueue().sycl_device
Expand Down Expand Up @@ -1115,3 +1116,31 @@ def test_invalid_dtype(self, dtype):
def test_invalid_usm_type(self, usm_type):
# dtype must be float32 or float64
assert_raises(ValueError, RandomState().uniform, usm_type=usm_type)

def test_size_castable_to_integer(self):
M = numpy.int64(31)
N = numpy.int64(31)
K = 63 # plain Python int

sizes = [(M, K), (M, N), (K, N)]
for size in sizes:
result = RandomState().uniform(size=size)
assert result.shape == size

@testing.with_requires("numpy>=2.3.2")
@pytest.mark.parametrize("xp", [numpy, dpnp])
@pytest.mark.parametrize(
"size",
[True, [True], dpnp.bool(True), numpy.array(True), numpy.array([True])],
)
def test_bool_size(self, xp, size):
rs = xp.random.RandomState()
assert_raises(TypeError, rs.uniform, size=size)

@pytest.mark.parametrize("size", [numpy.array(1), numpy.array([2])])
def test_numpy_ndarray_size(self, size):
result = RandomState().uniform(size=size)
assert result.shape == size

def test_dpnp_ndarray_size(self):
assert_raises(ValueError, RandomState().uniform, size=dpnp.array(1))
Loading