Skip to content

Commit 8fa2166

Browse files
authored
Implemented dpnp.frombuffer, dpnp.fromfile and dpnp.fromstring (#1727)
* Implemented dpnp.frombuffer, dpnp.fromfile and dpnp.fromstring * Address the comments
1 parent 44ea638 commit 8fa2166

File tree

5 files changed

+322
-31
lines changed

5 files changed

+322
-31
lines changed

dpnp/dpnp_iface_arraycreation.py

Lines changed: 264 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,23 +1399,114 @@ def eye(
13991399
)
14001400

14011401

1402-
def frombuffer(buffer, **kwargs):
1403-
"""
1402+
def frombuffer(
1403+
buffer,
1404+
dtype=float,
1405+
count=-1,
1406+
offset=0,
1407+
*,
1408+
like=None,
1409+
device=None,
1410+
usm_type="device",
1411+
sycl_queue=None,
1412+
):
1413+
r"""
14041414
Interpret a buffer as a 1-dimensional array.
14051415
14061416
For full documentation refer to :obj:`numpy.frombuffer`.
14071417
1418+
Parameters
1419+
----------
1420+
buffer : buffer_like
1421+
An object that exposes the buffer interface.
1422+
dtype : data-type, optional
1423+
Data-type of the returned array.
1424+
Default is the default floating point data type for the device where
1425+
the returned array is allocated.
1426+
count : int, optional
1427+
Number of items to read. ``-1`` means all data in the buffer.
1428+
offset : int, optional
1429+
Start reading the buffer from this offset (in bytes); default: 0.
1430+
device : {None, string, SyclDevice, SyclQueue}, optional
1431+
An array API concept of device where the output array is created.
1432+
The `device` can be ``None`` (the default), an OneAPI filter selector
1433+
string, an instance of :class:`dpctl.SyclDevice` corresponding to
1434+
a non-partitioned SYCL device, an instance of :class:`dpctl.SyclQueue`,
1435+
or a `Device` object returned by
1436+
:obj:`dpnp.dpnp_array.dpnp_array.device` property.
1437+
usm_type : {"device", "shared", "host"}, optional
1438+
The type of SYCL USM allocation for the output array.
1439+
Default is "device".
1440+
sycl_queue : {None, SyclQueue}, optional
1441+
A SYCL queue to use for output array allocation and copying.
1442+
1443+
Returns
1444+
-------
1445+
out : dpnp.ndarray
1446+
A 1-dimensional array created from input buffer object.
1447+
14081448
Limitations
14091449
-----------
1410-
Only float64, float32, int64, int32 types are supported.
1450+
Parameter `like` is supported only with default value ``None``.
1451+
Otherwise, the function raises `NotImplementedError` exception.
14111452
1412-
"""
1453+
Notes
1454+
-----
1455+
This uses :obj:`numpy.frombuffer` and coerces the result to a DPNP array.
14131456
1414-
return call_origin(numpy.frombuffer, buffer, **kwargs)
1457+
See also
1458+
--------
1459+
:obj:`dpnp.fromfile` : Construct array from data in a text or binary file.
1460+
:obj:`dpnp.fromiter` : Construct array from an iterable object.
1461+
:obj:`dpnp.fromstring` : Construct array from the text data in a string.
14151462
1463+
Examples
1464+
--------
1465+
>>> import dpnp as np
1466+
>>> s = b'\x01\x02\x03\x04'
1467+
>>> np.frombuffer(s, dtype=np.int32)
1468+
array([67305985], dtype=int32)
1469+
>>> np.frombuffer(b'\x01\x02\x03\x04\x05', dtype='u1', count=3)
1470+
array([1, 2, 3], dtype=uint8)
1471+
1472+
Creating an array on a different device or with a specified usm_type
1473+
1474+
>>> x = np.frombuffer(s, dtype=np.int32) # default case
1475+
>>> x.device, x.usm_type
1476+
(Device(level_zero:gpu:0), 'device')
1477+
1478+
>>> y = np.frombuffer(s, dtype=np.int32, device='cpu')
1479+
>>> y.device, y.usm_type
1480+
(Device(opencl:cpu:0), 'device')
1481+
1482+
>>> z = np.frombuffer(s, dtype=np.int32, usm_type="host")
1483+
>>> z.device, z.usm_type
1484+
(Device(level_zero:gpu:0), 'host')
14161485
1417-
def fromfile(file, **kwargs):
14181486
"""
1487+
1488+
_check_limitations(like=like)
1489+
return asarray(
1490+
numpy.frombuffer(buffer, dtype=dtype, count=count, offset=offset),
1491+
device=device,
1492+
usm_type=usm_type,
1493+
sycl_queue=sycl_queue,
1494+
)
1495+
1496+
1497+
def fromfile(
1498+
file,
1499+
dtype=float,
1500+
count=-1,
1501+
sep="",
1502+
offset=0,
1503+
*,
1504+
like=None,
1505+
device=None,
1506+
usm_type="device",
1507+
sycl_queue=None,
1508+
):
1509+
r"""
14191510
Construct an array from data in a text or binary file.
14201511
14211512
A highly efficient way of reading binary data with a known data-type,
@@ -1424,13 +1515,107 @@ def fromfile(file, **kwargs):
14241515
14251516
For full documentation refer to :obj:`numpy.fromfile`.
14261517
1518+
Parameters
1519+
----------
1520+
file : file or str or Path
1521+
Open file object or filename.
1522+
dtype : data-type, optional
1523+
Data type of the returned array.
1524+
For binary files, it is used to determine the size and byte-order
1525+
of the items in the file.
1526+
Default is the default floating point data type for the device where
1527+
the returned array is allocated.
1528+
count : int, optional
1529+
Number of items to read. ``-1`` means all items (i.e., the complete
1530+
file).
1531+
sep : str, optional
1532+
Separator between items if `file` is a text file.
1533+
Empty ("") separator means the file should be treated as binary.
1534+
Spaces (" ") in the separator match zero or more whitespace characters.
1535+
A separator consisting only of spaces must match at least one
1536+
whitespace.
1537+
offset : int, optional
1538+
The offset (in bytes) from the file's current position. Defaults to 0.
1539+
Only permitted for binary files.
1540+
device : {None, string, SyclDevice, SyclQueue}, optional
1541+
An array API concept of device where the output array is created.
1542+
The `device` can be ``None`` (the default), an OneAPI filter selector
1543+
string, an instance of :class:`dpctl.SyclDevice` corresponding to
1544+
a non-partitioned SYCL device, an instance of :class:`dpctl.SyclQueue`,
1545+
or a `Device` object returned by
1546+
:obj:`dpnp.dpnp_array.dpnp_array.device` property.
1547+
usm_type : {"device", "shared", "host"}, optional
1548+
The type of SYCL USM allocation for the output array.
1549+
Default is "device".
1550+
sycl_queue : {None, SyclQueue}, optional
1551+
A SYCL queue to use for output array allocation and copying.
1552+
1553+
Returns
1554+
-------
1555+
out : dpnp.ndarray
1556+
A 1-dimensional array created from data in a text or binary file.
1557+
14271558
Limitations
14281559
-----------
1429-
Only float64, float32, int64, int32 types are supported.
1560+
Parameter `like` is supported only with default value ``None``.
1561+
Otherwise, the function raises `NotImplementedError` exception.
1562+
1563+
Notes
1564+
-----
1565+
This uses :obj:`numpy.fromfile` and coerces the result to a DPNP array.
1566+
1567+
See also
1568+
--------
1569+
:obj:`dpnp.frombuffer` : Construct array from the buffer data.
1570+
:obj:`dpnp.fromiter` : Construct array from an iterable object.
1571+
:obj:`dpnp.fromstring` : Construct array from the text data in a string.
1572+
:obj:`dpnp.load` : Load arrays or pickled objects from files.
1573+
:obj:`dpnp.save` : Save an array to a binary file.
1574+
:obj:`dpnp.ndarray.tofile` : Write array to a file as text or binary.
1575+
:obj:`dpnp.loadtxt` : More flexible way of loading data from a text file.
1576+
1577+
Examples
1578+
--------
1579+
Save the data to a temporary file:
1580+
1581+
>>> import tempfile
1582+
>>> fh = tempfile.TemporaryFile()
1583+
>>> fh.write(b"\x00\x01\x02\x03\x04")
1584+
>>> fh.flush()
1585+
>>> fh.seek(0)
1586+
1587+
Construct an array:
1588+
1589+
>>> import dpnp as np
1590+
>>> np.fromfile(fh, dtype="u1")
1591+
array([0, 1, 2, 3, 4], dtype=uint8)
1592+
1593+
Creating an array on a different device or with a specified usm_type
1594+
1595+
>>> fh.seek(0)
1596+
>>> x = np.fromfile(fh, dtype="u1") # default case
1597+
>>> x.device, x.usm_type
1598+
(Device(level_zero:gpu:0), 'device')
1599+
1600+
>>> fh.seek(0)
1601+
>>> y = np.fromfile(fh, dtype="u1", device='cpu')
1602+
>>> y.device, y.usm_type
1603+
(Device(opencl:cpu:0), 'device')
1604+
1605+
>>> fh.seek(0)
1606+
>>> z = np.fromfile(fh, dtype="u1", usm_type="host")
1607+
>>> z.device, z.usm_type
1608+
(Device(level_zero:gpu:0), 'host')
14301609
14311610
"""
14321611

1433-
return call_origin(numpy.fromfile, file, **kwargs)
1612+
_check_limitations(like=like)
1613+
return asarray(
1614+
numpy.fromfile(file, dtype=dtype, count=count, sep=sep, offset=offset),
1615+
device=device,
1616+
usm_type=usm_type,
1617+
sycl_queue=sycl_queue,
1618+
)
14341619

14351620

14361621
def fromfunction(function, shape, **kwargs):
@@ -1466,19 +1651,87 @@ def fromiter(iterable, dtype, count=-1):
14661651
return call_origin(numpy.fromiter, iterable, dtype, count)
14671652

14681653

1469-
def fromstring(string, **kwargs):
1654+
def fromstring(
1655+
string,
1656+
dtype=float,
1657+
count=-1,
1658+
*,
1659+
sep,
1660+
like=None,
1661+
device=None,
1662+
usm_type="device",
1663+
sycl_queue=None,
1664+
):
14701665
"""
14711666
A new 1-D array initialized from text data in a string.
14721667
14731668
For full documentation refer to :obj:`numpy.fromstring`.
14741669
1670+
Parameters
1671+
----------
1672+
string : str
1673+
A string containing the data.
1674+
dtype : data-type, optional
1675+
The data type of the array.
1676+
For binary input data, the data must be in exactly this format.
1677+
Default is the default floating point data type for the device where
1678+
the returned array is allocated.
1679+
count : int, optional
1680+
Read this number of `dtype` elements from the data. If this is negative
1681+
(the default), the count will be determined from the length of the data.
1682+
sep : str, optional
1683+
The string separating numbers in the data; extra whitespace between
1684+
elements is also ignored.
1685+
device : {None, string, SyclDevice, SyclQueue}, optional
1686+
An array API concept of device where the output array is created.
1687+
The `device` can be ``None`` (the default), an OneAPI filter selector
1688+
string, an instance of :class:`dpctl.SyclDevice` corresponding to
1689+
a non-partitioned SYCL device, an instance of :class:`dpctl.SyclQueue`,
1690+
or a `Device` object returned by
1691+
:obj:`dpnp.dpnp_array.dpnp_array.device` property.
1692+
usm_type : {"device", "shared", "host"}, optional
1693+
The type of SYCL USM allocation for the output array.
1694+
Default is "device".
1695+
sycl_queue : {None, SyclQueue}, optional
1696+
A SYCL queue to use for output array allocation and copying.
1697+
1698+
Returns
1699+
-------
1700+
out : dpnp.ndarray
1701+
The constructed array.
1702+
14751703
Limitations
14761704
-----------
1477-
Only float64, float32, int64, int32 types are supported.
1705+
Parameter `like` is supported only with default value ``None``.
1706+
Otherwise, the function raises `NotImplementedError` exception.
1707+
1708+
Notes
1709+
-----
1710+
This uses :obj:`numpy.fromstring` and coerces the result to a DPNP array.
1711+
1712+
See also
1713+
--------
1714+
:obj:`dpnp.frombuffer` : Construct array from the buffer data.
1715+
:obj:`dpnp.fromfile` : Construct array from data in a text or binary file.
1716+
:obj:`dpnp.fromiter` : Construct array from an iterable object.
1717+
1718+
Examples
1719+
--------
1720+
>>> import dpnp as np
1721+
>>> np.fromstring('1 2', dtype=int, sep=' ')
1722+
array([1, 2])
1723+
>>> np.fromstring('1, 2', dtype=int, sep=',')
1724+
array([1, 2])
14781725
14791726
"""
14801727

1481-
return call_origin(numpy.fromstring, string, **kwargs)
1728+
_check_limitations(like=like)
1729+
return asarray(
1730+
numpy.fromstring(string, dtype=dtype, count=count, sep=sep),
1731+
device=device,
1732+
usm_type=usm_type,
1733+
sycl_queue=sycl_queue,
1734+
)
14821735

14831736

14841737
def full(

tests/test_arraycreation.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def test_exception_order(func, args):
5252
pytest.param("asfortranarray", [2]),
5353
pytest.param("empty", [(2,)]),
5454
pytest.param("eye", [2]),
55+
pytest.param("frombuffer", [b"\x01\x02\x03\x04"]),
5556
pytest.param("full", [(2,), 4]),
5657
pytest.param("identity", [2]),
5758
pytest.param("ones", [(2,)]),
@@ -208,21 +209,14 @@ def test_eye(N, M, k, dtype, order):
208209
assert_array_equal(func(numpy), func(dpnp))
209210

210211

211-
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
212-
@pytest.mark.parametrize(
213-
"dtype",
214-
get_all_dtypes(
215-
no_float16=False, no_none=False if has_support_aspect64() else True
216-
),
217-
)
212+
@pytest.mark.parametrize("dtype", get_all_dtypes(no_float16=False))
218213
def test_frombuffer(dtype):
219214
buffer = b"12345678ABCDEF00"
220215
func = lambda xp: xp.frombuffer(buffer, dtype=dtype)
221-
assert_allclose(func(dpnp), func(numpy))
216+
assert_dtype_allclose(func(dpnp), func(numpy))
222217

223218

224-
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
225-
@pytest.mark.parametrize("dtype", get_all_dtypes())
219+
@pytest.mark.parametrize("dtype", get_all_dtypes(no_float16=False))
226220
def test_fromfile(dtype):
227221
with tempfile.TemporaryFile() as fh:
228222
fh.write(b"\x00\x01\x02\x03\x04\x05\x06\x07\x08")
@@ -236,7 +230,7 @@ def test_fromfile(dtype):
236230
fh.seek(0)
237231
dpnp_res = func(dpnp)
238232

239-
assert_almost_equal(dpnp_res, np_res)
233+
assert_dtype_allclose(dpnp_res, np_res)
240234

241235

242236
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
@@ -260,7 +254,6 @@ def test_fromiter(dtype):
260254
assert_array_equal(func(dpnp), func(numpy))
261255

262256

263-
@pytest.mark.usefixtures("allow_fall_back_on_numpy")
264257
@pytest.mark.parametrize("dtype", get_all_dtypes(no_float16=False))
265258
def test_fromstring(dtype):
266259
string = "1 2 3 4"

0 commit comments

Comments
 (0)