halib 0.2.35__py3-none-any.whl → 0.2.36__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.
- halib/exp/perf/profiler.py +51 -7
- halib/utils/plotly_op.py +8 -3
- {halib-0.2.35.dist-info → halib-0.2.36.dist-info}/METADATA +2 -2
- {halib-0.2.35.dist-info → halib-0.2.36.dist-info}/RECORD +7 -7
- {halib-0.2.35.dist-info → halib-0.2.36.dist-info}/WHEEL +0 -0
- {halib-0.2.35.dist-info → halib-0.2.36.dist-info}/licenses/LICENSE.txt +0 -0
- {halib-0.2.35.dist-info → halib-0.2.36.dist-info}/top_level.txt +0 -0
halib/exp/perf/profiler.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import time
|
|
3
3
|
import json
|
|
4
|
-
from pathlib import Path
|
|
5
4
|
from pprint import pprint
|
|
6
5
|
from threading import Lock
|
|
7
6
|
from functools import wraps
|
|
@@ -13,6 +12,7 @@ import plotly.graph_objects as go
|
|
|
13
12
|
import plotly.express as px # for dynamic color scales
|
|
14
13
|
|
|
15
14
|
from contextlib import contextmanager
|
|
15
|
+
from typing import Dict
|
|
16
16
|
|
|
17
17
|
from ...common.common import ConsoleLog
|
|
18
18
|
from ...system.path import *
|
|
@@ -171,6 +171,50 @@ class zProfiler:
|
|
|
171
171
|
finally:
|
|
172
172
|
self.step_end(ctx_name, step_name)
|
|
173
173
|
|
|
174
|
+
def merge_data(self, other_time_dict: Dict):
|
|
175
|
+
"""
|
|
176
|
+
Aggregates profiling data from an external dictionary into the current instance.
|
|
177
|
+
|
|
178
|
+
This method is designed for multiprocessing scenarios where worker processes
|
|
179
|
+
collect data in isolated memory spaces. It merges contexts and appends
|
|
180
|
+
step timings to the main profiler.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
other_time_dict (Dict): The `time_dict` returned from a worker process
|
|
184
|
+
(usually via `future.result()`).
|
|
185
|
+
|
|
186
|
+
Example:
|
|
187
|
+
>>> with ProcessPoolExecutor() as executor:
|
|
188
|
+
>>> # ... submit tasks ...
|
|
189
|
+
>>> futures = [executor.submit(worker_task, args) for args in task_args]
|
|
190
|
+
>>> for future in as_completed(futures):
|
|
191
|
+
>>> worker_data = future.result()
|
|
192
|
+
>>> main_profiler.merge_data(worker_data)
|
|
193
|
+
"""
|
|
194
|
+
with self._lock:
|
|
195
|
+
for ctx_name, other_ctx_data in other_time_dict.items():
|
|
196
|
+
# 1. New Context: Copy entire structure
|
|
197
|
+
if ctx_name not in self.time_dict:
|
|
198
|
+
self.time_dict[ctx_name] = other_ctx_data
|
|
199
|
+
continue
|
|
200
|
+
|
|
201
|
+
# 2. Existing Context: Merge Steps
|
|
202
|
+
local_step_dict = self.time_dict[ctx_name]["step_dict"]
|
|
203
|
+
other_step_dict = other_ctx_data["step_dict"]
|
|
204
|
+
|
|
205
|
+
for step_name, other_timings in other_step_dict.items():
|
|
206
|
+
if step_name not in local_step_dict:
|
|
207
|
+
local_step_dict[step_name] = other_timings
|
|
208
|
+
else:
|
|
209
|
+
# Append the list of timings (extend list of lists)
|
|
210
|
+
local_step_dict[step_name].extend(other_timings)
|
|
211
|
+
|
|
212
|
+
# 3. Aggregate metadata (report counts, etc.)
|
|
213
|
+
if "report_count" in other_ctx_data:
|
|
214
|
+
self.time_dict[ctx_name]["report_count"] += other_ctx_data[
|
|
215
|
+
"report_count"
|
|
216
|
+
]
|
|
217
|
+
|
|
174
218
|
def _step_dict_to_detail(self, ctx_step_dict):
|
|
175
219
|
"""
|
|
176
220
|
'ctx_step_dict': {
|
|
@@ -182,9 +226,9 @@ class zProfiler:
|
|
|
182
226
|
│ │ │ [278091.230944486, 278091.251378469],
|
|
183
227
|
│ }
|
|
184
228
|
"""
|
|
185
|
-
assert
|
|
186
|
-
|
|
187
|
-
)
|
|
229
|
+
assert (
|
|
230
|
+
len(ctx_step_dict.keys()) > 0
|
|
231
|
+
), "step_dict must have only one key (step_name) for detail."
|
|
188
232
|
normed_ctx_step_dict = {}
|
|
189
233
|
for step_name, time_list in ctx_step_dict.items():
|
|
190
234
|
if not isinstance(ctx_step_dict[step_name], list):
|
|
@@ -246,9 +290,9 @@ class zProfiler:
|
|
|
246
290
|
report_dict[ctx_name]["step_dict"]["summary"]["avg_time"][
|
|
247
291
|
f"avg_{step_name}"
|
|
248
292
|
] = avg_time
|
|
249
|
-
report_dict[ctx_name]["step_dict"]["summary"][
|
|
250
|
-
total_avg_time
|
|
251
|
-
|
|
293
|
+
report_dict[ctx_name]["step_dict"]["summary"][
|
|
294
|
+
"total_avg_time"
|
|
295
|
+
] = total_avg_time
|
|
252
296
|
report_dict[ctx_name]["step_dict"]["summary"] = dict(
|
|
253
297
|
sorted(report_dict[ctx_name]["step_dict"]["summary"].items())
|
|
254
298
|
)
|
halib/utils/plotly_op.py
CHANGED
|
@@ -17,7 +17,10 @@ class PlotlyUtils:
|
|
|
17
17
|
parts = name.split("__")
|
|
18
18
|
exp_id = parts[-2] if len(parts) >= 2 else name
|
|
19
19
|
exp_ids.append(exp_id)
|
|
20
|
-
|
|
20
|
+
# ! make sure series index matches df index
|
|
21
|
+
# ! if not, it will cause misalignment issues later
|
|
22
|
+
assert len(exp_ids) == len(df), "exp_id_extractor: Length mismatch"
|
|
23
|
+
return pd.Series(exp_ids, index=df.index)
|
|
21
24
|
|
|
22
25
|
@staticmethod
|
|
23
26
|
def exp_id_formatter(exp_id: str) -> str:
|
|
@@ -148,8 +151,10 @@ class PlotlyUtils:
|
|
|
148
151
|
table.dataTable thead th {{
|
|
149
152
|
background-color: #333;
|
|
150
153
|
color: white;
|
|
151
|
-
padding: 8px !important;
|
|
154
|
+
padding: 8px 12px !important;
|
|
155
|
+
padding-right: 20px !important; /* THIS LINE FIXES THE OVERLAP */
|
|
152
156
|
font-size: 12px;
|
|
157
|
+
position: relative; /* Ensures sort icons align correctly */
|
|
153
158
|
}}
|
|
154
159
|
table.dataTable tbody td {{
|
|
155
160
|
padding: 4px 8px !important; /* Compact rows */
|
|
@@ -157,7 +162,7 @@ class PlotlyUtils:
|
|
|
157
162
|
|
|
158
163
|
#exp_table tbody tr:nth-child(even), #selected_table tbody tr:nth-child(even) {{ background-color: #f2f2f2; }}
|
|
159
164
|
#exp_table tbody tr:nth-child(odd), #selected_table tbody tr:nth-child(odd) {{ background-color: #ffffff; }}
|
|
160
|
-
#exp_table tbody tr:hover, #selected_table tbody tr:hover {{ background-color: #
|
|
165
|
+
#exp_table tbody tr:hover, #selected_table tbody tr:hover {{ background-color: #adadad; }}
|
|
161
166
|
|
|
162
167
|
h2 {{ color: #2c3e50; border-bottom: 2px solid #eee; padding-bottom: 10px; margin-top: 40px; }}
|
|
163
168
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: halib
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.36
|
|
4
4
|
Summary: Small library for common tasks
|
|
5
5
|
Author: Hoang Van Ha
|
|
6
6
|
Author-email: hoangvanhauit@gmail.com
|
|
@@ -57,7 +57,7 @@ Dynamic: summary
|
|
|
57
57
|
|
|
58
58
|
## v0.2.x (Experiment & Core Updates)
|
|
59
59
|
|
|
60
|
-
### **v0.2.
|
|
60
|
+
### **v0.2.36**
|
|
61
61
|
|
|
62
62
|
- ✨ **New Feature:**: introduce `utils.PlotlyUtils` with parallel coordinates plot and data table support
|
|
63
63
|
|
|
@@ -35,7 +35,7 @@ halib/exp/perf/gpu_mon.py,sha256=vD41_ZnmPLKguuq9X44SB_vwd9JrblO4BDzHLXZhhFY,223
|
|
|
35
35
|
halib/exp/perf/perfcalc.py,sha256=zb0eGt24kPVC2HTq9M095wP6y8TqOicWy52BxAigap0,19834
|
|
36
36
|
halib/exp/perf/perfmetrics.py,sha256=qRiNiCKGUSTLY7gPMVMuVHGAAyeosfGWup2eM4490aw,5485
|
|
37
37
|
halib/exp/perf/perftb.py,sha256=IWElg3OB5dmhfxnY8pMZvkL2y_EnvLmEx3gJlpUR1Fs,31066
|
|
38
|
-
halib/exp/perf/profiler.py,sha256=
|
|
38
|
+
halib/exp/perf/profiler.py,sha256=Ar7MeWZ8xBo6Inp5-3Kl8bVgk996oPDAjFno9p3Kamc,21247
|
|
39
39
|
halib/exp/viz/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
40
|
halib/exp/viz/plot.py,sha256=51FhD1mH4nthTrY3K4mrO5pxI5AzvHXpZy5_ToqkYHs,28580
|
|
41
41
|
halib/filetype/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -100,14 +100,14 @@ halib/utils/dict_op.py,sha256=wYE6Iw-_CnCWdMg9tpJ2Y2-e2ESkW9FxmdBkZkbUh80,299
|
|
|
100
100
|
halib/utils/gpu_mon.py,sha256=vD41_ZnmPLKguuq9X44SB_vwd9JrblO4BDzHLXZhhFY,2233
|
|
101
101
|
halib/utils/list.py,sha256=bbey9_0IaMXnHx1pudv3C3_WU9uFQEQ5qHPklSN-7o0,498
|
|
102
102
|
halib/utils/listop.py,sha256=Vpa8_2fI0wySpB2-8sfTBkyi_A4FhoFVVvFiuvW8N64,339
|
|
103
|
-
halib/utils/plotly_op.py,sha256=
|
|
103
|
+
halib/utils/plotly_op.py,sha256=AkrY7UIHz5qnqrGkgpgiadLSlbVGEZh4Un43ntG5zy0,10259
|
|
104
104
|
halib/utils/slack.py,sha256=2ugWE_eJ0s479ObACJbx7iEu3kjMPD4Rt2hEwuMpuNQ,3099
|
|
105
105
|
halib/utils/slack_op.py,sha256=2ugWE_eJ0s479ObACJbx7iEu3kjMPD4Rt2hEwuMpuNQ,3099
|
|
106
106
|
halib/utils/tele_noti.py,sha256=-4WXZelCA4W9BroapkRyIdUu9cUVrcJJhegnMs_WpGU,5928
|
|
107
107
|
halib/utils/video.py,sha256=zLoj5EHk4SmP9OnoHjO8mLbzPdtq6gQPzTQisOEDdO8,3261
|
|
108
108
|
halib/utils/wandb_op.py,sha256=qqDdTMW4J07bzuJTTg2HoLAPs21nVEbwt2-Aa5ZKiVk,4336
|
|
109
|
-
halib-0.2.
|
|
110
|
-
halib-0.2.
|
|
111
|
-
halib-0.2.
|
|
112
|
-
halib-0.2.
|
|
113
|
-
halib-0.2.
|
|
109
|
+
halib-0.2.36.dist-info/licenses/LICENSE.txt,sha256=qZssdna4aETiR8znYsShUjidu-U4jUT9Q-EWNlZ9yBQ,1100
|
|
110
|
+
halib-0.2.36.dist-info/METADATA,sha256=KsZ_QxXIwLzC06Xd6xR-iGiGgsKYj7L3ZD4fqqDItzo,8379
|
|
111
|
+
halib-0.2.36.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
112
|
+
halib-0.2.36.dist-info/top_level.txt,sha256=7AD6PLaQTreE0Fn44mdZsoHBe_Zdd7GUmjsWPyQ7I-k,6
|
|
113
|
+
halib-0.2.36.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|