code: def process_in_parallel(
      tag, total_range_size, binary, output_dir, opts=""
  ):
      """Run the specified binary cfg.NUM_GPUS times in parallel, each time as a
      subprocess that uses one GPU. The binary must accept the command line
      arguments `--range {start} {end}` that specify a data processing range.
      """
      # Snapshot the current cfg state in order to pass to the inference
      # subprocesses
      cfg_file = os.path.join(
          output_dir, "{}_range_config.yaml".format(tag)
      )
      with open(cfg_file, "w") as f:
          yaml.dump(cfg, stream=f)
      subprocess_env = os.environ.copy()
      processes = []
      subinds = np.array_split(range(total_range_size), cfg.NUM_GPUS)
      # Determine GPUs to use
      cuda_visible_devices = os.environ.get("CUDA_VISIBLE_DEVICES")
      if cuda_visible_devices:
          gpu_inds = map(int, cuda_visible_devices.split(","))
          assert (
              -1 not in gpu_inds
          ), "Hiding GPU indices using the '-1' index is not supported"
      else:
          gpu_inds = range(cfg.NUM_GPUS)
      # Run the binary in cfg.NUM_GPUS subprocesses
      for i, gpu_ind in enumerate(gpu_inds):
          start = subinds[i][0]
          end = subinds[i][-1] + 1
          subprocess_env["CUDA_VISIBLE_DEVICES"] = str(gpu_ind)
          cmd = "{binary} --range {start} {end} --cfg {cfg_file} NUM_GPUS 1 {opts}"
          cmd = cmd.format(
              binary=shlex_quote(binary),
              start=int(start),
              end=int(end),
              cfg_file=shlex_quote(cfg_file),
              opts=" ".join([shlex_quote(opt) for opt in opts]),
          )
          logger.info("{} range command {}: {}".format(tag, i, cmd))
          if i == 0:
              subprocess_stdout = subprocess.PIPE
          else:
              filename = os.path.join(
                  output_dir,
                  "%s_range_%s_%s.stdout" % (tag, start, end),
              )
              subprocess_stdout = open(
                  filename, "w"
              )  # NOQA (close below)
          p = subprocess.Popen(
              cmd,
              shell=True,
              env=subprocess_env,
              stdout=subprocess_stdout,
              stderr=subprocess.STDOUT,
              bufsize=1,
          )
          processes.append((i, p, start, end, subprocess_stdout))
      # Log output from inference processes and collate their results
      outputs = []
      for i, p, start, end, subprocess_stdout in processes:
          log_subprocess_output(i, p, output_dir, tag, start, end)
          if isinstance(
              subprocess_stdout, file
          ):  # NOQA (Python 2 for now)
              subprocess_stdout.close()
          range_file = os.path.join(
              output_dir, "%s_range_%s_%s.pkl" % (tag, start, end)
          )
          range_data = pickle.load(open(range_file))
          outputs.append(range_data)
      return outputs
  
file_path: dense-pose/detectron/utils/subprocess.py
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from __future__ import unicode_literals
  import os
  import yaml
  import numpy
  import subprocess
  import cPickle
  from six.moves import shlex_quote
  from detectron.core.config import cfg
  import logging
label_desc: Use image node_id 1 for calling a global function with example usage: process_in_parallel(tag, total_range_size, binary, output_dir, opts) and returns: outputs