Skip to content

Commit 2316acb

Browse files
Merge branch 'master' into raghav/29359
2 parents e5ede62 + 8333ef4 commit 2316acb

39 files changed

+1731
-214
lines changed

.github/workflows/actions.yml

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,7 @@ jobs:
132132
pip install -r requirements-openvino.txt --progress-bar off --upgrade
133133
pip uninstall -y keras keras-nightly
134134
pip install -e "." --progress-bar off --upgrade
135-
- name: Lint
136-
run: bash shell/lint.sh
137-
- name: Check for API changes
138-
run: |
139-
bash shell/api_gen.sh
140-
git status
141-
clean=$(git status | grep "nothing to commit")
142-
if [ -z "$clean" ]; then
143-
echo "Please run shell/api_gen.sh to generate API."
144-
exit 1
145-
fi
135+
- name: Install pre-commit
136+
run: pip install pre-commit && pre-commit install
137+
- name: Run pre-commit
138+
run: pre-commit run --all-files --hook-stage manual

.pre-commit-config.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
repos:
2+
- repo: local
3+
hooks:
4+
- id: api-gen
5+
name: api_gen
6+
entry: |
7+
bash shell/api_gen.sh
8+
git status
9+
clean=$(git status | grep "nothing to commit")
10+
if [ -z "$clean" ]; then
11+
echo "Please run shell/api_gen.sh to generate API."
12+
exit 1
13+
fi
14+
language: system
15+
stages: [pre-commit, manual]
16+
require_serial: true
17+
- repo: https://github.com/astral-sh/ruff-pre-commit
18+
rev: v0.9.2
19+
hooks:
20+
- id: ruff
21+
args: [--config, pyproject.toml, --fix, .]
22+
stages: [pre-commit]
23+
- id: ruff-format
24+
args: [--config, pyproject.toml, .]
25+
stages: [pre-commit]
26+
- id: ruff
27+
args: [--config, pyproject.toml, .]
28+
stages: [manual]
29+
- id: ruff-format
30+
args: ["--check", --config, pyproject.toml, .]
31+
stages: [manual]

