Spaces:
Running
Running
| import signal | |
| import time | |
| from typing import Any, Callable | |
| import torch | |
| from easydict import EasyDict | |
| from .time_helper_base import TimeWrapper | |
| from .time_helper_cuda import get_cuda_time_wrapper | |
| def build_time_helper(cfg: EasyDict = None, wrapper_type: str = None) -> Callable[[], 'TimeWrapper']: | |
| """ | |
| Overview: | |
| Build the timehelper | |
| Arguments: | |
| - cfg (:obj:`dict`): | |
| The config file, which is a multilevel dict, have large domain like | |
| evaluate, common, model, train etc, and each large domain | |
| has it's smaller domain. | |
| - wrapper_type (:obj:`str`): The type of wrapper returned, support ``['time', 'cuda']`` | |
| Returns: | |
| - time_wrapper (:obj:`TimeWrapper`): | |
| Return the corresponding timewrapper, Reference: ``ding.utils.timehelper.TimeWrapperTime`` | |
| and ``ding.utils.timehelper.get_cuda_time_wrapper``. | |
| """ | |
| # Note: wrapper_type has higher priority | |
| if wrapper_type is not None: | |
| time_wrapper_type = wrapper_type | |
| elif cfg is not None: | |
| time_wrapper_type = cfg.common.time_wrapper_type | |
| else: | |
| raise RuntimeError('Either wrapper_type or cfg should be provided.') | |
| if time_wrapper_type == 'time': | |
| return TimeWrapperTime | |
| elif time_wrapper_type == 'cuda': | |
| if torch.cuda.is_available(): | |
| # lazy initialize to make code runnable locally | |
| return get_cuda_time_wrapper() | |
| else: | |
| return TimeWrapperTime | |
| else: | |
| raise KeyError('invalid time_wrapper_type: {}'.format(time_wrapper_type)) | |
| class EasyTimer: | |
| """ | |
| Overview: | |
| A decent timer wrapper that can be used easily. | |
| Interfaces: | |
| ``__init__``, ``__enter__``, ``__exit__`` | |
| Example: | |
| >>> wait_timer = EasyTimer() | |
| >>> with wait_timer: | |
| >>> func(...) | |
| >>> time_ = wait_timer.value # in second | |
| """ | |
| def __init__(self, cuda=True): | |
| """ | |
| Overview: | |
| Init class EasyTimer | |
| Arguments: | |
| - cuda (:obj:`bool`): Whether to build timer with cuda type | |
| """ | |
| if torch.cuda.is_available() and cuda: | |
| time_wrapper_type = "cuda" | |
| else: | |
| time_wrapper_type = "time" | |
| self._timer = build_time_helper(wrapper_type=time_wrapper_type) | |
| self.value = 0.0 | |
| def __enter__(self): | |
| """ | |
| Overview: | |
| Enter timer, start timing | |
| """ | |
| self.value = 0.0 | |
| self._timer.start_time() | |
| def __exit__(self, *args): | |
| """ | |
| Overview: | |
| Exit timer, stop timing | |
| """ | |
| self.value = self._timer.end_time() | |
| class TimeWrapperTime(TimeWrapper): | |
| """ | |
| Overview: | |
| A class method that inherit from ``TimeWrapper`` class | |
| Interfaces: | |
| ``start_time``, ``end_time`` | |
| """ | |
| # overwrite | |
| def start_time(cls): | |
| """ | |
| Overview: | |
| Implement and override the ``start_time`` method in ``TimeWrapper`` class | |
| """ | |
| cls.start = time.time() | |
| # overwrite | |
| def end_time(cls): | |
| """ | |
| Overview: | |
| Implement and override the end_time method in ``TimeWrapper`` class | |
| Returns: | |
| - time(:obj:`float`): The time between ``start_time`` and end_time | |
| """ | |
| cls.end = time.time() | |
| return cls.end - cls.start | |
| class WatchDog(object): | |
| """ | |
| Overview: | |
| Simple watchdog timer to detect timeouts | |
| Arguments: | |
| - timeout (:obj:`int`): Timeout value of the ``watchdog [seconds]``. | |
| .. note:: | |
| If it is not reset before exceeding this value, ``TimeourError`` raised. | |
| Interfaces: | |
| ``start``, ``stop`` | |
| Examples: | |
| >>> watchdog = WatchDog(x) # x is a timeout value | |
| >>> ... | |
| >>> watchdog.start() | |
| >>> ... # Some function | |
| """ | |
| def __init__(self, timeout: int = 1): | |
| """ | |
| Overview: | |
| Initialize watchdog with ``timeout`` value. | |
| Arguments: | |
| - timeout (:obj:`int`): Timeout value of the ``watchdog [seconds]``. | |
| """ | |
| self._timeout = timeout + 1 | |
| self._failed = False | |
| def start(self): | |
| """ | |
| Overview: | |
| Start watchdog. | |
| """ | |
| signal.signal(signal.SIGALRM, self._event) | |
| signal.alarm(self._timeout) | |
| def _event(signum: Any, frame: Any): | |
| """ | |
| Overview: | |
| Event handler for watchdog. | |
| Arguments: | |
| - signum (:obj:`Any`): Signal number. | |
| - frame (:obj:`Any`): Current stack frame. | |
| """ | |
| raise TimeoutError() | |
| def stop(self): | |
| """ | |
| Overview: | |
| Stop watchdog with ``alarm(0)``, ``SIGALRM``, and ``SIG_DFL`` signals. | |
| """ | |
| signal.alarm(0) | |
| signal.signal(signal.SIGALRM, signal.SIG_DFL) | |