Skip to content

Commit a78b4fd

Browse files
committed
Resolve dpt.asarray failed to copy input numpy.ndarray #2055
adds _from_numpy_empty_like_orderK utility function
1 parent f57963e commit a78b4fd

File tree

2 files changed

+54
-41
lines changed

2 files changed

+54
-41
lines changed

dpctl/tensor/_copy_utils.py

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ def _copy_from_numpy_into(dst, np_ary):
116116
)
117117

118118

119-
def from_numpy(np_ary, /, *, device=None, usm_type="device", sycl_queue=None):
119+
def from_numpy(
120+
np_ary, /, *, device=None, usm_type="device", sycl_queue=None, order="K"
121+
):
120122
"""
121123
from_numpy(arg, device=None, usm_type="device", sycl_queue=None)
122124
@@ -349,6 +351,31 @@ def _copy_from_usm_ndarray_to_usm_ndarray(dst, src):
349351
_copy_same_shape(dst, src_same_shape)
350352

351353

354+
def _make_empty_like_orderK(X, dt, usm_type, dev):
355+
st = list(X.strides)
356+
perm = sorted(
357+
range(X.ndim),
358+
key=lambda d: builtins.abs(st[d]) if X.shape[d] > 1 else 0,
359+
reverse=True,
360+
)
361+
inv_perm = sorted(range(X.ndim), key=lambda i: perm[i])
362+
sh = X.shape
363+
sh_sorted = tuple(sh[i] for i in perm)
364+
R = dpt.empty(sh_sorted, dtype=dt, usm_type=usm_type, device=dev, order="C")
365+
if min(st) < 0:
366+
st_sorted = [st[i] for i in perm]
367+
sl = tuple(
368+
(
369+
slice(None, None, -1)
370+
if st_sorted[i] < 0
371+
else slice(None, None, None)
372+
)
373+
for i in range(X.ndim)
374+
)
375+
R = R[sl]
376+
return dpt.permute_dims(R, inv_perm)
377+
378+
352379
def _empty_like_orderK(X, dt, usm_type=None, dev=None):
353380
"""Returns empty array like `x`, using order='K'
354381
@@ -371,28 +398,28 @@ def _empty_like_orderK(X, dt, usm_type=None, dev=None):
371398
return dpt.empty_like(
372399
X, dtype=dt, usm_type=usm_type, device=dev, order="F"
373400
)
374-
st = list(X.strides)
375-
perm = sorted(
376-
range(X.ndim),
377-
key=lambda d: builtins.abs(st[d]) if X.shape[d] > 1 else 0,
378-
reverse=True,
379-
)
380-
inv_perm = sorted(range(X.ndim), key=lambda i: perm[i])
381-
sh = X.shape
382-
sh_sorted = tuple(sh[i] for i in perm)
383-
R = dpt.empty(sh_sorted, dtype=dt, usm_type=usm_type, device=dev, order="C")
384-
if min(st) < 0:
385-
st_sorted = [st[i] for i in perm]
386-
sl = tuple(
387-
(
388-
slice(None, None, -1)
389-
if st_sorted[i] < 0
390-
else slice(None, None, None)
391-
)
392-
for i in range(X.ndim)
401+
return _make_empty_like_orderK(X, dt, usm_type, dev)
402+
403+
404+
def _from_numpy_empty_like_orderK(X, dt, usm_type, dev):
405+
"""Returns empty usm_ndarray like NumPy array `x`, using order='K'
406+
407+
For an array `x` that was obtained by permutation of a contiguous
408+
array the returned array will have the same shape and the same
409+
strides as `x`.
410+
"""
411+
if not isinstance(X, np.ndarray):
412+
raise TypeError(f"Expected np.ndarray, got {type(X)}")
413+
fl = X.flags
414+
if fl["C"] or X.size <= 1:
415+
return dpt.usm_ndarray(
416+
X.shape, dtype=dt, usm_type=usm_type, device=dev, order="C"
393417
)
394-
R = R[sl]
395-
return dpt.permute_dims(R, inv_perm)
418+
elif fl["F"]:
419+
return dpt.usm_ndarray(
420+
X.shape, dtype=dt, usm_type=usm_type, device=dev, order="F"
421+
)
422+
return _make_empty_like_orderK(X, dt, usm_type, dev)
396423

397424

398425
def _empty_like_pair_orderK(X1, X2, dt, res_shape, usm_type, dev):

dpctl/tensor/_ctors.py

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
import dpctl.tensor as dpt
2525
import dpctl.tensor._tensor_impl as ti
2626
import dpctl.utils
27-
from dpctl.tensor._copy_utils import _empty_like_orderK
27+
from dpctl.tensor._copy_utils import (
28+
_empty_like_orderK,
29+
_from_numpy_empty_like_orderK,
30+
)
2831
from dpctl.tensor._data_types import _get_dtype
2932
from dpctl.tensor._device import normalize_queue_device
3033
from dpctl.tensor._usmarray import _is_object_with_buffer_protocol
@@ -243,24 +246,7 @@ def _asarray_from_numpy_ndarray(
243246
if order == "K":
244247
# new USM allocation
245248
_ensure_native_dtype_device_support(dtype, copy_q.sycl_device)
246-
res = dpt.usm_ndarray(
247-
ary.shape,
248-
dtype=dtype,
249-
buffer=usm_type,
250-
order="C",
251-
buffer_ctor_kwargs={"queue": copy_q},
252-
)
253-
original_strides = ary.strides
254-
ind = sorted(
255-
range(ary.ndim),
256-
key=lambda i: abs(original_strides[i]),
257-
reverse=True,
258-
)
259-
new_strides = tuple(res.strides[ind[i]] for i in ind)
260-
# reuse previously made USM allocation
261-
res = dpt.usm_ndarray(
262-
res.shape, dtype=res.dtype, buffer=res.usm_data, strides=new_strides
263-
)
249+
res = _from_numpy_empty_like_orderK(ary, dtype, usm_type, copy_q)
264250
else:
265251
_ensure_native_dtype_device_support(dtype, copy_q.sycl_device)
266252
res = dpt.usm_ndarray(

0 commit comments

Comments
 (0)