Skip to content

OpenVINO: linspace #21209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 58 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 55 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
a9ba69a
OpenVINO: linspace and logspace
vi-shruti Apr 21, 2025
e95aba3
Updated for Commit
vi-shruti Apr 21, 2025
2933a49
Addressing pytest
vi-shruti Apr 21, 2025
94c678e
Addressing pytest
vi-shruti Apr 21, 2025
47cc458
Addressing pytest
vi-shruti Apr 22, 2025
54ecce1
Update numpy.py
vi-shruti Apr 22, 2025
00ef089
Update numpy.py
vi-shruti Apr 22, 2025
b449b7f
Update numpy.py
vi-shruti Apr 22, 2025
f1bc6f3
Update numpy.py
vi-shruti Apr 22, 2025
c11347e
Update numpy.py
vi-shruti Apr 22, 2025
831ceee
Update numpy.py
vi-shruti Apr 22, 2025
6744166
Update numpy.py
vi-shruti Apr 22, 2025
9683006
Update numpy.py
vi-shruti Apr 22, 2025
51cd940
Update numpy.py
vi-shruti Apr 22, 2025
01188fc
Update numpy.py
vi-shruti Apr 22, 2025
9368989
Update numpy.py
vi-shruti Apr 22, 2025
5aa98c0
Update numpy.py
vi-shruti Apr 22, 2025
98c9e04
Update numpy.py
vi-shruti Apr 22, 2025
6df399e
Update numpy.py
vi-shruti Apr 22, 2025
647c69e
Updated linspace
vi-shruti Apr 25, 2025
93e481e
Merge branch 'master' of https://github.com/vi-shruti/keras
vi-shruti Apr 25, 2025
92d384f
Update excluded_concrete_tests.txt
vi-shruti Apr 25, 2025
dc1e1e9
Update numpy.py
vi-shruti Apr 25, 2025
25fc834
Update numpy.py
vi-shruti Apr 25, 2025
d8aa091
Update numpy.py
vi-shruti Apr 25, 2025
5e3c537
Update numpy.py
vi-shruti Apr 26, 2025
2df8827
Update numpy.py
vi-shruti Apr 26, 2025
998a35b
Update numpy.py
vi-shruti Apr 26, 2025
7d30d96
Update numpy.py
vi-shruti Apr 27, 2025
2a9ec53
Update numpy.py
vi-shruti Apr 27, 2025
cdc91d9
Update numpy.py
vi-shruti Apr 27, 2025
004fce9
Update numpy.py
vi-shruti Apr 27, 2025
dc8081f
Update numpy.py
vi-shruti Apr 27, 2025
43f0125
Update numpy.py
vi-shruti Apr 27, 2025
fae2a81
Update numpy.py
vi-shruti Apr 27, 2025
3cf5427
Update numpy.py
vi-shruti Apr 27, 2025
a62795d
Update numpy.py
vi-shruti Apr 29, 2025
3c60459
Update numpy.py
vi-shruti Apr 29, 2025
d65d92c
Update numpy.py
vi-shruti Apr 29, 2025
37e96c1
Update numpy.py
vi-shruti Apr 29, 2025
af33c76
Update numpy.py
vi-shruti Apr 29, 2025
a26d3a6
Update numpy.py
vi-shruti Apr 29, 2025
5dc78bf
Update numpy.py
vi-shruti Apr 29, 2025
280be55
Update numpy.py
vi-shruti Apr 29, 2025
f982384
Update numpy.py
vi-shruti Apr 30, 2025
6a5fb1b
Update numpy.py
vi-shruti Apr 30, 2025
536b11a
Update numpy.py
vi-shruti Apr 30, 2025
abe68e4
Update numpy.py
vi-shruti Apr 30, 2025
0a39e5f
Update numpy.py
vi-shruti Apr 30, 2025
7d43dbf
Update numpy.py
vi-shruti Apr 30, 2025
fb5649f
Update numpy.py
vi-shruti Apr 30, 2025
e3fdbfa
Update numpy.py
vi-shruti Apr 30, 2025
96d17ff
Update numpy.py
vi-shruti Apr 30, 2025
209daf0
Update numpy.py
vi-shruti Apr 30, 2025
724b143
Update numpy.py
vi-shruti Apr 30, 2025
e60d708
Update numpy.py
vi-shruti May 5, 2025
9c7fbee
Update numpy.py
vi-shruti May 5, 2025
c6991f9
Update numpy.py
vi-shruti May 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions keras/src/backend/openvino/excluded_concrete_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ NumpyDtypeTest::test_inner
NumpyDtypeTest::test_isfinite
NumpyDtypeTest::test_isinf
NumpyDtypeTest::test_isnan
NumpyDtypeTest::test_linspace
NumpyDtypeTest::test_logaddexp
NumpyDtypeTest::test_logspace
NumpyDtypeTest::test_matmul_
Expand Down Expand Up @@ -142,7 +141,6 @@ NumpyTwoInputOpsCorrectnessTest::test_digitize
NumpyTwoInputOpsCorrectnessTest::test_divide_no_nan
NumpyTwoInputOpsCorrectnessTest::test_einsum
NumpyTwoInputOpsCorrectnessTest::test_inner
NumpyTwoInputOpsCorrectnessTest::test_linspace
NumpyTwoInputOpsCorrectnessTest::test_logspace
NumpyTwoInputOpsCorrectnessTest::test_outer
NumpyTwoInputOpsCorrectnessTest::test_quantile
Expand Down
153 changes: 150 additions & 3 deletions keras/src/backend/openvino/numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -910,9 +910,156 @@ def less_equal(x1, x2):
def linspace(
start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0
):
raise NotImplementedError(
"`linspace` is not supported with openvino backend"
)
"""
Return evenly spaced numbers over a specified interval.

Returns `num` evenly spaced samples, calculated over the
interval [`start`, `stop`].

The endpoint of the interval can optionally be excluded.

Parameters
----------
start : array_like
The starting value of the sequence.
stop : array_like
The end value of the sequence, unless `endpoint` is set to False.
In that case, the sequence consists of all but the last of ``num + 1``
evenly spaced samples, so that `stop` is excluded. Note that the step
size changes when `endpoint` is False.
num : int, optional
Number of samples to generate. Default is 50. Must be non-negative.
endpoint : bool, optional
If True, `stop` is the last sample. Otherwise, it is not included.
Default is True.
retstep : bool, optional
If True, return (`samples`, `step`), where `step` is the spacing
between samples.
dtype : dtype, optional
The type of the output array. If `dtype` is not given, the data type
is inferred from `start` and `stop`. The inferred dtype will never be
an integer; `float` is chosen even if the arguments would produce an
array of integers.
axis : int, optional
The axis in the result to store the samples. Relevant only if start
or stop are array-like. By default (0), the samples will be along a
new axis inserted at the beginning. Use -1 to get an axis at the end.

Returns
-------
samples : ndarray
There are `num` equally spaced samples in the closed interval
``[start, stop]`` or the half-open interval ``[start, stop)``
(depending on whether `endpoint` is True or False).
step : float, optional
Only returned if `retstep` is True

Size of spacing between samples.
"""

