예제 #1
0
 def __init__(
     self,
     host,
     port=9091,
     port_end=9199,
     web_port=0,
     timeout_client=600,
     timeout_server=600,
     tracker_addr=None,
     index_page=None,
     resource_files=None,
 ):
     self.proc = PopenWorker()
     # send the function
     self.proc.send(
         _popen_start_proxy_server,
         [
             host,
             port,
             port_end,
             web_port,
             timeout_client,
             timeout_server,
             tracker_addr,
             index_page,
             resource_files,
         ],
     )
     # receive the port
     self.port = self.proc.recv()
     self.host = host
예제 #2
0
def test_popen_initializer():
    initargs = [1, 2, 3]
    proc = PopenWorker(initializer=initializer, initargs=initargs)
    proc.send(after_initializer)
    test_global_state_1, test_global_state_2, test_global_state_3 = proc.recv()
    assert test_global_state_1 == initargs[0]
    assert test_global_state_2 == initargs[1]
    assert test_global_state_3 == initargs[2]
예제 #3
0
def test_popen_worker_reuses():
    proc = PopenWorker(maximum_uses=None)

    proc.send(os.getpid)
    initial_pid = proc.recv()

    proc.send(os.getpid)
    assert proc.recv() == initial_pid
예제 #4
0
def test_popen_worker_recycles():
    proc = PopenWorker(maximum_uses=2)

    proc.send(os.getpid)
    initial_pid = proc.recv()
    assert psutil.pid_exists(initial_pid)

    proc.send(os.getpid)
    assert proc.recv() == initial_pid
    assert psutil.pid_exists(initial_pid)

    proc.send(os.getpid)
    assert proc.recv() != initial_pid
    assert not psutil.pid_exists(initial_pid)
예제 #5
0
def test_popen_worker():
    proc = PopenWorker()

    with pytest.raises(TimeoutError):
        proc.send(identity_after, [1, 100], timeout=0.01)
        proc.recv()

    with pytest.raises(ChildProcessError):
        proc.send(terminate_self)
        proc.recv()

    proc.send(identity_after, [2, 0])
    assert proc.recv() == 2

    proc.send(identity_after, [4, 0.0001])
    assert proc.recv() == 4
예제 #6
0
def test_popen_ffi():
    proc = PopenWorker(register_ffi)

    # call python function via ffi
    initargs = [0]
    proc.send(call_py_ffi, initargs)
    assert proc.recv() == initargs[0]

    # call cpp function via ffi
    initargs = [1]
    proc.send(call_cpp_ffi, initargs)
    assert proc.recv() == initargs[0]

    # call python function from cpp function via ffi
    initargs = [2]
    proc.send(call_cpp_py_ffi, initargs)
    assert proc.recv() == initargs[0]
예제 #7
0
 def __init__(self, host="0.0.0.0", port=9190, port_end=9199, silent=False):
     if silent:
         logger.setLevel(logging.WARN)
     self.proc = PopenWorker()
     # send the function
     self.proc.send(
         _popen_start_tracker_server,
         [
             host,
             port,
             port_end,
             silent,
         ],
     )
     # receive the port
     self.port, self.stop_key = self.proc.recv()
     self.host = host
예제 #8
0
 def __init__(
     self,
     host="0.0.0.0",
     port=9091,
     port_end=9199,
     is_proxy=False,
     tracker_addr=None,
     key="",
     load_library=None,
     custom_addr=None,
     silent=False,
     no_fork=False,
     server_init_callback=None,
 ):
     try:
         if _ffi_api.ServerLoop is None:
             raise RuntimeError("Please compile with USE_RPC=1")
     except NameError:
         raise RuntimeError("Please compile with USE_RPC=1")
     self.proc = PopenWorker()
     # send the function
     self.proc.send(
         _popen_start_rpc_server,
         [
             host,
             port,
             port_end,
             is_proxy,
             tracker_addr,
             key,
             load_library,
             custom_addr,
             silent,
             no_fork,
             server_init_callback,
         ],
     )
     # receive the port
     self.port = self.proc.recv()
     self.host = host
예제 #9
0
def wrapper_for_call_function_with_timeout(timeout,
                                           func,
                                           args=(),
                                           kwargs=None):
    """Wrapper for call_func_with_timeout."""
    def wrapper(*_args, **_kwargs):
        """
        This wrapper is needed because the cloudpicle
        cannot serialize objects that contain pointers (RPCSession)
        """
        func(*_args, **_kwargs)
        return StatusKind.COMPLETE

    worker = PopenWorker()
    ret = call_func_with_timeout(worker,
                                 timeout=timeout,
                                 func=wrapper,
                                 args=args,
                                 kwargs=kwargs)
    if isinstance(ret, Exception):
        raise ret
    return ret
예제 #10
0
def test_popen_worker_recycles_with_initializer():
    initargs = [1, 2, 3]
    proc = PopenWorker(initializer=initializer,
                       initargs=initargs,
                       maximum_uses=3)

    proc.send(os.getpid)
    initial_pid = proc.recv()

    proc.send(after_initializer)
    assert list(proc.recv()) == initargs

    proc.send(os.getpid)
    assert proc.recv() == initial_pid

    # The process should be recycled with this send.
    proc.send(os.getpid)
    assert proc.recv() != initial_pid

    # But the initializer should've run this time as well.
    proc.send(after_initializer)
    assert list(proc.recv()) == initargs
예제 #11
0
def local_run(
    inputs,
    build_results,
    timeout=10,
    number=3,
    repeat=1,
    min_repeat_ms=0,
    cooldown_interval=0,
    enable_cpu_cache_flush=False,
    verbose=1,
):
    """
    Run function of LocalRunner 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.
    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.
    """

    measure_results = []
    assert len(inputs) == len(
        build_results), "Measure input size should be equal to build results"
    worker = PopenWorker()
    for inp, build_res in zip(inputs, build_results):
        if build_res.error_no != 0:
            res = (
                (MAX_FLOAT, ),
                build_res.error_no,
                build_res.error_msg,
                build_res.time_cost,
                time.time(),
            )
        else:
            args = prepare_runner_args(inp, build_res)
            res = call_func_with_timeout(
                worker,
                timeout,
                _timed_eval_func,
                args=(
                    inp.serialize(),
                    build_res,
                    args,
                    number,
                    repeat,
                    min_repeat_ms,
                    cooldown_interval,
                    enable_cpu_cache_flush,
                    verbose,
                ),
            )
            if isinstance(res, TimeoutError):
                if verbose >= 1:
                    print("*T", end="", flush=True)  # Run timeout
                res = (
                    (MAX_FLOAT, ),
                    MeasureErrorNo.RUN_TIMEOUT,
                    None,
                    build_res.time_cost + timeout,
                    time.time(),
                )
            elif isinstance(res, Exception):
                if verbose >= 1:
                    print("*E", end="", flush=True)  # Run error
                res = (
                    (MAX_FLOAT, ),
                    MeasureErrorNo.RUNTIME_DEVICE,
                    str(res),
                    build_res.time_cost + timeout,
                    time.time(),
                )

        measure_results.append(MeasureResult(*res))

    if verbose >= 1:
        print("", flush=True)

    return measure_results