Spaces:
Paused
Paused
| # Copyright (c) Meta Platforms, Inc. and affiliates. | |
| # All rights reserved. | |
| # | |
| # This source code is licensed under the license found in the | |
| # LICENSE file in the root directory of this source tree. | |
| import copy | |
| import time | |
| from contextlib import contextmanager | |
| from typing import Generator, Optional | |
| from mmengine.utils.manager import ManagerMixin, _accquire_lock, _release_lock | |
| class DefaultScope(ManagerMixin): | |
| """Scope of current task used to reset the current registry, which can be | |
| accessed globally. | |
| Consider the case of resetting the current ``Registry`` by | |
| ``default_scope`` in the internal module which cannot access runner | |
| directly, it is difficult to get the ``default_scope`` defined in | |
| ``Runner``. However, if ``Runner`` created ``DefaultScope`` instance | |
| by given ``default_scope``, the internal module can get | |
| ``default_scope`` by ``DefaultScope.get_current_instance`` everywhere. | |
| Args: | |
| name (str): Name of default scope for global access. | |
| scope_name (str): Scope of current task. | |
| Examples: | |
| >>> from mmengine.model import MODELS | |
| >>> # Define default scope in runner. | |
| >>> DefaultScope.get_instance('task', scope_name='mmdet') | |
| >>> # Get default scope globally. | |
| >>> scope_name = DefaultScope.get_instance('task').scope_name | |
| """ | |
| def __init__(self, name: str, scope_name: str): | |
| super().__init__(name) | |
| assert isinstance( | |
| scope_name, | |
| str), (f'scope_name should be a string, but got {scope_name}') | |
| self._scope_name = scope_name | |
| def scope_name(self) -> str: | |
| """ | |
| Returns: | |
| str: Get current scope. | |
| """ | |
| return self._scope_name | |
| def get_current_instance(cls) -> Optional['DefaultScope']: | |
| """Get latest created default scope. | |
| Since default_scope is an optional argument for ``Registry.build``. | |
| ``get_current_instance`` should return ``None`` if there is no | |
| ``DefaultScope`` created. | |
| Examples: | |
| >>> default_scope = DefaultScope.get_current_instance() | |
| >>> # There is no `DefaultScope` created yet, | |
| >>> # `get_current_instance` return `None`. | |
| >>> default_scope = DefaultScope.get_instance( | |
| >>> 'instance_name', scope_name='mmengine') | |
| >>> default_scope.scope_name | |
| mmengine | |
| >>> default_scope = DefaultScope.get_current_instance() | |
| >>> default_scope.scope_name | |
| mmengine | |
| Returns: | |
| Optional[DefaultScope]: Return None If there has not been | |
| ``DefaultScope`` instance created yet, otherwise return the | |
| latest created DefaultScope instance. | |
| """ | |
| _accquire_lock() | |
| if cls._instance_dict: | |
| instance = super().get_current_instance() | |
| else: | |
| instance = None | |
| _release_lock() | |
| return instance | |
| def overwrite_default_scope(cls, scope_name: Optional[str]) -> Generator: | |
| """overwrite the current default scope with `scope_name`""" | |
| if scope_name is None: | |
| yield | |
| else: | |
| tmp = copy.deepcopy(cls._instance_dict) | |
| # To avoid create an instance with the same name. | |
| time.sleep(1e-6) | |
| cls.get_instance(f'overwrite-{time.time()}', scope_name=scope_name) | |
| try: | |
| yield | |
| finally: | |
| cls._instance_dict = tmp | |