Skip to content

Commit

Permalink
Merge branch 'master' into divide_in_place
Browse files Browse the repository at this point in the history
  • Loading branch information
vtavana authored Nov 8, 2023
2 parents 88c113d + 247a266 commit abc4c4a
Show file tree
Hide file tree
Showing 9 changed files with 614 additions and 247 deletions.
113 changes: 0 additions & 113 deletions dpnp/dpnp_algo/dpnp_algo_arraycreation.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ and the rest of the library
__all__ += [
"dpnp_copy",
"dpnp_diag",
"dpnp_geomspace",
"dpnp_linspace",
"dpnp_logspace",
"dpnp_ptp",
"dpnp_trace",
"dpnp_vander",
Expand Down Expand Up @@ -138,116 +135,6 @@ cpdef utils.dpnp_descriptor dpnp_diag(utils.dpnp_descriptor v, int k):
return result


cpdef utils.dpnp_descriptor dpnp_geomspace(start, stop, num, endpoint, dtype, axis):
cdef shape_type_c obj_shape = utils._object_to_tuple(num)
cdef utils.dpnp_descriptor result = utils_py.create_output_descriptor_py(obj_shape, dtype, None)

if endpoint:
steps_count = num - 1
else:
steps_count = num

# if there are steps, then fill values
if steps_count > 0:
step = dpnp.power(dpnp.float64(stop) / start, 1.0 / steps_count)
mult = step
for i in range(1, result.size):
result.get_pyobj()[i] = start * mult
mult = mult * step
else:
step = dpnp.nan

# if result is not empty, then fiil first and last elements
if num > 0:
result.get_pyobj()[0] = start
if endpoint and result.size > 1:
result.get_pyobj()[result.size - 1] = stop

return result


def dpnp_linspace(start, stop, num, dtype=None, device=None, usm_type=None, sycl_queue=None, endpoint=True, retstep=False, axis=0):
usm_type_alloc, sycl_queue_alloc = utils_py.get_usm_allocations([start, stop])

# Get sycl_queue.
if sycl_queue is None and device is None:
sycl_queue = sycl_queue_alloc
sycl_queue_normalized = dpnp.get_normalized_queue_device(sycl_queue=sycl_queue, device=device)

# Get temporary usm_type for getting dtype.
if usm_type is None:
_usm_type = "device" if usm_type_alloc is None else usm_type_alloc
else:
_usm_type = usm_type

# Get dtype.
if not hasattr(start, "dtype") and not dpnp.isscalar(start):
start = dpnp.asarray(start, usm_type=_usm_type, sycl_queue=sycl_queue_normalized)
if not hasattr(stop, "dtype") and not dpnp.isscalar(stop):
stop = dpnp.asarray(stop, usm_type=_usm_type, sycl_queue=sycl_queue_normalized)
dt = numpy.result_type(start, stop, float(num))
dt = utils_py.map_dtype_to_device(dt, sycl_queue_normalized.sycl_device)
if dtype is None:
dtype = dt

if dpnp.isscalar(start) and dpnp.isscalar(stop):
# Call linspace() function for scalars.
res = dpnp_container.linspace(start,
stop,
num,
dtype=dt,
usm_type=_usm_type,
sycl_queue=sycl_queue_normalized,
endpoint=endpoint)
else:
num = operator.index(num)
if num < 0:
raise ValueError("Number of points must be non-negative")

# Get final usm_type and copy arrays if needed with current dtype, usm_type and sycl_queue.
# Do not need to copy usm_ndarray by usm_type if it is not explicitly stated.
if usm_type is None:
usm_type = _usm_type
if not hasattr(start, "usm_type"):
_start = dpnp.asarray(start, dtype=dt, usm_type=usm_type, sycl_queue=sycl_queue_normalized)
else:
_start = dpnp.asarray(start, dtype=dt, sycl_queue=sycl_queue_normalized)
if not hasattr(stop, "usm_type"):
_stop = dpnp.asarray(stop, dtype=dt, usm_type=usm_type, sycl_queue=sycl_queue_normalized)
else:
_stop = dpnp.asarray(stop, dtype=dt, sycl_queue=sycl_queue_normalized)
else:
_start = dpnp.asarray(start, dtype=dt, usm_type=usm_type, sycl_queue=sycl_queue_normalized)
_stop = dpnp.asarray(stop, dtype=dt, usm_type=usm_type, sycl_queue=sycl_queue_normalized)

# FIXME: issue #1304. Mathematical operations with scalar don't follow data type.
_num = dpnp.asarray((num - 1) if endpoint else num, dtype=dt, usm_type=usm_type, sycl_queue=sycl_queue_normalized)

step = (_stop - _start) / _num

res = dpnp_container.arange(0,
stop=num,
step=1,
dtype=dt,
usm_type=usm_type,
sycl_queue=sycl_queue_normalized)

res = res.reshape((-1,) + (1,) * step.ndim)
res = res * step + _start

if endpoint and num > 1:
res[-1] = dpnp_container.full(step.shape, _stop)

if numpy.issubdtype(dtype, dpnp.integer):
dpnp.floor(res, out=res)
return res.astype(dtype)


cpdef utils.dpnp_descriptor dpnp_logspace(start, stop, num, endpoint, base, dtype, axis):
temp = dpnp.linspace(start, stop, num=num, endpoint=endpoint)
return dpnp.get_dpnp_descriptor(dpnp.astype(dpnp.power(base, temp), dtype))


cpdef dpnp_ptp(utils.dpnp_descriptor arr, axis=None):
cdef shape_type_c shape_arr = arr.shape
cdef shape_type_c output_shape
Expand Down
258 changes: 258 additions & 0 deletions dpnp/dpnp_algo/dpnp_arraycreation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
import operator

import numpy

import dpnp
import dpnp.dpnp_container as dpnp_container
import dpnp.dpnp_utils as utils

__all__ = [
"dpnp_geomspace",
"dpnp_linspace",
"dpnp_logspace",
]


def dpnp_geomspace(
start,
stop,
num,
dtype=None,
device=None,
usm_type=None,
sycl_queue=None,
endpoint=True,
axis=0,
):
usm_type_alloc, sycl_queue_alloc = utils.get_usm_allocations([start, stop])

if sycl_queue is None and device is None:
sycl_queue = sycl_queue_alloc
sycl_queue_normalized = dpnp.get_normalized_queue_device(
sycl_queue=sycl_queue, device=device
)

if usm_type is None:
_usm_type = "device" if usm_type_alloc is None else usm_type_alloc
else:
_usm_type = usm_type

if not dpnp.is_supported_array_type(start):
start = dpnp.asarray(
start, usm_type=_usm_type, sycl_queue=sycl_queue_normalized
)
if not dpnp.is_supported_array_type(stop):
stop = dpnp.asarray(
stop, usm_type=_usm_type, sycl_queue=sycl_queue_normalized
)

dt = numpy.result_type(start, stop, float(num))
dt = utils.map_dtype_to_device(dt, sycl_queue_normalized.sycl_device)
if dtype is None:
dtype = dt

if dpnp.any(start == 0) or dpnp.any(stop == 0):
raise ValueError("Geometric sequence cannot include zero")

out_sign = dpnp.ones(
dpnp.broadcast_arrays(start, stop)[0].shape,
dtype=dt,
usm_type=_usm_type,
sycl_queue=sycl_queue_normalized,
)
# Avoid negligible real or imaginary parts in output by rotating to
# positive real, calculating, then undoing rotation
if dpnp.issubdtype(dt, dpnp.complexfloating):
all_imag = (start.real == 0.0) & (stop.real == 0.0)
if dpnp.any(all_imag):
start[all_imag] = start[all_imag].imag
stop[all_imag] = stop[all_imag].imag
out_sign[all_imag] = 1j

both_negative = (dpnp.sign(start) == -1) & (dpnp.sign(stop) == -1)
if dpnp.any(both_negative):
dpnp.negative(start[both_negative], out=start[both_negative])
dpnp.negative(stop[both_negative], out=stop[both_negative])
dpnp.negative(out_sign[both_negative], out=out_sign[both_negative])

log_start = dpnp.log10(start)
log_stop = dpnp.log10(stop)
result = dpnp_logspace(
log_start,
log_stop,
num=num,
endpoint=endpoint,
base=10.0,
dtype=dtype,
usm_type=_usm_type,
sycl_queue=sycl_queue_normalized,
)

if num > 0:
result[0] = start
if num > 1 and endpoint:
result[-1] = stop

result = out_sign * result

if axis != 0:
result = dpnp.moveaxis(result, 0, axis)

return result.astype(dtype, copy=False)


def dpnp_linspace(
start,
stop,
num,
dtype=None,
device=None,
usm_type=None,
sycl_queue=None,
endpoint=True,
retstep=False,
axis=0,
):
usm_type_alloc, sycl_queue_alloc = utils.get_usm_allocations([start, stop])

if sycl_queue is None and device is None:
sycl_queue = sycl_queue_alloc
sycl_queue_normalized = dpnp.get_normalized_queue_device(
sycl_queue=sycl_queue, device=device
)

if usm_type is None:
_usm_type = "device" if usm_type_alloc is None else usm_type_alloc
else:
_usm_type = usm_type

if not hasattr(start, "dtype") and not dpnp.isscalar(start):
start = dpnp.asarray(
start, usm_type=_usm_type, sycl_queue=sycl_queue_normalized
)
if not hasattr(stop, "dtype") and not dpnp.isscalar(stop):
stop = dpnp.asarray(
stop, usm_type=_usm_type, sycl_queue=sycl_queue_normalized
)

dt = numpy.result_type(start, stop, float(num))
dt = utils.map_dtype_to_device(dt, sycl_queue_normalized.sycl_device)
if dtype is None:
dtype = dt

num = operator.index(num)
if num < 0:
raise ValueError("Number of points must be non-negative")
step_num = (num - 1) if endpoint else num

step_nan = False
if step_num == 0:
step_nan = True
step = dpnp.nan

if dpnp.isscalar(start) and dpnp.isscalar(stop):
# Call linspace() function for scalars.
res = dpnp_container.linspace(
start,
stop,
num,
dtype=dt,
usm_type=_usm_type,
sycl_queue=sycl_queue_normalized,
endpoint=endpoint,
)
if retstep is True and step_nan is False:
step = (stop - start) / step_num
else:
_start = dpnp.asarray(
start,
dtype=dt,
usm_type=_usm_type,
sycl_queue=sycl_queue_normalized,
)
_stop = dpnp.asarray(
stop, dtype=dt, usm_type=_usm_type, sycl_queue=sycl_queue_normalized
)

res = dpnp_container.arange(
0,
stop=num,
step=1,
dtype=dt,
usm_type=_usm_type,
sycl_queue=sycl_queue_normalized,
)

if step_nan is False:
step = (_stop - _start) / step_num
res = res.reshape((-1,) + (1,) * step.ndim)
res = res * step + _start

if endpoint and num > 1:
res[-1] = dpnp_container.full(step.shape, _stop)

if axis != 0:
res = dpnp.moveaxis(res, 0, axis)

if numpy.issubdtype(dtype, dpnp.integer):
dpnp.floor(res, out=res)

res = res.astype(dtype, copy=False)

if retstep is True:
if dpnp.isscalar(step):
step = dpnp.asarray(
step, usm_type=res.usm_type, sycl_queue=res.sycl_queue
)
return (res, step)

return res


def dpnp_logspace(
start,
stop,
num=50,
device=None,
usm_type=None,
sycl_queue=None,
endpoint=True,
base=10.0,
dtype=None,
axis=0,
):
if not dpnp.isscalar(base):
usm_type_alloc, sycl_queue_alloc = utils.get_usm_allocations(
[start, stop, base]
)

if sycl_queue is None and device is None:
sycl_queue = sycl_queue_alloc
sycl_queue = dpnp.get_normalized_queue_device(
sycl_queue=sycl_queue, device=device
)

if usm_type is None:
usm_type = "device" if usm_type_alloc is None else usm_type_alloc
else:
usm_type = usm_type
start = dpnp.asarray(start, usm_type=usm_type, sycl_queue=sycl_queue)
stop = dpnp.asarray(stop, usm_type=usm_type, sycl_queue=sycl_queue)
base = dpnp.asarray(base, usm_type=usm_type, sycl_queue=sycl_queue)
[start, stop, base] = dpnp.broadcast_arrays(start, stop, base)
base = dpnp.expand_dims(base, axis=axis)

res = dpnp_linspace(
start,
stop,
num=num,
device=device,
usm_type=usm_type,
sycl_queue=sycl_queue,
endpoint=endpoint,
axis=axis,
)

if dtype is None:
return dpnp.power(base, res)
return dpnp.power(base, res).astype(dtype, copy=False)
Loading

0 comments on commit abc4c4a

Please sign in to comment.