def METHOD_NAME(func, device: str, nwarmup=WARMUP_ROUNDS, num_iter=10, flops=True) -> Tuple[float, float, Optional[Tuple[torch.Tensor]]]:
    "Run one step of the model, and return the latency in milliseconds."
    # Warm-up `nwarmup` rounds
    for _i in range(nwarmup):
        func()
    result_summary = []
    if flops:
        model_analyzer = ModelAnalyzer()
        model_analyzer.start_monitor()
        model_analyzer.set_monitoring_interval(0.01)
    for _i in range(num_iter):
        if device == "cuda":
            torch.cuda.synchronize()
            # Collect time_ns() instead of time() which does not provide better precision than 1
            # second according to https://docs.python.org/3/library/time.html#time.time.
            t0 = time.time_ns()
            func()
            torch.cuda.synchronize()  # Wait for the events to be recorded!
            t1 = time.time_ns()
        else:
            t0 = time.time_ns()
            func()
            t1 = time.time_ns()
        result_summary.append((t1 - t0) / NANOSECONDS_PER_MILLISECONDS)
    if flops:
        model_analyzer.stop_monitor()
        model_analyzer.aggregate()
        tflops = model_analyzer.calculate_flops()
    wall_latency = numpy.median(result_summary)
    return (wall_latency, tflops)