Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented dpnp.fromfunction, dpnp.fromiter and dpnp.loadtxt #1728

Merged
merged 13 commits into from
Feb 25, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
10 changes: 5 additions & 5 deletions doc/reference/creation.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
.. _routines.creation:

Array Creation Routines
Array creation routines
=======================

.. https://docs.scipy.org/doc/numpy/reference/routines.array-creation.html

Basic creation routines
From shape or value
-----------------------

.. autosummary::
Expand All @@ -24,7 +24,7 @@ Basic creation routines
dpnp.full_like


Creation from other data
From existing data
------------------------

.. autosummary::
Expand All @@ -35,6 +35,7 @@ Creation from other data
dpnp.asarray
dpnp.asanyarray
dpnp.ascontiguousarray
dpnp.astype
dpnp.copy
dpnp.frombuffer
dpnp.from_dlpack
Expand All @@ -61,7 +62,7 @@ Numerical ranges
dpnp.ogrid


Matrix creation
Building matrices
---------------

.. autosummary::
Expand All @@ -82,5 +83,4 @@ The Matrix class
:toctree: generated/
:nosignatures:

dpnp.mat
dpnp.bmat
266 changes: 255 additions & 11 deletions dpnp/dpnp_iface_arraycreation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1618,7 +1618,17 @@ def fromfile(
)


def fromfunction(function, shape, **kwargs):
def fromfunction(
function,
shape,
*,
dtype=float,
like=None,
device=None,
usm_type="device",
sycl_queue=None,
**kwargs,
):
"""
Construct an array by executing a function over each coordinate.

Expand All @@ -1627,28 +1637,189 @@ def fromfunction(function, shape, **kwargs):

For full documentation refer to :obj:`numpy.fromfunction`.

Parameters
----------
function : callable
The function is called with N parameters, where N is the rank of
`shape`. Each parameter represents the coordinates of the array varying
along a specific axis. For example, if `shape` were ``(2, 2)``, then
the parameters would be ``array([[0, 0], [1, 1]])`` and
``array([[0, 1], [0, 1]])``.
shape : (N,) tuple of ints
Shape of the output array, which also determines the shape of
the coordinate arrays passed to `function`.
dtype : data-type, optional
Data-type of the coordinate arrays passed to `function`.
Default is the default floating point data type for the device where
the returned array is allocated.
device : {None, string, SyclDevice, SyclQueue}, optional
An array API concept of device where the output array is created.
The `device` can be ``None`` (the default), an OneAPI filter selector
string, an instance of :class:`dpctl.SyclDevice` corresponding to
a non-partitioned SYCL device, an instance of :class:`dpctl.SyclQueue`,
or a `Device` object returned by
:obj:`dpnp.dpnp_array.dpnp_array.device` property.
usm_type : {"device", "shared", "host"}, optional
The type of SYCL USM allocation for the output array.
Default is "device".
sycl_queue : {None, SyclQueue}, optional
A SYCL queue to use for output array allocation and copying.

Returns
-------
out : dpnp.ndarray
The result of the call to `function` is passed back directly.
Therefore the shape of `fromfunction` is completely determined by
`function`.

Limitations
-----------
Only float64, float32, int64, int32 types are supported.
Parameter `like` is supported only with default value ``None``.
Otherwise, the function raises `NotImplementedError` exception.

Notes
-----
This uses :obj:`numpy.fromfunction` and coerces the result to a DPNP array.
Keywords other than `dtype` and `like` are passed to `function`.

See also
--------
:obj:`dpnp.indices` : Return an array representing the indices of a grid.
:obj:`dpnp.meshgrid` : Return coordinate matrices from coordinate vectors.

Examples
--------
>>> import dpnp as np
>>> np.fromfunction(lambda i, j: i, (2, 2), dtype=float)
array([[0., 0.],
[1., 1.]])

>>> np.fromfunction(lambda i, j: j, (2, 2), dtype=float)
array([[0., 1.],
[0., 1.]])

>>> np.fromfunction(lambda i, j: i == j, (3, 3), dtype=int)
array([[ True, False, False],
[False, True, False],
[False, False, True]])

>>> np.fromfunction(lambda i, j: i + j, (3, 3), dtype=int)
array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4]])

Creating an array on a different device or with a specified usm_type

>>> x = np.fromfunction(lambda i, j: i - j, (3, 3)) # default case
>>> x.device, x.usm_type
(Device(level_zero:gpu:0), 'device')

>>> y = np.fromfunction(lambda i, j: i - j, (3, 3), device='cpu')
>>> y.device, y.usm_type
(Device(opencl:cpu:0), 'device')

>>> z = np.fromfunction(lambda i, j: i - j, (3, 3), usm_type="host")
>>> z.device, z.usm_type
(Device(level_zero:gpu:0), 'host')

"""

