Skip to content

Commit 329e137

Browse files
committed
Fix GridPatchDataset cache edge cases (#9100)
Signed-off-by: Jeffrey Qiu <77599736+hongjie-qiu@users.noreply.github.com>
1 parent d1306f6 commit 329e137

2 files changed

Lines changed: 32 additions & 7 deletions

File tree

monai/data/grid_dataset.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,11 @@ def set_data(self, data: Sequence) -> None:
279279
self.cache_num = min(int(self.set_num), int(len(mapping) * self.set_rate), len(mapping))
280280
self._hash_keys = list(mapping)[: self.cache_num]
281281
indices = list(mapping.values())[: self.cache_num]
282-
self._cache, self._cache_other = zip(*self._fill_cache(indices)) # type: ignore
282+
cache_items = self._fill_cache(indices)
283+
if cache_items:
284+
self._cache, self._cache_other = zip(*cache_items) # type: ignore
285+
else:
286+
self._cache, self._cache_other = [], []
283287

284288
def _fill_cache(self, indices=None) -> list:
285289
"""
@@ -339,12 +343,9 @@ def _generate_patches(self, src, **apply_args):
339343

340344
def __iter__(self):
341345
if self.cache:
342-
cache_index = None
343346
for image in super().__iter__():
344347
key = self.hash_func(image)
345-
if key in self._hash_keys:
346-
# if existing in cache, try to get the index in cache
347-
cache_index = self._hash_keys.index(key)
348+
cache_index = self._hash_keys.index(key) if key in self._hash_keys else None
348349
if cache_index is None:
349350
# no cache for this index, execute all the transforms directly
350351
yield from self._generate_patches(self.patch_iter(image))
@@ -354,11 +355,11 @@ def __iter__(self):
354355
"Cache buffer is not initialized, please call `set_data()` before epoch begins."
355356
)
356357
data = self._cache[cache_index]
357-
other = self._cache_other[cache_index]
358358

359359
# load data from cache and execute from the first random transform
360360
data = deepcopy(data) if self.copy_cache else data
361-
yield from self._generate_patches(zip(data, other), start=self.first_random)
361+
cached_patches = zip(data, self._cache_other[cache_index]) if self.with_coordinates else zip(data)
362+
yield from self._generate_patches(cached_patches, start=self.first_random)
362363
else:
363364
for image in super().__iter__():
364365
yield from self._generate_patches(self.patch_iter(image))

tests/data/test_grid_dataset.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ def test_set_data(self):
200200
np.testing.assert_equal(tuple(item[0].shape), (2, 1, 2, 2))
201201
np.testing.assert_allclose(item[0], np.array([[[[81, 91], [121, 131]]], [[[101, 111], [141, 151]]]]), rtol=1e-4)
202202
np.testing.assert_allclose(item[1], np.array([[[0, 1], [2, 4], [0, 2]], [[0, 1], [2, 4], [2, 4]]]), rtol=1e-5)
203+
203204
# simulate another epoch, the cache content should not be modified
204205
for item in DataLoader(dataset, batch_size=2, shuffle=False, num_workers=num_workers):
205206
np.testing.assert_equal(tuple(item[0].shape), (2, 1, 2, 2))
@@ -217,6 +218,29 @@ def test_set_data(self):
217218
)
218219
np.testing.assert_allclose(item[1], np.array([[[0, 1], [2, 4], [0, 2]], [[0, 1], [2, 4], [2, 4]]]), rtol=1e-5)
219220

221+
def test_partial_cache_preserves_uncached_items(self):
222+
dataset = GridPatchDataset(
223+
data=[[1], [2]], patch_iter=identity_generator, cache=True, cache_rate=0.5, progress=False
224+
)
225+
226+
self.assertEqual(list(dataset), [(1, 0), (2, 0)])
227+
228+
def test_cache_without_coordinates(self):
229+
dataset = GridPatchDataset(
230+
data=[[1, 2]], patch_iter=identity_generator, with_coordinates=False, cache=True, progress=False
231+
)
232+
233+
self.assertEqual(list(dataset), [1, 2])
234+
235+
def test_zero_sized_cache(self):
236+
for cache_kwargs in ({"cache_rate": 0.0}, {"cache_num": 0}):
237+
with self.subTest(**cache_kwargs):
238+
dataset = GridPatchDataset(
239+
data=[[1], [2]], patch_iter=identity_generator, cache=True, progress=False, **cache_kwargs
240+
)
241+
242+
self.assertEqual(list(dataset), [(1, 0), (2, 0)])
243+
220244

221245
if __name__ == "__main__":
222246
unittest.main()

0 commit comments

Comments
 (0)