halib 0.2.19__tar.gz → 0.2.20__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.
- {halib-0.2.19 → halib-0.2.20}/PKG-INFO +4 -1
- {halib-0.2.19 → halib-0.2.20}/README.md +3 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/perf/profiler.py +131 -12
- {halib-0.2.19 → halib-0.2.20}/halib.egg-info/PKG-INFO +4 -1
- {halib-0.2.19 → halib-0.2.20}/setup.py +1 -1
- {halib-0.2.19 → halib-0.2.20}/.gitignore +0 -0
- {halib-0.2.19 → halib-0.2.20}/GDriveFolder.txt +0 -0
- {halib-0.2.19 → halib-0.2.20}/LICENSE.txt +0 -0
- {halib-0.2.19 → halib-0.2.20}/MANIFEST.in +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/__init__.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/common/__init__.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/common/common.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/common/rich_color.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/__init__.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/core/__init__.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/core/base_config.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/core/base_exp.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/core/param_gen.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/core/wandb_op.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/data/__init__.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/data/dataclass_util.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/data/dataset.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/data/torchloader.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/perf/__init__.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/perf/flop_calc.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/perf/gpu_mon.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/perf/perfcalc.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/perf/perfmetrics.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/perf/perftb.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/viz/__init__.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/exp/viz/plot.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/filetype/__init__.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/filetype/csvfile.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/filetype/ipynb.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/filetype/jsonfile.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/filetype/textfile.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/filetype/videofile.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/filetype/yamlfile.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/online/__init__.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/online/gdrive.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/online/gdrive_mkdir.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/online/projectmake.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/online/tele_noti.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/system/__init__.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/system/_list_pc.csv +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/system/cmd.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/system/filesys.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/system/path.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/utils/__init__.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/utils/dict.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib/utils/list.py +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib.egg-info/SOURCES.txt +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib.egg-info/dependency_links.txt +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib.egg-info/requires.txt +0 -0
- {halib-0.2.19 → halib-0.2.20}/halib.egg-info/top_level.txt +0 -0
- {halib-0.2.19 → halib-0.2.20}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: halib
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.20
|
|
4
4
|
Summary: Small library for common tasks
|
|
5
5
|
Author: Hoang Van Ha
|
|
6
6
|
Author-email: hoangvanhauit@gmail.com
|
|
@@ -56,6 +56,9 @@ Dynamic: summary
|
|
|
56
56
|
|
|
57
57
|
## v0.2.x (Experiment & Core Updates)
|
|
58
58
|
|
|
59
|
+
### **v0.2.20**
|
|
60
|
+
- 🚀 **Improvement:** `exp.perf.profiler` - allow to export *report dict* as csv files for further analysis
|
|
61
|
+
|
|
59
62
|
### **v0.2.19**
|
|
60
63
|
- ✨ **New Feature:** Added `exp.core.param_gen` to facilitate fast generation of parameter combination sweeps (grid search) using YAML configurations.
|
|
61
64
|
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## v0.2.x (Experiment & Core Updates)
|
|
4
4
|
|
|
5
|
+
### **v0.2.20**
|
|
6
|
+
- 🚀 **Improvement:** `exp.perf.profiler` - allow to export *report dict* as csv files for further analysis
|
|
7
|
+
|
|
5
8
|
### **v0.2.19**
|
|
6
9
|
- ✨ **New Feature:** Added `exp.core.param_gen` to facilitate fast generation of parameter combination sweeps (grid search) using YAML configurations.
|
|
7
10
|
|
|
@@ -182,9 +182,9 @@ class zProfiler:
|
|
|
182
182
|
│ │ │ [278091.230944486, 278091.251378469],
|
|
183
183
|
│ }
|
|
184
184
|
"""
|
|
185
|
-
assert (
|
|
186
|
-
|
|
187
|
-
)
|
|
185
|
+
assert len(ctx_step_dict.keys()) > 0, (
|
|
186
|
+
"step_dict must have only one key (step_name) for detail."
|
|
187
|
+
)
|
|
188
188
|
normed_ctx_step_dict = {}
|
|
189
189
|
for step_name, time_list in ctx_step_dict.items():
|
|
190
190
|
if not isinstance(ctx_step_dict[step_name], list):
|
|
@@ -246,14 +246,126 @@ class zProfiler:
|
|
|
246
246
|
report_dict[ctx_name]["step_dict"]["summary"]["avg_time"][
|
|
247
247
|
f"avg_{step_name}"
|
|
248
248
|
] = avg_time
|
|
249
|
-
report_dict[ctx_name]["step_dict"]["summary"][
|
|
250
|
-
|
|
251
|
-
|
|
249
|
+
report_dict[ctx_name]["step_dict"]["summary"]["total_avg_time"] = (
|
|
250
|
+
total_avg_time
|
|
251
|
+
)
|
|
252
252
|
report_dict[ctx_name]["step_dict"]["summary"] = dict(
|
|
253
253
|
sorted(report_dict[ctx_name]["step_dict"]["summary"].items())
|
|
254
254
|
)
|
|
255
255
|
return report_dict
|
|
256
256
|
|
|
257
|
+
def get_report_dataframes(self):
|
|
258
|
+
"""
|
|
259
|
+
Returns two pandas DataFrames containing profiling data.
|
|
260
|
+
|
|
261
|
+
Returns:
|
|
262
|
+
tuple: (df_summary, df_detail)
|
|
263
|
+
- df_summary: Aggregated stats (Context, Step, Avg, %, Count)
|
|
264
|
+
- df_detail: Raw duration for every single iteration
|
|
265
|
+
"""
|
|
266
|
+
try:
|
|
267
|
+
import pandas as pd
|
|
268
|
+
except ImportError:
|
|
269
|
+
logger.error(
|
|
270
|
+
"Pandas is required for get_pandas_dfs(). Please pip install pandas."
|
|
271
|
+
)
|
|
272
|
+
return None, None
|
|
273
|
+
|
|
274
|
+
# Get full data structure
|
|
275
|
+
data = self.get_report_dict(with_detail=True)
|
|
276
|
+
|
|
277
|
+
summary_rows = []
|
|
278
|
+
detail_rows = []
|
|
279
|
+
|
|
280
|
+
for ctx_name, ctx_data in data.items():
|
|
281
|
+
summary = ctx_data["step_dict"]["summary"]
|
|
282
|
+
detail_dict = ctx_data["step_dict"]["detail"]
|
|
283
|
+
|
|
284
|
+
# --- 1. Build Summary Data ---
|
|
285
|
+
# Iterate keys in 'avg_time' to ensure we capture all steps
|
|
286
|
+
for avg_key, avg_val in summary["avg_time"].items():
|
|
287
|
+
step_name = avg_key.replace("avg_", "")
|
|
288
|
+
|
|
289
|
+
# Get corresponding percent
|
|
290
|
+
per_key = f"per_{step_name}"
|
|
291
|
+
percent_val = summary["percent_time"].get(per_key, 0.0)
|
|
292
|
+
|
|
293
|
+
# Get sample count from detail list length
|
|
294
|
+
count = len(detail_dict.get(step_name, []))
|
|
295
|
+
|
|
296
|
+
summary_rows.append(
|
|
297
|
+
{
|
|
298
|
+
"context_name": ctx_name,
|
|
299
|
+
"step_name": step_name,
|
|
300
|
+
"avg_time_sec": avg_val,
|
|
301
|
+
"percent_total": percent_val,
|
|
302
|
+
"sample_count": count,
|
|
303
|
+
}
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
# --- 2. Build Detail Data ---
|
|
307
|
+
for step_name, time_list in detail_dict.items():
|
|
308
|
+
# time_list format: [(idx, duration), (idx, duration)...]
|
|
309
|
+
for item in time_list:
|
|
310
|
+
if len(item) == 2:
|
|
311
|
+
idx, duration = item
|
|
312
|
+
detail_rows.append(
|
|
313
|
+
{
|
|
314
|
+
"context_name": ctx_name,
|
|
315
|
+
"step_name": step_name,
|
|
316
|
+
"iteration_idx": idx,
|
|
317
|
+
"duration_sec": duration,
|
|
318
|
+
}
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
# Create DataFrames
|
|
322
|
+
df_summary = pd.DataFrame(summary_rows)
|
|
323
|
+
df_detail = pd.DataFrame(detail_rows)
|
|
324
|
+
|
|
325
|
+
# Reorder columns for readability (optional but nice)
|
|
326
|
+
if not df_summary.empty:
|
|
327
|
+
df_summary = df_summary[
|
|
328
|
+
[
|
|
329
|
+
"context_name",
|
|
330
|
+
"step_name",
|
|
331
|
+
"avg_time_sec",
|
|
332
|
+
"percent_total",
|
|
333
|
+
"sample_count",
|
|
334
|
+
]
|
|
335
|
+
]
|
|
336
|
+
|
|
337
|
+
if not df_detail.empty:
|
|
338
|
+
df_detail = df_detail[
|
|
339
|
+
["context_name", "step_name", "iteration_idx", "duration_sec"]
|
|
340
|
+
]
|
|
341
|
+
|
|
342
|
+
return df_summary, df_detail
|
|
343
|
+
|
|
344
|
+
def get_report_csv_files(self, outdir, tag="profiler"):
|
|
345
|
+
"""
|
|
346
|
+
Exports profiling data to two CSV files:
|
|
347
|
+
1. {tag}_summary.csv: Aggregated stats (Avg time, %)
|
|
348
|
+
2. {tag}_detailed_logs.csv: Raw duration for every iteration
|
|
349
|
+
|
|
350
|
+
Args:
|
|
351
|
+
outdir (str): Directory to save files.
|
|
352
|
+
tag (str): Optional prefix for filenames.
|
|
353
|
+
"""
|
|
354
|
+
|
|
355
|
+
if not os.path.exists(outdir):
|
|
356
|
+
os.makedirs(outdir)
|
|
357
|
+
tag_str = f"{tag}_" if tag else ""
|
|
358
|
+
summary_file = os.path.join(outdir, f"{tag_str}summary.csv")
|
|
359
|
+
detail_file = os.path.join(outdir, f"{tag_str}detailed_logs.csv")
|
|
360
|
+
|
|
361
|
+
df_summary, df_detail = self.get_report_dataframes()
|
|
362
|
+
if df_summary is not None:
|
|
363
|
+
df_summary.to_csv(summary_file, index=False, sep=";", encoding="utf-8")
|
|
364
|
+
logger.info(f"Saved summary CSV to: {summary_file}")
|
|
365
|
+
if df_detail is not None:
|
|
366
|
+
df_detail.to_csv(detail_file, index=False, sep=";", encoding="utf-8")
|
|
367
|
+
logger.info(f"Saved detailed logs CSV to: {detail_file}")
|
|
368
|
+
|
|
257
369
|
@classmethod
|
|
258
370
|
def plot_formatted_data(
|
|
259
371
|
cls, profiler_data, outdir=None, file_format="png", do_show=False, tag=""
|
|
@@ -282,9 +394,13 @@ class zProfiler:
|
|
|
282
394
|
|
|
283
395
|
assert n_steps > 0, "No steps found for context: {}".format(ctx)
|
|
284
396
|
# Generate dynamic colors
|
|
285
|
-
colors =
|
|
286
|
-
|
|
287
|
-
|
|
397
|
+
colors = (
|
|
398
|
+
px.colors.sample_colorscale(
|
|
399
|
+
"Viridis", [i / (n_steps - 1) for i in range(n_steps)]
|
|
400
|
+
)
|
|
401
|
+
if n_steps > 1
|
|
402
|
+
else [px.colors.sample_colorscale("Viridis", [0])[0]]
|
|
403
|
+
)
|
|
288
404
|
# pprint(f'{len(colors)} colors generated for {n_steps} steps')
|
|
289
405
|
color_map = dict(zip(step_names, colors))
|
|
290
406
|
|
|
@@ -301,7 +417,7 @@ class zProfiler:
|
|
|
301
417
|
go.Bar(
|
|
302
418
|
x=step_names,
|
|
303
419
|
y=list(avg_times.values()),
|
|
304
|
-
text=[f"{v*1000:.2f} ms" for v in avg_times.values()],
|
|
420
|
+
text=[f"{v * 1000:.2f} ms" for v in avg_times.values()],
|
|
305
421
|
textposition="outside",
|
|
306
422
|
marker=dict(color=[color_map[s] for s in step_names]),
|
|
307
423
|
name="", # unified legend
|
|
@@ -345,7 +461,9 @@ class zProfiler:
|
|
|
345
461
|
# Save figure
|
|
346
462
|
if outdir is not None:
|
|
347
463
|
file_prefix = ctx if len(tag_str) == 0 else f"{tag_str}_{ctx}"
|
|
348
|
-
file_path = os.path.join(
|
|
464
|
+
file_path = os.path.join(
|
|
465
|
+
outdir, f"{file_prefix}_summary.{file_format.lower()}"
|
|
466
|
+
)
|
|
349
467
|
fig.write_image(file_path)
|
|
350
468
|
pprint(f"Saved figure to: 🔽")
|
|
351
469
|
pprint_local_path(file_path)
|
|
@@ -368,6 +486,7 @@ class zProfiler:
|
|
|
368
486
|
return self.plot_formatted_data(
|
|
369
487
|
report, outdir=outdir, file_format=file_format, do_show=do_show, tag=tag
|
|
370
488
|
)
|
|
489
|
+
|
|
371
490
|
def meta_info(self):
|
|
372
491
|
"""
|
|
373
492
|
Print the structure of the profiler's time dictionary.
|
|
@@ -375,7 +494,7 @@ class zProfiler:
|
|
|
375
494
|
"""
|
|
376
495
|
for ctx_name, ctx_dict in self.time_dict.items():
|
|
377
496
|
with ConsoleLog(f"Context: {ctx_name}"):
|
|
378
|
-
step_names = list(ctx_dict[
|
|
497
|
+
step_names = list(ctx_dict["step_dict"].keys())
|
|
379
498
|
for step_name in step_names:
|
|
380
499
|
pprint(f"Step: {step_name}")
|
|
381
500
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: halib
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.20
|
|
4
4
|
Summary: Small library for common tasks
|
|
5
5
|
Author: Hoang Van Ha
|
|
6
6
|
Author-email: hoangvanhauit@gmail.com
|
|
@@ -56,6 +56,9 @@ Dynamic: summary
|
|
|
56
56
|
|
|
57
57
|
## v0.2.x (Experiment & Core Updates)
|
|
58
58
|
|
|
59
|
+
### **v0.2.20**
|
|
60
|
+
- 🚀 **Improvement:** `exp.perf.profiler` - allow to export *report dict* as csv files for further analysis
|
|
61
|
+
|
|
59
62
|
### **v0.2.19**
|
|
60
63
|
- ✨ **New Feature:** Added `exp.core.param_gen` to facilitate fast generation of parameter combination sweeps (grid search) using YAML configurations.
|
|
61
64
|
|
|
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
|
|
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
|