return call_origin(numpy.fromfunction, function, shape, **kwargs)
_check_limitations(like=like)
return asarray(
numpy.fromfunction(function, shape, dtype=dtype, **kwargs),
device=device,
usm_type=usm_type,
sycl_queue=sycl_queue,
)


def fromiter(iterable, dtype, count=-1):
def fromiter(
iter,
dtype,
count=-1,
*,
like=None,
device=None,
usm_type="device",
sycl_queue=None,
):
"""
Create a new 1-dimensional array from an iterable object.

For full documentation refer to :obj:`numpy.fromiter`.

Parameters
----------
iter : iterable object
An iterable object providing data for the array.
dtype : data-type
The data-type of the returned array.
count : int, optional
The number of items to read from *iterable*. The default is -1,
which means all data is read.
device : {None, string, SyclDevice, SyclQueue}, optional
An array API concept of device where the output array is created.
The `device` can be ``None`` (the default), an OneAPI filter selector
string, an instance of :class:`dpctl.SyclDevice` corresponding to
a non-partitioned SYCL device, an instance of :class:`dpctl.SyclQueue`,
or a `Device` object returned by
:obj:`dpnp.dpnp_array.dpnp_array.device` property.
usm_type : {"device", "shared", "host"}, optional
The type of SYCL USM allocation for the output array.
Default is "device".
sycl_queue : {None, SyclQueue}, optional
A SYCL queue to use for output array allocation and copying.

Returns
-------
out : dpnp.ndarray
The output array.

Limitations
-----------
Only float64, float32, int64, int32 types are supported.
Parameter `like` is supported only with default value ``None``.
Otherwise, the function raises `NotImplementedError` exception.

Notes
-----
This uses :obj:`numpy.fromiter` and coerces the result to a DPNP array.

See also
--------
:obj:`dpnp.frombuffer` : Construct array from the buffer data.
:obj:`dpnp.fromfile` : Construct array from data in a text or binary file.
:obj:`dpnp.fromstring` : Construct array from the text data in a string.

Examples
--------
>>> import dpnp as np
>>> iterable = (a * a for a in range(5))
>>> np.fromiter(iterable, float)
array([ 0., 1., 4., 9., 16.])

Creating an array on a different device or with a specified usm_type

>>> x = np.fromiter(iterable, np.int32) # default case
>>> x.device, x.usm_type
(Device(level_zero:gpu:0), 'device')

>>> y = np.fromiter(iterable, np.int32, device='cpu')
>>> y.device, y.usm_type
(Device(opencl:cpu:0), 'device')

>>> z = np.fromiter(iterable, np.int32, usm_type="host")
>>> z.device, z.usm_type
(Device(level_zero:gpu:0), 'host')

"""

return call_origin(numpy.fromiter, iterable, dtype, count)
_check_limitations(like=like)
return asarray(
numpy.fromiter(iter, dtype, count=count),
device=device,
usm_type=usm_type,
sycl_queue=sycl_queue,
)


