class_docstr: Maintains a pool of TuningProcesses to benchmark kernels in parallel
  across devices. By default, we create one TuningProcess per device and
  set the sub-process environment to make only that device visible.
class_docstr_tok: ["Maintains","a","pool","of","TuningProcesses","to","benchmark","kernels","in","parallel","across","devices",".","By","default",",","we","create","one","TuningProcess","per","device","and","set","the","sub-process","environment","to","make","only","that","device","visible","."]
docstr: Start the child processes.
docstr_tok: ["Start","the","child","processes","."]
code: def initialize(self) -> None:
      """
      Start the child processes.
      """
      assert (self.processes is None) == (self.executor is None)
      if self.processes is not None:
          return
  
      devices = self.get_device_list()
      log.debug("Sub-process autotune device list: %s", devices)
  
      # Launch the child processes and push a msg to "warm up"
      self.processes = queue.Queue()
      for device in devices:
          p = TuningProcess(device=device)
          p.initialize()
          p.put(Ping())
          self.processes.put(p)
  
      # Wait for the initialization to finish
      for p in self.processes.queue:
          assert isinstance(p.get(), Pong)
  
      # Use a thread pool to manage distributing work to the subprocesses.
      # Threads block on an available process, so it makes sense to match
      # the number of threads with the number of devices.
      self.executor = ThreadPoolExecutor(max_workers=len(devices))
  
      # Register the exit handler for the parent process so it will terminate
      # the child processes.
      global EXIT_HANDLER_REGISTERED
      if not EXIT_HANDLER_REGISTERED:
          EXIT_HANDLER_REGISTERED = True
          import atexit
  
          atexit.register(self.terminate)
  
imports: from __future__ import annotations
  import contextlib
  import dataclasses
  import functools
  import logging
  import os
  import queue
  import time
  import warnings
  from concurrent.futures import ThreadPoolExecutor
  from ctypes import byref, c_size_t, c_void_p
  from multiprocessing.process import BaseProcess
  from multiprocessing.queues import Queue
  from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, TYPE_CHECKING, Union
  import torch
  from torch import multiprocessing
  from torch._dynamo.testing import rand_strided
  from torch._inductor import ir
  from torch._inductor.codecache import CUDACodeCache, DLLWrapper, PyCodeCache
  from .None import config
  from .utils import do_bench
  from .virtualized import V
label_desc: Use image node_id 1 for calling the TuningProcessPool obj's underlying member method code with example usage: obj.initialize() without return types