Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion keras/src/backend/openvino/excluded_concrete_tests.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
NumPyTestRot90
NumpyDtypeTest::test_add_
NumpyDtypeTest::test_angle
NumpyDtypeTest::test_argpartition
Expand Down
65 changes: 63 additions & 2 deletions keras/src/backend/openvino/numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -1117,22 +1117,28 @@ def expm1(x):

def flip(x, axis=None):
x_node = get_ov_output(x)
ndim = x.ndim

# Using OpenVINO tensor shape
ndim = len(x_node.get_partial_shape())
if ndim is None:
raise ValueError(
"The `flip` operation does not support tensors with dynamic rank"
"The `flip` operation does not support tensors with dynamic rank "
"for the OpenVINO backend."
)

if axis is None:
axis = list(range(ndim))
elif isinstance(axis, int):
axis = [axis]

axis = [a + ndim if a < 0 else a for a in axis]

begin = [0] * ndim
end = [0] * ndim
strides = [1] * ndim
for a in axis:
strides[a] = -1

all_ones_mask = [1] * ndim
result = ov_opset.strided_slice(
data=x_node,
Expand All @@ -1145,6 +1151,61 @@ def flip(x, axis=None):
return OpenVINOKerasTensor(result.output(0))


def rot90(array, k=1, axes=(0, 1)):
"""Rotate an array by 90 degrees in the plane specified by axes."""
array = get_ov_output(array)

if not isinstance(axes, (tuple, list)) or len(axes) != 2:
raise ValueError("axes must be a tuple of length 2")

shape = array.get_partial_shape()
ndim = shape.rank.get_length()
if ndim is None:
raise ValueError(
"`rot90` does not support tensors with dynamic rank "
"for the OpenVINO backend."
)

axis1 = canonicalize_axis(axes[0], ndim)
axis2 = canonicalize_axis(axes[1], ndim)

if axis1 == axis2:
raise ValueError("axes must be different")

k = k % 4
if k == 0:
return OpenVINOKerasTensor(array)

result = array

for _ in range(k):
# 1️ Transpose axis1 <-> axis2
perm = list(range(ndim))
perm[axis1], perm[axis2] = perm[axis2], perm[axis1]
perm_const = ov_opset.constant(perm, Type.i32).output(0)
result = ov_opset.transpose(result, perm_const).output(0)

# 2️ Reverse along axis1 using StridedSlice
begin = [0] * ndim
end = [0] * ndim
strides = [1] * ndim
strides[axis1] = -1

begin_mask = [1] * ndim
end_mask = [1] * ndim

result = ov_opset.strided_slice(
data=result,
begin=begin,
end=end,
strides=strides,
begin_mask=begin_mask,
end_mask=end_mask,
).output(0)

return OpenVINOKerasTensor(result)


def floor(x):
x = get_ov_output(x)
x_type = x.get_element_type()
Expand Down