Skip to content

Commit d452bd6

Browse files
committed
Merge branch 'further_cicd_cleanup' of github.com:ericspod/MONAI into further_cicd_cleanup
2 parents 75e7861 + d3ac4e4 commit d452bd6

2 files changed

Lines changed: 42 additions & 55 deletions

File tree

monai/data/dataset.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -609,24 +609,26 @@ def __init__(
609609
# the cache is created without multi-threading
610610
self._read_env: Any | None = None
611611
# this runs on the primary thread/process
612-
self._fill_cache_start_reader(show_progress=self.progress)
613-
print(f"Accessing lmdb file: {self.db_file.absolute()}.")
612+
read_env = self._fill_cache_start_reader(show_progress=self.progress)
613+
read_env.close()
614614

615615
def set_data(self, data: Sequence):
616616
"""
617617
Set the input data and delete all the out-dated cache content.
618-
619618
"""
619+
self.close()
620620
super().set_data(data=data)
621621
self._read_env = self._fill_cache_start_reader(show_progress=self.progress)
622622

623623
def _safe_serialize(self, val):
624+
"""Serialize the tensor/array `val` using the pickle protocol, and return its bytes object."""
624625
out = BytesIO()
625626
torch.save(convert_to_tensor(val), out, pickle_protocol=self.pickle_protocol)
626627
out.seek(0)
627628
return out.read()
628629

629630
def _safe_deserialize(self, val):
631+
"""Load the object from the given bytes data, this must be loadable as weights only using `torch.load`."""
630632
return torch.load(BytesIO(val), map_location="cpu", weights_only=True)
631633

632634
def _fill_cache_start_reader(self, show_progress=True):
@@ -687,10 +689,7 @@ def _fill_cache_start_reader(self, show_progress=True):
687689
return lmdb.open(path=f"{self.db_file}", subdir=False, **self.lmdb_kwargs)
688690

689691
def _cachecheck(self, item_transformed):
690-
"""
691-
if the item is not found in the lmdb file, resolves to the persistent cache default behaviour.
692-
693-
"""
692+
"""If the item is not found in the lmdb file, resolves to the persistent cache default behaviour."""
694693
if self._read_env is None:
695694
# this runs on multiple processes, each one should have its own env.
696695
self._read_env = self._fill_cache_start_reader(show_progress=False)
@@ -715,7 +714,14 @@ def info(self):
715714
out = dict(self._read_env.info())
716715
out["size"] = len(self.data)
717716
out["filename"] = f"{self.db_file.absolute()}"
717+
self.close()
718718
return out
719+
720+
def close(self):
721+
"""Close the read environment and set it to None, if it exists."""
722+
if self._read_env:
723+
self._read_env.close()
724+
self._read_env = None
719725

720726

721727
class CacheDataset(Dataset):

tests/data/test_lmdbdataset.py

Lines changed: 29 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import numpy as np
2020
from parameterized import parameterized
2121

22-
from monai.data import LMDBDataset, json_hashing
22+
from monai.data import LMDBDataset, json_hashing, pickle_hashing
2323
from monai.transforms import Compose, LoadImaged, SimulateDelayd, Transform
2424
from tests.test_utils import skip_if_windows
2525

@@ -76,7 +76,7 @@
7676
SimulateDelayd(keys=["image", "label", "extra"], delay_time=[1e-7, 1e-6, 1e-5]),
7777
],
7878
(128, 128, 128),
79-
{"db_name": "testdb", "lmdb_kwargs": {"map_size": 2 * 1024**2}},
79+
{"db_name": "testdb", "lmdb_kwargs": {"map_size": 50 * 1024**2}},
8080
]
8181

8282

@@ -91,36 +91,16 @@ def __call__(self, data):
9191

9292
@skip_if_windows
9393
class TestLMDBDataset(unittest.TestCase):
94-
def test_cache(self):
95-
"""testing no inplace change to the hashed item"""
94+
@parameterized.expand([(pickle_hashing,), (json_hashing,)])
95+
def test_cache(self, hash_func):
96+
"""Testing no inplace change to the hashed item."""
9697
items = [[list(range(i))] for i in range(5)]
9798

