Skip to content

Commit ba94752

Browse files
abhishek002002Orbax Authors
authored andcommitted
Synchronize OperationIdGenerator across processes in multihost tests.
PiperOrigin-RevId: 929817113
1 parent 58ca426 commit ba94752

3 files changed

Lines changed: 39 additions & 0 deletions

File tree

checkpoint/orbax/checkpoint/_src/futures/synchronization.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ def get_current_operation_id(cls) -> str:
6565
"""Returns the current operation id."""
6666
return str(cls._operation_id)
6767

68+
@classmethod
69+
def set_operation_id(cls, operation_id: int) -> None:
70+
"""Synchronizes the operation id counter to allow lagging ranks to catch up."""
71+
cls._operation_id = operation_id
72+
cls._operation_id_counter = itertools.count(operation_id + 1)
73+
6874

6975
class MultihostSynchronizedValue(Generic[_T]):
7076
"""A thread-safe value that is synchronized across all processes."""

checkpoint/orbax/checkpoint/_src/testing/oss/multiprocess_test.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from absl.testing import absltest
3333
import jax
3434
from jax import config
35+
from orbax.checkpoint._src.futures import synchronization
3536
from orbax.checkpoint._src.multihost import multihost
3637
import portpicker
3738

@@ -318,6 +319,15 @@ def setUp(self):
318319
f"multiprocess_test_ensure_all_processes_arrive_at_test_case_{self._testMethodName}",
319320
10000,
320321
)
322+
sync_key = f"sync_op_id_{self._testMethodName}"
323+
if jax.process_index() == 0:
324+
client.key_value_set(
325+
sync_key,
326+
synchronization.OperationIdGenerator.get_current_operation_id(),
327+
allow_overwrite=True,
328+
)
329+
max_op_id = int(client.blocking_key_value_get(sync_key, 10000))
330+
synchronization.OperationIdGenerator.set_operation_id(max_op_id)
321331

322332
def multiprocess_create_tempdir(self, name: str | None = None) -> str:
323333
"""Creates a temporary directory for the test."""

checkpoint/orbax/checkpoint/_src/testing/oss/run_tests.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
from absl import app
2323
from absl import flags
2424
from absl import logging
25+
import jax
26+
from orbax.checkpoint._src.futures import synchronization
27+
from orbax.checkpoint._src.multihost import multihost
2528
import pytest
2629
import yaml
2730

@@ -130,6 +133,26 @@ def main(argv: Sequence[str]) -> None:
130133

131134
logging.info('Running test: %s (found from %s)', test_path, test_file_yaml)
132135
try:
136+
try:
137+
client = multihost.get_jax_distributed_client()
138+
if client is not None:
139+
normalized_name = (
140+
test_file_yaml.replace('/', '_').replace(':', '_')
141+
)
142+
sync_key = f'sync_op_id_file_{normalized_name}'
143+
if jax.process_index() == 0:
144+
client.key_value_set(
145+
sync_key,
146+
synchronization.OperationIdGenerator.get_current_operation_id(),
147+
allow_overwrite=True,
148+
)
149+
max_op_id = int(client.blocking_key_value_get(sync_key, 10000))
150+
synchronization.OperationIdGenerator.set_operation_id(max_op_id)
151+
except Exception as sync_e: # pylint: disable=broad-exception-caught
152+
logging.warning(
153+
'Could not synchronize OperationIdGenerator for file: %s', sync_e
154+
)
155+
133156
exit_code = pytest.main([test_path])
134157
if exit_code == 0:
135158
results[test_file_yaml] = 'PASSED'

0 commit comments

Comments
 (0)