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

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        # for some reason, python 3.8 thinks `Distribution` has no attribute `name`?
56        pckgs: list[tuple[str, str]] = [(x.name, x.version) for x in distributions()]  # type: ignore[attr-defined]
57        return {
58            "n_packages": len(pckgs),
59            "packages": pckgs,
60        }

installed packages info

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

pytorch and cuda information

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