|
|
|
|
|
import copy
|
|
|
import time
|
|
|
from contextlib import contextmanager
|
|
|
from typing import Generator, Optional
|
|
|
|
|
|
from ..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
|
|
|
|
|
|
@property
|
|
|
def scope_name(self) -> str:
|
|
|
"""
|
|
|
Returns:
|
|
|
str: Get current scope.
|
|
|
"""
|
|
|
return self._scope_name
|
|
|
|
|
|
@classmethod
|
|
|
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
|
|
|
|
|
|
@classmethod
|
|
|
@contextmanager
|
|
|
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)
|
|
|
|
|
|
time.sleep(1e-6)
|
|
|
cls.get_instance(f'overwrite-{time.time()}', scope_name=scope_name)
|
|
|
try:
|
|
|
yield
|
|
|
finally:
|
|
|
cls._instance_dict = tmp
|
|
|
|