halib 0.2.34__tar.gz → 0.2.36__tar.gz

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.
Files changed (58) hide show
  1. {halib-0.2.34 → halib-0.2.36}/PKG-INFO +2 -2
  2. {halib-0.2.34 → halib-0.2.36}/README.md +1 -1
  3. {halib-0.2.34 → halib-0.2.36}/halib/exp/perf/profiler.py +51 -7
  4. {halib-0.2.34 → halib-0.2.36}/halib/utils/plotly_op.py +41 -22
  5. {halib-0.2.34 → halib-0.2.36}/halib.egg-info/PKG-INFO +2 -2
  6. {halib-0.2.34 → halib-0.2.36}/setup.py +1 -1
  7. {halib-0.2.34 → halib-0.2.36}/.gitignore +0 -0
  8. {halib-0.2.34 → halib-0.2.36}/GDriveFolder.txt +0 -0
  9. {halib-0.2.34 → halib-0.2.36}/LICENSE.txt +0 -0
  10. {halib-0.2.34 → halib-0.2.36}/MANIFEST.in +0 -0
  11. {halib-0.2.34 → halib-0.2.36}/halib/__init__.py +0 -0
  12. {halib-0.2.34 → halib-0.2.36}/halib/common/__init__.py +0 -0
  13. {halib-0.2.34 → halib-0.2.36}/halib/common/common.py +0 -0
  14. {halib-0.2.34 → halib-0.2.36}/halib/common/rich_color.py +0 -0
  15. {halib-0.2.34 → halib-0.2.36}/halib/exp/__init__.py +0 -0
  16. {halib-0.2.34 → halib-0.2.36}/halib/exp/core/__init__.py +0 -0
  17. {halib-0.2.34 → halib-0.2.36}/halib/exp/core/base_config.py +0 -0
  18. {halib-0.2.34 → halib-0.2.36}/halib/exp/core/base_exp.py +0 -0
  19. {halib-0.2.34 → halib-0.2.36}/halib/exp/core/param_gen.py +0 -0
  20. {halib-0.2.34 → halib-0.2.36}/halib/exp/data/__init__.py +0 -0
  21. {halib-0.2.34 → halib-0.2.36}/halib/exp/data/dataclass_util.py +0 -0
  22. {halib-0.2.34 → halib-0.2.36}/halib/exp/data/dataset.py +0 -0
  23. {halib-0.2.34 → halib-0.2.36}/halib/exp/data/torchloader.py +0 -0
  24. {halib-0.2.34 → halib-0.2.36}/halib/exp/perf/__init__.py +0 -0
  25. {halib-0.2.34 → halib-0.2.36}/halib/exp/perf/flop_calc.py +0 -0
  26. {halib-0.2.34 → halib-0.2.36}/halib/exp/perf/gpu_mon.py +0 -0
  27. {halib-0.2.34 → halib-0.2.36}/halib/exp/perf/perfcalc.py +0 -0
  28. {halib-0.2.34 → halib-0.2.36}/halib/exp/perf/perfmetrics.py +0 -0
  29. {halib-0.2.34 → halib-0.2.36}/halib/exp/perf/perftb.py +0 -0
  30. {halib-0.2.34 → halib-0.2.36}/halib/exp/viz/__init__.py +0 -0
  31. {halib-0.2.34 → halib-0.2.36}/halib/exp/viz/plot.py +0 -0
  32. {halib-0.2.34 → halib-0.2.36}/halib/filetype/__init__.py +0 -0
  33. {halib-0.2.34 → halib-0.2.36}/halib/filetype/csvfile.py +0 -0
  34. {halib-0.2.34 → halib-0.2.36}/halib/filetype/ipynb.py +0 -0
  35. {halib-0.2.34 → halib-0.2.36}/halib/filetype/jsonfile.py +0 -0
  36. {halib-0.2.34 → halib-0.2.36}/halib/filetype/textfile.py +0 -0
  37. {halib-0.2.34 → halib-0.2.36}/halib/filetype/videofile.py +0 -0
  38. {halib-0.2.34 → halib-0.2.36}/halib/filetype/yamlfile.py +0 -0
  39. {halib-0.2.34 → halib-0.2.36}/halib/online/__init__.py +0 -0
  40. {halib-0.2.34 → halib-0.2.36}/halib/online/gdrive.py +0 -0
  41. {halib-0.2.34 → halib-0.2.36}/halib/online/gdrive_mkdir.py +0 -0
  42. {halib-0.2.34 → halib-0.2.36}/halib/online/projectmake.py +0 -0
  43. {halib-0.2.34 → halib-0.2.36}/halib/online/tele_noti.py +0 -0
  44. {halib-0.2.34 → halib-0.2.36}/halib/system/__init__.py +0 -0
  45. {halib-0.2.34 → halib-0.2.36}/halib/system/_list_pc.csv +0 -0
  46. {halib-0.2.34 → halib-0.2.36}/halib/system/cmd.py +0 -0
  47. {halib-0.2.34 → halib-0.2.36}/halib/system/filesys.py +0 -0
  48. {halib-0.2.34 → halib-0.2.36}/halib/system/path.py +0 -0
  49. {halib-0.2.34 → halib-0.2.36}/halib/utils/__init__.py +0 -0
  50. {halib-0.2.34 → halib-0.2.36}/halib/utils/dict.py +0 -0
  51. {halib-0.2.34 → halib-0.2.36}/halib/utils/list.py +0 -0
  52. {halib-0.2.34 → halib-0.2.36}/halib/utils/slack_op.py +0 -0
  53. {halib-0.2.34 → halib-0.2.36}/halib/utils/wandb_op.py +0 -0
  54. {halib-0.2.34 → halib-0.2.36}/halib.egg-info/SOURCES.txt +0 -0
  55. {halib-0.2.34 → halib-0.2.36}/halib.egg-info/dependency_links.txt +0 -0
  56. {halib-0.2.34 → halib-0.2.36}/halib.egg-info/requires.txt +0 -0
  57. {halib-0.2.34 → halib-0.2.36}/halib.egg-info/top_level.txt +0 -0
  58. {halib-0.2.34 → halib-0.2.36}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: halib
