code: def criterion_parallel_apply(
      module, inputs, targets, kwargs_tup=None, sync=False
  ):
      """Data Parallel Criterion"""
      if kwargs_tup:
          assert len(inputs) == len(kwargs_tup)
      else:
          kwargs_tup = ({},) * len(inputs)
  
      lock = threading.Lock()
      results = {}
  
      def _worker(
          i,
          module,
          input,
          target,
          kwargs,
          results,
          is_recording,
          is_training,
          lock,
      ):
          try:
              if is_recording:
                  with autograd.record(is_training):
                      output = module(*(input + target), **kwargs)
                      output.wait_to_read()
              else:
                  output = module(*(input + target), **kwargs)
                  output.wait_to_read()
              with lock:
                  results[i] = output
          except Exception as e:
              with lock:
                  results[i] = e
  
      is_training = bool(autograd.is_training())
      is_recording = autograd.is_recording()
  
      threads = [
          threading.Thread(
              target=_worker,
              args=(
                  i,
                  module,
                  input,
                  target,
                  kwargs,
                  results,
                  is_recording,
                  is_training,
                  lock,
              ),
          )
          for i, (input, target, kwargs) in enumerate(
              zip(inputs, targets, kwargs_tup)
          )
      ]
  
      if sync:
          for thread in threads:
              thread.start()
          for thread in threads:
              thread.join()
          outputs = []
          for i in range(len(inputs)):
              output = results[i]
              if isinstance(output, Exception):
                  raise output
              outputs.append(output)
          return tuple(outputs)
      else:
          outputs = [
              module(*(input + target), **kwargs)
              for (input, target, kwargs) in zip(
                  inputs, targets, kwargs_tup
              )
          ]
          return tuple(outputs)
  
imports: import threading
  from mxnet import autograd
  from mxnet.gluon.utils import split_and_load
  from mxnet.ndarray import NDArray
label_desc: Use image node_id 4 for calling a global function with example usage: criterion_parallel_apply(module, inputs, targets, kwargs_tup, sync) and returns: tuple, tuple