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

Class ThreadContainer

monai/utils/jupyter_utils.py:262–372  ·  view source on GitHub ↗

Contains a running `Engine` object within a separate thread from main thread in a Jupyter notebook. This allows an engine to begin a run in the background and allow the starting notebook cell to complete. A user can thus start a run and then navigate away from the notebook without conce

Source from the content-addressed store, hash-verified

260
261
262class ThreadContainer(Thread):
263 """
264 Contains a running `Engine` object within a separate thread from main thread in a Jupyter notebook. This
265 allows an engine to begin a run in the background and allow the starting notebook cell to complete. A
266 user can thus start a run and then navigate away from the notebook without concern for loosing connection
267 with the running cell. All output is acquired through methods which synchronize with the running engine
268 using an internal `lock` member, acquiring this lock allows the engine to be inspected while it's prevented
269 from starting the next iteration.
270
271 Args:
272 engine: wrapped `Engine` object, when the container is started its `run` method is called
273 loss_transform: callable to convert an output dict into a single numeric value
274 metric_transform: callable to convert a named metric value into a single numeric value
275 status_format: format string for status key-value pairs.
276 """
277
278 def __init__(
279 self,
280 engine: Engine,
281 loss_transform: Callable = _get_loss_from_output,
282 metric_transform: Callable = lambda name, value: value,
283 status_format: str = "{}: {:.4}",
284 ):
285 super().__init__()
286 self.lock = RLock()
287 self.engine = engine
288 self._status_dict: dict[str, Any] = {}
289 self.loss_transform = loss_transform
290 self.metric_transform = metric_transform
291 self.fig: plt.Figure | None = None
292 self.status_format = status_format
293
294 self.engine.add_event_handler(Events.ITERATION_COMPLETED, self._update_status)
295
296 def run(self):
297 """Calls the `run` method of the wrapped engine."""
298 self.engine.run()
299
300 def stop(self):
301 """Stop the engine and join the thread."""
302 self.engine.terminate()
303 self.join()
304
305 def _update_status(self):
306 """Called as an event, updates the internal status dict at the end of iterations."""
307 with self.lock:
308 state = self.engine.state
309 stats: dict[str, Any] = {
310 StatusMembers.EPOCHS.value: 0,
311 StatusMembers.ITERS.value: 0,
312 StatusMembers.LOSS.value: float("nan"),
313 }
314
315 if state is not None:
316 if state.max_epochs is not None and state.max_epochs >= 1:
317 epoch = f"{state.epoch}/{state.max_epochs}"
318 else:
319 epoch = str(state.epoch)

Callers 2

test_containerMethod · 0.90
test_plotMethod · 0.90

Calls

no outgoing calls

Tested by 2

test_containerMethod · 0.72
test_plotMethod · 0.72

Used in the wild real call sites across dependent graphs

searching dependent graphs…