From a9ba69affb40c8d74a9c4dea551e67ca12da2bc2 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Mon, 21 Apr 2025 15:20:23 +0530 Subject: [PATCH 01/57] OpenVINO: linspace and logspace linspace and logspace Implementations --- .../openvino/excluded_concrete_tests.txt | 2 - keras/src/backend/openvino/numpy.py | 79 +++++++++++++++++-- pytest.ini | 3 + 3 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 pytest.ini diff --git a/keras/src/backend/openvino/excluded_concrete_tests.txt b/keras/src/backend/openvino/excluded_concrete_tests.txt index a7fec75c875e..e290c618f9f1 100644 --- a/keras/src/backend/openvino/excluded_concrete_tests.txt +++ b/keras/src/backend/openvino/excluded_concrete_tests.txt @@ -26,10 +26,8 @@ NumpyDtypeTest::test_inner NumpyDtypeTest::test_isfinite NumpyDtypeTest::test_isinf NumpyDtypeTest::test_isnan -NumpyDtypeTest::test_linspace NumpyDtypeTest::test_log1p NumpyDtypeTest::test_logaddexp -NumpyDtypeTest::test_logspace NumpyDtypeTest::test_matmul_ NumpyDtypeTest::test_max NumpyDtypeTest::test_mean diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index f5c88fbff63b..7dd164d01828 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -910,9 +910,67 @@ 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" - ) + if not isinstance(num, int) or num <= 0: + raise ValueError(f"Expected 'num' to be a positive integer, got {num}") + if not isinstance(axis, int): + raise TypeError(f"Expected 'axis' to be an integer, got {type(axis)}") + + if stop is None: + start, stop = get_ov_output(0), get_ov_output(start) + else: + start, stop = get_ov_output(start), get_ov_output(stop) + + if dtype is None: + result_type = dtypes.result_type( + ov_to_keras_type(start.get_element_type()), + ov_to_keras_type(stop.get_element_type()), + "float32", + ) + dtype = OPENVINO_DTYPES[result_type] + else: + dtype = OPENVINO_DTYPES[standardize_dtype(dtype)] + + start = ov_opset.convert(start, dtype) + stop = ov_opset.convert(stop, dtype) + + num_const = ov_opset.constant(num, dtype=Type.i32).output(0) + num_f = ov_opset.convert(num_const, dtype).output(0) + + if endpoint: + step = ov_opset.subtract(stop, start) + denom = ov_opset.subtract(num_f, ov_opset.constant(1, dtype)) + step = ov_opset.divide(step, denom) + else: + step = ov_opset.subtract(stop, start) + step = ov_opset.divide(step, num_f) + + range_indices = ov_opset.range( + ov_opset.constant(0, dtype), + num_f, + ov_opset.constant(1, dtype), + dtype, + ).output(0) + linspace_vals = ov_opset.add( + ov_opset.multiply(range_indices, step), start + ).output(0) + + if axis < 0 or axis >= len(linspace_vals.shape): + raise ValueError( + f"Invalid axis {axis} for reshaping the tensor with shape {linspace_vals.shape}" + ) + + if axis != 0: + shape = [-1] + linspace_vals = ov_opset.reshape(linspace_vals, shape, False).output(0) + linspace_vals = ov_opset.unsqueeze( + linspace_vals, ov_opset.constant(axis, Type.i32) + ).output(0) + + result = OpenVINOKerasTensor(linspace_vals) + + if retstep: + return result, OpenVINOKerasTensor(step) + return result def log(x): @@ -983,9 +1041,20 @@ def logical_or(x1, x2): def logspace(start, stop, num=50, endpoint=True, base=10, dtype=None, axis=0): - raise NotImplementedError( - "`logspace` is not supported with openvino backend" + if not isinstance(base, (int, float)) or base <= 0: + raise ValueError(f"Expected 'base' to be a positive number, got {base}") + + lin_vals = linspace( + start, stop, num=num, endpoint=endpoint, dtype=dtype, axis=axis ) + if isinstance(lin_vals, tuple): + lin_vals = lin_vals[0] + lin_vals = get_ov_output(lin_vals) + dtype = lin_vals.get_element_type() + + base_const = ov_opset.constant(base, dtype).output(0) + logspace_vals = ov_opset.power(base_const, lin_vals).output(0) + return OpenVINOKerasTensor(logspace_vals) def maximum(x1, x2): diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 000000000000..83635a5b7b9b --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +env = + KERAS_BACKEND=openvino \ No newline at end of file From e95aba319cbaf7b5cc34df6b76df578e2df268c4 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Mon, 21 Apr 2025 15:32:53 +0530 Subject: [PATCH 02/57] Updated for Commit --- keras/src/backend/openvino/excluded_concrete_tests.txt | 2 -- pytest.ini | 3 --- 2 files changed, 5 deletions(-) delete mode 100644 pytest.ini diff --git a/keras/src/backend/openvino/excluded_concrete_tests.txt b/keras/src/backend/openvino/excluded_concrete_tests.txt index e290c618f9f1..ee974bdc38a7 100644 --- a/keras/src/backend/openvino/excluded_concrete_tests.txt +++ b/keras/src/backend/openvino/excluded_concrete_tests.txt @@ -145,8 +145,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 NumpyTwoInputOpsCorrectnessTest::test_take_along_axis diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 83635a5b7b9b..000000000000 --- a/pytest.ini +++ /dev/null @@ -1,3 +0,0 @@ -[pytest] -env = - KERAS_BACKEND=openvino \ No newline at end of file From 2933a49b637eaea8292c829e622cd981f5ba2c6a Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Mon, 21 Apr 2025 21:57:42 +0530 Subject: [PATCH 03/57] Addressing pytest --- keras/src/backend/openvino/numpy.py | 38 +++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 7dd164d01828..27fb4dd7a652 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -910,7 +910,7 @@ def less_equal(x1, x2): def linspace( start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0 ): - if not isinstance(num, int) or num <= 0: + if not isinstance(num, int) or num < 0: raise ValueError(f"Expected 'num' to be a positive integer, got {num}") if not isinstance(axis, int): raise TypeError(f"Expected 'axis' to be an integer, got {type(axis)}") @@ -933,6 +933,24 @@ def linspace( start = ov_opset.convert(start, dtype) stop = ov_opset.convert(stop, dtype) + if num == 0: + shape = [0] + if hasattr(start, "get_partial_shape"): + start_shape = list(start.get_partial_shape()) + if len(start_shape) != 0 and not start_shape[0].is_dynamic: + shape = [0] + [dim.get_length() for dim in start_shape[1:]] + empty = ov_opset.reshape( + ov_opset.constant([], dtype), shape, special_zero=False + ).output(0) + return ( + OpenVINOKerasTensor(empty) + if not retstep + else ( + OpenVINOKerasTensor(empty), + OpenVINOKerasTensor(ov_opset.constant(0, dtype)), + ) + ) + num_const = ov_opset.constant(num, dtype=Type.i32).output(0) num_f = ov_opset.convert(num_const, dtype).output(0) @@ -950,24 +968,24 @@ def linspace( ov_opset.constant(1, dtype), dtype, ).output(0) - linspace_vals = ov_opset.add( - ov_opset.multiply(range_indices, step), start + + broadcast_step = ov_opset.broadcast( + step, ov_opset.shape_of(range_indices) + ).output(0) + broadcast_start = ov_opset.broadcast( + start, ov_opset.shape_of(range_indices) ).output(0) - if axis < 0 or axis >= len(linspace_vals.shape): - raise ValueError( - f"Invalid axis {axis} for reshaping the tensor with shape {linspace_vals.shape}" - ) + linspace_vals = ov_opset.add( + ov_opset.multiply(range_indices, broadcast_step), broadcast_start + ).output(0) if axis != 0: - shape = [-1] - linspace_vals = ov_opset.reshape(linspace_vals, shape, False).output(0) linspace_vals = ov_opset.unsqueeze( linspace_vals, ov_opset.constant(axis, Type.i32) ).output(0) result = OpenVINOKerasTensor(linspace_vals) - if retstep: return result, OpenVINOKerasTensor(step) return result From 94c678e0bcb10f9cbf8dde5b75b8f4a7ded79b86 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Mon, 21 Apr 2025 23:26:38 +0530 Subject: [PATCH 04/57] Addressing pytest --- keras/src/backend/openvino/numpy.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 27fb4dd7a652..c54779d91e40 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -911,7 +911,9 @@ def linspace( start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0 ): if not isinstance(num, int) or num < 0: - raise ValueError(f"Expected 'num' to be a positive integer, got {num}") + raise ValueError( + f"Expected 'num' to be a non-negative integer, got {num}" + ) if not isinstance(axis, int): raise TypeError(f"Expected 'axis' to be an integer, got {type(axis)}") @@ -935,12 +937,13 @@ def linspace( if num == 0: shape = [0] - if hasattr(start, "get_partial_shape"): - start_shape = list(start.get_partial_shape()) - if len(start_shape) != 0 and not start_shape[0].is_dynamic: - shape = [0] + [dim.get_length() for dim in start_shape[1:]] + start_shape = start.get_partial_shape() + if start_shape.rank.is_static and start_shape.rank.get_length() > 0: + shape = [0] + [dim.get_length() for dim in start_shape[1:]] empty = ov_opset.reshape( - ov_opset.constant([], dtype), shape, special_zero=False + ov_opset.constant([], dtype), + ov_opset.constant(shape, dtype=Type.i64), + special_zero=False, ).output(0) return ( OpenVINOKerasTensor(empty) @@ -969,11 +972,13 @@ def linspace( dtype, ).output(0) + # Broadcast step and start with explicit shape matching + target_shape = ov_opset.shape_of(range_indices) broadcast_step = ov_opset.broadcast( - step, ov_opset.shape_of(range_indices) + step, target_shape, broadcast_spec="NUMPY" ).output(0) broadcast_start = ov_opset.broadcast( - start, ov_opset.shape_of(range_indices) + start, target_shape, broadcast_spec="NUMPY" ).output(0) linspace_vals = ov_opset.add( From 47cc4587d5e82852a4862e4d500a490bd02fef76 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 11:12:06 +0530 Subject: [PATCH 05/57] Addressing pytest --- keras/src/backend/openvino/numpy.py | 36 ++++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index c54779d91e40..2f78d4d4457f 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -936,22 +936,18 @@ def linspace( stop = ov_opset.convert(stop, dtype) if num == 0: - shape = [0] - start_shape = start.get_partial_shape() - if start_shape.rank.is_static and start_shape.rank.get_length() > 0: - shape = [0] + [dim.get_length() for dim in start_shape[1:]] - empty = ov_opset.reshape( - ov_opset.constant([], dtype), - ov_opset.constant(shape, dtype=Type.i64), - special_zero=False, + shape = ov_opset.shape_of(start) + empty_shape = ov_opset.concat( + [ov_opset.constant([0], dtype=Type.i64), shape], 0 ).output(0) + empty = ov_opset.broadcast( + ov_opset.constant([], dtype), empty_shape, broadcast_spec="NUMPY" + ).output(0) + empty_tensor = OpenVINOKerasTensor(empty) return ( - OpenVINOKerasTensor(empty) - if not retstep - else ( - OpenVINOKerasTensor(empty), - OpenVINOKerasTensor(ov_opset.constant(0, dtype)), - ) + (empty_tensor, OpenVINOKerasTensor(ov_opset.constant(0, dtype))) + if retstep + else empty_tensor ) num_const = ov_opset.constant(num, dtype=Type.i32).output(0) @@ -972,8 +968,16 @@ def linspace( dtype, ).output(0) - # Broadcast step and start with explicit shape matching - target_shape = ov_opset.shape_of(range_indices) + step_shape = ov_opset.shape_of(step) + step_rank = ov_opset.shape_of(step_shape) + cond = ov_opset.equal(step_rank, ov_opset.constant([0], dtype=Type.i64)) + step = ov_opset.unsqueeze(step, ov_opset.constant(0, Type.i64)).output(0) + step = ov_opset.select(cond, step, step).output(0) + + target_shape = ov_opset.concat( + [ov_opset.shape_of(range_indices), ov_opset.shape_of(step)[1:]], 0 + ).output(0) + broadcast_step = ov_opset.broadcast( step, target_shape, broadcast_spec="NUMPY" ).output(0) From 54ecce1e02f318e46053fd0e73260c769c62d921 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 12:28:50 +0530 Subject: [PATCH 06/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 148 ++++++++++++++++------------ 1 file changed, 85 insertions(+), 63 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 2f78d4d4457f..0c599228e74d 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -910,17 +910,21 @@ def less_equal(x1, x2): def linspace( start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0 ): - if not isinstance(num, int) or num < 0: - raise ValueError( - f"Expected 'num' to be a non-negative integer, got {num}" - ) + if hasattr(num, "node"): + num_const = num.node + elif hasattr(num, "get_output_element"): + num_const = num + else: + if not isinstance(num, (int, np.integer)): + raise ValueError( + f"Expected 'num' to be an integer or tensor, got {type(num)}" + ) + num_const = ov_opset.constant(num, dtype=Type.i32) + if not isinstance(axis, int): raise TypeError(f"Expected 'axis' to be an integer, got {type(axis)}") - if stop is None: - start, stop = get_ov_output(0), get_ov_output(start) - else: - start, stop = get_ov_output(start), get_ov_output(stop) + start, stop = get_ov_output(start), get_ov_output(stop) if dtype is None: result_type = dtypes.result_type( @@ -935,69 +939,81 @@ def linspace( start = ov_opset.convert(start, dtype) stop = ov_opset.convert(stop, dtype) - if num == 0: - shape = ov_opset.shape_of(start) - empty_shape = ov_opset.concat( - [ov_opset.constant([0], dtype=Type.i64), shape], 0 - ).output(0) - empty = ov_opset.broadcast( - ov_opset.constant([], dtype), empty_shape, broadcast_spec="NUMPY" - ).output(0) - empty_tensor = OpenVINOKerasTensor(empty) - return ( - (empty_tensor, OpenVINOKerasTensor(ov_opset.constant(0, dtype))) - if retstep - else empty_tensor - ) + zero = ov_opset.constant(0, dtype=Type.i32) + one = ov_opset.constant(1, dtype=Type.i32) + one_f = ov_opset.convert(one, dtype) + + num_f = ov_opset.convert(num_const, dtype) - num_const = ov_opset.constant(num, dtype=Type.i32).output(0) - num_f = ov_opset.convert(num_const, dtype).output(0) + is_zero = ov_opset.equal(num_const, zero) + is_one = ov_opset.equal(num_const, one) if endpoint: - step = ov_opset.subtract(stop, start) - denom = ov_opset.subtract(num_f, ov_opset.constant(1, dtype)) - step = ov_opset.divide(step, denom) + denom = ov_opset.subtract(num_f, one_f) + denom = ov_opset.select(is_one, one_f, denom) else: - step = ov_opset.subtract(stop, start) - step = ov_opset.divide(step, num_f) - - range_indices = ov_opset.range( - ov_opset.constant(0, dtype), - num_f, - ov_opset.constant(1, dtype), - dtype, - ).output(0) + denom = num_f - step_shape = ov_opset.shape_of(step) - step_rank = ov_opset.shape_of(step_shape) - cond = ov_opset.equal(step_rank, ov_opset.constant([0], dtype=Type.i64)) - step = ov_opset.unsqueeze(step, ov_opset.constant(0, Type.i64)).output(0) - step = ov_opset.select(cond, step, step).output(0) + step = ov_opset.divide(ov_opset.subtract(stop, start), denom) - target_shape = ov_opset.concat( - [ov_opset.shape_of(range_indices), ov_opset.shape_of(step)[1:]], 0 - ).output(0) + range_vals = ov_opset.range( + ov_opset.constant(0, dtype), num_f, one_f, dtype + ) - broadcast_step = ov_opset.broadcast( - step, target_shape, broadcast_spec="NUMPY" - ).output(0) - broadcast_start = ov_opset.broadcast( - start, target_shape, broadcast_spec="NUMPY" - ).output(0) + def unsqueeze_for_broadcasting(tensor): + if len(tensor.get_partial_shape()) == 0: + return ov_opset.unsqueeze(tensor, ov_opset.constant(0, Type.i64)) + return tensor - linspace_vals = ov_opset.add( - ov_opset.multiply(range_indices, broadcast_step), broadcast_start - ).output(0) + if len(start.get_partial_shape()) == 0: + # Scalar case + linspace_vals = ov_opset.add( + ov_opset.multiply(range_vals, step), start + ).output(0) + else: + range_shape = ov_opset.shape_of(range_vals) + start_shape = ov_opset.shape_of(start) + + target_shape = ov_opset.concat([range_shape, start_shape], 0) + + step_broadcast = ov_opset.broadcast( + unsqueeze_for_broadcasting(step), target_shape + ).output(0) + start_broadcast = ov_opset.broadcast( + unsqueeze_for_broadcasting(start), target_shape + ).output(0) + + linspace_vals = ov_opset.add( + ov_opset.multiply(range_vals, step_broadcast), start_broadcast + ).output(0) if axis != 0: linspace_vals = ov_opset.unsqueeze( linspace_vals, ov_opset.constant(axis, Type.i32) ).output(0) - result = OpenVINOKerasTensor(linspace_vals) + empty_shape = ov_opset.concat([zero, ov_opset.shape_of(start)], 0) + empty_array = ov_opset.broadcast( + ov_opset.constant([], dtype), empty_shape + ).output(0) + + single_val = start + + if axis != 0 and len(single_val.get_partial_shape()) > 0: + single_val = ov_opset.unsqueeze( + single_val, ov_opset.constant(axis, Type.i32) + ).output(0) + + result = ov_opset.select( + is_zero, empty_array, ov_opset.select(is_one, single_val, linspace_vals) + ) + if retstep: - return result, OpenVINOKerasTensor(step) - return result + nan_val = ov_opset.constant(np.nan, dtype) + step_result = ov_opset.select(is_zero, nan_val, step) + return OpenVINOKerasTensor(result), OpenVINOKerasTensor(step_result) + + return OpenVINOKerasTensor(result) def log(x): @@ -1071,16 +1087,22 @@ def logspace(start, stop, num=50, endpoint=True, base=10, dtype=None, axis=0): if not isinstance(base, (int, float)) or base <= 0: raise ValueError(f"Expected 'base' to be a positive number, got {base}") - lin_vals = linspace( + lin_results = linspace( start, stop, num=num, endpoint=endpoint, dtype=dtype, axis=axis ) - if isinstance(lin_vals, tuple): - lin_vals = lin_vals[0] - lin_vals = get_ov_output(lin_vals) - dtype = lin_vals.get_element_type() + lin_vals = lin_results[0] if isinstance(lin_results, tuple) else lin_results + + lin_node = lin_vals.node + result_dtype = lin_node.get_element_type() + + base_const = ov_opset.constant(base, result_dtype) + + base_broadcast = ov_opset.broadcast( + base_const, ov_opset.shape_of(lin_node) + ).output(0) + + logspace_vals = ov_opset.power(base_broadcast, lin_node).output(0) - base_const = ov_opset.constant(base, dtype).output(0) - logspace_vals = ov_opset.power(base_const, lin_vals).output(0) return OpenVINOKerasTensor(logspace_vals) From 00ef08936ca48fad1809ebdbb7c54ffc25e26a53 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 13:05:43 +0530 Subject: [PATCH 07/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 0c599228e74d..109bd2ff3ac5 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -961,12 +961,11 @@ def linspace( ) def unsqueeze_for_broadcasting(tensor): - if len(tensor.get_partial_shape()) == 0: + if tensor.get_input_partial_shape(0).rank == 0: return ov_opset.unsqueeze(tensor, ov_opset.constant(0, Type.i64)) return tensor - if len(start.get_partial_shape()) == 0: - # Scalar case + if start.get_input_partial_shape(0).rank == 0: linspace_vals = ov_opset.add( ov_opset.multiply(range_vals, step), start ).output(0) @@ -999,7 +998,7 @@ def unsqueeze_for_broadcasting(tensor): single_val = start - if axis != 0 and len(single_val.get_partial_shape()) > 0: + if axis != 0 and start.get_input_partial_shape(0).rank > 0: single_val = ov_opset.unsqueeze( single_val, ov_opset.constant(axis, Type.i32) ).output(0) From b449b7f473ac91ef09c4d7041a7521ef83e82b96 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 14:25:53 +0530 Subject: [PATCH 08/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 109bd2ff3ac5..f5a873769d54 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -940,6 +940,7 @@ def linspace( stop = ov_opset.convert(stop, dtype) zero = ov_opset.constant(0, dtype=Type.i32) + zero_i64 = ov_opset.constant(0, dtype=Type.i64) one = ov_opset.constant(1, dtype=Type.i32) one_f = ov_opset.convert(one, dtype) @@ -991,7 +992,7 @@ def unsqueeze_for_broadcasting(tensor): linspace_vals, ov_opset.constant(axis, Type.i32) ).output(0) - empty_shape = ov_opset.concat([zero, ov_opset.shape_of(start)], 0) + empty_shape = ov_opset.concat([zero_i64, ov_opset.shape_of(start)], 0) empty_array = ov_opset.broadcast( ov_opset.constant([], dtype), empty_shape ).output(0) From f1bc6f3f938dbeb4588a2e9af24dcf241c48e262 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 14:43:39 +0530 Subject: [PATCH 09/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 48 ++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index f5a873769d54..54162ee01d4a 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -949,11 +949,8 @@ def linspace( is_zero = ov_opset.equal(num_const, zero) is_one = ov_opset.equal(num_const, one) - if endpoint: - denom = ov_opset.subtract(num_f, one_f) - denom = ov_opset.select(is_one, one_f, denom) - else: - denom = num_f + denom = ov_opset.subtract(num_f, one_f) if endpoint else num_f + denom = ov_opset.select(is_one, one_f, denom) step = ov_opset.divide(ov_opset.subtract(stop, start), denom) @@ -961,31 +958,35 @@ def linspace( ov_opset.constant(0, dtype), num_f, one_f, dtype ) - def unsqueeze_for_broadcasting(tensor): - if tensor.get_input_partial_shape(0).rank == 0: + def ensure_tensor_has_dim(tensor): + shape = tensor.get_output_partial_shape(0) + if shape.rank.get_length() == 0: return ov_opset.unsqueeze(tensor, ov_opset.constant(0, Type.i64)) return tensor - if start.get_input_partial_shape(0).rank == 0: - linspace_vals = ov_opset.add( - ov_opset.multiply(range_vals, step), start - ).output(0) + start = ensure_tensor_has_dim(start) + stop = ensure_tensor_has_dim(stop) + step = ensure_tensor_has_dim(step) + + if ( + start.get_output_partial_shape(0).rank.get_length() == 1 + and start.get_output_partial_shape(0).get_dimension(0).is_static + ): + range_shape = ov_opset.shape_of(range_vals) + start_shape = ov_opset.shape_of(start) + target_shape = ov_opset.concat([range_shape, start_shape[1:]], 0) + step_broadcast = ov_opset.broadcast(step, target_shape).output(0) + start_broadcast = ov_opset.broadcast(start, target_shape).output(0) else: range_shape = ov_opset.shape_of(range_vals) start_shape = ov_opset.shape_of(start) - target_shape = ov_opset.concat([range_shape, start_shape], 0) + step_broadcast = ov_opset.broadcast(step, target_shape).output(0) + start_broadcast = ov_opset.broadcast(start, target_shape).output(0) - step_broadcast = ov_opset.broadcast( - unsqueeze_for_broadcasting(step), target_shape - ).output(0) - start_broadcast = ov_opset.broadcast( - unsqueeze_for_broadcasting(start), target_shape - ).output(0) - - linspace_vals = ov_opset.add( - ov_opset.multiply(range_vals, step_broadcast), start_broadcast - ).output(0) + linspace_vals = ov_opset.add( + ov_opset.multiply(range_vals, step_broadcast), start_broadcast + ).output(0) if axis != 0: linspace_vals = ov_opset.unsqueeze( @@ -998,8 +999,7 @@ def unsqueeze_for_broadcasting(tensor): ).output(0) single_val = start - - if axis != 0 and start.get_input_partial_shape(0).rank > 0: + if axis != 0 and start.get_output_partial_shape(0).rank.get_length() > 0: single_val = ov_opset.unsqueeze( single_val, ov_opset.constant(axis, Type.i32) ).output(0) From c11347e3701930d3297acb5037310ce0ef56cd8a Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 15:03:28 +0530 Subject: [PATCH 10/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 34 +++++++++++++++-------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 54162ee01d4a..971fa3fa76e2 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -968,21 +968,23 @@ def ensure_tensor_has_dim(tensor): stop = ensure_tensor_has_dim(stop) step = ensure_tensor_has_dim(step) - if ( - start.get_output_partial_shape(0).rank.get_length() == 1 - and start.get_output_partial_shape(0).get_dimension(0).is_static - ): - range_shape = ov_opset.shape_of(range_vals) - start_shape = ov_opset.shape_of(start) - target_shape = ov_opset.concat([range_shape, start_shape[1:]], 0) - step_broadcast = ov_opset.broadcast(step, target_shape).output(0) - start_broadcast = ov_opset.broadcast(start, target_shape).output(0) - else: - range_shape = ov_opset.shape_of(range_vals) - start_shape = ov_opset.shape_of(start) - target_shape = ov_opset.concat([range_shape, start_shape], 0) - step_broadcast = ov_opset.broadcast(step, target_shape).output(0) - start_broadcast = ov_opset.broadcast(start, target_shape).output(0) + range_shape = ov_opset.shape_of(range_vals) + start_shape = ov_opset.shape_of(start) + + rank_len = start.get_output_partial_shape(0).rank.get_length() + rank_const = ov_opset.constant([rank_len], Type.i64) + + start_shape_sliced = ov_opset.slice( + start_shape, + ov_opset.constant([1], Type.i64), + rank_const, + ov_opset.constant([1], Type.i64), + ) + + target_shape = ov_opset.concat([range_shape, start_shape_sliced], 0) + + step_broadcast = ov_opset.broadcast(step, target_shape).output(0) + start_broadcast = ov_opset.broadcast(start, target_shape).output(0) linspace_vals = ov_opset.add( ov_opset.multiply(range_vals, step_broadcast), start_broadcast @@ -993,7 +995,7 @@ def ensure_tensor_has_dim(tensor): linspace_vals, ov_opset.constant(axis, Type.i32) ).output(0) - empty_shape = ov_opset.concat([zero_i64, ov_opset.shape_of(start)], 0) + empty_shape = ov_opset.concat([zero_i64, start_shape], 0) empty_array = ov_opset.broadcast( ov_opset.constant([], dtype), empty_shape ).output(0) From 831ceee3b08e18d310f97935740f688cfe971a1c Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 15:28:12 +0530 Subject: [PATCH 11/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 41 +++++++++++++++++------------ 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 971fa3fa76e2..b9c2ed5b282e 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -940,18 +940,18 @@ def linspace( stop = ov_opset.convert(stop, dtype) zero = ov_opset.constant(0, dtype=Type.i32) - zero_i64 = ov_opset.constant(0, dtype=Type.i64) + zero_i64 = ov_opset.constant([0], dtype=Type.i64) one = ov_opset.constant(1, dtype=Type.i32) one_f = ov_opset.convert(one, dtype) - num_f = ov_opset.convert(num_const, dtype) - is_zero = ov_opset.equal(num_const, zero) is_one = ov_opset.equal(num_const, one) - denom = ov_opset.subtract(num_f, one_f) if endpoint else num_f - denom = ov_opset.select(is_one, one_f, denom) - + denom = ( + ov_opset.select(is_one, one_f, ov_opset.subtract(num_f, one_f)) + if endpoint + else num_f + ) step = ov_opset.divide(ov_opset.subtract(stop, start), denom) range_vals = ov_opset.range( @@ -983,8 +983,12 @@ def ensure_tensor_has_dim(tensor): target_shape = ov_opset.concat([range_shape, start_shape_sliced], 0) - step_broadcast = ov_opset.broadcast(step, target_shape).output(0) - start_broadcast = ov_opset.broadcast(start, target_shape).output(0) + step_broadcast = ov_opset.broadcast( + step, target_shape, broadcast_spec="NUMPY" + ).output(0) + start_broadcast = ov_opset.broadcast( + start, target_shape, broadcast_spec="NUMPY" + ).output(0) linspace_vals = ov_opset.add( ov_opset.multiply(range_vals, step_broadcast), start_broadcast @@ -997,7 +1001,7 @@ def ensure_tensor_has_dim(tensor): empty_shape = ov_opset.concat([zero_i64, start_shape], 0) empty_array = ov_opset.broadcast( - ov_opset.constant([], dtype), empty_shape + ov_opset.constant([], dtype), empty_shape, broadcast_spec="NUMPY" ).output(0) single_val = start @@ -1089,21 +1093,24 @@ def logspace(start, stop, num=50, endpoint=True, base=10, dtype=None, axis=0): if not isinstance(base, (int, float)) or base <= 0: raise ValueError(f"Expected 'base' to be a positive number, got {base}") - lin_results = linspace( + lin_vals = linspace( start, stop, num=num, endpoint=endpoint, dtype=dtype, axis=axis ) - lin_vals = lin_results[0] if isinstance(lin_results, tuple) else lin_results + if isinstance(lin_vals, tuple): + lin_vals = lin_vals[0] - lin_node = lin_vals.node - result_dtype = lin_node.get_element_type() + lin_vals = get_ov_output(lin_vals) + dtype = lin_vals.get_element_type() - base_const = ov_opset.constant(base, result_dtype) + base_const = ov_opset.constant(base, dtype) + base_reshaped = ov_opset.reshape( + base_const, ov_opset.constant([], dtype=Type.i64), False + ) base_broadcast = ov_opset.broadcast( - base_const, ov_opset.shape_of(lin_node) + base_reshaped, ov_opset.shape_of(lin_vals), broadcast_spec="NUMPY" ).output(0) - - logspace_vals = ov_opset.power(base_broadcast, lin_node).output(0) + logspace_vals = ov_opset.power(base_broadcast, lin_vals).output(0) return OpenVINOKerasTensor(logspace_vals) From 6744166e2a53cfaa5f7efe4ca2d384bf28c7ee1e Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 15:40:47 +0530 Subject: [PATCH 12/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index b9c2ed5b282e..60d097dc80aa 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -974,7 +974,7 @@ def ensure_tensor_has_dim(tensor): rank_len = start.get_output_partial_shape(0).rank.get_length() rank_const = ov_opset.constant([rank_len], Type.i64) - start_shape_sliced = ov_opset.slice( + start_shape_sliced = ov_opset.strided_slice( start_shape, ov_opset.constant([1], Type.i64), rank_const, @@ -983,6 +983,17 @@ def ensure_tensor_has_dim(tensor): target_shape = ov_opset.concat([range_shape, start_shape_sliced], 0) + def ensure_minimum_shape(tensor): + shape = tensor.get_output_partial_shape(0) + if shape.rank.get_length() == 1 and shape[0].get_length() == 0: + return ov_opset.reshape( + tensor, ov_opset.constant([1], dtype=Type.i64), False + ) + return tensor + + step = ensure_minimum_shape(step) + start = ensure_minimum_shape(start) + step_broadcast = ov_opset.broadcast( step, target_shape, broadcast_spec="NUMPY" ).output(0) From 9683006e2159a37cc425be3a4c56788ed145760e Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 16:06:23 +0530 Subject: [PATCH 13/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 60d097dc80aa..3955b15eabb6 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -979,6 +979,8 @@ def ensure_tensor_has_dim(tensor): ov_opset.constant([1], Type.i64), rank_const, ov_opset.constant([1], Type.i64), + begin_mask=[0], + end_mask=[0], ) target_shape = ov_opset.concat([range_shape, start_shape_sliced], 0) From 51cd9404dce9485d1e03f5419bf088dc615bd522 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 16:19:32 +0530 Subject: [PATCH 14/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 3955b15eabb6..37d713b6c4b1 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1115,6 +1115,13 @@ def logspace(start, stop, num=50, endpoint=True, base=10, dtype=None, axis=0): lin_vals = get_ov_output(lin_vals) dtype = lin_vals.get_element_type() + if isinstance(num, (int, np.integer)) and num == 0: + empty_shape = ov_opset.shape_of(lin_vals) + empty = ov_opset.broadcast( + ov_opset.constant([], dtype), empty_shape, broadcast_spec="NUMPY" + ).output(0) + return OpenVINOKerasTensor(empty) + base_const = ov_opset.constant(base, dtype) base_reshaped = ov_opset.reshape( base_const, ov_opset.constant([], dtype=Type.i64), False From 01188fc0e79e6db85c9b7953f953d25f242b6cee Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 16:38:30 +0530 Subject: [PATCH 15/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 37d713b6c4b1..ebf8619932e8 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1115,24 +1115,30 @@ def logspace(start, stop, num=50, endpoint=True, base=10, dtype=None, axis=0): lin_vals = get_ov_output(lin_vals) dtype = lin_vals.get_element_type() - if isinstance(num, (int, np.integer)) and num == 0: - empty_shape = ov_opset.shape_of(lin_vals) - empty = ov_opset.broadcast( - ov_opset.constant([], dtype), empty_shape, broadcast_spec="NUMPY" - ).output(0) - return OpenVINOKerasTensor(empty) + if hasattr(num, "get_output_element"): + num_tensor = num + else: + num_tensor = ov_opset.constant(num, dtype=Type.i32) + + is_zero = ov_opset.equal(num_tensor, ov_opset.constant(0, dtype=Type.i32)) + + empty_shape = ov_opset.shape_of(lin_vals) + empty = ov_opset.broadcast( + ov_opset.constant([], dtype), empty_shape, broadcast_spec="NUMPY" + ).output(0) base_const = ov_opset.constant(base, dtype) base_reshaped = ov_opset.reshape( base_const, ov_opset.constant([], dtype=Type.i64), False ) - base_broadcast = ov_opset.broadcast( base_reshaped, ov_opset.shape_of(lin_vals), broadcast_spec="NUMPY" ).output(0) + logspace_vals = ov_opset.power(base_broadcast, lin_vals).output(0) + final_vals = ov_opset.select(is_zero, empty, logspace_vals) - return OpenVINOKerasTensor(logspace_vals) + return OpenVINOKerasTensor(final_vals) def maximum(x1, x2): From 9368989426b9794dd9e00c829c9ef312f7c04b85 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 17:02:56 +0530 Subject: [PATCH 16/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 37 +++++++++++++++++------------ 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index ebf8619932e8..9595a8d8db1c 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1106,15 +1106,6 @@ def logspace(start, stop, num=50, endpoint=True, base=10, dtype=None, axis=0): if not isinstance(base, (int, float)) or base <= 0: raise ValueError(f"Expected 'base' to be a positive number, got {base}") - lin_vals = linspace( - start, stop, num=num, endpoint=endpoint, dtype=dtype, axis=axis - ) - if isinstance(lin_vals, tuple): - lin_vals = lin_vals[0] - - lin_vals = get_ov_output(lin_vals) - dtype = lin_vals.get_element_type() - if hasattr(num, "get_output_element"): num_tensor = num else: @@ -1122,11 +1113,28 @@ def logspace(start, stop, num=50, endpoint=True, base=10, dtype=None, axis=0): is_zero = ov_opset.equal(num_tensor, ov_opset.constant(0, dtype=Type.i32)) - empty_shape = ov_opset.shape_of(lin_vals) - empty = ov_opset.broadcast( - ov_opset.constant([], dtype), empty_shape, broadcast_spec="NUMPY" + start_tensor = get_ov_output(start) + empty_shape = ov_opset.concat( + [ + ov_opset.constant([0], dtype=Type.i64), + ov_opset.shape_of(start_tensor), + ], + 0, + ) + empty_array = ov_opset.broadcast( + ov_opset.constant([], dtype or Type.f32), + empty_shape, + broadcast_spec="NUMPY", ).output(0) + lin_vals = linspace( + start, stop, num=num_tensor, endpoint=endpoint, dtype=dtype, axis=axis + ) + if isinstance(lin_vals, tuple): + lin_vals = lin_vals[0] + lin_vals = get_ov_output(lin_vals) + dtype = lin_vals.get_element_type() + base_const = ov_opset.constant(base, dtype) base_reshaped = ov_opset.reshape( base_const, ov_opset.constant([], dtype=Type.i64), False @@ -1134,10 +1142,9 @@ def logspace(start, stop, num=50, endpoint=True, base=10, dtype=None, axis=0): base_broadcast = ov_opset.broadcast( base_reshaped, ov_opset.shape_of(lin_vals), broadcast_spec="NUMPY" ).output(0) + log_vals = ov_opset.power(base_broadcast, lin_vals).output(0) - logspace_vals = ov_opset.power(base_broadcast, lin_vals).output(0) - final_vals = ov_opset.select(is_zero, empty, logspace_vals) - + final_vals = ov_opset.select(is_zero, empty_array, log_vals) return OpenVINOKerasTensor(final_vals) From 5aa98c060609c3c6cd03054244926b744f7f3b02 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 17:23:46 +0530 Subject: [PATCH 17/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 9595a8d8db1c..51af9ce8b093 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1013,8 +1013,12 @@ def ensure_minimum_shape(tensor): ).output(0) empty_shape = ov_opset.concat([zero_i64, start_shape], 0) + empty_const = ov_opset.constant([], dtype) + empty_const = ov_opset.reshape( + empty_const, ov_opset.constant([1], dtype=Type.i64), False + ) empty_array = ov_opset.broadcast( - ov_opset.constant([], dtype), empty_shape, broadcast_spec="NUMPY" + empty_const, empty_shape, broadcast_spec="NUMPY" ).output(0) single_val = start @@ -1114,17 +1118,26 @@ def logspace(start, stop, num=50, endpoint=True, base=10, dtype=None, axis=0): is_zero = ov_opset.equal(num_tensor, ov_opset.constant(0, dtype=Type.i32)) start_tensor = get_ov_output(start) + shape_dtype = Type.i64 + dtype_resolved = ( + OPENVINO_DTYPES["float32"] + if dtype is None + else OPENVINO_DTYPES[standardize_dtype(dtype)] + ) + empty_shape = ov_opset.concat( [ - ov_opset.constant([0], dtype=Type.i64), + ov_opset.constant([0], dtype=shape_dtype), ov_opset.shape_of(start_tensor), ], 0, ) + empty_const = ov_opset.constant([], dtype_resolved) + empty_const = ov_opset.reshape( + empty_const, ov_opset.constant([1], dtype=shape_dtype), False + ) empty_array = ov_opset.broadcast( - ov_opset.constant([], dtype or Type.f32), - empty_shape, - broadcast_spec="NUMPY", + empty_const, empty_shape, broadcast_spec="NUMPY" ).output(0) lin_vals = linspace( @@ -1135,9 +1148,11 @@ def logspace(start, stop, num=50, endpoint=True, base=10, dtype=None, axis=0): lin_vals = get_ov_output(lin_vals) dtype = lin_vals.get_element_type() - base_const = ov_opset.constant(base, dtype) + base_const = ov_opset.constant( + base, OPENVINO_DTYPES[standardize_dtype(str(dtype))] + ) base_reshaped = ov_opset.reshape( - base_const, ov_opset.constant([], dtype=Type.i64), False + base_const, ov_opset.constant([], dtype=shape_dtype), False ) base_broadcast = ov_opset.broadcast( base_reshaped, ov_opset.shape_of(lin_vals), broadcast_spec="NUMPY" From 98c9e04318a36a21b2498980a74c1f84206dc462 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 17:55:54 +0530 Subject: [PATCH 18/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 51af9ce8b093..539f3603ddb6 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1015,7 +1015,7 @@ def ensure_minimum_shape(tensor): empty_shape = ov_opset.concat([zero_i64, start_shape], 0) empty_const = ov_opset.constant([], dtype) empty_const = ov_opset.reshape( - empty_const, ov_opset.constant([1], dtype=Type.i64), False + empty_const, ov_opset.constant([0], dtype=Type.i64), False ) empty_array = ov_opset.broadcast( empty_const, empty_shape, broadcast_spec="NUMPY" @@ -1134,7 +1134,7 @@ def logspace(start, stop, num=50, endpoint=True, base=10, dtype=None, axis=0): ) empty_const = ov_opset.constant([], dtype_resolved) empty_const = ov_opset.reshape( - empty_const, ov_opset.constant([1], dtype=shape_dtype), False + empty_const, ov_opset.constant([0], dtype=shape_dtype), False ) empty_array = ov_opset.broadcast( empty_const, empty_shape, broadcast_spec="NUMPY" From 6df399ed3d60ce2159c30c34ce171533214bc101 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 22 Apr 2025 18:21:17 +0530 Subject: [PATCH 19/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 539f3603ddb6..4a2b54cf5c5d 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -914,6 +914,8 @@ def linspace( num_const = num.node elif hasattr(num, "get_output_element"): num_const = num + elif hasattr(num, "output"): + num_const = num.output(0) else: if not isinstance(num, (int, np.integer)): raise ValueError( @@ -943,7 +945,9 @@ def linspace( zero_i64 = ov_opset.constant([0], dtype=Type.i64) one = ov_opset.constant(1, dtype=Type.i32) one_f = ov_opset.convert(one, dtype) + num_f = ov_opset.convert(num_const, dtype) + is_zero = ov_opset.equal(num_const, zero) is_one = ov_opset.equal(num_const, one) @@ -1110,10 +1114,16 @@ def logspace(start, stop, num=50, endpoint=True, base=10, dtype=None, axis=0): if not isinstance(base, (int, float)) or base <= 0: raise ValueError(f"Expected 'base' to be a positive number, got {base}") - if hasattr(num, "get_output_element"): + if isinstance(num, (int, np.integer)): + num_tensor = ov_opset.constant(num, dtype=Type.i32) + elif hasattr(num, "get_output_element"): num_tensor = num + elif isinstance(num, ov_opset.Constant): + num_tensor = num.output(0) else: - num_tensor = ov_opset.constant(num, dtype=Type.i32) + raise ValueError( + f"Expected 'num' to be an integer or tensor, got {type(num)}" + ) is_zero = ov_opset.equal(num_tensor, ov_opset.constant(0, dtype=Type.i32)) From 647c69e5cf1469030c4cd63db8bb403d9755c985 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Fri, 25 Apr 2025 09:27:25 +0530 Subject: [PATCH 20/57] Updated linspace --- .../openvino/excluded_concrete_tests.txt | 2 + keras/src/backend/openvino/numpy.py | 225 ++++-------------- 2 files changed, 49 insertions(+), 178 deletions(-) diff --git a/keras/src/backend/openvino/excluded_concrete_tests.txt b/keras/src/backend/openvino/excluded_concrete_tests.txt index ee974bdc38a7..60ae77ab1090 100644 --- a/keras/src/backend/openvino/excluded_concrete_tests.txt +++ b/keras/src/backend/openvino/excluded_concrete_tests.txt @@ -28,6 +28,7 @@ NumpyDtypeTest::test_isinf NumpyDtypeTest::test_isnan NumpyDtypeTest::test_log1p NumpyDtypeTest::test_logaddexp +NumpyDtypeTest::test_logspace NumpyDtypeTest::test_matmul_ NumpyDtypeTest::test_max NumpyDtypeTest::test_mean @@ -145,6 +146,7 @@ NumpyTwoInputOpsCorrectnessTest::test_digitize NumpyTwoInputOpsCorrectnessTest::test_divide_no_nan NumpyTwoInputOpsCorrectnessTest::test_einsum NumpyTwoInputOpsCorrectnessTest::test_inner +NumpyTwoInputOpsCorrectnessTest::test_logspace NumpyTwoInputOpsCorrectnessTest::test_outer NumpyTwoInputOpsCorrectnessTest::test_quantile NumpyTwoInputOpsCorrectnessTest::test_take_along_axis diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 4a2b54cf5c5d..16b401f770b2 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -910,137 +910,63 @@ def less_equal(x1, x2): def linspace( start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0 ): - if hasattr(num, "node"): - num_const = num.node - elif hasattr(num, "get_output_element"): - num_const = num - elif hasattr(num, "output"): - num_const = num.output(0) - else: - if not isinstance(num, (int, np.integer)): - raise ValueError( - f"Expected 'num' to be an integer or tensor, got {type(num)}" - ) - num_const = ov_opset.constant(num, dtype=Type.i32) - - if not isinstance(axis, int): - raise TypeError(f"Expected 'axis' to be an integer, got {type(axis)}") + dtype = dtype or config.floatx() + dtype = OPENVINO_DTYPES[dtype] - start, stop = get_ov_output(start), get_ov_output(stop) + start_node = get_ov_output(start, dtype) + stop_node = get_ov_output(stop, dtype) - if dtype is None: - result_type = dtypes.result_type( - ov_to_keras_type(start.get_element_type()), - ov_to_keras_type(stop.get_element_type()), - "float32", - ) - dtype = OPENVINO_DTYPES[result_type] + if isinstance(num, OpenVINOKerasTensor): + num_node = get_ov_output(num, Type.i32) + elif isinstance(num, int): + num_node = ov_opset.constant(num, Type.i32).output(0) else: - dtype = OPENVINO_DTYPES[standardize_dtype(dtype)] - - start = ov_opset.convert(start, dtype) - stop = ov_opset.convert(stop, dtype) - - zero = ov_opset.constant(0, dtype=Type.i32) - zero_i64 = ov_opset.constant([0], dtype=Type.i64) - one = ov_opset.constant(1, dtype=Type.i32) - one_f = ov_opset.convert(one, dtype) - - num_f = ov_opset.convert(num_const, dtype) - - is_zero = ov_opset.equal(num_const, zero) - is_one = ov_opset.equal(num_const, one) - - denom = ( - ov_opset.select(is_one, one_f, ov_opset.subtract(num_f, one_f)) - if endpoint - else num_f - ) - step = ov_opset.divide(ov_opset.subtract(stop, start), denom) - - range_vals = ov_opset.range( - ov_opset.constant(0, dtype), num_f, one_f, dtype - ) + raise TypeError(f"`num` must be an int or tensor. Got {type(num)}") - def ensure_tensor_has_dim(tensor): - shape = tensor.get_output_partial_shape(0) - if shape.rank.get_length() == 0: - return ov_opset.unsqueeze(tensor, ov_opset.constant(0, Type.i64)) - return tensor - - start = ensure_tensor_has_dim(start) - stop = ensure_tensor_has_dim(stop) - step = ensure_tensor_has_dim(step) - - range_shape = ov_opset.shape_of(range_vals) - start_shape = ov_opset.shape_of(start) - - rank_len = start.get_output_partial_shape(0).rank.get_length() - rank_const = ov_opset.constant([rank_len], Type.i64) - - start_shape_sliced = ov_opset.strided_slice( - start_shape, - ov_opset.constant([1], Type.i64), - rank_const, - ov_opset.constant([1], Type.i64), - begin_mask=[0], - end_mask=[0], - ) - - target_shape = ov_opset.concat([range_shape, start_shape_sliced], 0) - - def ensure_minimum_shape(tensor): - shape = tensor.get_output_partial_shape(0) - if shape.rank.get_length() == 1 and shape[0].get_length() == 0: - return ov_opset.reshape( - tensor, ov_opset.constant([1], dtype=Type.i64), False - ) - return tensor - - step = ensure_minimum_shape(step) - start = ensure_minimum_shape(start) - - step_broadcast = ov_opset.broadcast( - step, target_shape, broadcast_spec="NUMPY" - ).output(0) - start_broadcast = ov_opset.broadcast( - start, target_shape, broadcast_spec="NUMPY" - ).output(0) - - linspace_vals = ov_opset.add( - ov_opset.multiply(range_vals, step_broadcast), start_broadcast - ).output(0) - - if axis != 0: - linspace_vals = ov_opset.unsqueeze( - linspace_vals, ov_opset.constant(axis, Type.i32) + # Adjust stop if endpoint is False + if not endpoint: + num_minus_1 = ov_opset.subtract( + num_node, ov_opset.constant(1, Type.i32) ).output(0) + step = ov_opset.divide( + ov_opset.subtract(stop_node, start_node), + ov_opset.convert(num_minus_1, dtype), + ).output(0) + stop_node = ov_opset.subtract(stop_node, step).output(0) - empty_shape = ov_opset.concat([zero_i64, start_shape], 0) - empty_const = ov_opset.constant([], dtype) - empty_const = ov_opset.reshape( - empty_const, ov_opset.constant([0], dtype=Type.i64), False - ) - empty_array = ov_opset.broadcast( - empty_const, empty_shape, broadcast_spec="NUMPY" + linspace_node = ov_opset.linspace( + start_node, stop_node, num_node, dtype ).output(0) - single_val = start - if axis != 0 and start.get_output_partial_shape(0).rank.get_length() > 0: - single_val = ov_opset.unsqueeze( - single_val, ov_opset.constant(axis, Type.i32) + # Handle axis reshaping + if axis != 0: + # Determine rank of the new shape + if isinstance(num, int): + num_val = num + else: + # Fallback to placeholder rank if dynamic — safe default + num_val = -1 + rank = axis + 1 if axis >= 0 else abs(axis) + 1 + target_shape = [1] * rank + target_shape[axis] = num_val + shape_const = ov_opset.constant(target_shape, Type.i32).output(0) + linspace_node = ov_opset.reshape( + linspace_node, shape_const, special_zero=False ).output(0) - result = ov_opset.select( - is_zero, empty_array, ov_opset.select(is_one, single_val, linspace_vals) - ) - if retstep: - nan_val = ov_opset.constant(np.nan, dtype) - step_result = ov_opset.select(is_zero, nan_val, step) - return OpenVINOKerasTensor(result), OpenVINOKerasTensor(step_result) + step = ov_opset.divide( + ov_opset.subtract(stop_node, start_node), + ov_opset.convert( + ov_opset.subtract( + num_node, ov_opset.constant(1, Type.i32) + ).output(0), + dtype, + ), + ).output(0) + return OpenVINOKerasTensor(linspace_node), OpenVINOKerasTensor(step) - return OpenVINOKerasTensor(result) + return OpenVINOKerasTensor(linspace_node) def log(x): @@ -1111,66 +1037,9 @@ def logical_or(x1, x2): def logspace(start, stop, num=50, endpoint=True, base=10, dtype=None, axis=0): - if not isinstance(base, (int, float)) or base <= 0: - raise ValueError(f"Expected 'base' to be a positive number, got {base}") - - if isinstance(num, (int, np.integer)): - num_tensor = ov_opset.constant(num, dtype=Type.i32) - elif hasattr(num, "get_output_element"): - num_tensor = num - elif isinstance(num, ov_opset.Constant): - num_tensor = num.output(0) - else: - raise ValueError( - f"Expected 'num' to be an integer or tensor, got {type(num)}" - ) - - is_zero = ov_opset.equal(num_tensor, ov_opset.constant(0, dtype=Type.i32)) - - start_tensor = get_ov_output(start) - shape_dtype = Type.i64 - dtype_resolved = ( - OPENVINO_DTYPES["float32"] - if dtype is None - else OPENVINO_DTYPES[standardize_dtype(dtype)] - ) - - empty_shape = ov_opset.concat( - [ - ov_opset.constant([0], dtype=shape_dtype), - ov_opset.shape_of(start_tensor), - ], - 0, - ) - empty_const = ov_opset.constant([], dtype_resolved) - empty_const = ov_opset.reshape( - empty_const, ov_opset.constant([0], dtype=shape_dtype), False - ) - empty_array = ov_opset.broadcast( - empty_const, empty_shape, broadcast_spec="NUMPY" - ).output(0) - - lin_vals = linspace( - start, stop, num=num_tensor, endpoint=endpoint, dtype=dtype, axis=axis - ) - if isinstance(lin_vals, tuple): - lin_vals = lin_vals[0] - lin_vals = get_ov_output(lin_vals) - dtype = lin_vals.get_element_type() - - base_const = ov_opset.constant( - base, OPENVINO_DTYPES[standardize_dtype(str(dtype))] - ) - base_reshaped = ov_opset.reshape( - base_const, ov_opset.constant([], dtype=shape_dtype), False + raise NotImplementedError( + "`logspace` is not supported with openvino backend" ) - base_broadcast = ov_opset.broadcast( - base_reshaped, ov_opset.shape_of(lin_vals), broadcast_spec="NUMPY" - ).output(0) - log_vals = ov_opset.power(base_broadcast, lin_vals).output(0) - - final_vals = ov_opset.select(is_zero, empty_array, log_vals) - return OpenVINOKerasTensor(final_vals) def maximum(x1, x2): From 92d384f4321966a88f48aefc213987a22bd5d573 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Fri, 25 Apr 2025 09:56:39 +0530 Subject: [PATCH 21/57] Update excluded_concrete_tests.txt --- keras/src/backend/openvino/excluded_concrete_tests.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/keras/src/backend/openvino/excluded_concrete_tests.txt b/keras/src/backend/openvino/excluded_concrete_tests.txt index e8a4bc693555..c3a0fc99d668 100644 --- a/keras/src/backend/openvino/excluded_concrete_tests.txt +++ b/keras/src/backend/openvino/excluded_concrete_tests.txt @@ -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_ @@ -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 From dc1e1e98289a03064170c135e3414779731d2f23 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Fri, 25 Apr 2025 11:19:51 +0530 Subject: [PATCH 22/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 91 ++++++++++++++++------------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 98788485310a..31c3cb612921 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -911,62 +911,69 @@ def linspace( start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0 ): dtype = dtype or config.floatx() - dtype = OPENVINO_DTYPES[dtype] + ov_dtype = OPENVINO_DTYPES[dtype] - start_node = get_ov_output(start, dtype) - stop_node = get_ov_output(stop, dtype) + start_node = get_ov_output(start, ov_dtype) + stop_node = get_ov_output(stop, ov_dtype) + start_node, stop_node = _align_operand_types( + start_node, stop_node, "linspace()" + ) if isinstance(num, OpenVINOKerasTensor): num_node = get_ov_output(num, Type.i32) elif isinstance(num, int): num_node = ov_opset.constant(num, Type.i32).output(0) else: - raise TypeError(f"`num` must be an int or tensor. Got {type(num)}") + raise TypeError("`num` must be an int or OpenVINOKerasTensor.") + + zero_const = ov_opset.constant(0, Type.i32).output(0) + one_const = ov_opset.constant(1, Type.i32).output(0) - # Adjust stop if endpoint is False + effective_num = num_node if not endpoint: - num_minus_1 = ov_opset.subtract( - num_node, ov_opset.constant(1, Type.i32) - ).output(0) - step = ov_opset.divide( - ov_opset.subtract(stop_node, start_node), - ov_opset.convert(num_minus_1, dtype), - ).output(0) - stop_node = ov_opset.subtract(stop_node, step).output(0) + effective_num = ov_opset.subtract(num_node, one_const).output(0) - linspace_node = ov_opset.linspace( - start_node, stop_node, num_node, dtype + # Compute step = (stop - start) / (num - 1) + step_node = ov_opset.divide( + ov_opset.subtract(stop_node, start_node), + ov_opset.convert(effective_num, ov_dtype), ).output(0) - # Handle axis reshaping - if axis != 0: - # Determine rank of the new shape - if isinstance(num, int): - num_val = num - else: - # Fallback to placeholder rank if dynamic — safe default - num_val = -1 - rank = axis + 1 if axis >= 0 else abs(axis) + 1 - target_shape = [1] * rank - target_shape[axis] = num_val - shape_const = ov_opset.constant(target_shape, Type.i32).output(0) - linspace_node = ov_opset.reshape( - linspace_node, shape_const, special_zero=False - ).output(0) + range_node = ov_opset.range( + zero_const, num_node, one_const, Type.i32 + ).output(0) - if retstep: - step = ov_opset.divide( - ov_opset.subtract(stop_node, start_node), - ov_opset.convert( - ov_opset.subtract( - num_node, ov_opset.constant(1, Type.i32) - ).output(0), - dtype, - ), - ).output(0) - return OpenVINOKerasTensor(linspace_node), OpenVINOKerasTensor(step) + range_node = ov_opset.convert(range_node, ov_dtype).output(0) + + rank_start = start_node.get_partial_shape().rank.get_length() + if axis < 0: + axis = rank_start + 1 + axis + + rank = max(axis + 1, rank_start + 1) + # rank = len(start_node.get_partial_shape()) + 1 + + target_shape = [1] * rank + target_shape[axis] = -1 + + shape_const = ov_opset.constant(target_shape, Type.i32).output(0) + range_node = ov_opset.reshape( + range_node, shape_const, special_zero=False + ).output(0) - return OpenVINOKerasTensor(linspace_node) + broadcast_shape = ov_opset.shape_of(range_node, Type.i32).output(0) + step_broadcast = ov_opset.broadcast(step_node, broadcast_shape).output(0) + start_broadcast = ov_opset.broadcast(start_node, broadcast_shape).output(0) + + linspace_result = ov_opset.add( + start_broadcast, + ov_opset.multiply(step_broadcast, range_node).output(0), + ).output(0) + + if retstep: + return OpenVINOKerasTensor(linspace_result), OpenVINOKerasTensor( + step_node + ) + return OpenVINOKerasTensor(linspace_result) def log(x): From 25fc83422660afd887eadce8e1833819103d08ba Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Fri, 25 Apr 2025 15:09:58 +0530 Subject: [PATCH 23/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 31c3cb612921..33b964462fd1 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -935,7 +935,9 @@ def linspace( # Compute step = (stop - start) / (num - 1) step_node = ov_opset.divide( - ov_opset.subtract(stop_node, start_node), + ov_opset.convert( + ov_opset.subtract(stop_node, start_node), ov_dtype + ).output(0), ov_opset.convert(effective_num, ov_dtype), ).output(0) @@ -946,6 +948,9 @@ def linspace( range_node = ov_opset.convert(range_node, ov_dtype).output(0) rank_start = start_node.get_partial_shape().rank.get_length() + if rank_start is None or rank_start == 0: + rank_start = 1 + if axis < 0: axis = rank_start + 1 + axis From d8aa091f590b5e97707380ae0e6ec68603f86af6 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Fri, 25 Apr 2025 16:06:17 +0530 Subject: [PATCH 24/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 33b964462fd1..431a27ad455b 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -933,7 +933,6 @@ def linspace( if not endpoint: effective_num = ov_opset.subtract(num_node, one_const).output(0) - # Compute step = (stop - start) / (num - 1) step_node = ov_opset.divide( ov_opset.convert( ov_opset.subtract(stop_node, start_node), ov_dtype @@ -948,7 +947,7 @@ def linspace( range_node = ov_opset.convert(range_node, ov_dtype).output(0) rank_start = start_node.get_partial_shape().rank.get_length() - if rank_start is None or rank_start == 0: + if rank_start is None or rank_start < 1: rank_start = 1 if axis < 0: From 5e3c5374b24feebe2af448889e8b16e051091366 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Sat, 26 Apr 2025 15:16:42 +0530 Subject: [PATCH 25/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 431a27ad455b..3ac5c6de2319 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -951,9 +951,9 @@ def linspace( rank_start = 1 if axis < 0: - axis = rank_start + 1 + axis + axis += rank_start # + axis + 1 - rank = max(axis + 1, rank_start + 1) + rank = max(axis + 1, rank_start) # rank = len(start_node.get_partial_shape()) + 1 target_shape = [1] * rank From 2df8827412e270111ac7e999d8bb0c9042184c4a Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Sat, 26 Apr 2025 15:24:41 +0530 Subject: [PATCH 26/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 3ac5c6de2319..c022b24e2d35 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -953,7 +953,7 @@ def linspace( if axis < 0: axis += rank_start # + axis + 1 - rank = max(axis + 1, rank_start) + rank = max(axis, rank_start) # rank = len(start_node.get_partial_shape()) + 1 target_shape = [1] * rank From 998a35b506b3cb25e0a93431b1a1431fa6389986 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Sat, 26 Apr 2025 15:45:19 +0530 Subject: [PATCH 27/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index c022b24e2d35..77ed80a5dc5b 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -946,14 +946,14 @@ def linspace( range_node = ov_opset.convert(range_node, ov_dtype).output(0) - rank_start = start_node.get_partial_shape().rank.get_length() - if rank_start is None or rank_start < 1: - rank_start = 1 + rank = start_node.get_partial_shape().rank.get_length() + # if rank_start is None or rank_start < 1: + # rank_start = 1 if axis < 0: - axis += rank_start # + axis + 1 + axis += rank # + axis + 1 - rank = max(axis, rank_start) + # rank = max(axis, rank) # rank = len(start_node.get_partial_shape()) + 1 target_shape = [1] * rank From 7d30d96fb1977a1888051a95764aa7ec59b690f2 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Sun, 27 Apr 2025 11:35:15 +0530 Subject: [PATCH 28/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 44 +++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 77ed80a5dc5b..61a8d5f598dc 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -946,22 +946,42 @@ def linspace( range_node = ov_opset.convert(range_node, ov_dtype).output(0) - rank = start_node.get_partial_shape().rank.get_length() - # if rank_start is None or rank_start < 1: - # rank_start = 1 + start_shape = ov_opset.shape_of(start_node, Type.i32).output(0) + rank_start = start_node.get_partial_shape().rank.get_length() - if axis < 0: - axis += rank # + axis + 1 + if rank_start is None or rank_start < 1: + rank_start = 1 - # rank = max(axis, rank) - # rank = len(start_node.get_partial_shape()) + 1 + if axis < 0: + axis += rank_start + + final_rank = max(axis + 1, rank_start) + + dims = [] + for i in range(final_rank): + if i < axis: + dims.append( + ov_opset.slice( + start_shape, + ov_opset.constant([i], Type.i32).output(0), + ov_opset.constant([i + 1], Type.i32).output(0), + ).output(0) + ) + elif i == axis: + dims.append(ov_opset.constant([-1], Type.i32).output(0)) + else: + dims.append( + ov_opset.slice( + start_shape, + ov_opset.constant([i - 1], Type.i32).output(0), + ov_opset.constant([i], Type.i32).output(0), + ).output(0) + ) - target_shape = [1] * rank - target_shape[axis] = -1 + target_shape = ov_opset.concat(dims, axis=0).output(0) - shape_const = ov_opset.constant(target_shape, Type.i32).output(0) range_node = ov_opset.reshape( - range_node, shape_const, special_zero=False + range_node, target_shape, special_zero=False ).output(0) broadcast_shape = ov_opset.shape_of(range_node, Type.i32).output(0) @@ -970,7 +990,7 @@ def linspace( linspace_result = ov_opset.add( start_broadcast, - ov_opset.multiply(step_broadcast, range_node).output(0), + ov_opset.multiply(step_broadcast, range_node), ).output(0) if retstep: From 2a9ec536d500ee3d0bde3a513a93fb148be0248b Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Sun, 27 Apr 2025 11:44:20 +0530 Subject: [PATCH 29/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 61a8d5f598dc..f50e26c5026d 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -955,7 +955,7 @@ def linspace( if axis < 0: axis += rank_start - final_rank = max(axis + 1, rank_start) + final_rank = max(axis, rank_start) dims = [] for i in range(final_rank): From cdc91d9ecbe320cff19d79eddae5d656ed696cf7 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Sun, 27 Apr 2025 11:54:56 +0530 Subject: [PATCH 30/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index f50e26c5026d..ce1107af0d3d 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -947,18 +947,18 @@ def linspace( range_node = ov_opset.convert(range_node, ov_dtype).output(0) start_shape = ov_opset.shape_of(start_node, Type.i32).output(0) - rank_start = start_node.get_partial_shape().rank.get_length() + rank = start_node.get_partial_shape().rank.get_length() - if rank_start is None or rank_start < 1: - rank_start = 1 + if rank is None or rank < 1: + rank = 1 if axis < 0: - axis += rank_start + axis += rank - final_rank = max(axis, rank_start) + # final_rank = max(axis, rank_start) dims = [] - for i in range(final_rank): + for i in range(rank): if i < axis: dims.append( ov_opset.slice( From 004fce9815cbe95be7e5ed0b5fc0a35872c63bf6 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Sun, 27 Apr 2025 14:05:15 +0530 Subject: [PATCH 31/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 68 +++++++++++++++-------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index ce1107af0d3d..5c2c014ea64a 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -940,49 +940,50 @@ def linspace( ov_opset.convert(effective_num, ov_dtype), ).output(0) - range_node = ov_opset.range( - zero_const, num_node, one_const, Type.i32 - ).output(0) - - range_node = ov_opset.convert(range_node, ov_dtype).output(0) + def expand_node(node, node_shape, axis, final_rank): + dims = [] + for i in range(final_rank): + if i < axis: + dims.append( + ov_opset.slice( + node_shape, + ov_opset.constant([i], Type.i32).output(0), + ov_opset.constant([i + 1], Type.i32).output(0), + ).output(0) + ) + elif i == axis: + dims.append(ov_opset.constant([1], Type.i32).output(0)) + else: + dims.append( + ov_opset.slice( + node_shape, + ov_opset.constant([i - 1], Type.i32).output(0), + ov_opset.constant([i], Type.i32).output(0), + ).output(0) + ) + expanded_shape = ov_opset.concat(dims, axis=0).output(0) + return ov_opset.reshape( + node, expanded_shape, special_zero=False + ).output(0) - start_shape = ov_opset.shape_of(start_node, Type.i32).output(0) rank = start_node.get_partial_shape().rank.get_length() - if rank is None or rank < 1: rank = 1 if axis < 0: axis += rank - # final_rank = max(axis, rank_start) - - dims = [] - for i in range(rank): - if i < axis: - dims.append( - ov_opset.slice( - start_shape, - ov_opset.constant([i], Type.i32).output(0), - ov_opset.constant([i + 1], Type.i32).output(0), - ).output(0) - ) - elif i == axis: - dims.append(ov_opset.constant([-1], Type.i32).output(0)) - else: - dims.append( - ov_opset.slice( - start_shape, - ov_opset.constant([i - 1], Type.i32).output(0), - ov_opset.constant([i], Type.i32).output(0), - ).output(0) - ) + range_node = ov_opset.range( + zero_const, num_node, one_const, Type.i32 + ).output(0) + range_node = ov_opset.convert(range_node, ov_dtype).output(0) - target_shape = ov_opset.concat(dims, axis=0).output(0) + step_node_shape = ov_opset.shape_of(step_node, Type.i32).output(0) + start_node_shape = ov_opset.shape_of(start_node, Type.i32).output(0) - range_node = ov_opset.reshape( - range_node, target_shape, special_zero=False - ).output(0) + range_node = expand_node(range_node, start_node_shape, axis, rank) + step_node = expand_node(step_node, step_node_shape, axis, rank) + start_node = expand_node(start_node, start_node_shape, axis, rank) broadcast_shape = ov_opset.shape_of(range_node, Type.i32).output(0) step_broadcast = ov_opset.broadcast(step_node, broadcast_shape).output(0) @@ -997,6 +998,7 @@ def linspace( return OpenVINOKerasTensor(linspace_result), OpenVINOKerasTensor( step_node ) + return OpenVINOKerasTensor(linspace_result) From dc8081ffbb40b1e1f1a469ffb752662acb77cebe Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Sun, 27 Apr 2025 15:08:22 +0530 Subject: [PATCH 32/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 76 ++++++++++++++--------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 5c2c014ea64a..a40cc4b44054 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -940,50 +940,50 @@ def linspace( ov_opset.convert(effective_num, ov_dtype), ).output(0) - def expand_node(node, node_shape, axis, final_rank): - dims = [] - for i in range(final_rank): - if i < axis: - dims.append( - ov_opset.slice( - node_shape, - ov_opset.constant([i], Type.i32).output(0), - ov_opset.constant([i + 1], Type.i32).output(0), - ).output(0) - ) - elif i == axis: - dims.append(ov_opset.constant([1], Type.i32).output(0)) - else: - dims.append( - ov_opset.slice( - node_shape, - ov_opset.constant([i - 1], Type.i32).output(0), - ov_opset.constant([i], Type.i32).output(0), - ).output(0) - ) - expanded_shape = ov_opset.concat(dims, axis=0).output(0) - return ov_opset.reshape( - node, expanded_shape, special_zero=False - ).output(0) - - rank = start_node.get_partial_shape().rank.get_length() - if rank is None or rank < 1: - rank = 1 - - if axis < 0: - axis += rank - range_node = ov_opset.range( zero_const, num_node, one_const, Type.i32 ).output(0) range_node = ov_opset.convert(range_node, ov_dtype).output(0) - step_node_shape = ov_opset.shape_of(step_node, Type.i32).output(0) - start_node_shape = ov_opset.shape_of(start_node, Type.i32).output(0) + def expand_along_axis(node, axis): + node_shape = ov_opset.shape_of(node, Type.i32).output(0) + input_rank = node.get_partial_shape().rank.get_length() + + # Normalize axis + if axis < 0: + axis += input_rank + + pre_shape = ov_opset.slice( + node_shape, + ov_opset.constant([0], Type.i32).output(0), + ov_opset.constant([axis], Type.i32).output(0), + ).output(0) + + post_shape = ov_opset.slice( + node_shape, + ov_opset.constant([axis], Type.i32).output(0), + ov_opset.constant([input_rank], Type.i32).output(0), + ).output(0) + + one_dim = ov_opset.constant([1], Type.i32).output(0) + new_shape = ov_opset.concat( + [pre_shape, one_dim, post_shape], axis=0 + ).output(0) + + return ov_opset.reshape(node, new_shape, special_zero=False).output(0) + + input_rank = start_node.get_partial_shape().rank.get_length() + if input_rank is None or input_rank < 1: + input_rank = 1 + normalized_axis = axis if axis >= 0 else axis + input_rank + if normalized_axis < 0: + raise ValueError( + f"`axis={axis}` is out of bounds for input rank {input_rank}" + ) - range_node = expand_node(range_node, start_node_shape, axis, rank) - step_node = expand_node(step_node, step_node_shape, axis, rank) - start_node = expand_node(start_node, start_node_shape, axis, rank) + range_node = expand_along_axis(range_node, normalized_axis) + step_node = expand_along_axis(step_node, normalized_axis) + start_node = expand_along_axis(start_node, normalized_axis) broadcast_shape = ov_opset.shape_of(range_node, Type.i32).output(0) step_broadcast = ov_opset.broadcast(step_node, broadcast_shape).output(0) From 43f01257172f21f996572eccfc58a8ef851b712f Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Sun, 27 Apr 2025 15:22:22 +0530 Subject: [PATCH 33/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index a40cc4b44054..b3e2afa33684 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -951,18 +951,21 @@ def expand_along_axis(node, axis): # Normalize axis if axis < 0: - axis += input_rank + axis += input_rank + 1 + step = ov_opset.constant([1], Type.i32).output(0) pre_shape = ov_opset.slice( node_shape, ov_opset.constant([0], Type.i32).output(0), ov_opset.constant([axis], Type.i32).output(0), + step, ).output(0) post_shape = ov_opset.slice( node_shape, ov_opset.constant([axis], Type.i32).output(0), ov_opset.constant([input_rank], Type.i32).output(0), + step, ).output(0) one_dim = ov_opset.constant([1], Type.i32).output(0) From fae2a81dbc22378c1d0c57b19e0b8c78b1491b05 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Sun, 27 Apr 2025 15:31:26 +0530 Subject: [PATCH 34/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index b3e2afa33684..386ecda57f72 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -951,7 +951,7 @@ def expand_along_axis(node, axis): # Normalize axis if axis < 0: - axis += input_rank + 1 + axis += input_rank step = ov_opset.constant([1], Type.i32).output(0) pre_shape = ov_opset.slice( From 3cf5427e7e4240bb698cc113382d8f6f23bf96a1 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Sun, 27 Apr 2025 15:58:59 +0530 Subject: [PATCH 35/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 386ecda57f72..b5b06e7cfd9f 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -989,8 +989,14 @@ def expand_along_axis(node, axis): start_node = expand_along_axis(start_node, normalized_axis) broadcast_shape = ov_opset.shape_of(range_node, Type.i32).output(0) - step_broadcast = ov_opset.broadcast(step_node, broadcast_shape).output(0) - start_broadcast = ov_opset.broadcast(start_node, broadcast_shape).output(0) + step_broadcast = ov_opset.reshape( + step_node, broadcast_shape, special_zero=False + ).output(0) + start_broadcast = ov_opset.reshape( + start_node, broadcast_shape, special_zero=False + ).output(0) + # step_broadcast = ov_opset.broadcast(step_node, broadcast_shape).output(0) + # start_broadcast = ov_opset.broadcast(start_node, broadcast_shape).output(0) linspace_result = ov_opset.add( start_broadcast, From a62795df08b9346c3de5fcb109d6b1cc1f40d6ac Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 29 Apr 2025 14:18:23 +0530 Subject: [PATCH 36/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 181 ++++++++++++++++------------ 1 file changed, 103 insertions(+), 78 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index b5b06e7cfd9f..c889a75772e3 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -910,105 +910,130 @@ def less_equal(x1, x2): def linspace( start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0 ): + """ + 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 = dtype or config.floatx() - ov_dtype = OPENVINO_DTYPES[dtype] + dtype = OPENVINO_DTYPES[dtype] - start_node = get_ov_output(start, ov_dtype) - stop_node = get_ov_output(stop, ov_dtype) - start_node, stop_node = _align_operand_types( - start_node, stop_node, "linspace()" - ) + start = get_ov_output(start, dtype) + stop = get_ov_output(stop, dtype) + start, stop = _align_operand_types(start, stop, "linspace()") if isinstance(num, OpenVINOKerasTensor): - num_node = get_ov_output(num, Type.i32) + num = get_ov_output(num, Type.i32) elif isinstance(num, int): - num_node = ov_opset.constant(num, Type.i32).output(0) + num = ov_opset.constant(num, Type.i32).output(0) else: raise TypeError("`num` must be an int or OpenVINOKerasTensor.") - zero_const = ov_opset.constant(0, Type.i32).output(0) - one_const = ov_opset.constant(1, Type.i32).output(0) - - effective_num = num_node - if not endpoint: - effective_num = ov_opset.subtract(num_node, one_const).output(0) - - step_node = ov_opset.divide( - ov_opset.convert( - ov_opset.subtract(stop_node, start_node), ov_dtype - ).output(0), - ov_opset.convert(effective_num, ov_dtype), - ).output(0) - - range_node = ov_opset.range( - zero_const, num_node, one_const, Type.i32 - ).output(0) - range_node = ov_opset.convert(range_node, ov_dtype).output(0) - - def expand_along_axis(node, axis): - node_shape = ov_opset.shape_of(node, Type.i32).output(0) - input_rank = node.get_partial_shape().rank.get_length() + 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) - # Normalize axis - if axis < 0: - axis += input_rank - - step = ov_opset.constant([1], Type.i32).output(0) - pre_shape = ov_opset.slice( - node_shape, - ov_opset.constant([0], Type.i32).output(0), - ov_opset.constant([axis], Type.i32).output(0), - step, - ).output(0) + div = ov_opset.subtract(num, one_i).output(0) if endpoint else num - post_shape = ov_opset.slice( - node_shape, - ov_opset.constant([axis], Type.i32).output(0), - ov_opset.constant([input_rank], Type.i32).output(0), - step, - ).output(0) + zero = ov_opset.convert(zero_i, dtype).output(0) + one = ov_opset.convert(one_i, dtype).output(0) + num_f = ov_opset.convert(num, dtype).output(0) - one_dim = ov_opset.constant([1], Type.i32).output(0) - new_shape = ov_opset.concat( - [pre_shape, one_dim, post_shape], axis=0 - ).output(0) + seq = ov_opset.range(zero, num_f, one).output(0) - return ov_opset.reshape(node, new_shape, special_zero=False).output(0) + delta = ov_opset.subtract(stop, start).output(0) + div_f = ov_opset.convert(div, dtype).output(0) - input_rank = start_node.get_partial_shape().rank.get_length() - if input_rank is None or input_rank < 1: - input_rank = 1 - normalized_axis = axis if axis >= 0 else axis + input_rank - if normalized_axis < 0: - raise ValueError( - f"`axis={axis}` is out of bounds for input rank {input_rank}" - ) + nan_const = ov_opset.constant(float("nan"), dtype).output(0) + cond = ov_opset.greater(div, zero_i).output(0) - range_node = expand_along_axis(range_node, normalized_axis) - step_node = expand_along_axis(step_node, normalized_axis) - start_node = expand_along_axis(start_node, normalized_axis) + step_val = ov_opset.divide(delta, div_f).output(0) + step = ov_opset.select(cond, step_val, nan_const).output(0) - broadcast_shape = ov_opset.shape_of(range_node, Type.i32).output(0) - step_broadcast = ov_opset.reshape( - step_node, broadcast_shape, special_zero=False + eq_zero = ov_opset.equal(step, zero).output(0) + any_zero = ov_opset.reduce_logical_or( + eq_zero, ov_opset.constant([0], Type.i64), False ).output(0) - start_broadcast = ov_opset.reshape( - start_node, broadcast_shape, special_zero=False + y_norm = ov_opset.multiply(seq, step).output(0) + y_denorm = ov_opset.multiply( + ov_opset.divide(seq, div_f).output(0), delta ).output(0) - # step_broadcast = ov_opset.broadcast(step_node, broadcast_shape).output(0) - # start_broadcast = ov_opset.broadcast(start_node, broadcast_shape).output(0) + y_pos = ov_opset.select(any_zero, y_denorm, y_norm).output(0) - linspace_result = ov_opset.add( - start_broadcast, - ov_opset.multiply(step_broadcast, range_node), + y_zero = ov_opset.multiply(seq, delta).output(0) + y = ov_opset.add( + ov_opset.select(cond, y_pos, y_zero).output(0), start ).output(0) - if retstep: - return OpenVINOKerasTensor(linspace_result), OpenVINOKerasTensor( - step_node - ) + if endpoint: + idx = ov_opset.subtract(num, one_i).output(0) + idx64 = ov_opset.convert(idx, Type.i64).output(0) + idx_tensor = ov_opset.reshape( + idx64, ov_opset.constant([1], Type.i64) + ).output(0) + stop_tensor = ov_opset.reshape( + stop, ov_opset.constant([1], Type.i64) + ).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) + ).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, dtype).output(0) - return OpenVINOKerasTensor(linspace_result) + return (y, step) if retstep else y def log(x): From 3c604595f60cf2765dcdb9daacb974d40f6fec9e Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 29 Apr 2025 14:36:45 +0530 Subject: [PATCH 37/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index c889a75772e3..bdab66679052 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -981,7 +981,7 @@ def linspace( one = ov_opset.convert(one_i, dtype).output(0) num_f = ov_opset.convert(num, dtype).output(0) - seq = ov_opset.range(zero, num_f, one).output(0) + seq = ov_opset.range(zero, num_f, one, dtype).output(0) delta = ov_opset.subtract(stop, start).output(0) div_f = ov_opset.convert(div, dtype).output(0) From d65d92c6a8c2e896b63fda1288ff9ae37cd15f44 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 29 Apr 2025 15:01:38 +0530 Subject: [PATCH 38/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index bdab66679052..a48ba9dba410 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -994,11 +994,11 @@ def linspace( eq_zero = ov_opset.equal(step, zero).output(0) any_zero = ov_opset.reduce_logical_or( - eq_zero, ov_opset.constant([0], Type.i64), False + 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_f).output(0), delta + ov_opset.convert(ov_opset.divide(seq, div_f).output(0)).output(0), delta ).output(0) y_pos = ov_opset.select(any_zero, y_denorm, y_norm).output(0) @@ -1009,12 +1009,12 @@ def linspace( if endpoint: idx = ov_opset.subtract(num, one_i).output(0) - idx64 = ov_opset.convert(idx, Type.i64).output(0) + idx32 = ov_opset.convert(idx, Type.i32).output(0) idx_tensor = ov_opset.reshape( - idx64, ov_opset.constant([1], Type.i64) + idx32, ov_opset.constant([1], Type.i32) ).output(0) stop_tensor = ov_opset.reshape( - stop, ov_opset.constant([1], Type.i64) + stop, ov_opset.constant([1], Type.i32) ).output(0) y = ov_opset.scatter_elements_update( y, idx_tensor, stop_tensor, 0 From 37e96c1d9604e85070031923e7bf6705afb2186b Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 29 Apr 2025 15:22:59 +0530 Subject: [PATCH 39/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index a48ba9dba410..11edbe7c1fea 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -983,13 +983,19 @@ def linspace( seq = ov_opset.range(zero, num_f, one, dtype).output(0) - delta = ov_opset.subtract(stop, start).output(0) + delta = ov_opset.convert( + ov_opset.subtract(stop, start).output(0), dtype + ).output(0) div_f = ov_opset.convert(div, dtype).output(0) - nan_const = ov_opset.constant(float("nan"), dtype).output(0) cond = ov_opset.greater(div, zero_i).output(0) - step_val = ov_opset.divide(delta, div_f).output(0) + nan_const = ov_opset.convert( + ov_opset.divide(zero, zero).output(0), dtype + ).output(0) + step_val = ov_opset.convert( + ov_opset.divide(delta, div_f).output(0), dtype + ).output(0) step = ov_opset.select(cond, step_val, nan_const).output(0) eq_zero = ov_opset.equal(step, zero).output(0) @@ -998,7 +1004,8 @@ def linspace( ).output(0) y_norm = ov_opset.multiply(seq, step).output(0) y_denorm = ov_opset.multiply( - ov_opset.convert(ov_opset.divide(seq, div_f).output(0)).output(0), delta + ov_opset.divide(seq, div_f).output(0), + delta, ).output(0) y_pos = ov_opset.select(any_zero, y_denorm, y_norm).output(0) From af33c76e3c4cd6058a8d57dc051d77ababd460a3 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 29 Apr 2025 16:04:46 +0530 Subject: [PATCH 40/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 11edbe7c1fea..9eceec1684e8 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -982,6 +982,10 @@ def linspace( 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 = [-1] + [1] * ndim + dims_const = ov_opset.constant(dims, Type.i32) + seq = ov_opset.reshape(seq, dims_const, False).output(0) delta = ov_opset.convert( ov_opset.subtract(stop, start).output(0), dtype @@ -1002,26 +1006,31 @@ def linspace( 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_f).output(0), delta, ).output(0) - y_pos = ov_opset.select(any_zero, y_denorm, y_norm).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.multiply(seq, delta).output(0) + y_zero = ov_opset.convert( + ov_opset.multiply(seq, delta).output(0), dtype + ).output(0) y = ov_opset.add( ov_opset.select(cond, y_pos, y_zero).output(0), start ).output(0) if endpoint: idx = ov_opset.subtract(num, one_i).output(0) - idx32 = ov_opset.convert(idx, Type.i32).output(0) + idx = ov_opset.convert(idx, Type.i32).output(0) idx_tensor = ov_opset.reshape( - idx32, ov_opset.constant([1], Type.i32) + idx, ov_opset.constant([1], Type.i32), False ).output(0) stop_tensor = ov_opset.reshape( - stop, ov_opset.constant([1], Type.i32) + stop, ov_opset.constant([1], Type.i32), False ).output(0) y = ov_opset.scatter_elements_update( y, idx_tensor, stop_tensor, 0 @@ -1033,13 +1042,12 @@ def linspace( 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) + 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, dtype).output(0) - return (y, step) if retstep else y From a26d3a60fa8674590b6122d0b77500d1c5faa85f Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 29 Apr 2025 17:58:03 +0530 Subject: [PATCH 41/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 9eceec1684e8..8e1b3644491c 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1020,18 +1020,20 @@ def linspace( ov_opset.multiply(seq, delta).output(0), dtype ).output(0) y = ov_opset.add( - ov_opset.select(cond, y_pos, y_zero).output(0), start + 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 = ov_opset.convert(idx, Type.i64).output(0) idx_tensor = ov_opset.reshape( - idx, ov_opset.constant([1], Type.i32), False - ).output(0) - stop_tensor = ov_opset.reshape( - stop, ov_opset.constant([1], Type.i32), False + idx, ov_opset.constant([1], Type.i64), False ).output(0) + shape_start = ov_opset.shape(start).output(0) + one_const = ov_opset.constant([1], Type.i64) + stop_shape = ov_opset.concat([one_const, shape_start], 0).output(0) + stop_tensor = ov_opset.reshape(stop, stop_shape, False).output(0) y = ov_opset.scatter_elements_update( y, idx_tensor, stop_tensor, 0 ).output(0) From 5dc78bfd0c2bd4049e7856ce56a6a44ffd2c542c Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 29 Apr 2025 18:25:48 +0530 Subject: [PATCH 42/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 8e1b3644491c..b9bccc96c182 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1026,12 +1026,12 @@ def linspace( if endpoint: idx = ov_opset.subtract(num, one_i).output(0) - idx = ov_opset.convert(idx, Type.i64).output(0) + idx = ov_opset.convert(idx, Type.i32).output(0) idx_tensor = ov_opset.reshape( - idx, ov_opset.constant([1], Type.i64), False + idx, ov_opset.constant([1], Type.i32), False ).output(0) - shape_start = ov_opset.shape(start).output(0) - one_const = ov_opset.constant([1], Type.i64) + shape_start = ov_opset.shape_of(start).output(0) + one_const = ov_opset.constant([1], Type.i32) stop_shape = ov_opset.concat([one_const, shape_start], 0).output(0) stop_tensor = ov_opset.reshape(stop, stop_shape, False).output(0) y = ov_opset.scatter_elements_update( From 280be55c70fce75c451fb4ede99a9d9604ab00d6 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Tue, 29 Apr 2025 18:35:56 +0530 Subject: [PATCH 43/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index b9bccc96c182..556cf397e95b 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1031,7 +1031,7 @@ def linspace( idx, ov_opset.constant([1], Type.i32), False ).output(0) shape_start = ov_opset.shape_of(start).output(0) - one_const = ov_opset.constant([1], Type.i32) + one_const = ov_opset.constant([1], Type.i64) stop_shape = ov_opset.concat([one_const, shape_start], 0).output(0) stop_tensor = ov_opset.reshape(stop, stop_shape, False).output(0) y = ov_opset.scatter_elements_update( From f982384b8a1c979dcfbb0380f83eccb4f1947d83 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Wed, 30 Apr 2025 12:23:47 +0530 Subject: [PATCH 44/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 556cf397e95b..3c0dd7a0a936 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1002,6 +1002,11 @@ def linspace( ).output(0) step = ov_opset.select(cond, step_val, nan_const).output(0) + s_shape = ov_opset.shape_of(start).output(0) + one_tensor = ov_opset.constant([1], Type.i32) + s_shape = ov_opset.concat([one_tensor, s_shape], 0).output(0) + step = ov_opset.reshape(step, s_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 @@ -1027,13 +1032,13 @@ def linspace( if endpoint: idx = ov_opset.subtract(num, one_i).output(0) idx = ov_opset.convert(idx, Type.i32).output(0) - idx_tensor = ov_opset.reshape( - idx, ov_opset.constant([1], Type.i32), False - ).output(0) - shape_start = ov_opset.shape_of(start).output(0) - one_const = ov_opset.constant([1], Type.i64) - stop_shape = ov_opset.concat([one_const, shape_start], 0).output(0) - stop_tensor = ov_opset.reshape(stop, stop_shape, False).output(0) + target_shape = ov_opset.concat([one_tensor, s_shape], 0).output(0) + # idx_tensor = ov_opset.reshape( + # idx, ov_opset.constant([1], Type.i64), False + # ).output(0) + # stop_tensor = ov_opset.reshape(stop, s_shape, False).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) From 6a5fb1bfeb9df9632d9cd5b494f31b1d2577d876 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Wed, 30 Apr 2025 13:29:10 +0530 Subject: [PATCH 45/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 3c0dd7a0a936..31063bed0361 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1002,10 +1002,10 @@ def linspace( ).output(0) step = ov_opset.select(cond, step_val, nan_const).output(0) - s_shape = ov_opset.shape_of(start).output(0) - one_tensor = ov_opset.constant([1], Type.i32) - s_shape = ov_opset.concat([one_tensor, s_shape], 0).output(0) - step = ov_opset.reshape(step, s_shape, False).output(0) + target_shape = ov_opset.shape_of(start).output(0) + one_tensor = ov_opset.constant([1], Type.i64) + target_shape = ov_opset.concat([one_tensor, target_shape], 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( @@ -1032,7 +1032,6 @@ def linspace( if endpoint: idx = ov_opset.subtract(num, one_i).output(0) idx = ov_opset.convert(idx, Type.i32).output(0) - target_shape = ov_opset.concat([one_tensor, s_shape], 0).output(0) # idx_tensor = ov_opset.reshape( # idx, ov_opset.constant([1], Type.i64), False # ).output(0) From 536b11a6530156ef334ba48f46356a78201c1988 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Wed, 30 Apr 2025 13:40:27 +0530 Subject: [PATCH 46/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 31063bed0361..0ef06c5b1cff 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -962,7 +962,7 @@ def linspace( start = get_ov_output(start, dtype) stop = get_ov_output(stop, dtype) - start, stop = _align_operand_types(start, stop, "linspace()") + # start, stop = _align_operand_types(start, stop, "linspace()") if isinstance(num, OpenVINOKerasTensor): num = get_ov_output(num, Type.i32) From abe68e401b9cb36ce6e56fb281f618ce39a0694c Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Wed, 30 Apr 2025 14:18:16 +0530 Subject: [PATCH 47/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 0ef06c5b1cff..401753177bd5 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -963,6 +963,8 @@ def linspace( start = get_ov_output(start, dtype) stop = get_ov_output(stop, dtype) # start, stop = _align_operand_types(start, stop, "linspace()") + start = ov_opset.convert(start, dtype).output(0) + stop = ov_opset.convert(stop, dtype).output(0) if isinstance(num, OpenVINOKerasTensor): num = get_ov_output(num, Type.i32) @@ -976,6 +978,8 @@ def linspace( 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) + div = ov_opset.convert(div, Type.i32).output(0) zero = ov_opset.convert(zero_i, dtype).output(0) one = ov_opset.convert(one_i, dtype).output(0) @@ -990,7 +994,6 @@ def linspace( delta = ov_opset.convert( ov_opset.subtract(stop, start).output(0), dtype ).output(0) - div_f = ov_opset.convert(div, dtype).output(0) cond = ov_opset.greater(div, zero_i).output(0) @@ -998,7 +1001,7 @@ def linspace( ov_opset.divide(zero, zero).output(0), dtype ).output(0) step_val = ov_opset.convert( - ov_opset.divide(delta, div_f).output(0), dtype + ov_opset.divide(delta, div).output(0), dtype ).output(0) step = ov_opset.select(cond, step_val, nan_const).output(0) @@ -1014,7 +1017,7 @@ def linspace( y_norm = ov_opset.multiply(seq, step).output(0) y_denorm = ov_opset.multiply( - ov_opset.divide(seq, div_f).output(0), + ov_opset.divide(seq, div).output(0), delta, ).output(0) y_pos = ov_opset.convert( From 0a39e5fd6feb1d79205da1c784c7facedf666914 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Wed, 30 Apr 2025 14:27:37 +0530 Subject: [PATCH 48/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 401753177bd5..0bf117e17657 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -978,8 +978,8 @@ def linspace( 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) - div = ov_opset.convert(div, Type.i32).output(0) + div = ov_opset.convert(div, dtype).output(0) + # div = ov_opset.convert(div, Type.i32).output(0) zero = ov_opset.convert(zero_i, dtype).output(0) one = ov_opset.convert(one_i, dtype).output(0) From 7d43dbf80d7da169c62c9f92722291f4b5d0b4c8 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Wed, 30 Apr 2025 14:38:46 +0530 Subject: [PATCH 49/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 0bf117e17657..20594efa46d3 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -979,7 +979,6 @@ def linspace( div = ov_opset.subtract(num, one_i).output(0) if endpoint else num div = ov_opset.convert(div, dtype).output(0) - # div = ov_opset.convert(div, Type.i32).output(0) zero = ov_opset.convert(zero_i, dtype).output(0) one = ov_opset.convert(one_i, dtype).output(0) @@ -995,7 +994,7 @@ def linspace( ov_opset.subtract(stop, start).output(0), dtype ).output(0) - cond = ov_opset.greater(div, zero_i).output(0) + cond = ov_opset.greater(div, zero).output(0) nan_const = ov_opset.convert( ov_opset.divide(zero, zero).output(0), dtype From fb5649feab3745e6e505ba6eee1dd33753cae58f Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Wed, 30 Apr 2025 15:00:27 +0530 Subject: [PATCH 50/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 20594efa46d3..060344e26188 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1056,7 +1056,7 @@ def linspace( y = ov_opset.transpose(y, perm).output(0) y = ov_opset.convert(y, dtype).output(0) - return (y, step) if retstep else y + return (OpenVINOKerasTensor(y), step) if retstep else OpenVINOKerasTensor(y) def log(x): From e3fdbfa925d406f60f95c987e532e615dbfc657e Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Wed, 30 Apr 2025 15:18:42 +0530 Subject: [PATCH 51/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 060344e26188..2ee5adefb276 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -957,7 +957,7 @@ def linspace( Size of spacing between samples. """ - dtype = dtype or config.floatx() + dtype = standardize_dtype(dtype) or config.floatx() dtype = OPENVINO_DTYPES[dtype] start = get_ov_output(start, dtype) From 96d17ff6f7b9e1399045a0d8c1850972f432fb73 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Wed, 30 Apr 2025 16:46:42 +0530 Subject: [PATCH 52/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 56 +++++++++++++++-------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 2ee5adefb276..b77dc013fa38 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -958,11 +958,11 @@ def linspace( """ dtype = standardize_dtype(dtype) or config.floatx() - dtype = OPENVINO_DTYPES[dtype] + out_dtype = OPENVINO_DTYPES[dtype] + dtype = OPENVINO_DTYPES[config.floatx()] start = get_ov_output(start, dtype) stop = get_ov_output(stop, dtype) - # start, stop = _align_operand_types(start, stop, "linspace()") start = ov_opset.convert(start, dtype).output(0) stop = ov_opset.convert(stop, dtype).output(0) @@ -980,33 +980,35 @@ def linspace( div = ov_opset.subtract(num, one_i).output(0) if endpoint else num div = ov_opset.convert(div, dtype).output(0) - zero = ov_opset.convert(zero_i, dtype).output(0) - one = ov_opset.convert(one_i, 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).output(0) - seq = ov_opset.range(zero, num_f, one, dtype).output(0) ndim = len(start.shape) - dims = [-1] + [1] * ndim - dims_const = ov_opset.constant(dims, Type.i32) - seq = ov_opset.reshape(seq, dims_const, False).output(0) - - delta = ov_opset.convert( - ov_opset.subtract(stop, start).output(0), dtype + 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) - cond = ov_opset.greater(div, zero).output(0) + delta = ov_opset.subtract(stop, start).output(0) - nan_const = ov_opset.convert( - ov_opset.divide(zero, zero).output(0), dtype - ).output(0) - step_val = ov_opset.convert( - ov_opset.divide(delta, div).output(0), dtype - ).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.shape_of(start).output(0) - one_tensor = ov_opset.constant([1], Type.i64) - target_shape = ov_opset.concat([one_tensor, target_shape], 0).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) @@ -1034,10 +1036,6 @@ def linspace( if endpoint: idx = ov_opset.subtract(num, one_i).output(0) idx = ov_opset.convert(idx, Type.i32).output(0) - # idx_tensor = ov_opset.reshape( - # idx, ov_opset.constant([1], Type.i64), False - # ).output(0) - # stop_tensor = ov_opset.reshape(stop, s_shape, False).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( @@ -1055,8 +1053,12 @@ def linspace( perm = ov_opset.concat([pre, zero_i, post], 0).output(0) y = ov_opset.transpose(y, perm).output(0) - y = ov_opset.convert(y, dtype).output(0) - return (OpenVINOKerasTensor(y), step) if retstep else OpenVINOKerasTensor(y) + y = ov_opset.convert(y, out_dtype).output(0) + if retstep: + return OpenVINOKerasTensor(y), ov_opset.convert(step, out_dtype).output( + 0 + ) + return OpenVINOKerasTensor(y) def log(x): From 209daf050a7eb247ad552c08d78916c6d0b9e431 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Wed, 30 Apr 2025 18:09:21 +0530 Subject: [PATCH 53/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index b77dc013fa38..f116f2b91f77 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -983,7 +983,7 @@ def linspace( 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).output(0) + seq = ov_opset.range(zero, num_f, one, dtype).output(0) ndim = len(start.shape) dims = ov_opset.concat( From 724b143da96cb5ce1296591ddb081f9b2ac5affc Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Wed, 30 Apr 2025 18:42:09 +0530 Subject: [PATCH 54/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index f116f2b91f77..f3904d76005f 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -972,6 +972,7 @@ def linspace( num = ov_opset.constant(num, Type.i32).output(0) else: raise TypeError("`num` must be an int or OpenVINOKerasTensor.") + num = ov_opset.convert(num, Type.i32).output(0) zero_i = ov_opset.constant(0, Type.i32).output(0) one_i = ov_opset.constant(1, Type.i32).output(0) From e60d7083cf65f032db0264ca0c9b40f913d60fa6 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Mon, 5 May 2025 22:15:37 +0530 Subject: [PATCH 55/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index f3904d76005f..1aecc77330be 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -963,16 +963,7 @@ def linspace( 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) - - 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.") - num = ov_opset.convert(num, Type.i32).output(0) + num = get_ov_output(num, Type.i32) zero_i = ov_opset.constant(0, Type.i32).output(0) one_i = ov_opset.constant(1, Type.i32).output(0) @@ -1055,10 +1046,10 @@ def linspace( y = ov_opset.transpose(y, perm).output(0) y = ov_opset.convert(y, out_dtype).output(0) + + return_step = ov_opset.convert(step, out_dtype).output(0) if retstep: - return OpenVINOKerasTensor(y), ov_opset.convert(step, out_dtype).output( - 0 - ) + return (OpenVINOKerasTensor(y), OpenVINOKerasTensor(return_step)) return OpenVINOKerasTensor(y) From 9c7fbeeff124ed85a8d7910eada6bad8e1ae7615 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Mon, 5 May 2025 22:44:59 +0530 Subject: [PATCH 56/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 1aecc77330be..0108098663a0 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -963,6 +963,9 @@ def linspace( 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) + num = get_ov_output(num, Type.i32) zero_i = ov_opset.constant(0, Type.i32).output(0) From c6991f9bd41bd85ed125a6e6af63e9a367608300 Mon Sep 17 00:00:00 2001 From: Shruti Vishwakarma Date: Thu, 8 May 2025 12:29:09 +0530 Subject: [PATCH 57/57] Update numpy.py --- keras/src/backend/openvino/numpy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 0108098663a0..f1836fd9476c 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -967,6 +967,7 @@ def linspace( stop = ov_opset.convert(stop, dtype).output(0) num = get_ov_output(num, Type.i32) + num = ov_opset.convert(num, Type.i32).output(0) zero_i = ov_opset.constant(0, Type.i32).output(0) one_i = ov_opset.constant(1, Type.i32).output(0)