Skip to content

Commit c278dbf

Browse files
Merge branch 'master' into gsoc2025
2 parents eaaaa86 + df481e9 commit c278dbf

File tree

17 files changed

+775
-190
lines changed

17 files changed

+775
-190
lines changed

keras/api/_tf_keras/keras/ops/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@
191191
from keras.src.ops.numpy import greater_equal as greater_equal
192192
from keras.src.ops.numpy import hamming as hamming
193193
from keras.src.ops.numpy import hanning as hanning
194+
from keras.src.ops.numpy import heaviside as heaviside
194195
from keras.src.ops.numpy import histogram as histogram
195196
from keras.src.ops.numpy import hstack as hstack
196197
from keras.src.ops.numpy import identity as identity

keras/api/_tf_keras/keras/ops/numpy/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
from keras.src.ops.numpy import greater_equal as greater_equal
8181
from keras.src.ops.numpy import hamming as hamming
8282
from keras.src.ops.numpy import hanning as hanning
83+
from keras.src.ops.numpy import heaviside as heaviside
8384
from keras.src.ops.numpy import histogram as histogram
8485
from keras.src.ops.numpy import hstack as hstack
8586
from keras.src.ops.numpy import identity as identity

keras/api/ops/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@
191191
from keras.src.ops.numpy import greater_equal as greater_equal
192192
from keras.src.ops.numpy import hamming as hamming
193193
from keras.src.ops.numpy import hanning as hanning
194+
from keras.src.ops.numpy import heaviside as heaviside
194195
from keras.src.ops.numpy import histogram as histogram
195196
from keras.src.ops.numpy import hstack as hstack
196197
from keras.src.ops.numpy import identity as identity

keras/api/ops/numpy/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
from keras.src.ops.numpy import greater_equal as greater_equal
8181
from keras.src.ops.numpy import hamming as hamming
8282
from keras.src.ops.numpy import hanning as hanning
83+
from keras.src.ops.numpy import heaviside as heaviside
8384
from keras.src.ops.numpy import histogram as histogram
8485
from keras.src.ops.numpy import hstack as hstack
8586
from keras.src.ops.numpy import identity as identity

keras/src/backend/jax/numpy.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ def hanning(x):
5252
return jnp.hanning(x)
5353

5454

55+
def heaviside(x1, x2):
56+
x1 = convert_to_tensor(x1)
57+
x2 = convert_to_tensor(x2)
58+
return jnp.heaviside(x1, x2)
59+
60+
5561
def kaiser(x, beta):
5662
x = convert_to_tensor(x)
5763
return jnp.kaiser(x, beta)

keras/src/backend/numpy/numpy.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,19 @@ def hanning(x):
320320
return np.hanning(x).astype(config.floatx())
321321

322322

323+
def heaviside(x1, x2):
324+
x1 = convert_to_tensor(x1)
325+
x2 = convert_to_tensor(x2)
326+
327+
dtype = dtypes.result_type(x1.dtype, x2.dtype)
328+
if dtype in ["int8", "int16", "int32", "uint8", "uint16", "uint32"]:
329+
dtype = config.floatx()
330+
elif dtype in ["int64"]:
331+
dtype = "float64"
332+
333+
return np.heaviside(x1, x2).astype(dtype)
334+
335+
323336
def kaiser(x, beta):
324337
x = convert_to_tensor(x)
325338
return np.kaiser(x, beta).astype(config.floatx())

