CoolFace
Modelpublic

KieDani/SegformerPlusPlus

sourceHugging Facegpl-3.0updated 1y agoView on Hugging Face
1likes
default_scope.py96 linesDownload Raw Back to Registry
1# Copyright (c) OpenMMLab. All rights reserved.
2import copy
3import time
4from contextlib import contextmanager
5from typing import Generator, Optional
6
7from ..utils.manager import ManagerMixin, _accquire_lock, _release_lock
8
9
10class DefaultScope(ManagerMixin):
11    """Scope of current task used to reset the current registry, which can be
12    accessed globally.
13
14    Consider the case of resetting the current ``Registry`` by
15    ``default_scope`` in the internal module which cannot access runner
16    directly, it is difficult to get the ``default_scope`` defined in
17    ``Runner``. However, if ``Runner`` created ``DefaultScope`` instance
18    by given ``default_scope``, the internal module can get
19    ``default_scope`` by ``DefaultScope.get_current_instance`` everywhere.
20
21    Args:
22        name (str): Name of default scope for global access.
23        scope_name (str): Scope of current task.
24
25    Examples:
26        >>> from mmengine.model import MODELS
27        >>> # Define default scope in runner.
28        >>> DefaultScope.get_instance('task', scope_name='mmdet')
29        >>> # Get default scope globally.
30        >>> scope_name = DefaultScope.get_instance('task').scope_name
31    """
32
33    def __init__(self, name: str, scope_name: str):
34        super().__init__(name)
35        assert isinstance(
36            scope_name,
37            str), (f'scope_name should be a string, but got {scope_name}')
38        self._scope_name = scope_name
39
40    @property
41    def scope_name(self) -> str:
42        """
43        Returns:
44            str: Get current scope.
45        """
46        return self._scope_name
47
48    @classmethod
49    def get_current_instance(cls) -> Optional['DefaultScope']:
50        """Get latest created default scope.
51
52        Since default_scope is an optional argument for ``Registry.build``.
53        ``get_current_instance`` should return ``None`` if there is no
54        ``DefaultScope`` created.
55
56        Examples:
57            >>> default_scope = DefaultScope.get_current_instance()
58            >>> # There is no `DefaultScope` created yet,
59            >>> # `get_current_instance` return `None`.
60            >>> default_scope = DefaultScope.get_instance(
61            >>>     'instance_name', scope_name='mmengine')
62            >>> default_scope.scope_name
63            mmengine
64            >>> default_scope = DefaultScope.get_current_instance()
65            >>> default_scope.scope_name
66            mmengine
67
68        Returns:
69            Optional[DefaultScope]: Return None If there has not been
70            ``DefaultScope`` instance created yet, otherwise return the
71            latest created DefaultScope instance.
72        """
73        _accquire_lock()
74        if cls._instance_dict:
75            instance = super().get_current_instance()
76        else:
77            instance = None
78        _release_lock()
79        return instance
80
81    @classmethod
82    @contextmanager
83    def overwrite_default_scope(cls, scope_name: Optional[str]) -> Generator:
84        """Overwrite the current default scope with `scope_name`"""
85        if scope_name is None:
86            yield
87        else:
88            tmp = copy.deepcopy(cls._instance_dict)
89            # To avoid create an instance with the same name.
90            time.sleep(1e-6)
91            cls.get_instance(f'overwrite-{time.time()}', scope_name=scope_name)
92            try:
93                yield
94            finally:
95                cls._instance_dict = tmp
96