diff --git a/keras/src/backend/openvino/excluded_concrete_tests.txt b/keras/src/backend/openvino/excluded_concrete_tests.txt index 004f8c2f87fb..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 @@ -100,7 +99,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..e17c54d8d955 100644 --- a/keras/src/backend/openvino/numpy.py +++ b/keras/src/backend/openvino/numpy.py @@ -1097,9 +1097,47 @@ 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. " + f"Received: {len(x)} input array(s)." + ) + 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": + 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): + reshape_parts = [one] * n + if indexing == "xy": + if i == 0: + reshape_parts[1] = shapes[0] + elif i == 1: + reshape_parts[0] = shapes[1] + else: + reshape_parts[i] = shapes[i] + else: + reshape_parts[i] = shapes[i] + + 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)) + + return outputs def min(x, axis=None, keepdims=False, initial=None):