halib 0.2.13__py3-none-any.whl → 0.2.14__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.
@@ -1,19 +1,48 @@
1
1
  import os
2
2
  import time
3
3
  import json
4
-
5
4
  from pathlib import Path
6
5
  from pprint import pprint
7
6
  from threading import Lock
7
+ from functools import wraps
8
8
  from loguru import logger
9
9
 
10
+ # Plotting libraries
10
11
  from plotly.subplots import make_subplots
11
12
  import plotly.graph_objects as go
12
13
  import plotly.express as px # for dynamic color scales
13
14
 
14
15
  from ...common.common import ConsoleLog
16
+ from ...system.path import *
17
+
18
+
19
+ # ==========================================
20
+ # 1. The Decorator
21
+ # ==========================================
22
+ def check_enabled(func):
23
+ """
24
+ Decorator to skip method execution if the profiler is disabled.
25
+
26
+ This acts as a 'guard clause' for the entire function. If the profiler
27
+ instance has 'enabled=False', the decorated function is not executed at all,
28
+ saving processing time and avoiding side effects.
29
+ """
30
+
31
+ @wraps(func)
32
+ def wrapper(self, *args, **kwargs):
33
+ # Gracefully handle cases where 'enabled' might not be set yet (default to True)
34
+ # print('check_enabled called')
35
+ if not getattr(self, "enabled", True):
36
+ # print('Profiler disabled, skipping function execution.')
37
+ return # Exit immediately, returning None
38
+ return func(self, *args, **kwargs)
15
39
 
40
+ return wrapper
16
41
 
42
+
43
+ # ==========================================
44
+ # 2. The Class
45
+ # ==========================================
17
46
  class zProfiler:
