Skip to content

Commit 6e97f6e

Browse files
Vinti Pandeymeta-codesync[bot]
authored andcommitted
Fix broken tests in torchsnapshot
Summary: --- The test `test_read_sharded_tensor` was failing with `FileNotFoundError` because each of the 4 distributed worker processes was creating its own independent temporary directory via `tempfile.TemporaryDirectory()`. When rank 0 created a snapshot in its temporary directory, other ranks would try to read from their own (different) temporary directories, which didn't contain the snapshot files. Fixed by implementing a proper distributed temporary directory pattern: 1. Rank 0 creates the temp directory using `tempfile.mkdtemp()` 2. The path is broadcast to all ranks using `dist.broadcast_object_list()` 3. All ranks use the same shared path for snapshot operations 4. Proper cleanup with a `dist.barrier()` before rank 0 removes the temp directory to prevent race conditions --- test_dict_store was failing due to mismatched regex. fixing the regex fixed test Reviewed By: galrotem Differential Revision: D89585177 fbshipit-source-id: 3ee6c7c283d8ddc2cd539843931a052fa51c1933
1 parent df45917 commit 6e97f6e

2 files changed

Lines changed: 29 additions & 13 deletions

File tree

tests/test_dist_store.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,13 @@ def _test_linear_barrier_timeout() -> None:
7878
# should timeout in .arrive() and other non-leader ranks should timeout
7979
# in .depart().
8080
if rank == 0:
81-
with tc.assertRaisesRegex(RuntimeError, "Socket Timeout"):
81+
with tc.assertRaisesRegex(RuntimeError, "timeout"):
8282
barrier.arrive(timeout=timedelta(seconds=5))
8383
elif rank == 1:
8484
pass
8585
else:
8686
barrier.arrive(timeout=timedelta(seconds=5))
87-
with tc.assertRaisesRegex(RuntimeError, "Socket Timeout"):
87+
with tc.assertRaisesRegex(RuntimeError, "timeout"):
8888
barrier.depart(timeout=timedelta(seconds=5))
8989

9090
dist.barrier()
@@ -102,7 +102,7 @@ def _test_linear_barrier_timeout() -> None:
102102
pass
103103
else:
104104
barrier.arrive(timeout=timedelta(seconds=5))
105-
with tc.assertRaisesRegex(RuntimeError, "Socket Timeout"):
105+
with tc.assertRaisesRegex(RuntimeError, "timeout"):
106106
barrier.depart(timeout=timedelta(seconds=5))
107107

108108
dist.barrier()

tests/test_read_object.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,24 +64,40 @@ def _test_read_sharded_tensor() -> None:
6464
for foo_shard, bar_shard in zip(foo.local_shards(), bar.local_shards()):
6565
tc.assertFalse(torch.allclose(foo_shard.tensor, bar_shard.tensor))
6666

67-
with tempfile.TemporaryDirectory() as path:
67+
# Create temp directory on rank 0 and broadcast path to all ranks
68+
if dist.get_rank() == 0:
69+
path = tempfile.mkdtemp()
70+
else:
71+
path = ""
72+
path_list = [path]
73+
dist.broadcast_object_list(path_list, src=0)
74+
path = path_list[0]
75+
76+
try:
6877
snapshot = torchsnapshot.Snapshot.take(
6978
path=path, app_state={"state": torchsnapshot.StateDict(foo=foo)}
7079
)
7180
snapshot.read_object("0/state/foo", obj_out=bar)
7281
baz = snapshot.read_object("0/state/foo")
7382

74-
for foo_shard, bar_shard in zip(foo.local_shards(), bar.local_shards()):
75-
tc.assertTrue(torch.allclose(foo_shard.tensor, bar_shard.tensor))
83+
for foo_shard, bar_shard in zip(foo.local_shards(), bar.local_shards()):
84+
tc.assertTrue(torch.allclose(foo_shard.tensor, bar_shard.tensor))
7685

77-
tc.assertEqual(baz.shape, torch.Size([20_000, 128]))
86+
tc.assertEqual(baz.shape, torch.Size([20_000, 128]))
7887

79-
gathered_foo_tensor = torch.empty(20_000, 128)
80-
if dist.get_rank() == 0:
81-
foo.gather(dst=0, out=gathered_foo_tensor)
82-
tc.assertTrue(torch.allclose(baz, gathered_foo_tensor))
83-
else:
84-
foo.gather(dst=0, out=None)
88+
gathered_foo_tensor = torch.empty(20_000, 128)
89+
if dist.get_rank() == 0:
90+
foo.gather(dst=0, out=gathered_foo_tensor)
91+
tc.assertTrue(torch.allclose(baz, gathered_foo_tensor))
92+
else:
93+
foo.gather(dst=0, out=None)
94+
finally:
95+
# Clean up the temp directory on rank 0
96+
dist.barrier()
97+
if dist.get_rank() == 0:
98+
import shutil
99+
100+
shutil.rmtree(path, ignore_errors=True)
85101

86102
def test_read_sharded_tensor(self) -> None:
87103
lc = get_pet_launch_config(nproc=4)

0 commit comments

Comments
 (0)