Abstraction for launching a helper process to benchmark kernels. Spawns the parent process and uses multiprocessing queues to send benchmark requests and return results.
| 76 | |
| 77 | @dataclasses.dataclass |
| 78 | class TuningProcess: |
| 79 | """ |
| 80 | Abstraction for launching a helper process to benchmark kernels. Spawns |
| 81 | the parent process and uses multiprocessing queues to send benchmark |
| 82 | requests and return results. |
| 83 | """ |
| 84 | |
| 85 | device: Optional[int] = None |
| 86 | process: Optional[BaseProcess] = None |
| 87 | request_queue: Optional[Queue[Any]] = None |
| 88 | response_queue: Optional[Queue[Any]] = None |
| 89 | |
| 90 | @staticmethod |
| 91 | def process_main( |
| 92 | request_queue: Queue[Any], |
| 93 | response_queue: Queue[Any], |
| 94 | ) -> None: |
| 95 | """ |
| 96 | Entry point for the child process. |
| 97 | """ |
| 98 | log.debug( |
| 99 | "Entering TuningProcess child. Visible devices = %s", |
| 100 | os.environ.get(CUDA_VISIBLE_DEVICES), |
| 101 | ) |
| 102 | try: |
| 103 | TuningProcess.workloop(request_queue, response_queue) |
| 104 | except Exception as ex: |
| 105 | log.exception("Exception in TuningProcess: %s", ex) |
| 106 | |
| 107 | @staticmethod |
| 108 | def workloop(request_queue: Queue[Any], response_queue: Queue[Any]) -> None: |
| 109 | """ |
| 110 | Work loop for the benchmarking subprocess. |
| 111 | """ |
| 112 | while True: |
| 113 | obj = request_queue.get() |
| 114 | |
| 115 | if obj is None: |
| 116 | break # None is a sentinel for the child to terminate |
| 117 | elif isinstance(obj, Ping): |
| 118 | response_queue.put(Pong()) |
| 119 | elif isinstance(obj, BenchmarkRequest): |
| 120 | response_queue.put(obj.benchmark()) |
| 121 | else: |
| 122 | raise RuntimeError(f"Invalid request type {type(obj)}") |
| 123 | |
| 124 | def valid(self) -> bool: |
| 125 | """ |
| 126 | True if the sub-process has been initialized. |
| 127 | """ |
| 128 | return ( |
| 129 | self.process is not None |
| 130 | and self.request_queue is not None |
| 131 | and self.response_queue is not None |
| 132 | ) |
| 133 | |
| 134 | def clear(self) -> None: |
| 135 | """ |
no outgoing calls
no test coverage detected
searching dependent graphs…