Skip to content

Commit 763277f

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 763277f

File tree

2 files changed

+51
-40
lines changed

2 files changed

+51
-40
lines changed

dpctl/tensor/_copy_utils.py

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,31 @@ def _copy_from_usm_ndarray_to_usm_ndarray(dst, src):
349349
_copy_same_shape(dst, src_same_shape)
350350

351351

352+
def _make_empty_like_orderK(X, dt, usm_type, dev):
353+
st = list(X.strides)
354+
perm = sorted(
355+
range(X.ndim),
356+
key=lambda d: builtins.abs(st[d]) if X.shape[d] > 1 else 0,
357+
reverse=True,
358+
)
359+
inv_perm = sorted(range(X.ndim), key=lambda i: perm[i])
360+
sh = X.shape
361+
sh_sorted = tuple(sh[i] for i in perm)
362+
R = dpt.empty(sh_sorted, dtype=dt, usm_type=usm_type, device=dev, order="C")
363+
if min(st) < 0:
364+
st_sorted = [st[i] for i in perm]
365+
sl = tuple(
366+
(
367+
slice(None, None, -1)
368+
if st_sorted[i] < 0
369+
else slice(None, None, None)
370+
)
371+
for i in range(X.ndim)
372+
)
373+
R = R[sl]
374+
return dpt.permute_dims(R, inv_perm)
375+
376+
352377
def _empty_like_orderK(X, dt, usm_type=None, dev=None):
353378
"""Returns empty array like `x`, using order='K'
354379
@@ -371,28 +396,28 @@ def _empty_like_orderK(X, dt, usm_type=None, dev=None):
371396
return dpt.empty_like(
372397
X, dtype=dt, usm_type=usm_type, device=dev, order="F"
373398
)
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)
399+
return _make_empty_like_orderK(X, dt, usm_type, dev)
400+
401+
402+
def _from_numpy_empty_like_orderK(X, dt, usm_type, dev):
403+
"""Returns empty usm_ndarray like NumPy array `x`, using order='K'
404+
405+
For an array `x` that was obtained by permutation of a contiguous
406+
array the returned array will have the same shape and the same
407+
strides as `x`.
408+
"""
409+
if not isinstance(X, np.ndarray):
410+
raise TypeError(f"Expected np.ndarray, got {type(X)}")
411+
fl = X.flags
412+
if fl["C"] or X.size <= 1:
413+
return dpt.usm_ndarray(
414+
X.shape, dtype=dt, usm_type=usm_type, device=dev, order="C"
393415
)
394-
R = R[sl]
395-
return dpt.permute_dims(R, inv_perm)
416+
elif fl["F"]:
417+
return dpt.usm_ndarray(
418+
X.shape, dtype=dt, usm_type=usm_type, device=dev, order="F"
419+
)
420+
return _make_empty_like_orderK(X, dt, usm_type, dev)
396421

397422

398423
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)