docs for muutils v0.8.12
View Source on GitHub

muutils.sysinfo

utilities for getting information about the system, see SysInfo class


  1"utilities for getting information about the system, see `SysInfo` class"
  2
  3from __future__ import annotations
  4
  5import subprocess
  6import sys
  7import typing
  8from importlib.metadata import distributions
  9
 10
 11def _popen(cmd: list[str], split_out: bool = False) -> dict[str, typing.Any]:
 12    p: subprocess.Popen = subprocess.Popen(
 13        cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE
 14    )
 15
 16    stdout, stderr = p.communicate()
 17
 18    p_out: typing.Union[str, list[str], None]
 19    if stdout:
 20        p_out = stdout.decode("utf-8")
 21        if split_out:
 22            assert isinstance(p_out, str)
 23            p_out = p_out.strip().split("\n")
 24    else:
 25        p_out = None
 26
 27    return {
 28        "stdout": p_out,
 29        "stderr": stderr.decode("utf-8") if stderr else None,
 30        "returncode": p.returncode if p.returncode is None else int(p.returncode),
 31    }
 32
 33
 34class SysInfo:
 35    """getters for various information about the system"""
 36
 37    @staticmethod
 38    def python() -> dict:
 39        """details about python version"""
 40        ver_tup = sys.version_info
 41        return {
 42            "version": sys.version,
 43            "version_info": ver_tup,
 44            "major": ver_tup[0],
 45            "minor": ver_tup[1],
 46            "micro": ver_tup[2],
 47            "releaselevel": ver_tup[3],
 48            "serial": ver_tup[4],
 49        }
 50
 51    @staticmethod
 52    def pip() -> dict:
 53        """installed packages info"""
 54        # in python <= 3.9  `Distribution` has no attribute `name`
 55        pckgs: list[tuple[str, str]] = [
 56            (
 57                (
 58                    x.metadata.get("Name", "<unknown>")  # type: ignore[attr-defined]
 59                    if sys.version_info < (3, 10)
 60                    else x.name  # type: ignore[attr-defined]
 61                ),
 62                x.version,
 63            )
 64            for x in distributions()
 65        ]
 66        return {
 67            "n_packages": len(pckgs),
 68            "packages": pckgs,
 69        }
 70
 71    @staticmethod
 72    def pytorch() -> dict:
 73        """pytorch and cuda information"""
 74        try:
 75            import torch
 76            import torch.version
 77        except Exception as e:
 78            return {
 79                "importable": False,
 80                "error": str(e),
 81            }
 82
 83        output: dict = {"importable": True}
 84
 85        output["torch.__version__"] = torch.__version__
 86        output["torch.version.cuda"] = torch.version.cuda
 87        output["torch.version.debug"] = torch.version.debug
 88        output["torch.version.git_version"] = torch.version.git_version
 89        output["torch.version.hip"] = torch.version.hip
 90        output["torch.cuda.is_available()"] = torch.cuda.is_available()
 91        output["torch.cuda.device_count()"] = torch.cuda.device_count()
 92        output["torch.cuda.is_initialized()"] = torch.cuda.is_initialized()
 93
 94        if torch.cuda.is_available():
 95            import os
 96
 97            cuda_version_nvcc: str = os.popen("nvcc --version").read()
 98            output["nvcc --version"] = cuda_version_nvcc.split("\n")
 99
