Skip to content

Commit 4fb40cd

Browse files
Added docstrings to asarray and empty
Change default of asarray's order keyword from "K" to "C" Fixed issue pointed out by Denis (processing of order in empty) Added support for objects with buffer protocol in asarray.
1 parent 2d85f91 commit 4fb40cd

File tree

1 file changed

+93
-6
lines changed

1 file changed

+93
-6
lines changed

dpctl/tensor/_ctors.py

Lines changed: 93 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,17 @@ def _asarray_from_numpy_ndarray(
229229
return res
230230

231231

232+
def _is_object_with_buffer_protocol(obj):
233+
"Returns True if object support Python buffer protocol"
234+
try:
235+
# use context manager to ensure
236+
# buffer is instantly released
237+
with memoryview(obj):
238+
return True
239+
except TypeError:
240+
return False
241+
242+
232243
def asarray(
233244
obj,
234245
dtype=None,
@@ -238,7 +249,45 @@ def asarray(
238249
sycl_queue=None,
239250
order="K",
240251
):
241-
"""Represents object `obj` as usm_ndarray"""
252+
"""asarray(obj, dtype=None, copy=None, order="K",
253+
device=None, usm_type=None, sycl_queue=None)
254+
255+
Converts `obj` to :class:`dpctl.tensor.usm_ndarray`.
256+
257+
Args:
258+
obj: Python object to convert. Can be an instance of `usm_ndarray`,
259+
an object representing SYCL USM allocation and implementing
260+
`__sycl_usm_array_interface__` protocol, an instance
261+
of `numpy.ndarray`, an object supporting Python buffer protocol,
262+
a Python scalar, or a (possibly nested) sequence of Python scalars.
263+
dtype (data type, optional): output array data type. If `dtype` is
264+
`None`, the output array data type is inferred from data types in
265+
`obj`. Default: `None`
266+
copy (`bool`, optional): boolean indicating whether or not to copy the
267+
input. If `True`, always creates a copy. If `False`, need to copy
268+
raises `ValueError`. If `None`, try to reuse existing memory
269+
allocations if possible, but allowed to perform a copy otherwise.
270+
Default: `None`.
271+
order ("C","F","A","K", optional): memory layout of the output array.
272+
Default: "C"
273+
device (optional): array API concept of device where the output array
274+
is created. `device` can be `None`, a oneAPI filter selector string,
275+
an instance of :class:`dpctl.SyclDevice` corresponding to a
276+
non-partitioned SYCL device, an instance of
277+
:class:`dpctl.SyclQueue`, or a `Device` object returnedby
278+
`dpctl.tensor.usm_array.device`. Default: `None`.
279+
usm_type ("device"|"shared"|"host", optional): The type of SYCL USM
280+
allocation for the output array. For `usm_type=None` the allocation
281+
type is inferred from the input if `obj` has USM allocation, or
282+
`"device"` is used instead. Default: `None`.
283+
sycl_queue: (:class:`dpctl.SyclQueue`, optional): The SYCL queue to use
284+
for output array allocation and copying. `sycl_queue` and `device`
285+
are exclusive keywords, i.e. use one or another. If both are
286+
specified, a `TypeError` is raised unless both imply the same
287+
underlying SYCL queue to be used. If both a `None`, the
288+
`dpctl.SyclQueue()` is used for allocation and copying.
289+
Default: `None`.
290+
"""
242291
# 1. Check that copy is a valid keyword
243292
if copy not in [None, True, False]:
244293
raise TypeError(
@@ -313,9 +362,17 @@ def asarray(
313362
sycl_queue=sycl_queue,
314363
order=order,
315364
)
316-
elif hasattr(obj, "__dlpack__"):
317-
raise NotImplementedError(
318-
"Support for __dlpack__ is not yet implemented"
365+
elif _is_object_with_buffer_protocol(obj):
366+
if copy is False:
367+
raise ValueError(
368+
f"Converting {type(obj)} to usm_ndarray requires a copy"
369+
)
370+
return _asarray_from_numpy_ndarray(
371+
np.array(obj),
372+
dtype=dtype,
373+
usm_type=usm_type,
374+
sycl_queue=sycl_queue,
375+
order=order,
319376
)
320377
elif isinstance(obj, (list, tuple, range)):
321378
if copy is False:
@@ -335,6 +392,10 @@ def asarray(
335392
raise NotImplementedError(
336393
"Converting Python sequences is not implemented"
337394
)
395+
if copy is False:
396+
raise ValueError(
397+
f"Converting {type(obj)} to usm_ndarray requires a copy"
398+
)
338399
# obj is a scalar, create 0d array
339400
return _asarray_from_numpy_ndarray(
340401
np.asarray(obj),
@@ -348,9 +409,35 @@ def asarray(
348409
def empty(
349410
sh, dtype="f8", order="C", device=None, usm_type="device", sycl_queue=None
350411
):
351-
"""Creates empty usm_ndarray"""
412+
"""dpctl.tensor.empty(shape, dtype="f8", order="C", device=None,
413+
usm_type="device", sycl_queue=None)
414+
415+
Creates `usm_ndarray` from uninitialized USM allocation.
416+
417+
Args:
418+
shape (tuple): Dimensions of the array to be created.
419+
dtype (optional): data type of the array. Can be typestring,
420+
a `numpy.dtype` object, `numpy` char string, or a numpy
421+
scalar type. Default: "f8"
422+
order ("C", or F"): memory layout for the array. Default: "C"
423+
device (optional): array API concept of device where the output array
424+
is created. `device` can be `None`, a oneAPI filter selector string,
425+
an instance of :class:`dpctl.SyclDevice` corresponding to a
426+
non-partitioned SYCL device, an instance of
427+
:class:`dpctl.SyclQueue`, or a `Device` object returnedby
428+
`dpctl.tensor.usm_array.device`. Default: `None`.
429+
usm_type ("device"|"shared"|"host", optional): The type of SYCL USM
430+
allocation for the output array. Default: `"device"`.
431+
sycl_queue: (:class:`dpctl.SyclQueue`, optional): The SYCL queue to use
432+
for output array allocation and copying. `sycl_queue` and `device`
433+
are exclusive keywords, i.e. use one or another. If both are
434+
specified, a `TypeError` is raised unless both imply the same
435+
underlying SYCL queue to be used. If both a `None`, the
436+
`dpctl.SyclQueue()` is used for allocation and copying.
437+
Default: `None`.
438+
"""
352439
dtype = np.dtype(dtype)
353-
if len(order) == 0 or order[0] not in "CcFf":
440+
if not isinstance(order, str) or len(order) == 0 or order[0] not in "CcFf":
354441
raise ValueError(
355442
"Unrecognized order keyword value, expecting 'F' or 'C'."
356443
)

0 commit comments

Comments
 (0)