18
47
  """A singleton profiler to measure execution time of contexts and steps.
19
48
 
@@ -41,13 +70,24 @@ class zProfiler:
41
70
  cls._instance = super().__new__(cls)
42
71
  return cls._instance
43
72
 
44
- def __init__(
45
- self,
46
- ):
73
+ def __init__(self, enabled=None):
74
+ """
75
+ Args:
76
+ enabled (bool, optional):
77
+ - If True/False: Updates the enabled state immediately.
78
+ - If None: Keeps the current state (defaults to True on first init).
79
+ """
80
+ # 1. First-time initialization
47
81
  if not hasattr(self, "_initialized"):
82
+ self.enabled = enabled if enabled is not None else True
48
83
  self.time_dict = {}
49
84
  self._initialized = True
50
85
 
86
+ # 2. If initialized, allow updating 'enabled' ONLY if explicitly passed
87
+ elif enabled is not None:
88
+ self.enabled = enabled
89
+
90
+ @check_enabled
51
91
  def ctx_start(self, ctx_name="ctx_default"):
52
92
  if not isinstance(ctx_name, str) or not ctx_name:
53
93
  raise ValueError("ctx_name must be a non-empty string")
@@ -59,6 +99,7 @@ class zProfiler:
59
99
  }
60
100
  self.time_dict[ctx_name]["report_count"] += 1
61
101
 
102
+ @check_enabled
62
103
  def ctx_end(self, ctx_name="ctx_default", report_func=None):
63
104
  if ctx_name not in self.time_dict:
64
105
  return
@@ -67,6 +108,7 @@ class zProfiler:
67
108
  self.time_dict[ctx_name]["end"] - self.time_dict[ctx_name]["start"]
68
109
  )
69
110
 
111
+ @check_enabled
70
112
  def step_start(self, ctx_name, step_name):
71
113
  if not isinstance(step_name, str) or not step_name:
72
114
  raise ValueError("step_name must be a non-empty string")
@@ -76,6 +118,7 @@ class zProfiler:
76
118
  self.time_dict[ctx_name]["step_dict"][step_name] = []
77
119
  self.time_dict[ctx_name]["step_dict"][step_name].append([time.perf_counter()])
78
120
 
121
+ @check_enabled
79
122
  def step_end(self, ctx_name, step_name):
80
123
  if (
81
124
  ctx_name not in self.time_dict
@@ -167,7 +210,6 @@ class zProfiler:
167
210
  )
168
211
  return report_dict
169
212
 
170
- @classmethod
171
213
  @classmethod
172
214
  def plot_formatted_data(
173
215
  cls, profiler_data, outdir=None, file_format="png", do_show=False, tag=""
@@ -261,7 +303,8 @@ class zProfiler:
261
303
  file_prefix = ctx if len(tag_str) == 0 else f"{tag_str}_{ctx}"
262
304
  file_path = os.path.join(outdir, f"{file_prefix}_summary.{file_format.lower()}")
263
305
  fig.write_image(file_path)
264
- print(f"Saved figure: {file_path}")
306
+ pprint(f"Saved figure to: 🔽")
307
+ pprint_local_path(file_path)
265
308
 
266
309
  results[ctx] = fig
267
310
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: halib
3
- Version: 0.2.13
3
+ Version: 0.2.14
4
4
  Summary: Small library for common tasks
5
5
  Author: Hoang Van Ha
6
6
  Author-email: hoangvanhauit@gmail.com
@@ -53,6 +53,9 @@ Dynamic: summary
53
53
 
54
54
  # Helper package for coding and automation
55
55
 
56
+ **Version 0.2.14**
57
+ + update `exp.perf.profiler`: add `enabled` flag to enable/disable profiling dynamically
58
+
56
59
  **Version 0.2.13**
57
60
  + reorganize packages with most changes in `research` package; also rename `research` to `exp` (package for experiment management and utilities)
58
61
  + update `exp/perfcalc.py` to allow save computed performance to csv file (without explicit calling method `calc_perfs`)
@@ -35,7 +35,7 @@ halib/exp/perf/gpu_mon.py,sha256=vD41_ZnmPLKguuq9X44SB_vwd9JrblO4BDzHLXZhhFY,223
35
35
  halib/exp/perf/perfcalc.py,sha256=p7rhVShiie7DT_s50lbvbGftVCkrWE0tQGFLUEmTXi0,18326
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=5ZjES8kAqEsSV1mC3Yr_1ivFLwQDc_yv4HY7dKt_AS0,11782
38
+ halib/exp/perf/profiler.py,sha256=57OO_BEC6CWKDCmLNyoYyz5nAvy-q8Lyc61afJkD0f4,13451
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
@@ -102,8 +102,8 @@ halib/utils/list.py,sha256=BM-8sRhYyqF7bh4p7TQtV7P_gnFruUCA6DTUOombaZg,337
102
102
  halib/utils/listop.py,sha256=Vpa8_2fI0wySpB2-8sfTBkyi_A4FhoFVVvFiuvW8N64,339
103
103
  halib/utils/tele_noti.py,sha256=-4WXZelCA4W9BroapkRyIdUu9cUVrcJJhegnMs_WpGU,5928
104
104
  halib/utils/video.py,sha256=zLoj5EHk4SmP9OnoHjO8mLbzPdtq6gQPzTQisOEDdO8,3261
105
- halib-0.2.13.dist-info/licenses/LICENSE.txt,sha256=qZssdna4aETiR8znYsShUjidu-U4jUT9Q-EWNlZ9yBQ,1100
106
- halib-0.2.13.dist-info/METADATA,sha256=f0Ammv1hiSO74ejAz5V_u6o73J8EzeFyoPBZ2Z3S_Ig,6838
107
- halib-0.2.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
108
- halib-0.2.13.dist-info/top_level.txt,sha256=7AD6PLaQTreE0Fn44mdZsoHBe_Zdd7GUmjsWPyQ7I-k,6
109
- halib-0.2.13.dist-info/RECORD,,
105
+ halib-0.2.14.dist-info/licenses/LICENSE.txt,sha256=qZssdna4aETiR8znYsShUjidu-U4jUT9Q-EWNlZ9yBQ,1100
106
+ halib-0.2.14.dist-info/METADATA,sha256=jEayj2DXN6lkHvIzsVFf1cix3zp0aOmVT7y09H6UhFE,6950
107
+ halib-0.2.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
108
+ halib-0.2.14.dist-info/top_level.txt,sha256=7AD6PLaQTreE0Fn44mdZsoHBe_Zdd7GUmjsWPyQ7I-k,6
109
+ halib-0.2.14.dist-info/RECORD,,
File without changes