MCPcopy Create free account
hub / github.com/Project-MONAI/MONAI / ThreadDataLoader

Class ThreadDataLoader

monai/data/thread_buffer.py:137–199  ·  view source on GitHub ↗

Subclass of `DataLoader` using a `ThreadBuffer` object to implement `__iter__` method asynchronously. This will iterate over data from the loader as expected however the data is generated on a separate thread. Use this class where a `DataLoader` instance is required and not just an iter

Source from the content-addressed store, hash-verified

135
136
137class ThreadDataLoader(DataLoader):
138 """
139 Subclass of `DataLoader` using a `ThreadBuffer` object to implement `__iter__` method asynchronously. This will
140 iterate over data from the loader as expected however the data is generated on a separate thread. Use this class
141 where a `DataLoader` instance is required and not just an iterable object.
142
143 The default behaviour with `repeats` set to 1 is to yield each batch as it is generated, however with a higher
144 value the generated batch is yielded that many times while underlying dataset asynchronously generates the next.
145 Typically not all relevant information is learned from a batch in a single iteration so training multiple times
146 on the same batch will still produce good training with minimal short-term overfitting while allowing a slow batch
147 generation process more time to produce a result. This duplication is done by simply yielding the same object many
148 times and not by regenerating the data.
149
150 Another typical usage is to accelerate light-weight preprocessing (usually cached all the deterministic transforms
151 and no IO operations), because it leverages the separate thread to execute preprocessing to avoid unnecessary IPC
152 between multiple workers of DataLoader. And as CUDA may not work well with the multi-processing of DataLoader,
153 `ThreadDataLoader` can be useful for GPU transforms. For more details:
154 https://github.com/Project-MONAI/tutorials/blob/master/acceleration/fast_model_training_guide.md.
155
156 The `use_thread_workers` will cause workers to be created as threads rather than processes although everything else
157 in terms of how the class works is unchanged. This allows multiple workers to be used in Windows for example, or in
158 any other situation where thread semantics is desired. Please note that some MONAI components like several datasets
159 and random transforms are not thread-safe and can't work as expected with `thread workers`, need to check all the
160 preprocessing components carefully before enabling `use_thread_workers`.
161
162 See:
163 * Fischetti et al. "Faster SGD training by minibatch persistency." ArXiv (2018) https://arxiv.org/abs/1806.07353
164 * Dami et al., "Faster Neural Network Training with Data Echoing" ArXiv (2020) https://arxiv.org/abs/1907.05550
165 * Ramezani et al. "GCN meets GPU: Decoupling "When to Sample" from "How to Sample"." NeurIPS (2020).
166 https://proceedings.neurips.cc/paper/2020/file/d714d2c5a796d5814c565d78dd16188d-Paper.pdf
167
168 Args:
169 dataset: input dataset.
170 buffer_size: number of items to buffer from the data source.
171 buffer_timeout: time to wait for an item from the buffer, or to wait while the buffer is full when adding items.
172 repeats: number of times to yield the same batch.
173 use_thread_workers: if True and num_workers > 0 the workers are created as threads instead of processes
174 kwargs: other arguments for `DataLoader` except for `dataset`.
175
176 """
177
178 def __init__(
179 self,
180 dataset: Dataset,
181 buffer_size: int = 1,
182 buffer_timeout: float = 0.01,
183 repeats: int = 1,
184 use_thread_workers: bool = False,
185 **kwargs,
186 ):
187 # if workers should be threads, create a new multiprocessing context with the process and queue types
188 # substituted with the shim types given above
189 if use_thread_workers and kwargs.get("num_workers", 0) > 0:
190 kwargs["multiprocessing_context"] = _ProcessThreadContext()
191 kwargs["persistent_workers"] = False
192
193 super().__init__(dataset, **kwargs)
194 self.buffer_size = buffer_size

Callers 7

test_train_timingMethod · 0.90
test_dataloaderMethod · 0.90
test_deterministicMethod · 0.90
test_thread_workersMethod · 0.90
test_valueMethod · 0.90

Calls

no outgoing calls

Tested by 7

test_train_timingMethod · 0.72
test_dataloaderMethod · 0.72
test_deterministicMethod · 0.72
test_thread_workersMethod · 0.72
test_valueMethod · 0.72

Used in the wild real call sites across dependent graphs

searching dependent graphs…