Skip to content

Commit 1a4f8a4

Browse files
authored
Adopt dpnp interface to asynchronous dpctl execution (Part #1) (#1897)
* Update manipulation functions * Update functions from the array creation container * Update dpnp array methods * Implement backward compatible solution * dpnp.meshgrid has to follow CFD and prohibit input arrays allocating on different SYCL queues * updated linspace, logspace and geomspace functions * Updated elementwise functions and astype * Updated counting and histogram functions * Switched back to use dppy/label/dev for coverage GH action * Removed dpnp_container.linspace since unused * Return dpnp ndarray for linspace, logspace and geomspace internal functions
1 parent 805d502 commit 1a4f8a4

11 files changed

+318
-216
lines changed

.github/workflows/generate_coverage.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121

2222
env:
2323
python-ver: '3.10'
24-
CHANNELS: '-c dppy/label/coverage -c intel -c conda-forge --override-channels'
24+
CHANNELS: '-c dppy/label/dev -c intel -c conda-forge --override-channels'
2525
# Install the latest oneAPI compiler to work around an issue
2626
INSTALL_ONE_API: 'yes'
2727

dpnp/dpnp_algo/dpnp_arraycreation.py

Lines changed: 59 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import math
22
import operator
33

4+
import dpctl.tensor as dpt
45
import dpctl.utils as dpu
56
import numpy
67

78
import dpnp
8-
import dpnp.dpnp_container as dpnp_container
99
import dpnp.dpnp_utils as utils
10+
from dpnp.dpnp_array import dpnp_array
1011

1112
__all__ = [
1213
"dpnp_geomspace",
@@ -16,6 +17,12 @@
1617
]
1718

1819

20+
def _as_usm_ndarray(a, usm_type, sycl_queue):
21+
if isinstance(a, dpnp_array):
22+
return a.get_array()
23+
return dpt.asarray(a, usm_type=usm_type, sycl_queue=sycl_queue)
24+
25+
1926
def dpnp_geomspace(
2027
start,
2128
stop,
@@ -40,14 +47,8 @@ def dpnp_geomspace(
4047
else:
4148
_usm_type = usm_type
4249

43-
if not dpnp.is_supported_array_type(start):
44-
start = dpnp.asarray(
45-
start, usm_type=_usm_type, sycl_queue=sycl_queue_normalized
46-
)
47-
if not dpnp.is_supported_array_type(stop):
48-
stop = dpnp.asarray(
49-
stop, usm_type=_usm_type, sycl_queue=sycl_queue_normalized
50-
)
50+
start = _as_usm_ndarray(start, _usm_type, sycl_queue_normalized)
51+
stop = _as_usm_ndarray(stop, _usm_type, sycl_queue_normalized)
5152

5253
dt = numpy.result_type(start, stop, float(num))
5354
dt = utils.map_dtype_to_device(dt, sycl_queue_normalized.sycl_device)
@@ -57,8 +58,8 @@ def dpnp_geomspace(
5758
if dpnp.any(start == 0) or dpnp.any(stop == 0):
5859
raise ValueError("Geometric sequence cannot include zero")
5960

60-
out_sign = dpnp.ones(
61-
dpnp.broadcast_arrays(start, stop)[0].shape,
61+
out_sign = dpt.ones(
62+
dpt.broadcast_arrays(start, stop)[0].shape,
6263
dtype=dt,
6364
usm_type=_usm_type,
6465
sycl_queue=sycl_queue_normalized,
@@ -72,15 +73,15 @@ def dpnp_geomspace(
7273
stop[all_imag] = stop[all_imag].imag
7374
out_sign[all_imag] = 1j
7475

75-
both_negative = (dpnp.sign(start) == -1) & (dpnp.sign(stop) == -1)
76+
both_negative = (dpt.sign(start) == -1) & (dpt.sign(stop) == -1)
7677
if dpnp.any(both_negative):
77-
dpnp.negative(start[both_negative], out=start[both_negative])
78-
dpnp.negative(stop[both_negative], out=stop[both_negative])
79-
dpnp.negative(out_sign[both_negative], out=out_sign[both_negative])
78+
dpt.negative(start[both_negative], out=start[both_negative])
79+
dpt.negative(stop[both_negative], out=stop[both_negative])
80+
dpt.negative(out_sign[both_negative], out=out_sign[both_negative])
8081

81-
log_start = dpnp.log10(start)
82-
log_stop = dpnp.log10(stop)
83-
result = dpnp_logspace(
82+
log_start = dpt.log10(start)
83+
log_stop = dpt.log10(stop)
84+
res = dpnp_logspace(
8485
log_start,
8586
log_stop,
8687
num=num,
@@ -89,19 +90,20 @@ def dpnp_geomspace(
8990
dtype=dtype,
9091
usm_type=_usm_type,
9192
sycl_queue=sycl_queue_normalized,
92-
)
93+
).get_array()
9394

9495
if num > 0:
95-
result[0] = start
96+
res[0] = start
9697
if num > 1 and endpoint:
97-
result[-1] = stop
98+
res[-1] = stop
9899

99-
result = out_sign * result
100+
res = out_sign * res
100101

101102
if axis != 0:
102-
result = dpnp.moveaxis(result, 0, axis)
103+
res = dpt.moveaxis(res, 0, axis)
103104

104-
return result.astype(dtype, copy=False)
105+
res = dpt.astype(res, dtype, copy=False)
106+
return dpnp_array._create_from_usm_ndarray(res)
105107

106108

107109
def dpnp_linspace(
@@ -129,14 +131,11 @@ def dpnp_linspace(
129131
else:
130132
_usm_type = usm_type
131133

132-
if not hasattr(start, "dtype") and not dpnp.isscalar(start):
133-
start = dpnp.asarray(
134-
start, usm_type=_usm_type, sycl_queue=sycl_queue_normalized
135-
)
136-
if not hasattr(stop, "dtype") and not dpnp.isscalar(stop):
137-
stop = dpnp.asarray(
138-
stop, usm_type=_usm_type, sycl_queue=sycl_queue_normalized
139-
)
134+
if not dpnp.isscalar(start):
135+
start = _as_usm_ndarray(start, _usm_type, sycl_queue_normalized)
136+
137+
if not dpnp.isscalar(stop):
138+
stop = _as_usm_ndarray(stop, _usm_type, sycl_queue_normalized)
140139

141140
dt = numpy.result_type(start, stop, float(num))
142141
dt = utils.map_dtype_to_device(dt, sycl_queue_normalized.sycl_device)
@@ -155,7 +154,7 @@ def dpnp_linspace(
155154

156155
if dpnp.isscalar(start) and dpnp.isscalar(stop):
157156
# Call linspace() function for scalars.
158-
res = dpnp_container.linspace(
157+
usm_res = dpt.linspace(
159158
start,
160159
stop,
161160
num,
@@ -167,17 +166,17 @@ def dpnp_linspace(
167166
if retstep is True and step_nan is False:
168167
step = (stop - start) / step_num
169168
else:
170-
_start = dpnp.asarray(
169+
usm_start = dpt.asarray(
171170
start,
172171
dtype=dt,
173172
usm_type=_usm_type,
174173
sycl_queue=sycl_queue_normalized,
175174
)
176-
_stop = dpnp.asarray(
175+
usm_stop = dpt.asarray(
177176
stop, dtype=dt, usm_type=_usm_type, sycl_queue=sycl_queue_normalized
178177
)
179178

180-
res = dpnp_container.arange(
179+
usm_res = dpt.arange(
181180
0,
182181
stop=num,
183182
step=1,
@@ -187,28 +186,29 @@ def dpnp_linspace(
187186
)
188187

189188
if step_nan is False:
190-
step = (_stop - _start) / step_num
191-
res = res.reshape((-1,) + (1,) * step.ndim)
192-
res = res * step + _start
189+
step = (usm_stop - usm_start) / step_num
190+
usm_res = dpt.reshape(usm_res, (-1,) + (1,) * step.ndim, copy=False)
191+
usm_res = usm_res * step
192+
usm_res += usm_start
193193

194194
if endpoint and num > 1:
195-
res[-1] = dpnp_container.full(step.shape, _stop)
195+
usm_res[-1] = dpt.full(step.shape, usm_stop)
196196

197197
if axis != 0:
198-
res = dpnp.moveaxis(res, 0, axis)
198+
usm_res = dpt.moveaxis(usm_res, 0, axis)
199199

200200
if numpy.issubdtype(dtype, dpnp.integer):
201-
dpnp.floor(res, out=res)
201+
dpt.floor(usm_res, out=usm_res)
202202

203-
res = res.astype(dtype, copy=False)
203+
res = dpt.astype(usm_res, dtype, copy=False)
204+
res = dpnp_array._create_from_usm_ndarray(res)
204205

205206
if retstep is True:
206207
if dpnp.isscalar(step):
207-
step = dpnp.asarray(
208+
step = dpt.asarray(
208209
step, usm_type=res.usm_type, sycl_queue=res.sycl_queue
209210
)
210-
return (res, step)
211-
211+
return res, dpnp_array._create_from_usm_ndarray(step)
212212
return res
213213

214214

@@ -239,12 +239,15 @@ def dpnp_logspace(
239239
usm_type = "device" if usm_type_alloc is None else usm_type_alloc
240240
else:
241241
usm_type = usm_type
242-
start = dpnp.asarray(start, usm_type=usm_type, sycl_queue=sycl_queue)
243-
stop = dpnp.asarray(stop, usm_type=usm_type, sycl_queue=sycl_queue)
244-
base = dpnp.asarray(base, usm_type=usm_type, sycl_queue=sycl_queue)
245-
[start, stop, base] = dpnp.broadcast_arrays(start, stop, base)
246-
base = dpnp.expand_dims(base, axis=axis)
247242

243+
start = _as_usm_ndarray(start, usm_type, sycl_queue)
244+
stop = _as_usm_ndarray(stop, usm_type, sycl_queue)
245+
base = _as_usm_ndarray(base, usm_type, sycl_queue)
246+
247+
[start, stop, base] = dpt.broadcast_arrays(start, stop, base)
248+
base = dpt.expand_dims(base, axis=axis)
249+
250+
# assume res as not a tuple, because retstep is False
248251
res = dpnp_linspace(
249252
start,
250253
stop,
@@ -254,11 +257,12 @@ def dpnp_logspace(
254257
sycl_queue=sycl_queue,
255258
endpoint=endpoint,
256259
axis=axis,
257-
)
260+
).get_array()
258261

259-
if dtype is None:
260-
return dpnp.power(base, res)
261-
return dpnp.power(base, res).astype(dtype, copy=False)
262+
dpt.pow(base, res, out=res)
263+
if dtype is not None:
264+
res = dpt.astype(res, dtype, copy=False)
265+
return dpnp_array._create_from_usm_ndarray(res)
262266

263267

264268
class dpnp_nd_grid:

0 commit comments

Comments
 (0)