def test_popen_pool_executor(): import tvm pool = PopenPoolExecutor(max_workers=2, timeout=0.01) value1 = pool.submit(identity_after, 1, 100) value2 = pool.submit(terminate_self) value3 = pool.submit(identity_after, 3, 0) value4 = pool.submit(tvm.runtime.String, "xyz") with pytest.raises(TimeoutError): value1.result() with pytest.raises(ChildProcessError): value2.result() assert value3.result() == 3 value = value4.result() assert isinstance(value, tvm.runtime.String) assert value == "xyz" pool = PopenPoolExecutor(max_workers=4, timeout=None) values = pool.map_with_error_catching(lambda x: x, range(100)) for idx, val in enumerate(values): assert val.value == idx
def local_builder_build(inputs, timeout, n_parallel, build_func="default", verbose=1): """ Build function of LocalBuilder to build the MeasureInputs to runnable modules. Parameters ---------- inputs : List[MeasureInput] The MeasureInputs to be built. timeout : int The timeout limit (in second) for each build thread. This is used in a wrapper of the multiprocessing.Process.join(). n_parallel : int Number of threads used to build in parallel. build_func : str = 'default' The name of build function to process the built module. verbose: int = 1 Verbosity level. 0 for silent, 1 to output information during program building. Returns ------- res : List[BuildResult] The build results of these MeasureInputs. """ assert build_func == BuildFunc.name, ( "BuildFunc.name: " + BuildFunc.name + ", but args is: " + build_func ) executor = PopenPoolExecutor( n_parallel, timeout, reset_global_scope, (AutotvmGlobalScope.current,) ) tuple_res = executor.map_with_error_catching( local_build_worker, [ ( i.serialize(), BuildFunc.build_func, verbose, ) for i in inputs ], ) results = [] for res in tuple_res: if res.status == StatusKind.COMPLETE: results.append(BuildResult(*res.value)) elif res.status == StatusKind.TIMEOUT: if verbose >= 1: print(".T", end="", flush=True) # Build timeout results.append(BuildResult(None, [], MeasureErrorNo.BUILD_TIMEOUT, None, timeout)) elif res.status == StatusKind.EXCEPTION: if verbose >= 1: print(".E", end="", flush=True) # Build error results.append( BuildResult(None, [], MeasureErrorNo.COMPILE_HOST, repr(res.value), timeout) ) else: raise ValueError("Result status is not expected. Unreachable branch") return results
def local_builder_build(inputs, timeout, n_parallel, build_func="default", verbose=1): """ Build function of LocalBuilder to build the MeasureInputs to runnable modules. Parameters ---------- inputs : List[MeasureInput] The MeasureInputs to be built. timeout : int The timeout limit (in second) for each build thread. This is used in a wrapper of the multiprocessing.Process.join(). n_parallel : int Number of threads used to build in parallel. build_func : str = 'default' The name of build function to process the built module. verbose: int = 1 Verbosity level. 0 for silent, 1 to output information during program building. Returns ------- res : List[BuildResult] The build results of these MeasureInputs. """ executor = PopenPoolExecutor(n_parallel, timeout) tuple_res = executor.map_with_error_catching( local_build_worker, [ ( i.serialize(), build_func, timeout, verbose, ) for i in inputs ], ) results = [] for res in tuple_res: if res.status == StatusKind.COMPLETE: results.append(BuildResult(*res.value)) else: assert res.status == StatusKind.TIMEOUT if verbose >= 1: print(".T", end="", flush=True) # Build timeout results.append(BuildResult(None, [], MeasureErrorNo.BUILD_TIMEOUT, None, timeout)) return results
def rpc_runner_run( inputs, build_results, key, host, port, priority=1, n_parallel=1, timeout=10, number=3, repeat=1, min_repeat_ms=0, cooldown_interval=0.0, enable_cpu_cache_flush=False, verbose=1, ): """Run function of RPCRunner to test the performance of the input BuildResults. Parameters ---------- inputs : List[MeasureInput] The MeasureInputs to be measured. build_results : List[BuildResult] The BuildResults to be measured. key : str The key of the device registered in the RPC tracker. host : str The host address of the RPC Tracker. port : int The port of RPC Tracker. priority : int = 1 The priority of this run request, larger is more prior. n_parallel : int = 1 The number of tasks run in parallel. timeout : int = 10 The timeout limit (in second) for each run. This is used in a wrapper of the multiprocessing.Process.join(). number : int = 3 The number of times to run the generated code for taking average. We call these runs as one `repeat` of measurement. repeat : int = 1 The number of times to repeat the measurement. In total, the generated code will be run (1 + number x repeat) times, where the first "1" is warm up and will be discarded. The returned result contains `repeat` costs, each of which is an average of `number` costs. min_repeat_ms : int = 0 The minimum duration of one `repeat` in milliseconds. By default, one `repeat` contains `number` runs. If this parameter is set, the parameters `number` will be dynamically adjusted to meet the minimum duration requirement of one `repeat`. i.e., When the run time of one `repeat` falls below this time, the `number` parameter will be automatically increased. cooldown_interval : float = 0.0 The cool down interval between two measurements in seconds. enable_cpu_cache_flush: bool = False Whether to flush cache on CPU between repeated measurements. Flushing cache can make the measured latency of one operator closer to its actual latency during end-to-end inference. To make this option effective, the argument `number` should also be set to 1. This is only has effect on CPU task. verbose: int = 1 Verbosity level. 0 for silent, 1 to output information during program measuring. Returns ------- res : List[MeasureResult] The measure results of these MeasureInputs. """ assert len(inputs) == len( build_results), "Measure input size should be equal to build results" # This pool is not doing computationally intensive work, so we can use threads executor = PopenPoolExecutor(n_parallel) tuple_res = executor.map_with_error_catching( _rpc_run_worker, [( inp.serialize(), build_res, prepare_runner_args(inp, build_res), key, host, port, priority, timeout, number, repeat, min_repeat_ms, cooldown_interval, enable_cpu_cache_flush, verbose, ) for inp, build_res in zip(inputs, build_results)], ) results = [] for i, res in enumerate(tuple_res): if res.status == StatusKind.COMPLETE: results.append(MeasureResult(*res.value)) else: assert res.status == StatusKind.TIMEOUT if verbose >= 1: print("*T", end="") # Run timeout build_res = build_results[i] results.append( MeasureResult( (MAX_FLOAT, ), MeasureErrorNo.RUN_TIMEOUT, None, build_res.time_cost + timeout, time.time(), )) if verbose >= 1: print("") return results