def fromstring(
Expand Down Expand Up @@ -2286,17 +2457,67 @@ def linspace(
)


def loadtxt(fname, **kwargs):
def loadtxt(
fname,
dtype=float,
like=None,
device=None,
usm_type=None,
antonwolfy marked this conversation as resolved.
Show resolved Hide resolved
sycl_queue=None,
**kwargs,
):
r"""
Load data from a text file.

Each row in the text file must have the same number of values.

For full documentation refer to :obj:`numpy.loadtxt`.

Parameters
----------
fname : file, str, pathlib.Path, list of str, generator
File, filename, list, or generator to read. If the filename extension
is ``.gz`` or ``.bz2``, the file is first decompressed. Note that
generators must return bytes or strings. The strings in a list or
produced by a generator are treated as lines.
dtype : data-type, optional
Data-type of the resulting array.
Default is the default floating point data type for the device where
the returned array is allocated.
A structured data-type is not supported.
device : {None, string, SyclDevice, SyclQueue}, optional
An array API concept of device where the output array is created.
The `device` can be ``None`` (the default), an OneAPI filter selector
string, an instance of :class:`dpctl.SyclDevice` corresponding to
a non-partitioned SYCL device, an instance of :class:`dpctl.SyclQueue`,
or a `Device` object returned by
:obj:`dpnp.dpnp_array.dpnp_array.device` property.
usm_type : {"device", "shared", "host"}, optional
The type of SYCL USM allocation for the output array.
Default is "device".
antonwolfy marked this conversation as resolved.
Show resolved Hide resolved
sycl_queue : {None, SyclQueue}, optional
A SYCL queue to use for output array allocation and copying.

Returns
-------
out : dpnp.ndarray
Data read from the text file.

Limitations
-----------
Only float64, float32, int64, int32 types are supported.
Parameter `like` is supported only with default value ``None``.
Otherwise, the function raises `NotImplementedError` exception.

Notes
-----
This uses :obj:`numpy.loadtxt` and coerces the result to a DPNP array.

See also
--------
:obj:`dpnp.frombuffer` : Construct array from the buffer data.
:obj:`dpnp.fromstring` : Construct array from the text data in a string.
:obj:`dpnp.fromregex` : Construct an array from a text file,
using regular expression parsing.
:obj:`dpnp.load` : Load arrays or pickled objects from files.
:obj:`dpnp.genfromtxt` : Load data with missing values handled as specified.

Examples
--------
Expand All @@ -2307,9 +2528,32 @@ def loadtxt(fname, **kwargs):
array([[0., 1.],
[2., 3.]])

Creating an array on a different device or with a specified usm_type

>>> c = StringIO("0 1\n2 3")
>>> x = np.loadtxt(c, dtype=np.int32) # default case
>>> x.device, x.usm_type
(Device(level_zero:gpu:0), 'device')

>>> c = StringIO("0 1\n2 3")
>>> y = np.loadtxt(c, dtype=np.int32, device='cpu')
>>> y.device, y.usm_type
(Device(opencl:cpu:0), 'device')

>>> c = StringIO("0 1\n2 3")
>>> z = np.loadtxt(c, dtype=np.int32, usm_type="host")
>>> z.device, z.usm_type
(Device(level_zero:gpu:0), 'host')

"""

return call_origin(numpy.loadtxt, fname, **kwargs)
_check_limitations(like=like)
return asarray(
numpy.loadtxt(fname, dtype=dtype, **kwargs),
device=device,
usm_type=usm_type,
sycl_queue=sycl_queue,
)


def logspace(
Expand Down
5 changes: 1 addition & 4 deletions tests/test_arraycreation.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,6 @@ def test_fromfile(dtype):
assert_dtype_allclose(dpnp_res, np_res)


@pytest.mark.usefixtures("allow_fall_back_on_numpy")
@pytest.mark.parametrize(
"dtype", get_all_dtypes(no_bool=True, no_float16=False)
)
Expand All @@ -246,7 +245,6 @@ def func(x, y):
assert_array_equal(call_func(dpnp), call_func(numpy))


@pytest.mark.usefixtures("allow_fall_back_on_numpy")
@pytest.mark.parametrize("dtype", get_all_dtypes(no_float16=False))
def test_fromiter(dtype):
_iter = [1, 2, 3, 4]
Expand All @@ -268,7 +266,6 @@ def test_identity(n, dtype):
assert_array_equal(func(numpy), func(dpnp))


@pytest.mark.usefixtures("allow_fall_back_on_numpy")
@pytest.mark.parametrize("dtype", get_all_dtypes(no_float16=False))
def test_loadtxt(dtype):
func = lambda xp: xp.loadtxt(fh, dtype=dtype)
Expand All @@ -282,7 +279,7 @@ def test_loadtxt(dtype):
fh.seek(0)
dpnp_res = func(dpnp)

assert_array_equal(dpnp_res, np_res)
assert_array_equal(dpnp_res, np_res)


@pytest.mark.parametrize("dtype", get_all_dtypes(no_bool=True, no_complex=True))
Expand Down
Loading
Loading