[docs]classtimeit:""" Measure the time of a block of code. Args: print_tmpl (str, optional): The template to print the time. Defaults to None. Can be a string with a placeholder for the time, e.g., "func foo costs {:.5f} s" or a string without a placeholder, e.g., "func foo". Examples: >>> # doctest: +SKIP >>> with timeit(): ... time.sleep(1) it costs 1.00000 s >>> @timeit ... def foo(): ... time.sleep(1) foo costs 1.00000 s >>> @timeit("func foo") ... def foo(): ... time.sleep(1) func foo costs 1.00000 s """_has_tmpl:bool_print_tmpl:str_start_time:float@overloaddef__new__(cls,fn_or_print_tmpl:T)->T:...# type: ignore@overloaddef__new__(cls,fn_or_print_tmpl:Optional[str]=None)->"timeit":...# type: ignoredef__new__(cls,fn_or_print_tmpl:Optional[Union[T,str]]=None)->Union[T,"timeit"]:# type: ignoreinstance=super().__new__(cls)ifcallable(fn_or_print_tmpl):# handle case when decorator is used without parenthesesinstance._has_tmpl=Falseinstance._print_tmpl=str(fn_or_print_tmpl.__name__)+" costs {:.5f} s"returncast(T,instance(fn_or_print_tmpl))# __init__ is not calledreturninstancedef__init__(self,fn_or_print_tmpl:Optional[Union[Callable,str]]=None):ifcallable(fn_or_print_tmpl):return# skip initialization if called from __new__ with a functionhas_tmpl=fn_or_print_tmplisnotNoneifhas_tmpl:# no placeholder in print_tmplif"{"notinfn_or_print_tmpland"}"notinfn_or_print_tmpl:# type: ignoreprint_tmpl=fn_or_print_tmpl+" costs {:.5f} s"# type: ignoreelse:print_tmpl=fn_or_print_tmpl# type: ignoreelse:# default templateprint_tmpl="it costs {:.5f} s"self._has_tmpl=has_tmplself._print_tmpl=print_tmpl
[docs]classcuda_timeit(timeit):""" Measure the time of a block of code that may involve CUDA operations. We use CUDA events and synchronization for the accurate measurements. Args: print_tmpl (str, optional): The template to print the time. Defaults to None. Can be a string with a placeholder for the time, e.g., "func foo costs {:.5f} s" or a string without a placeholder, e.g., "func foo". """_start_event:torch.cuda.Event_end_event:torch.cuda.Event@overloaddef__new__(cls,fn_or_print_tmpl:T)->T:...# type: ignore@overloaddef__new__(cls,fn_or_print_tmpl:Optional[str]=None)->"cuda_timeit":...# type: ignoredef__new__(cls,fn_or_print_tmpl:Optional[Union[T,str]]=None)->Union[T,"cuda_timeit"]:# type: ignoreinstance=super().__new__(cls)ifcallable(fn_or_print_tmpl):# handle case when decorator is used without parenthesesinstance=cast("cuda_timeit",instance)# cast instance to cuda_timeitinstance._has_tmpl=Falseinstance._print_tmpl=str(fn_or_print_tmpl.__name__)+" costs {:.5f} s"instance._start_event=torch.cuda.Event(enable_timing=True)instance._end_event=torch.cuda.Event(enable_timing=True)returncast(T,instance(fn_or_print_tmpl))# __init__ is not called; cast the return valuereturncast("cuda_timeit",instance)def__init__(self,print_tmpl:Optional[str]=None):super().__init__(print_tmpl)ifnot_TORCH_AVAILABLEornottorch.cuda.is_available():raiseRuntimeError("CUDA is not available")self._start_event=torch.cuda.Event(enable_timing=True)self._end_event=torch.cuda.Event(enable_timing=True)