100            if torch.cuda.device_count() > 0:
101                n_devices: int = torch.cuda.device_count()
102                output["torch.cuda.current_device()"] = torch.cuda.current_device()
103                output["torch devices"] = []
104                for current_device in range(n_devices):
105                    try:
106                        # print(f'checking current device {current_device} of {torch.cuda.device_count()} devices')
107                        # print(f'\tdevice {current_device}')
108                        # dev_prop = torch.cuda.get_device_properties(torch.device(0))
109                        # print(f'\t    name:                   {dev_prop.name}')
110                        # print(f'\t    version:                {dev_prop.major}.{dev_prop.minor}')
111                        # print(f'\t    total_memory:           {dev_prop.total_memory}')
112                        # print(f'\t    multi_processor_count:  {dev_prop.multi_processor_count}')
113                        # print(f'\t')
114                        dev_prop = torch.cuda.get_device_properties(current_device)
115                        output["torch devices"].append(
116                            {
117                                "device": current_device,
118                                "name": dev_prop.name,
119                                "version": {
120                                    "major": dev_prop.major,
121                                    "minor": dev_prop.minor,
122                                },
123                                "total_memory": dev_prop.total_memory,
124                                "multi_processor_count": dev_prop.multi_processor_count,
125                            }
126                        )
127                    except Exception as e:
128                        output["torch devices"].append(
129                            {
130                                "device": current_device,
131                                "error": str(e),
132                            }
133                        )
134        return output
135
136    @staticmethod
137    def platform() -> dict:
138        import platform
139
140        items = [
141            "platform",
142            "machine",
143            "processor",
144            "system",
145            "version",
146            "architecture",
147            "uname",
148            "node",
149            "python_branch",
150            "python_build",
151            "python_compiler",
152            "python_implementation",
153        ]
154
155        return {x: getattr(platform, x)() for x in items}
156
157    @staticmethod
158    def git_info(with_log: bool = False) -> dict:
159        git_version: dict = _popen(["git", "version"])
160        git_status: dict = _popen(["git", "status"])
161        if not git_status["stderr"] or git_status["stderr"].startswith(
162            "fatal: not a git repository"
163        ):
164            return {
165                "git version": git_version["stdout"],
166                "git status": git_status,
167            }
168        else:
169            output: dict = {
170                "git version": git_version["stdout"],
171                "git status": git_status,
172                "git branch": _popen(["git", "branch"], split_out=True),
173                "git remote -v": _popen(["git", "remote", "-v"], split_out=True),
174            }
175            if with_log:
176                output["git log"] = _popen(["git", "log"], split_out=False)
177
178            return output
179
180    @classmethod
181    def get_all(
182        cls,
183        include: typing.Optional[tuple[str, ...]] = None,
184        exclude: tuple[str, ...] = tuple(),
185    ) -> dict:
186        include_meta: tuple[str, ...]
187        if include is None:
188            include_meta = tuple(cls.__dict__.keys())
189        else:
190            include_meta = include
191
192        return {
193            x: getattr(cls, x)()
194            for x in include_meta
195            if all(
196                [
197                    not x.startswith("_"),
198                    x not in exclude,
199                    callable(getattr(cls, x)),
200                    x != "get_all",
201                    x in include if include is not None else True,
202                ]
203            )
204        }
205
206
207if __name__ == "__main__":
208    import pprint
209
210    pprint.pprint(SysInfo.get_all())

class SysInfo:
 35class SysInfo:
 36    """getters for various information about the system"""
 37
 38    @staticmethod
 39    def python() -> dict:
 40        """details about python version"""
 41        ver_tup = sys.version_info
 42        return {
 43            "version": sys.version,
 44            "version_info": ver_tup,
 45            "major": ver_tup[0],
 46            "minor": ver_tup[1],
 47            "micro": ver_tup[2],
 48            "releaselevel": ver_tup[3],
 49            "serial": ver_tup[4],
 50        }
 51
 52    @staticmethod
 53    def pip() -> dict:
 54        """installed packages info"""
 55        # in python <= 3.9  `Distribution` has no attribute `name`
 56        pckgs: list[tuple[str, str]] = [
 57            (
 58                (
 59                    x.metadata.get("Name", "<unknown>")  # type: ignore[attr-defined]
 60                    if sys.version_info < (3, 10)
 61                    else x.name  # type: ignore[attr-defined]
 62                ),
 63                x.version,
 64            )
 65            for x in distributions()
 66        ]
 67        return {
 68            "n_packages": len(pckgs),
 69            "packages": pckgs,
 70        }
 71
 72    @staticmethod
 73    def pytorch() -> dict:
 74        """pytorch and cuda information"""
 75        try:
 76            import torch
 77            import torch.version
 78        except Exception as e:
 79            return {
 80                "importable": False,
 81                "error": str(e),
 82            }
 83
 84        output: dict = {"importable": True}
 85
 86        output["torch.__version__"] = torch.__version__
 87        output["torch.version.cuda"] = torch.version.cuda
 88        output["torch.version.debug"] = torch.version.debug
 89        output["torch.version.git_version"] = torch.version.git_version
 90        output["torch.version.hip"] = torch.version.hip
 91        output["torch.cuda.is_available()"] = torch.cuda.is_available()
 92        output["torch.cuda.device_count()"] = torch.cuda.device_count()
 93        output["torch.cuda.is_initialized()"] = torch.cuda.is_initialized()
 94
 95        if torch.cuda.is_available():
 96            import os
 97
 98            cuda_version_nvcc: str = os.popen("nvcc --version").read()
 99            output["nvcc --version"] = cuda_version_nvcc.split("\n")
