From 2d35e25117e09d24c1a294d87cd31bee96dd3c1d Mon Sep 17 00:00:00 2001 From: arunthakur009 Date: Wed, 20 Aug 2025 10:05:42 +0530 Subject: [PATCH 1/5] Added Numpy.meshgrid operation for openvino backend --- .../openvino/excluded_concrete_tests.txt | 1 - keras/src/backend/openvino/numpy.py | 49 +++++++++++++++++-- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/keras/src/backend/openvino/excluded_concrete_tests.txt b/keras/src/backend/openvino/excluded_concrete_tests.txt index 004f8c2f87fb..eaa0002fd43b 100644 --- a/keras/src/backend/openvino/excluded_concrete_tests.txt +++ b/keras/src/backend/openvino/excluded_concrete_tests.txt @@ -100,7 +100,6 @@ NumpyOneInputOpsCorrectnessTest::test_logaddexp NumpyOneInputOpsCorrectnessTest::test_max NumpyOneInputOpsCorrectnessTest::test_mean NumpyOneInputOpsCorrectnessTest::test_median -NumpyOneInputOpsCorrectnessTest::test_meshgrid NumpyOneInputOpsCorrectnessTest::test_pad_float16_constant_2 NumpyOneInputOpsCorrectnessTest::test_pad_float32_constant_2 NumpyOneInputOpsCorrectnessTest::test_pad_float64_constant_2 diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 9582ad3bca44..bbf02c863279 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1097,9 +1097,52 @@ def median(x, axis=None, keepdims=False): def meshgrid(*x, indexing="xy"): - raise NotImplementedError( - "`meshgrid` is not supported with openvino backend" - ) + if len(x) < 2: + raise ValueError("meshgrid requires at least 2 input arrays") + if indexing not in ("xy", "ij"): + raise ValueError("indexing must be either 'xy' or 'ij'") + + tensors = [get_ov_output(xi) for xi in x] + n = len(tensors) + + shapes = [ov_opset.shape_of(t, Type.i64).output(0) for t in tensors] # each is [Ni] + one = ov_opset.constant([1], Type.i64).output(0) + + if indexing == "xy" and n >= 2: + out_shape = ov_opset.concat([shapes[1], shapes[0]] + shapes[2:], axis=0).output(0) + else: + out_shape = ov_opset.concat(shapes, axis=0).output(0) + + outputs = [] + for i, t in enumerate(tensors): + parts = [] + for axis in range(n): + if indexing == "xy" and n >= 2: + if i == 0: + if axis == 0: + parts.append(one) + elif axis == 1: + parts.append(shapes[0]) + else: + parts.append(one if axis != i else shapes[i]) + elif i == 1: + if axis == 0: + parts.append(shapes[1]) + elif axis == 1: + parts.append(one) + else: + parts.append(one if axis != i else shapes[i]) + else: + parts.append(shapes[i] if axis == i else one) + else: + parts.append(shapes[i] if axis == i else one) + + reshape_shape = ov_opset.concat(parts, axis=0).output(0) + reshaped = ov_opset.reshape(t, reshape_shape, False).output(0) + broadcasted = ov_opset.broadcast(reshaped, out_shape).output(0) + outputs.append(OpenVINOKerasTensor(broadcasted)) + + return outputs def min(x, axis=None, keepdims=False, initial=None): From ff2bf19dedcc948ce012e88a66f0c925378f67ff Mon Sep 17 00:00:00 2001 From: arunthakur009 Date: Wed, 20 Aug 2025 10:33:34 +0530 Subject: [PATCH 2/5] Performed the changes suggested by the BOT --- keras/src/backend/openvino/numpy.py | 38 +++++++++++------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index bbf02c863279..41495d6ae8ff 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1108,36 +1108,26 @@ def meshgrid(*x, indexing="xy"): shapes = [ov_opset.shape_of(t, Type.i64).output(0) for t in tensors] # each is [Ni] one = ov_opset.constant([1], Type.i64).output(0) - if indexing == "xy" and n >= 2: - out_shape = ov_opset.concat([shapes[1], shapes[0]] + shapes[2:], axis=0).output(0) - else: + if indexing == "xy": + shape_list = [shapes[1], shapes[0]] + shapes[2:] + out_shape = ov_opset.concat(shape_list, axis=0).output(0) + else: out_shape = ov_opset.concat(shapes, axis=0).output(0) outputs = [] for i, t in enumerate(tensors): - parts = [] - for axis in range(n): - if indexing == "xy" and n >= 2: - if i == 0: - if axis == 0: - parts.append(one) - elif axis == 1: - parts.append(shapes[0]) - else: - parts.append(one if axis != i else shapes[i]) - elif i == 1: - if axis == 0: - parts.append(shapes[1]) - elif axis == 1: - parts.append(one) - else: - parts.append(one if axis != i else shapes[i]) - else: - parts.append(shapes[i] if axis == i else one) + reshape_parts = [one] * n + if indexing == "xy": + if i == 0: + reshape_parts[1] = shapes[0] + elif i == 1: + reshape_parts[0] = shapes[1] else: - parts.append(shapes[i] if axis == i else one) + reshape_parts[i] = shapes[i] + else: + reshape_parts[i] = shapes[i] - reshape_shape = ov_opset.concat(parts, axis=0).output(0) + reshape_shape = ov_opset.concat(reshape_parts, axis=0).output(0) reshaped = ov_opset.reshape(t, reshape_shape, False).output(0) broadcasted = ov_opset.broadcast(reshaped, out_shape).output(0) outputs.append(OpenVINOKerasTensor(broadcasted)) From 3774020218bc7a48a8b0cb65864950afee5bfe1c Mon Sep 17 00:00:00 2001 From: arunthakur009 Date: Thu, 21 Aug 2025 23:26:45 +0530 Subject: [PATCH 3/5] Performed the suggested changes --- keras/src/backend/openvino/excluded_concrete_tests.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/keras/src/backend/openvino/excluded_concrete_tests.txt b/keras/src/backend/openvino/excluded_concrete_tests.txt index eaa0002fd43b..a00f177f0eaa 100644 --- a/keras/src/backend/openvino/excluded_concrete_tests.txt +++ b/keras/src/backend/openvino/excluded_concrete_tests.txt @@ -43,7 +43,6 @@ NumpyDtypeTest::test_matmul_ NumpyDtypeTest::test_max NumpyDtypeTest::test_mean NumpyDtypeTest::test_median -NumpyDtypeTest::test_meshgrid NumpyDtypeTest::test_minimum_python_types NumpyDtypeTest::test_multiply NumpyDtypeTest::test_power From bf331c9410637bb6b0e5b63fd88fe91a524f9ac1 Mon Sep 17 00:00:00 2001 From: arunthakur009 Date: Fri, 22 Aug 2025 00:26:27 +0530 Subject: [PATCH 4/5] Minor changes --- keras/src/backend/openvino/numpy.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/keras/src/backend/openvino/numpy.py b/keras/src/backend/openvino/numpy.py index 41495d6ae8ff..0d1b838061af 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1105,13 +1105,15 @@ def meshgrid(*x, indexing="xy"): tensors = [get_ov_output(xi) for xi in x] n = len(tensors) - shapes = [ov_opset.shape_of(t, Type.i64).output(0) for t in tensors] # each is [Ni] + shapes = [ + ov_opset.shape_of(t, Type.i64).output(0) for t in tensors + ] # each is [Ni] one = ov_opset.constant([1], Type.i64).output(0) if indexing == "xy": shape_list = [shapes[1], shapes[0]] + shapes[2:] out_shape = ov_opset.concat(shape_list, axis=0).output(0) - else: + else: out_shape = ov_opset.concat(shapes, axis=0).output(0) outputs = [] @@ -1124,7 +1126,7 @@ def meshgrid(*x, indexing="xy"): reshape_parts[0] = shapes[1] else: reshape_parts[i] = shapes[i] - else: + else: reshape_parts[i] = shapes[i] reshape_shape = ov_opset.concat(reshape_parts, axis=0).output(0) From 0e4e3c8370d709af2132bece7998954938bde0cf Mon Sep 17 00:00:00 2001 From: arunthakur009 Date: Sat, 23 Aug 2025 02:18:11 +0530 Subject: [PATCH 5/5] Minor Changes --- 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 0d1b838061af..e17c54d8d955 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1098,7 +1098,10 @@ def median(x, axis=None, keepdims=False): def meshgrid(*x, indexing="xy"): if len(x) < 2: - raise ValueError("meshgrid requires at least 2 input arrays") + raise ValueError( + "meshgrid requires at least 2 input arrays. " + f"Received: {len(x)} input array(s)." + ) if indexing not in ("xy", "ij"): raise ValueError("indexing must be either 'xy' or 'ij'")