CONTRIBUTING.md

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,22 +107,35 @@ You can also add GPU support to your environment, see the
107107
[Adding GPU support](https://github.com/keras-team/keras/blob/master/README.md#adding-gpu-support)
108108
section of the README.
109109

110-
## Code style
110+
## Generating public API and formatting the code
111111

112-
Keras uses [Ruff](https://docs.astral.sh/ruff/) to format the code. Please refer to
113-
[requirements-common.txt](https://github.com/keras-team/keras/blob/master/requirements-common.txt)
114-
for the required versions. Run the following command **at the root directory of
115-
the repo** to format your code.
112+
For the first time you are setting up the repo, please run `pre-commit install`.
113+
Note that this needs to be done only once at the beginning.
114+
115+
Now, whenever you run `git commit -m "<message>"`, three things are
116+
automatically done:
117+
118+
- Public API generation
119+
- Code formatting
120+
- Code linting
121+
122+
If there's any error, the commit will not go through. Please fix the error (
123+
most of the times, the error is fixed automatically by the formatter/linter) and
124+
re-run the following:
116125

117126
```
118-
sh shell/format.sh
127+
git add .
128+
git commit -m "<message>" # This will not get logged as a duplicate commit.
119129
```
120130

121-
It will also display the errors that cannot be resolved by autoformatting. You
122-
need to follow the output of the command to resolve them manually.
131+
In case you want to run the above manually on all files, you can do the
132+
following:
133+
134+
```
135+
pre-commit run --all-files
136+
```
123137

124-
If you do not want to auto format the code but only show the lint errors, you
125-
can run `sh shell/lint.sh` **at the root directory of the repo**.
138+
KerasHub uses [Ruff](https://docs.astral.sh/ruff/) to format the code.
126139

127140
### Docstrings
128141

keras/api/_tf_keras/keras/losses/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from keras.src.losses.losses import BinaryFocalCrossentropy
1515
from keras.src.losses.losses import CategoricalCrossentropy
1616
from keras.src.losses.losses import CategoricalFocalCrossentropy
17+
from keras.src.losses.losses import CategoricalGeneralizedCrossEntropy
1718
from keras.src.losses.losses import CategoricalHinge
1819
from keras.src.losses.losses import Circle
1920
from keras.src.losses.losses import CosineSimilarity
@@ -34,6 +35,7 @@
3435
from keras.src.losses.losses import binary_focal_crossentropy
3536
from keras.src.losses.losses import categorical_crossentropy
3637
from keras.src.losses.losses import categorical_focal_crossentropy
38+
from keras.src.losses.losses import categorical_generalized_cross_entropy
3739
from keras.src.losses.losses import categorical_hinge
3840
from keras.src.losses.losses import circle
3941
from keras.src.losses.losses import cosine_similarity

keras/api/_tf_keras/keras/optimizers/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from keras.src.optimizers.lamb import Lamb
2020
from keras.src.optimizers.lion import Lion
2121
from keras.src.optimizers.loss_scale_optimizer import LossScaleOptimizer
22+
from keras.src.optimizers.muon import Muon
2223
from keras.src.optimizers.nadam import Nadam
2324
from keras.src.optimizers.optimizer import Optimizer
2425
from keras.src.optimizers.rmsprop import RMSprop

keras/api/losses/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from keras.src.losses.losses import BinaryFocalCrossentropy
1414
from keras.src.losses.losses import CategoricalCrossentropy
1515
from keras.src.losses.losses import CategoricalFocalCrossentropy
16+
from keras.src.losses.losses import CategoricalGeneralizedCrossEntropy
1617
from keras.src.losses.losses import CategoricalHinge
1718
from keras.src.losses.losses import Circle
1819
from keras.src.losses.losses import CosineSimilarity
@@ -33,6 +34,7 @@
3334
from keras.src.losses.losses import binary_focal_crossentropy
3435
from keras.src.losses.losses import categorical_crossentropy
3536
from keras.src.losses.losses import categorical_focal_crossentropy
37+
from keras.src.losses.losses import categorical_generalized_cross_entropy
3638
from keras.src.losses.losses import categorical_hinge
3739
from keras.src.losses.losses import circle
3840
from keras.src.losses.losses import cosine_similarity

keras/api/optimizers/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from keras.src.optimizers.lamb import Lamb
2020
from keras.src.optimizers.lion import Lion
2121
from keras.src.optimizers.loss_scale_optimizer import LossScaleOptimizer
22+
from keras.src.optimizers.muon import Muon
2223
from keras.src.optimizers.nadam import Nadam
2324
from keras.src.optimizers.optimizer import Optimizer
2425
from keras.src.optimizers.rmsprop import RMSprop

keras/src/backend/common/variables.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ def __init__(
9696
trainable=True,
9797
autocast=True,
9898
aggregation="none",
99+
synchronization="auto",
99100
name=None,
100101
):
101102
name = name or auto_name(self.__class__.__name__)
@@ -113,13 +114,28 @@ def __init__(
113114
"only_first_replica",
114115
):
115116
raise ValueError(
116-
"Invalid valid for argument `aggregation`. Expected "
117+
"Invalid value for argument `aggregation`. Expected "
117118
"one of `None`, `'none'`, `'mean'`, `'sum'`, "
118119
"`'only_first_replica'`. "
119120
f"Received: aggregation={aggregation}"
120121
)
121122
if aggregation is None:
122123
aggregation = "none"
124+
if synchronization not in (
125+
None,
126+
"none",
127+
"on_read",
128+
"on_write",
129+
"auto",
130+
):
131+
raise ValueError(
132+
"Invalid value for argument `synchronization`. Expected "
133+
"one of `None`, `'none'`, `'on_read'`, `'on_write'`, "
134+
"`'auto'`. "
135+
f"Received: synchronization={synchronization}"
136+
)
137+
if synchronization is None:
138+
synchronization = "none"
123139
self._name = name
124140
parent_path = current_path()
125141
if parent_path:
@@ -133,6 +149,7 @@ def __init__(
133149
self._trainable = bool(trainable)
134150
self._autocast = bool(autocast)
135151
self._aggregation = aggregation
152+
self._synchronization = synchronization
136153
# `self._overwrite_with_gradient` is an internal property to determine
137154
# whether this variable should be overwritten by the computed gradient.
138155
# Ref: https://github.com/google/flax/blob/main/flax/linen/fp8_ops.py
@@ -227,6 +244,11 @@ def aggregation(self):
227244
"""The strategy for aggregating this variable."""
228245
return self._aggregation
229246

247+
@property
248+
def synchronization(self):
249+
"""The strategy for synchronizing this variable."""
250+
return self._synchronization
251+
230252
@property
231253
def value(self):
232254
"""The current value of the variable (numpy array or backend tensor)."""

keras/src/backend/openvino/excluded_concrete_tests.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ NumpyOneInputOpsCorrectnessTest::test_hstack
9999
NumpyOneInputOpsCorrectnessTest::test_imag
100100
NumpyOneInputOpsCorrectnessTest::test_isfinite
101101
NumpyOneInputOpsCorrectnessTest::test_isinf
102-
NumpyOneInputOpsCorrectnessTest::test_log
102+
NumpyOneInputOpsCorrectnessTest::test_log1p
103+
NumpyOneInputOpsCorrectnessTest::test_log2
104+
NumpyOneInputOpsCorrectnessTest::test_logaddexp
103105
NumpyOneInputOpsCorrectnessTest::test_max
104106
NumpyOneInputOpsCorrectnessTest::test_mean
105107
NumpyOneInputOpsCorrectnessTest::test_median

keras/src/backend/openvino/numpy.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -841,11 +841,24 @@ def linspace(
841841

842842
def log(x):
843843
x = get_ov_output(x)
844+
x_type = x.get_element_type()
845+
if x_type.is_integral():
846+
x_type = OPENVINO_DTYPES[config.floatx()]
847+
x = ov_opset.convert(x, x_type)
844848
return OpenVINOKerasTensor(ov_opset.log(x).output(0))
845849

846850

847851
def log10(x):
848-
raise NotImplementedError("`log10` is not supported with openvino backend")
852+
x = get_ov_output(x)
853+
x_type = x.get_element_type()
854+
if x_type.is_integral():
855+
x_type = OPENVINO_DTYPES[config.floatx()]
856+
x = ov_opset.convert(x, x_type)
857+
log_x = ov_opset.log(x).output(0)
858+
const_10 = ov_opset.constant(10, x_type).output(0)
859+
log_10 = ov_opset.log(const_10).output(0)
860+
result = ov_opset.divide(log_x, log_10).output(0)
861+
return OpenVINOKerasTensor(result)
849862

850863

851864
def log1p(x):

0 commit comments

Comments
 (0)