9899
with tempfile.TemporaryDirectory() as tempdir:
99-
ds = LMDBDataset(items, transform=_InplaceXform(), cache_dir=tempdir, lmdb_kwargs={"map_size": 10 * 1024})
100-
self.assertEqual(items, [[[]], [[0]], [[0, 1]], [[0, 1, 2]], [[0, 1, 2, 3]]])
101-
ds1 = LMDBDataset(items, transform=_InplaceXform(), cache_dir=tempdir, lmdb_kwargs={"map_size": 10 * 1024})
102-
self.assertEqual(list(ds1), list(ds))
103-
self.assertEqual(items, [[[]], [[0]], [[0, 1]], [[0, 1, 2]], [[0, 1, 2, 3]]])
104-
105-
ds = LMDBDataset(
106-
items,
107-
transform=_InplaceXform(),
108-
cache_dir=tempdir,
109-
lmdb_kwargs={"map_size": 10 * 1024},
110-
hash_func=json_hashing,
111-
)
112-
self.assertEqual(items, [[[]], [[0]], [[0, 1]], [[0, 1, 2]], [[0, 1, 2, 3]]])
113-
ds1 = LMDBDataset(
114-
items,
115-
transform=_InplaceXform(),
116-
cache_dir=tempdir,
117-
lmdb_kwargs={"map_size": 10 * 1024},
118-
hash_func=json_hashing,
119-
)
120-
self.assertEqual(list(ds1), list(ds))
121-
self.assertEqual(items, [[[]], [[0]], [[0, 1]], [[0, 1, 2]], [[0, 1, 2, 3]]])
122-
123-
self.assertTrue(isinstance(ds1.info(), dict))
100+
ds = LMDBDataset(items, transform=_InplaceXform(), cache_dir=tempdir, hash_func=hash_func, progress=False)
101+
self.assertEqual(items, [[[]], [[0]], [[0, 1]], [[0, 1, 2]], [[0, 1, 2, 3]]], "Input dataset mutated.")
102+
self.assertNotEqual(items, list(ds), "Output data unmodified by transform.")
103+
self.assertIsInstance(ds.info(), dict)
124104

125105
@parameterized.expand([TEST_CASE_1, TEST_CASE_2, TEST_CASE_3, TEST_CASE_4, TEST_CASE_5, TEST_CASE_6, TEST_CASE_7])
126106
def test_shape(self, transform, expected_shape, kwargs=None):
@@ -146,16 +126,30 @@ def test_shape(self, transform, expected_shape, kwargs=None):
146126
},
147127
]
148128

129+
# update the data to cache
130+
test_data_new = [
131+
{
132+
"image": os.path.join(tempdir, "test_image1_new.nii.gz"),
133+
"label": os.path.join(tempdir, "test_label1_new.nii.gz"),
134+
"extra": os.path.join(tempdir, "test_extra1_new.nii.gz"),
135+
},
136+
{
137+
"image": os.path.join(tempdir, "test_image2_new.nii.gz"),
138+
"label": os.path.join(tempdir, "test_label2_new.nii.gz"),
139+
"extra": os.path.join(tempdir, "test_extra2_new.nii.gz"),
140+
},
141+
]
142+
149143
cache_dir = os.path.join(os.path.join(tempdir, "cache"), "data")
150-
dataset_precached = LMDBDataset(
151-
data=test_data, transform=transform, progress=False, cache_dir=cache_dir, **kwargs
152-
)
144+
ds_args = dict(data=test_data, transform=transform, progress=False, cache_dir=cache_dir, **kwargs)
145+
146+
dataset_precached = LMDBDataset(**ds_args)
153147
data1_precached = dataset_precached[0]
154148
data2_precached = dataset_precached[1]
155149

156-
dataset_postcached = LMDBDataset(
157-
data=test_data, transform=transform, progress=False, cache_dir=cache_dir, **kwargs
158-
)
150+
dataset_precached.close()
151+
152+
dataset_postcached = LMDBDataset(**ds_args)
159153
data1_postcached = dataset_postcached[0]
160154
data2_postcached = dataset_postcached[1]
161155

@@ -179,19 +173,6 @@ def test_shape(self, transform, expected_shape, kwargs=None):
179173
self.assertTupleEqual(data2_postcached["label"].shape, expected_shape)
180174
self.assertTupleEqual(data2_postcached["extra"].shape, expected_shape)
181175

182-
# update the data to cache
183-
test_data_new = [
184-
{
185-
"image": os.path.join(tempdir, "test_image1_new.nii.gz"),
186-
"label": os.path.join(tempdir, "test_label1_new.nii.gz"),
187-
"extra": os.path.join(tempdir, "test_extra1_new.nii.gz"),
188-
},
189-
{
190-
"image": os.path.join(tempdir, "test_image2_new.nii.gz"),
191-
"label": os.path.join(tempdir, "test_label2_new.nii.gz"),
192-
"extra": os.path.join(tempdir, "test_extra2_new.nii.gz"),
193-
},
194-
]
195176
# test new exchanged cache content
196177
if transform is None:
197178
dataset_postcached.set_data(data=test_data_new)

0 commit comments

Comments
 (0)