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 }