code: def _criterion_parallel_apply(
      modules, inputs, targets, kwargs_tup=None, devices=None
  ):
      assert len(modules) == len(inputs)
      assert len(targets) == len(inputs)
      if kwargs_tup:
          assert len(modules) == len(kwargs_tup)
      else:
          kwargs_tup = ({},) * len(modules)
      if devices is not None:
          assert len(modules) == len(devices)
      else:
          devices = [None] * len(modules)
  
      lock = threading.Lock()
      results = {}
      if torch_ver != "0.3":
          grad_enabled = torch.is_grad_enabled()
  
      def _worker(i, module, input, target, kwargs, device=None):
          if torch_ver != "0.3":
              torch.set_grad_enabled(grad_enabled)
          if device is None:
              device = get_a_var(input).get_device()
          try:
              if not isinstance(input, tuple):
                  input = (input,)
              with torch.cuda.device(device):
                  output = module(*(input + target), **kwargs)
              with lock:
                  results[i] = output
          except Exception as e:
              with lock:
                  results[i] = e
  
      if len(modules) > 1:
          threads = [
              threading.Thread(
                  target=_worker,
                  args=(i, module, input, target, kwargs, device),
              )
              for i, (
                  module,
                  input,
                  target,
                  kwargs,
                  device,
              ) in enumerate(
                  zip(modules, inputs, targets, kwargs_tup, devices)
              )
          ]
  
          for thread in threads:
              thread.start()
          for thread in threads:
              thread.join()
      else:
          _worker(0, modules[0], inputs[0], kwargs_tup[0], devices[0])
  
      outputs = []
      for i in range(len(inputs)):
          output = results[i]
          if isinstance(output, Exception):
              raise output
          outputs.append(output)
      return outputs
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import functools
  import threading
  import torch
  import torch.cuda.comm
  from torch.autograd import Variable, Function
  from torch.nn.parallel.data_parallel import DataParallel
  from torch.nn.parallel.parallel_apply import get_a_var
  from torch.nn.parallel._functions import ReduceAddCoalesced, Broadcast
label_desc: Use image node_id 2 for calling a global function with example usage: _criterion_parallel_apply(modules, inputs, targets, kwargs_tup, devices) and returns: outputs