dtype = standardize_dtype(dtype) or config.floatx()
out_dtype = OPENVINO_DTYPES[dtype]
dtype = OPENVINO_DTYPES[config.floatx()]

start = get_ov_output(start, dtype)
stop = get_ov_output(stop, dtype)
start = ov_opset.convert(start, dtype).output(0)
stop = ov_opset.convert(stop, dtype).output(0)
Comment on lines +966 to +967
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed because get_ov_output already performs convert. So please remove

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your review, @rkazants.
I've incorporated the rest of the changes but removing this seems to cause type errors.


if isinstance(num, OpenVINOKerasTensor):
num = get_ov_output(num, Type.i32)
elif isinstance(num, int):
num = ov_opset.constant(num, Type.i32).output(0)
else:
raise TypeError("`num` must be an int or OpenVINOKerasTensor.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think num = get_ov_output(num, Type.i32) should be enought for all cases

num = ov_opset.convert(num, Type.i32).output(0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed


zero_i = ov_opset.constant(0, Type.i32).output(0)
one_i = ov_opset.constant(1, Type.i32).output(0)
axis_i = ov_opset.constant(axis, Type.i32).output(0)

div = ov_opset.subtract(num, one_i).output(0) if endpoint else num
div = ov_opset.convert(div, dtype).output(0)

zero = ov_opset.constant(0.0, dtype).output(0)
one = ov_opset.constant(1.0, dtype).output(0)
num_f = ov_opset.convert(num, dtype).output(0)
seq = ov_opset.range(zero, num_f, one, dtype).output(0)

ndim = len(start.shape)
dims = ov_opset.concat(
[
ov_opset.constant([-1], Type.i32),
ov_opset.constant([1] * ndim, Type.i32),
],
0,
).output(0)
seq = ov_opset.reshape(seq, dims, False).output(0)

delta = ov_opset.subtract(stop, start).output(0)

cond = ov_opset.greater(div, zero).output(0)
nan_const = ov_opset.constant(float("nan"), dtype).output(0)
step_val = ov_opset.divide(delta, div).output(0)
step = ov_opset.select(cond, step_val, nan_const).output(0)

target_shape = ov_opset.concat(
[
ov_opset.constant([1], Type.i64),
ov_opset.shape_of(start).output(0),
],
0,
).output(0)
step = ov_opset.reshape(step, target_shape, False).output(0)

eq_zero = ov_opset.equal(step, zero).output(0)
any_zero = ov_opset.reduce_logical_or(
eq_zero, ov_opset.constant([0], Type.i32), False
).output(0)

y_norm = ov_opset.multiply(seq, step).output(0)
y_denorm = ov_opset.multiply(
ov_opset.divide(seq, div).output(0),
delta,
).output(0)
y_pos = ov_opset.convert(
ov_opset.select(any_zero, y_denorm, y_norm).output(0), dtype
).output(0)

y_zero = ov_opset.convert(
ov_opset.multiply(seq, delta).output(0), dtype
).output(0)
y = ov_opset.add(
ov_opset.convert(ov_opset.select(cond, y_pos, y_zero).output(0), dtype),
start,
).output(0)

if endpoint:
idx = ov_opset.subtract(num, one_i).output(0)
idx = ov_opset.convert(idx, Type.i32).output(0)
idx_tensor = ov_opset.broadcast(idx, target_shape).output(0)
stop_tensor = ov_opset.broadcast(stop, target_shape).output(0)
y = ov_opset.scatter_elements_update(
y, idx_tensor, stop_tensor, 0
).output(0)

if axis != 0:
rank = ov_opset.rank(y).output(0)
axis_p1 = ov_opset.add(axis_i, one_i).output(0)
pre = ov_opset.range(one_i, axis_p1, one_i).output(0)
post = ov_opset.range(axis_p1, rank, one_i).output(0)
zero_i = ov_opset.reshape(
zero_i, ov_opset.constant([1], Type.i32), False
).output(0)
perm = ov_opset.concat([pre, zero_i, post], 0).output(0)
y = ov_opset.transpose(y, perm).output(0)

y = ov_opset.convert(y, out_dtype).output(0)
if retstep:
return OpenVINOKerasTensor(y), ov_opset.convert(step, out_dtype).output(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create return_step variable and assign. return_step should be wrapped with OpenVINOKerasTensor

0
)
return OpenVINOKerasTensor(y)


def log(x):
Expand Down