100
101            if torch.cuda.device_count() > 0:
102                n_devices: int = torch.cuda.device_count()
103                output["torch.cuda.current_device()"] = torch.cuda.current_device()
104                output["torch devices"] = []
105                for current_device in range(n_devices):
106                    try:
107                        # print(f'checking current device {current_device} of {torch.cuda.device_count()} devices')
108                        # print(f'\tdevice {current_device}')
109                        # dev_prop = torch.cuda.get_device_properties(torch.device(0))
110                        # print(f'\t    name:                   {dev_prop.name}')
111                        # print(f'\t    version:                {dev_prop.major}.{dev_prop.minor}')
112                        # print(f'\t    total_memory:           {dev_prop.total_memory}')
113                        # print(f'\t    multi_processor_count:  {dev_prop.multi_processor_count}')
114                        # print(f'\t')
115                        dev_prop = torch.cuda.get_device_properties(current_device)
116                        output["torch devices"].append(
117                            {
118                                "device": current_device,
119                                "name": dev_prop.name,
120                                "version": {
121                                    "major": dev_prop.major,
122                                    "minor": dev_prop.minor,
123                                },
124                                "total_memory": dev_prop.total_memory,
125                                "multi_processor_count": dev_prop.multi_processor_count,
126                            }
127                        )
128                    except Exception as e:
129                        output["torch devices"].append(
130                            {
131                                "device": current_device,
132                                "error": str(e),
133                            }
134                        )
135        return output
136
137    @staticmethod
138    def platform() -> dict:
139        import platform
140
141        items = [
142            "platform",
143            "machine",
144            "processor",
145            "system",
146            "version",
147            "architecture",
148            "uname",
149            "node",
150            "python_branch",
151            "python_build",
152            "python_compiler",
153            "python_implementation",
154        ]
155
156        return {x: getattr(platform, x)() for x in items}
157
158    @staticmethod
159    def git_info(with_log: bool = False) -> dict:
160        git_version: dict = _popen(["git", "version"])
161        git_status: dict = _popen(["git", "status"])
162        if not git_status["stderr"] or git_status["stderr"].startswith(
163            "fatal: not a git repository"
164        ):
165            return {
166                "git version": git_version["stdout"],
167                "git status": git_status,
168            }
169        else:
170            output: dict = {
171                "git version": git_version["stdout"],
172                "git status": git_status,
173                "git branch": _popen(["git", "branch"], split_out=True),
174                "git remote -v": _popen(["git", "remote", "-v"], split_out=True),
175            }
176            if with_log:
177                output["git log"] = _popen(["git", "log"], split_out=False)
178
179            return output
180
181    @classmethod
182    def get_all(
183        cls,
184        include: typing.Optional[tuple[str, ...]] = None,
185        exclude: tuple[str, ...] = tuple(),
186    ) -> dict:
187        include_meta: tuple[str, ...]
188        if include is None:
189            include_meta = tuple(cls.__dict__.keys())
190        else:
191            include_meta = include
192
193        return {
194            x: getattr(cls, x)()
195            for x in include_meta
196            if all(
197                [
198                    not x.startswith("_"),
199                    x not in exclude,
200                    callable(getattr(cls, x)),
201                    x != "get_all",
202                    x in include if include is not None else True,
203                ]
204            )
205        }

getters for various information about the system

@staticmethod
def python() -> dict:
38    @staticmethod
39    def python() -> dict:
40        """details about python version"""
41        ver_tup = sys.version_info
42        return {
43            "version": sys.version,
44            "version_info": ver_tup,
45            "major": ver_tup[0],
46            "minor": ver_tup[1],
47            "micro": ver_tup[2],
48            "releaselevel": ver_tup[3],
49            "serial": ver_tup[4],
50        }

details about python version

@staticmethod
def pip() -> dict:
52    @staticmethod
53    def pip() -> dict:
54        """installed packages info"""
55        # in python <= 3.9  `Distribution` has no attribute `name`
56        pckgs: list[tuple[str, str]] = [
57            (
58                (
59                    x.metadata.get("Name", "<unknown>")  # type: ignore[attr-defined]
60                    if sys.version_info < (3, 10)
61                    else x.name  # type: ignore[attr-defined]
62                ),
63                x.version,
64            )
65            for x in distributions()
66        ]
67        return {
68            "n_packages": len(pckgs),
69            "packages": pckgs,
70        }

installed packages info

