code: def run_test_locally(self, fn, device_option=None, **kwargs):
      # Queue for assertion errors on subprocesses
      queue = Queue()
  
      # Capture any exception thrown by the subprocess
      def run_fn(*args, **kwargs):
          try:
              if device_option is None:
                  fn(*args, **kwargs)
                  workspace.ResetWorkspace()
              else:
                  with core.DeviceScope(device_option):
                      fn(*args, **kwargs)
                      workspace.ResetWorkspace()
          except Exception as ex:
              queue.put(ex)
  
      # Start N processes in the background
      procs = []
      for i in range(kwargs["comm_size"]):
          kwargs["comm_rank"] = i
          proc = Process(target=run_fn, kwargs=kwargs)
          proc.start()
          procs.append(proc)
  
      # Test complete, join background processes
      while len(procs) > 0:
          proc = procs.pop(0)
          while proc.is_alive():
              proc.join(1)
  
              # Raise exception if we find any.
              # Note that the following is executed ALSO after
              # the last process was joined, so if ANY exception
              # was raised, it will be re-raised here.
              if not queue.empty():
                  raise queue.get()
  
imports: from multiprocessing import Process, Queue
  import numpy
  import os
  import shutil
  import tempfile
  import unittest
  import time
  from unittest.mock import Mock
  from hypothesis import assume, given, settings
  import hypothesis.strategies
  from caffe2.proto import caffe2_pb2
  from caffe2.python import brew, core, cnn, data_parallel_model, dyndep, model_helper, optimizer, rnn_cell, workspace
  from caffe2.python.test_util import TestCase
label_desc: Use image node_id 2 for calling the DataParallelModelTest obj's underlying member method code with example usage: obj.run_test_locally(fn, device_option) without return types