3
- Version: 0.2.34
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.34**
60
+ ### **v0.2.36**
61
61
 
62
62
  - ✨ **New Feature:**: introduce `utils.PlotlyUtils` with parallel coordinates plot and data table support
63
63
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## v0.2.x (Experiment & Core Updates)
4
4
 
5
- ### **v0.2.34**
5
+ ### **v0.2.36**
6
6
 
7
7
  - ✨ **New Feature:**: introduce `utils.PlotlyUtils` with parallel coordinates plot and data table support
8
8
 
@@ -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 len(ctx_step_dict.keys()) > 0, (
186
- "step_dict must have only one key (step_name) for detail."
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"]["total_avg_time"] = (
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
  )
@@ -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
- return pd.Series(exp_ids)
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:
@@ -109,25 +112,13 @@ class PlotlyUtils:
109
112
  # 5. Prepare Table Display
110
113
  # Clean up columns: Move exp_id to front, drop internal numeric_id
111
114
  cols = ["exp_id"] + [c for c in df.columns if c not in ["exp_id", "numeric_id"]]
115
+ cols = [col for col in cols if col not in exclude_dims]
116
+
112
117
  df_display = df[cols].copy()
113
118
  df_display.insert(0, "Selection", '<button class="select-btn">Select</button>')
114
119
 
115
120
  chart_html = fig.to_html(full_html=False, include_plotlyjs="cdn")
116
121
 
117
- # Create a display copy with a 'Select' button column
118
- df_display = df.copy()
119
- df_display_cols = df_display.columns.tolist()
120
- # move 'exp_id' to the front for better visibility
121
- if "exp_id" in df_display_cols:
122
- df_display_cols.insert(
123
- 0, df_display_cols.pop(df_display_cols.index("exp_id"))
124
- )
125
- df_display = df_display[df_display_cols]
126
- # remove 'numeric_id' from display
127
- if "numeric_id" in df_display.columns:
128
- df_display = df_display.drop(columns=["numeric_id"])
129
- df_display.insert(0, "Selection", '<button class="select-btn">Select</button>')
130
-
131
122
  table_html = df_display.to_html(
132
123
  classes="display nowrap", table_id="exp_table", index=False, escape=False
133
124
  )