@staticmethod
def pytorch() -> dict:
 72    @staticmethod
 73    def pytorch() -> dict:
 74        """pytorch and cuda information"""
 75        try:
 76            import torch
 77            import torch.version
 78        except Exception as e:
 79            return {
 80                "importable": False,
 81                "error": str(e),
 82            }
 83
 84        output: dict = {"importable": True}
 85
 86        output["torch.__version__"] = torch.__version__
 87        output["torch.version.cuda"] = torch.version.cuda
 88        output["torch.version.debug"] = torch.version.debug
 89        output["torch.version.git_version"] = torch.version.git_version
 90        output["torch.version.hip"] = torch.version.hip
 91        output["torch.cuda.is_available()"] = torch.cuda.is_available()
 92        output["torch.cuda.device_count()"] = torch.cuda.device_count()
 93        output["torch.cuda.is_initialized()"] = torch.cuda.is_initialized()
 94
 95        if torch.cuda.is_available():
 96            import os
 97
 98            cuda_version_nvcc: str = os.popen("nvcc --version").read()
 99            output["nvcc --version"] = cuda_version_nvcc.split("\n")
100
101            if torch.cuda.device_count() > 0:
102                n_devices: int = torch.cuda.device_count()
103                output["torch.cuda.current_device()"] = torch.cuda.current_device()
104                output["torch devices"] = []
105                for current_device in range(n_devices):
106                    try:
107                        # print(f'checking current device {current_device} of {torch.cuda.device_count()} devices')
108                        # print(f'\tdevice {current_device}')
109                        # dev_prop = torch.cuda.get_device_properties(torch.device(0))
110                        # print(f'\t    name:                   {dev_prop.name}')
111                        # print(f'\t    version:                {dev_prop.major}.{dev_prop.minor}')
112                        # print(f'\t    total_memory:           {dev_prop.total_memory}')
113                        # print(f'\t    multi_processor_count:  {dev_prop.multi_processor_count}')
114                        # print(f'\t')
115                        dev_prop = torch.cuda.get_device_properties(current_device)
116                        output["torch devices"].append(
117                            {
118                                "device": current_device,
119                                "name": dev_prop.name,
120                                "version": {
121                                    "major": dev_prop.major,
122                                    "minor": dev_prop.minor,
123                                },
124                                "total_memory": dev_prop.total_memory,
125                                "multi_processor_count": dev_prop.multi_processor_count,
126                            }
127                        )
128                    except Exception as e:
129                        output["torch devices"].append(
130                            {
131                                "device": current_device,
132                                "error": str(e),
133                            }
134                        )
135        return output

pytorch and cuda information

@staticmethod
def platform() -> dict:
137    @staticmethod
138    def platform() -> dict:
139        import platform
140
141        items = [
142            "platform",
143            "machine",
144            "processor",
145            "system",
146            "version",
147            "architecture",
148            "uname",
149            "node",
150            "python_branch",
151            "python_build",
152            "python_compiler",
153            "python_implementation",
154        ]
155
156        return {x: getattr(platform, x)() for x in items}
@staticmethod
def git_info(with_log: bool = False) -> dict:
158    @staticmethod
159    def git_info(with_log: bool = False) -> dict:
160        git_version: dict = _popen(["git", "version"])
161        git_status: dict = _popen(["git", "status"])
162        if not git_status["stderr"] or git_status["stderr"].startswith(
163            "fatal: not a git repository"
164        ):
165            return {
166                "git version": git_version["stdout"],
167                "git status": git_status,
168            }
169        else:
170            output: dict = {
171                "git version": git_version["stdout"],
172                "git status": git_status,
173                "git branch": _popen(["git", "branch"], split_out=True),
174                "git remote -v": _popen(["git", "remote", "-v"], split_out=True),
175            }
176            if with_log:
177                output["git log"] = _popen(["git", "log"], split_out=False)
178
179            return output
@classmethod
def get_all( cls, include: Optional[tuple[str, ...]] = None, exclude: tuple[str, ...] = ()) -> dict:
181    @classmethod
182    def get_all(
183        cls,
184        include: typing.Optional[tuple[str, ...]] = None,
185        exclude: tuple[str, ...] = tuple(),
186    ) -> dict:
187        include_meta: tuple[str, ...]
188        if include is None:
189            include_meta = tuple(cls.__dict__.keys())
190        else:
191            include_meta = include
192
193        return {
194            x: getattr(cls, x)()
195            for x in include_meta
196            if all(
197                [
198                    not x.startswith("_"),
199                    x not in exclude,
200                    callable(getattr(cls, x)),
201                    x != "get_all",
202                    x in include if include is not None else True,
203                ]
204            )
205        }