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 }