@@ -141,16 +132,44 @@ class PlotlyUtils:
141
132
  <script type="text/javascript" charset="utf8" src="https://code.jquery.com/jquery-3.5.1.js"></script>
142
133
  <script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.js"></script>
143
134
  <style>
144
- body {{ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 20px; background-color: #f0f2f5; }}
145
- .container {{ background: white; padding: 30px; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.08); }}
135
+ body {{
136
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
137
+ margin: 20px;
138
+ background-color: #f0f2f5;
139
+ }}
140
+ .container {{
141
+ background: white;
142
+ padding: 30px;
143
+ border-radius: 12px;
144
+ box-shadow: 0 4px 20px rgba(0,0,0,0.08);
145
+ }}
146
+
147
+ /* --- TABLE FONT SIZE FIX --- */
148
+ table.dataTable {{
149
+ font-size: 11px; /* Smaller overall text */
150
+ }}
151
+ table.dataTable thead th {{
152
+ background-color: #333;
153
+ color: white;
154
+ padding: 8px 12px !important;
155
+ padding-right: 20px !important; /* THIS LINE FIXES THE OVERLAP */
156
+ font-size: 12px;
157
+ position: relative; /* Ensures sort icons align correctly */
158
+ }}
159
+ table.dataTable tbody td {{
160
+ padding: 4px 8px !important; /* Compact rows */
161
+ }}
162
+
146
163
  #exp_table tbody tr:nth-child(even), #selected_table tbody tr:nth-child(even) {{ background-color: #f2f2f2; }}
147
164
  #exp_table tbody tr:nth-child(odd), #selected_table tbody tr:nth-child(odd) {{ background-color: #ffffff; }}
148
- #exp_table tbody tr:hover, #selected_table tbody tr:hover {{ background-color: #e0e0e0; }}
149
- table.dataTable thead th {{ background-color: #333; color: white; padding: 12px; }}
165
+ #exp_table tbody tr:hover, #selected_table tbody tr:hover {{ background-color: #adadad; }}
166
+
150
167
  h2 {{ color: #2c3e50; border-bottom: 2px solid #eee; padding-bottom: 10px; margin-top: 40px; }}
151
- .select-btn {{ background-color: #28a745; color: white; border: none; padding: 5px 10px; cursor: pointer; border-radius: 4px; }}
152
- .remove-btn {{ background-color: #dc3545; color: white; border: none; padding: 5px 10px; cursor: pointer; border-radius: 4px; }}
153
- .clear-btn {{ background-color: #6c757d; color: white; border: none; padding: 10px 15px; cursor: pointer; border-radius: 4px; margin-bottom: 10px; }}
168
+
169
+ /* Smaller buttons */
170
+ .select-btn {{ background-color: #28a745; color: white; border: none; padding: 3px 7px; cursor: pointer; border-radius: 4px; font-size: 10px; }}
171
+ .remove-btn {{ background-color: #dc3545; color: white; border: none; padding: 3px 7px; cursor: pointer; border-radius: 4px; font-size: 10px; }}
172
+ .clear-btn {{ background-color: #6c757d; color: white; border: none; padding: 8px 12px; cursor: pointer; border-radius: 4px; margin-bottom: 10px; font-size: 12px; }}
154
173
  </style>
155
174
  </head>
156
175
  <body>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: halib
3
- Version: 0.2.34
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.34**
60
+ ### **v0.2.36**
61
61
 
62
62
  - ✨ **New Feature:**: introduce `utils.PlotlyUtils` with parallel coordinates plot and data table support
63
63
 
@@ -8,7 +8,7 @@ with open("requirements.txt", "r", encoding="utf-8") as f:
8
8
 
9
9
  setuptools.setup(
10
10
  name="halib",
11
- version="0.2.34",
11
+ version="0.2.36",
12
12
  author="Hoang Van Ha",
13
13
  author_email="hoangvanhauit@gmail.com",
14
14
  description="Small library for common tasks",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes