KieDani/SegformerPlusPlus
1
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 