keras/src/backend/openvino/excluded_concrete_tests.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ NumpyDtypeTest::test_bartlett
1111
NumpyDtypeTest::test_blackman
1212
NumpyDtypeTest::test_hamming
1313
NumpyDtypeTest::test_hanning
14+
NumpyDtypeTest::test_heaviside
1415
NumpyDtypeTest::test_kaiser
1516
NumpyDtypeTest::test_bitwise
1617
NumpyDtypeTest::test_cbrt
@@ -137,6 +138,7 @@ NumpyTwoInputOpsCorrectnessTest::test_cross
137138
NumpyTwoInputOpsCorrectnessTest::test_digitize
138139
NumpyTwoInputOpsCorrectnessTest::test_divide_no_nan
139140
NumpyTwoInputOpsCorrectnessTest::test_einsum
141+
NumpyTwoInputOpsCorrectnessTest::test_heaviside
140142
NumpyTwoInputOpsCorrectnessTest::test_inner
141143
NumpyTwoInputOpsCorrectnessTest::test_linspace
142144
NumpyTwoInputOpsCorrectnessTest::test_logspace
@@ -155,6 +157,8 @@ NumpyOneInputOpsDynamicShapeTest::test_kaiser
155157
NumpyOneInputOpsStaticShapeTest::test_angle
156158
NumpyOneInputOpsStaticShapeTest::test_cbrt
157159
NumpyOneInputOpsStaticShapeTest::test_deg2rad
160+
NumpyTwoInputOpsDynamicShapeTest::test_heaviside
161+
NumpyTwoInputOpsStaticShapeTest::test_heaviside
158162
CoreOpsBehaviorTests::test_associative_scan_invalid_arguments
159163
CoreOpsBehaviorTests::test_scan_invalid_arguments
160164
CoreOpsCallsTests::test_associative_scan_basic_call
@@ -195,7 +199,6 @@ MathOpsCorrectnessTest::test_istft4
195199
MathOpsCorrectnessTest::test_istft5
196200
MathOpsCorrectnessTest::test_istft6
197201
MathOpsCorrectnessTest::test_logdet
198-
MathOpsCorrectnessTest::test_logsumexp
199202
MathOpsCorrectnessTest::test_rfft0
200203
MathOpsCorrectnessTest::test_rfft1
201204
MathOpsCorrectnessTest::test_rfft2
@@ -277,4 +280,4 @@ TestMathErrors::test_invalid_fft_length
277280
TestMathErrors::test_istft_invalid_window_shape_2D_inputs
278281
TestMathErrors::test_stft_invalid_input_type
279282
TestMathErrors::test_stft_invalid_window
280-
TestMathErrors::test_stft_invalid_window_shape
283+
TestMathErrors::test_stft_invalid_window_shape

keras/src/backend/openvino/math.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,17 @@ def logsumexp(x, axis=None, keepdims=False):
4444
axis = list(axis)
4545
axis = ov_opset.constant(axis, Type.i32).output(0)
4646
const_zero = ov_opset.constant(0, x.get_element_type()).output(0)
47-
reduce_max = ov_opset.reduce_max(x, axis, keepdims).output(0)
47+
# Use keepdims=True for reduce_max to ensure proper broadcasting
48+
reduce_max = ov_opset.reduce_max(x, axis, True).output(0)
4849
is_finite = ov_opset.is_finite(reduce_max).output(0)
4950
norm_max = ov_opset.select(is_finite, reduce_max, const_zero).output(0)
5051
norm_max_sub = ov_opset.subtract(x, norm_max).output(0)
5152
exp_norm_max = ov_opset.exp(norm_max_sub).output(0)
5253
sum_exp = ov_opset.reduce_sum(exp_norm_max, axis, keepdims).output(0)
5354
log_sum_exp = ov_opset.log(sum_exp).output(0)
55+
# Squeeze norm_max if needed to match dimensions
56+
if not keepdims:
57+
norm_max = ov_opset.squeeze(norm_max, axis).output(0)
5458
log_sum_exp = ov_opset.add(norm_max, log_sum_exp).output(0)
5559
return OpenVINOKerasTensor(log_sum_exp)
5660

keras/src/backend/openvino/numpy.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,12 @@ def hamming(x):
481481
)
482482

483483

484+
def heaviside(x1, x2):
485+
raise NotImplementedError(
486+
"`heaviside` is not supported with openvino backend"
487+
)
488+
489+
484490
def kaiser(x, beta):
485491
raise NotImplementedError("`kaiser` is not supported with openvino backend")
486492

keras/src/backend/tensorflow/numpy.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,26 @@ def hanning(x):
156156
return tf.signal.hann_window(x, periodic=False)
157157

158158

159+
def heaviside(x1, x2):
160+
x1 = convert_to_tensor(x1)
161+
x2 = convert_to_tensor(x2)
162+
163+
dtype = dtypes.result_type(x1.dtype, x2.dtype)
164+
if dtype in ["int8", "int16", "int32", "uint8", "uint16", "uint32"]:
165+
dtype = config.floatx()
166+
elif dtype in ["int64"]:
167+
dtype = "float64"
168+
169+
x1 = tf.cast(x1, dtype)
170+
x2 = tf.cast(x2, dtype)
171+
172+
return tf.where(
173+
x1 < 0,
174+
tf.zeros_like(x1),
175+
tf.where(x1 > 0, tf.ones_like(x1), x2),
176+
)
177+
178+
159179
def kaiser(x, beta):
160180
x = convert_to_tensor(x, dtype=tf.int32)
161181
return tf.signal.kaiser_window(x, beta=beta)

0 commit comments

Comments
 (0)