litlogger 0.0.15__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- litlogger/__init__.py +5 -0
- litlogger/artifacts.py +9 -0
- litlogger/client.py +87 -0
- litlogger/colors.py +217 -0
- litlogger/diagnostics.py +193 -0
- litlogger/experiment.py +283 -0
- litlogger/file_writer.py +133 -0
- litlogger/generator.py +1280 -0
- litlogger/logger.py +330 -0
- litlogger/manager.py +212 -0
- litlogger-0.0.15.dist-info/LICENSE +201 -0
- litlogger-0.0.15.dist-info/METADATA +18 -0
- litlogger-0.0.15.dist-info/RECORD +15 -0
- litlogger-0.0.15.dist-info/WHEEL +5 -0
- litlogger-0.0.15.dist-info/top_level.txt +1 -0
litlogger/__init__.py
ADDED
litlogger/artifacts.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Copyright The Lightning AI team.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
+
#
|
|
5
|
+
from lightning_utilities import module_available
|
|
6
|
+
|
|
7
|
+
if module_available("litmodels"):
|
|
8
|
+
# for compatibility with past versions but could be dropped in the future
|
|
9
|
+
from litmodels import download_model, upload_model # noqa: F401
|
litlogger/client.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Copyright The Lightning AI team.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
+
#
|
|
5
|
+
import time
|
|
6
|
+
from functools import wraps
|
|
7
|
+
from logging import Logger
|
|
8
|
+
from typing import Any, Callable
|
|
9
|
+
|
|
10
|
+
import urllib3
|
|
11
|
+
from lightning_sdk.lightning_cloud.openapi.rest import ApiException
|
|
12
|
+
from lightning_sdk.lightning_cloud.rest_client import GridRestClient, _get_next_backoff_time, create_swagger_client
|
|
13
|
+
|
|
14
|
+
logger = Logger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _should_retry(ex: BaseException) -> bool:
|
|
18
|
+
if isinstance(ex, urllib3.exceptions.HTTPError):
|
|
19
|
+
return True
|
|
20
|
+
|
|
21
|
+
if "not found" in str(ex):
|
|
22
|
+
return False
|
|
23
|
+
|
|
24
|
+
if str(ex.status).startswith("4") and ex.status not in (400, 401, 404):
|
|
25
|
+
return True
|
|
26
|
+
|
|
27
|
+
return str(ex.status).startswith("5")
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _retry_wrapper(self: Any, func: Callable, max_retries: int = -1) -> Callable:
|
|
31
|
+
"""Returns the function decorated by a wrapper that retries the call several times if a connection error occurs.
|
|
32
|
+
|
|
33
|
+
The retries follow an exponential backoff.
|
|
34
|
+
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
@wraps(func)
|
|
38
|
+
def wrapped(*args: Any, **kwargs: Any) -> Any:
|
|
39
|
+
consecutive_errors = 0
|
|
40
|
+
|
|
41
|
+
while True:
|
|
42
|
+
try:
|
|
43
|
+
return func(self, *args, **kwargs)
|
|
44
|
+
except (ApiException, urllib3.exceptions.HTTPError) as ex:
|
|
45
|
+
if not _should_retry(ex):
|
|
46
|
+
raise ex
|
|
47
|
+
|
|
48
|
+
msg = f"error: {ex!s}" if isinstance(ex, urllib3.exceptions.HTTPError) else f"response: {ex.status}"
|
|
49
|
+
|
|
50
|
+
if consecutive_errors == max_retries:
|
|
51
|
+
raise RuntimeError(f"The {func.__name__} request failed to reach the server, {msg}.") from ex
|
|
52
|
+
|
|
53
|
+
consecutive_errors += 1
|
|
54
|
+
backoff_time = _get_next_backoff_time(consecutive_errors)
|
|
55
|
+
logger.warning(
|
|
56
|
+
f"The {func.__name__} request failed to reach the server, {msg}."
|
|
57
|
+
f" Retrying after {backoff_time} seconds."
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
time.sleep(backoff_time)
|
|
61
|
+
|
|
62
|
+
return wrapped
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class LitRestClient(GridRestClient):
|
|
66
|
+
"""The LitRestClient is a wrapper around the GridRestClient.
|
|
67
|
+
|
|
68
|
+
It wraps all methods to monitor connection exceptions and employs a retry strategy.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
max_retries: Maximum number of attempts where each delay between retries is exponential.
|
|
72
|
+
If set to -1, it will retry forever, in contrast if set 0, it runs it only once.
|
|
73
|
+
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
def __init__(self, max_retries: int = -1) -> None:
|
|
77
|
+
super().__init__(api_client=create_swagger_client())
|
|
78
|
+
if max_retries == 0:
|
|
79
|
+
return
|
|
80
|
+
for base_class in GridRestClient.__mro__:
|
|
81
|
+
for name, attribute in base_class.__dict__.items():
|
|
82
|
+
if callable(attribute) and attribute.__name__ != "__init__":
|
|
83
|
+
setattr(
|
|
84
|
+
self,
|
|
85
|
+
name,
|
|
86
|
+
_retry_wrapper(self, attribute, max_retries=max_retries),
|
|
87
|
+
)
|
litlogger/colors.py
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# Copyright The Lightning AI team.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
+
#
|
|
5
|
+
import random
|
|
6
|
+
from typing import Tuple
|
|
7
|
+
|
|
8
|
+
_LIGHT_THEME_COLORS = [
|
|
9
|
+
"#792EE5",
|
|
10
|
+
"#3FC55F",
|
|
11
|
+
"#E02C2D",
|
|
12
|
+
"#1877F2",
|
|
13
|
+
"#F1AA03",
|
|
14
|
+
"#D22CE0",
|
|
15
|
+
"#FF6666",
|
|
16
|
+
"#5CDB95",
|
|
17
|
+
"#FFA500",
|
|
18
|
+
"#00CED1",
|
|
19
|
+
"#FFD700",
|
|
20
|
+
"#BA55D3",
|
|
21
|
+
"#1E90FF",
|
|
22
|
+
"#FF1493",
|
|
23
|
+
"#228B22",
|
|
24
|
+
"#800000",
|
|
25
|
+
"#FF00FF",
|
|
26
|
+
"#00FA9A",
|
|
27
|
+
"#8B008B",
|
|
28
|
+
"#808080",
|
|
29
|
+
"#7029e0",
|
|
30
|
+
"#e52534",
|
|
31
|
+
"#1172e8",
|
|
32
|
+
"#cf33dc",
|
|
33
|
+
"#188a23",
|
|
34
|
+
"#7d0007",
|
|
35
|
+
"#8d0894",
|
|
36
|
+
"#7732dc",
|
|
37
|
+
"#e43029",
|
|
38
|
+
"#1d6eea",
|
|
39
|
+
"#23911d",
|
|
40
|
+
"#870009",
|
|
41
|
+
"#8b0383",
|
|
42
|
+
"#7427e3",
|
|
43
|
+
"#e92633",
|
|
44
|
+
"#1d6ef7",
|
|
45
|
+
"#d02edc",
|
|
46
|
+
"#188421",
|
|
47
|
+
"#860100",
|
|
48
|
+
"#8a0086",
|
|
49
|
+
"#792fe7",
|
|
50
|
+
"#e22830",
|
|
51
|
+
"#1075f1",
|
|
52
|
+
"#d02cdc",
|
|
53
|
+
"#2c861b",
|
|
54
|
+
"#780505",
|
|
55
|
+
"#930283",
|
|
56
|
+
"#7536e3",
|
|
57
|
+
"#d6252a",
|
|
58
|
+
"#cb24e3",
|
|
59
|
+
"#1e9126",
|
|
60
|
+
"#760000",
|
|
61
|
+
"#8d0893",
|
|
62
|
+
"#7124dc",
|
|
63
|
+
"#df292f",
|
|
64
|
+
"#1c74f2",
|
|
65
|
+
"#ce24da",
|
|
66
|
+
"#b05aca",
|
|
67
|
+
"#1f9123",
|
|
68
|
+
"#780009",
|
|
69
|
+
"#8b0790",
|
|
70
|
+
"#7c7b7e",
|
|
71
|
+
"#7d30e0",
|
|
72
|
+
"#da2e2b",
|
|
73
|
+
"#258122",
|
|
74
|
+
"#8b0a87",
|
|
75
|
+
"#7529e1",
|
|
76
|
+
"#dd2532",
|
|
77
|
+
"#1276f4",
|
|
78
|
+
"#d822da",
|
|
79
|
+
"#188321",
|
|
80
|
+
"#770a03",
|
|
81
|
+
"#920091",
|
|
82
|
+
"#7d26e6",
|
|
83
|
+
"#e92d2d",
|
|
84
|
+
"#1979ec",
|
|
85
|
+
"#d526d7",
|
|
86
|
+
"#23901b",
|
|
87
|
+
"#790700",
|
|
88
|
+
"#8e0185",
|
|
89
|
+
"#798082",
|
|
90
|
+
"#7134e0",
|
|
91
|
+
"#da2824",
|
|
92
|
+
"#1b77ef",
|
|
93
|
+
"#20851a",
|
|
94
|
+
"#7b0700",
|
|
95
|
+
"#870185",
|
|
96
|
+
"#797c85",
|
|
97
|
+
"#732aee",
|
|
98
|
+
"#e22a26",
|
|
99
|
+
"#146efb",
|
|
100
|
+
"#b551cc",
|
|
101
|
+
"#258c19",
|
|
102
|
+
"#870001",
|
|
103
|
+
"#900081",
|
|
104
|
+
"#768184",
|
|
105
|
+
"#8335ed",
|
|
106
|
+
"#e82634",
|
|
107
|
+
"#1c78eb",
|
|
108
|
+
"#1a8d24",
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
_DARK_THEME_COLORS = [
|
|
112
|
+
"#FA00F0",
|
|
113
|
+
"#00FA9A",
|
|
114
|
+
"#FA0000",
|
|
115
|
+
"#0091FA",
|
|
116
|
+
"#FFD700",
|
|
117
|
+
"#FF6666",
|
|
118
|
+
"#D22CE0",
|
|
119
|
+
"#5CDB95",
|
|
120
|
+
"#FFA500",
|
|
121
|
+
"#00CED1",
|
|
122
|
+
"#F1AA03",
|
|
123
|
+
"#BA55D3",
|
|
124
|
+
"#1E90FF",
|
|
125
|
+
"#FF1493",
|
|
126
|
+
"#228B22",
|
|
127
|
+
"#800000",
|
|
128
|
+
"#FF00FF",
|
|
129
|
+
"#3FC55F",
|
|
130
|
+
"#8B008B",
|
|
131
|
+
"#808080",
|
|
132
|
+
"#fe00ed",
|
|
133
|
+
"#06eea7",
|
|
134
|
+
"#0085f9",
|
|
135
|
+
"#f5cf00",
|
|
136
|
+
"#ff6b6c",
|
|
137
|
+
"#d224ee",
|
|
138
|
+
"#5fdfa1",
|
|
139
|
+
"#ffa700",
|
|
140
|
+
"#00cdd6",
|
|
141
|
+
"#ffa110",
|
|
142
|
+
"#b751d5",
|
|
143
|
+
"#128ef4",
|
|
144
|
+
"#ff1688",
|
|
145
|
+
"#ff08f6",
|
|
146
|
+
"#43c961",
|
|
147
|
+
"#7a8784",
|
|
148
|
+
"#ff00ef",
|
|
149
|
+
"#0bfaad",
|
|
150
|
+
"#0086f3",
|
|
151
|
+
"#ffd700",
|
|
152
|
+
"#ff646b",
|
|
153
|
+
"#5ce394",
|
|
154
|
+
"#ffab00",
|
|
155
|
+
"#00d0cf",
|
|
156
|
+
"#fbaa03",
|
|
157
|
+
"#219aff",
|
|
158
|
+
"#ff137b",
|
|
159
|
+
"#ff0cf1",
|
|
160
|
+
"#39d56b",
|
|
161
|
+
"#6f9176",
|
|
162
|
+
"#fb00ea",
|
|
163
|
+
"#00fbb8",
|
|
164
|
+
"#0a91fb",
|
|
165
|
+
"#f8d902",
|
|
166
|
+
"#fb7073",
|
|
167
|
+
"#54dca1",
|
|
168
|
+
"#fb9d02",
|
|
169
|
+
"#00c2db",
|
|
170
|
+
"#ffb30f",
|
|
171
|
+
"#268cf0",
|
|
172
|
+
"#f11170",
|
|
173
|
+
"#f211f2",
|
|
174
|
+
"#47ce7a",
|
|
175
|
+
"#719b73",
|
|
176
|
+
"#f305e3",
|
|
177
|
+
"#03ffbd",
|
|
178
|
+
"#048df6",
|
|
179
|
+
"#ffe200",
|
|
180
|
+
"#f56973",
|
|
181
|
+
"#4cdeaf",
|
|
182
|
+
"#ff9a0f",
|
|
183
|
+
"#00c3ce",
|
|
184
|
+
"#ffb417",
|
|
185
|
+
"#2898f6",
|
|
186
|
+
"#f10468",
|
|
187
|
+
"#ff03e5",
|
|
188
|
+
"#54d584",
|
|
189
|
+
"#6a9179",
|
|
190
|
+
"#fe0be3",
|
|
191
|
+
"#00fec0",
|
|
192
|
+
"#0097fb",
|
|
193
|
+
"#feef01",
|
|
194
|
+
"#f2756e",
|
|
195
|
+
"#4ee0a4",
|
|
196
|
+
"#f29902",
|
|
197
|
+
"#00cfce",
|
|
198
|
+
"#ffa91e",
|
|
199
|
+
"#2292f9",
|
|
200
|
+
"#fb0361",
|
|
201
|
+
"#f306e6",
|
|
202
|
+
"#4ed78e",
|
|
203
|
+
"#70897c",
|
|
204
|
+
"#fe05e8",
|
|
205
|
+
"#00f6bd",
|
|
206
|
+
"#00a6ff",
|
|
207
|
+
"#ffe900",
|
|
208
|
+
"#f67b78",
|
|
209
|
+
"#40d3a0",
|
|
210
|
+
"#e98e10",
|
|
211
|
+
"#00d0db",
|
|
212
|
+
]
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def _create_colors() -> Tuple[str, str]:
|
|
216
|
+
idx = random.randint(0, len(_DARK_THEME_COLORS) - 1)
|
|
217
|
+
return _LIGHT_THEME_COLORS[idx], _DARK_THEME_COLORS[idx]
|
litlogger/diagnostics.py
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# Copyright The Lightning AI team.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
+
#
|
|
5
|
+
import os
|
|
6
|
+
import platform
|
|
7
|
+
import re
|
|
8
|
+
import subprocess
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
import pkg_resources
|
|
12
|
+
import psutil
|
|
13
|
+
|
|
14
|
+
import litlogger
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def get_os_info() -> str:
|
|
18
|
+
"""Return a pretty name of operating system and its version: 'Ubuntu 20.04.6 LTS' or 'MacOS 15.0.1'.
|
|
19
|
+
|
|
20
|
+
If it's not possible, then the more verbose name is returned:
|
|
21
|
+
'Linux-5.15.0-1070-aws-x86_64-with-glibc2.31' or 'macOS-15.0.1-arm64-arm-64bit'.
|
|
22
|
+
"""
|
|
23
|
+
os_name = platform.system()
|
|
24
|
+
default_os_name = platform.platform()
|
|
25
|
+
|
|
26
|
+
if os_name == "Linux":
|
|
27
|
+
try:
|
|
28
|
+
with open("/etc/os-release", encoding="utf-8") as f:
|
|
29
|
+
for line in f:
|
|
30
|
+
if line.startswith("PRETTY_NAME"):
|
|
31
|
+
return line.strip().split("=")[1].strip('"')
|
|
32
|
+
return default_os_name
|
|
33
|
+
except FileNotFoundError:
|
|
34
|
+
return default_os_name
|
|
35
|
+
|
|
36
|
+
if os_name == "Darwin":
|
|
37
|
+
try:
|
|
38
|
+
version = platform.mac_ver()[0]
|
|
39
|
+
return f"MacOS {version}"
|
|
40
|
+
except Exception:
|
|
41
|
+
return default_os_name
|
|
42
|
+
|
|
43
|
+
return default_os_name
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def get_cpu_name() -> str:
|
|
47
|
+
"""Return the name of the CPU (e.g. Apple M3 Pro, Intel(R) Xeon(R) Platinum 8488C)."""
|
|
48
|
+
system = platform.system()
|
|
49
|
+
try:
|
|
50
|
+
if system == "Linux":
|
|
51
|
+
cpu_info = subprocess.check_output("grep 'model name' /proc/cpuinfo | head -n 1", shell=True, text=True)
|
|
52
|
+
return cpu_info.split(":")[1].strip()
|
|
53
|
+
|
|
54
|
+
if system == "Darwin":
|
|
55
|
+
cpu_info = subprocess.check_output(["sysctl", "-n", "machdep.cpu.brand_string"], text=True)
|
|
56
|
+
return cpu_info.strip()
|
|
57
|
+
|
|
58
|
+
return ""
|
|
59
|
+
except Exception:
|
|
60
|
+
return ""
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def get_gpu_info() -> dict:
|
|
64
|
+
"""Return Nvidia GPU info: name, count and memory size in GB.
|
|
65
|
+
|
|
66
|
+
Example output: {"name": "Nvidia T4, "count": 4, "memory_gb": 16}
|
|
67
|
+
"""
|
|
68
|
+
default_output = {
|
|
69
|
+
"name": "",
|
|
70
|
+
"count": 0,
|
|
71
|
+
"memory_gb": 0,
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
output = subprocess.check_output(
|
|
76
|
+
["nvidia-smi", "--query-gpu=name,memory.total", "--format=csv,noheader,nounits"], text=True
|
|
77
|
+
).strip()
|
|
78
|
+
|
|
79
|
+
if not output:
|
|
80
|
+
return default_output
|
|
81
|
+
|
|
82
|
+
gpu_list = output.split("\n")
|
|
83
|
+
gpu_name, gpu_memory_mib = re.split(r",\s+", gpu_list[0])
|
|
84
|
+
gpu_memory_gb = round((int(gpu_memory_mib) / 1e6) * 1024)
|
|
85
|
+
|
|
86
|
+
return {"name": gpu_name, "count": len(gpu_list), "memory_gb": gpu_memory_gb}
|
|
87
|
+
|
|
88
|
+
except Exception:
|
|
89
|
+
return default_output
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def get_cuda_version() -> str:
|
|
93
|
+
"""Return the CUDA version installed on the system."""
|
|
94
|
+
try:
|
|
95
|
+
output = subprocess.check_output(["nvcc", "--version"], text=True)
|
|
96
|
+
match = re.search(r"release (\d+\.\d+)", output)
|
|
97
|
+
return match.group(1) if match else ""
|
|
98
|
+
except Exception:
|
|
99
|
+
return ""
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def get_cudnn_version() -> str:
|
|
103
|
+
"""Return the cuDNN version installed on the system."""
|
|
104
|
+
cudnn_path = "/usr/include/cudnn_version.h"
|
|
105
|
+
if os.path.isfile(cudnn_path):
|
|
106
|
+
# Read the file content and find cuDNN version
|
|
107
|
+
with open(cudnn_path, encoding="utf-8") as fin:
|
|
108
|
+
content = fin.read()
|
|
109
|
+
# Find the major, minor, and patch versions of cuDNN
|
|
110
|
+
major = re.search(r"#define CUDNN_MAJOR (\d+)", content)
|
|
111
|
+
minor = re.search(r"#define CUDNN_MINOR (\d+)", content)
|
|
112
|
+
patch = re.search(r"#define CUDNN_PATCHLEVEL (\d+)", content)
|
|
113
|
+
if major and minor and patch:
|
|
114
|
+
return f"{major.group(1)}.{minor.group(1)}.{patch.group(1)}"
|
|
115
|
+
return ""
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _parse_cmd_arguments(cmd_args: str) -> list[str]:
|
|
119
|
+
"""Parse command-line arguments into a list of strings.
|
|
120
|
+
|
|
121
|
+
>>> _parse_cmd_arguments("--option1 value1 --flag2 --option3 value3 --option4=value4")
|
|
122
|
+
['--option1 value1', '--flag2', '--option3 value3', '--option4 value4']
|
|
123
|
+
"""
|
|
124
|
+
return ["--" + arg.replace("=", " ").strip() for arg in cmd_args.strip().split("--") if arg]
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def get_cli_args() -> str:
|
|
128
|
+
r"""Parse and format command-line arguments into a human-readable string.
|
|
129
|
+
|
|
130
|
+
Pairs flags with their values (e.g., `--option value`) and leaves standalone
|
|
131
|
+
flags (e.g., `--flag`). Returns one argument or pair per line.
|
|
132
|
+
|
|
133
|
+
Example:
|
|
134
|
+
For the input
|
|
135
|
+
`["--option1", "value1", "--flag2", "--option3", "value3", "--option4=value4", "--option5 value5 value6"]`,
|
|
136
|
+
the output would be:
|
|
137
|
+
`"--option1 value1\n--flag2\n--option3 value3\n--option4 value4\n--option5 value5 value6"`.
|
|
138
|
+
"""
|
|
139
|
+
args_str = " ".join(sys.argv[1:])
|
|
140
|
+
return "\n".join(_parse_cmd_arguments(args_str))
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def collect_system_info() -> dict:
|
|
144
|
+
"""Collects git, system, hardware and CLI args information."""
|
|
145
|
+
|
|
146
|
+
# git
|
|
147
|
+
def get_git_info(command: list[str], default_message: str) -> str:
|
|
148
|
+
try:
|
|
149
|
+
return subprocess.check_output(
|
|
150
|
+
command,
|
|
151
|
+
text=True,
|
|
152
|
+
stderr=subprocess.DEVNULL,
|
|
153
|
+
).strip()
|
|
154
|
+
except subprocess.CalledProcessError:
|
|
155
|
+
return default_message
|
|
156
|
+
|
|
157
|
+
git_repo_name = get_git_info(["git", "rev-parse", "--show-toplevel"], "Not a git repository").split("/")[-1]
|
|
158
|
+
git_branch = get_git_info(["git", "rev-parse", "--abbrev-ref", "HEAD"], "No branch found")
|
|
159
|
+
git_commit_hash = get_git_info(["git", "rev-parse", "HEAD"], "No commit hash found")
|
|
160
|
+
|
|
161
|
+
# software
|
|
162
|
+
litlogger_version = litlogger.__version__
|
|
163
|
+
installed_packages = "\n".join(sorted([f"{pkg.project_name}=={pkg.version}" for pkg in pkg_resources.working_set]))
|
|
164
|
+
|
|
165
|
+
# hardware
|
|
166
|
+
system_memory_gb = psutil.virtual_memory().total // 1024**3
|
|
167
|
+
gpu_info = get_gpu_info()
|
|
168
|
+
|
|
169
|
+
# args
|
|
170
|
+
execution_command = os.path.abspath(sys.argv[0])
|
|
171
|
+
cli_args = get_cli_args()
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
"git_repo_name": git_repo_name,
|
|
175
|
+
"git_branch": git_branch,
|
|
176
|
+
"git_commit_hash": git_commit_hash,
|
|
177
|
+
"os_name": get_os_info(),
|
|
178
|
+
"python_version": platform.python_version(),
|
|
179
|
+
"litlogger_version": litlogger_version,
|
|
180
|
+
"installed_packages": installed_packages,
|
|
181
|
+
"cpu_name": get_cpu_name(),
|
|
182
|
+
"cpu_count_logical": psutil.cpu_count(logical=True),
|
|
183
|
+
"cpu_count_physical": psutil.cpu_count(logical=False),
|
|
184
|
+
"system_memory_gb": system_memory_gb,
|
|
185
|
+
"gpu_name": gpu_info["name"],
|
|
186
|
+
"gpu_count": gpu_info["count"],
|
|
187
|
+
"gpu_memory_gb": gpu_info["memory_gb"],
|
|
188
|
+
"cuda_version": get_cuda_version(),
|
|
189
|
+
"cudnn_version": get_cudnn_version(),
|
|
190
|
+
"execution_command": execution_command,
|
|
191
|
+
"cli_args": cli_args,
|
|
192
|
+
"hostname": platform.node(),
|
|
193
|
+
}
|