halib 0.1.59__py3-none-any.whl → 0.1.61__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/utils/dataclass_util.py +1 -0
- halib/utils/gpu_mon.py +58 -0
- halib/utils/video.py +62 -0
- {halib-0.1.59.dist-info → halib-0.1.61.dist-info}/METADATA +6 -1
- {halib-0.1.59.dist-info → halib-0.1.61.dist-info}/RECORD +8 -6
- {halib-0.1.59.dist-info → halib-0.1.61.dist-info}/LICENSE.txt +0 -0
- {halib-0.1.59.dist-info → halib-0.1.61.dist-info}/WHEEL +0 -0
- {halib-0.1.59.dist-info → halib-0.1.61.dist-info}/top_level.txt +0 -0
halib/utils/dataclass_util.py
CHANGED
@@ -26,6 +26,7 @@ def yaml_to_dataclass(name: str, yaml_str: str):
|
|
26
26
|
data = yaml.safe_load(yaml_str)
|
27
27
|
return dict_to_dataclass(name, data)
|
28
28
|
|
29
|
+
|
29
30
|
def yamlfile_to_dataclass(name: str, file_path: str):
|
30
31
|
data_dict = yamlfile.load_yaml(file_path, to_dict=True)
|
31
32
|
if "__base__" in data_dict:
|
halib/utils/gpu_mon.py
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# install `pynvml_utils` package first
|
2
|
+
# see this repo: https://github.com/gpuopenanalytics/pynvml
|
3
|
+
from pynvml_utils import nvidia_smi
|
4
|
+
import time
|
5
|
+
import threading
|
6
|
+
from rich.pretty import pprint
|
7
|
+
|
8
|
+
class GPUMonitor:
|
9
|
+
def __init__(self, gpu_index=0, interval=0.01):
|
10
|
+
self.nvsmi = nvidia_smi.getInstance()
|
11
|
+
self.gpu_index = gpu_index
|
12
|
+
self.interval = interval
|
13
|
+
self.gpu_stats = []
|
14
|
+
self._running = False
|
15
|
+
self._thread = None
|
16
|
+
|
17
|
+
def _monitor(self):
|
18
|
+
while self._running:
|
19
|
+
stats = self.nvsmi.DeviceQuery("power.draw, memory.used")["gpu"][
|
20
|
+
self.gpu_index
|
21
|
+
]
|
22
|
+
# pprint(stats)
|
23
|
+
self.gpu_stats.append(
|
24
|
+
{
|
25
|
+
"power": stats["power_readings"]["power_draw"],
|
26
|
+
"power_unit": stats["power_readings"]["unit"],
|
27
|
+
"memory": stats["fb_memory_usage"]["used"],
|
28
|
+
"memory_unit": stats["fb_memory_usage"]["unit"],
|
29
|
+
}
|
30
|
+
)
|
31
|
+
time.sleep(self.interval)
|
32
|
+
|
33
|
+
def start(self):
|
34
|
+
if not self._running:
|
35
|
+
self._running = True
|
36
|
+
# clear previous stats
|
37
|
+
self.gpu_stats.clear()
|
38
|
+
self._thread = threading.Thread(target=self._monitor)
|
39
|
+
self._thread.start()
|
40
|
+
|
41
|
+
def stop(self):
|
42
|
+
if self._running:
|
43
|
+
self._running = False
|
44
|
+
self._thread.join()
|
45
|
+
# clear the thread reference
|
46
|
+
self._thread = None
|
47
|
+
|
48
|
+
def get_stats(self):
|
49
|
+
## return self.gpu_stats
|
50
|
+
assert self._running is False, "GPU monitor is still running. Stop it first."
|
51
|
+
|
52
|
+
powers = [s["power"] for s in self.gpu_stats if s["power"] is not None]
|
53
|
+
memories = [s["memory"] for s in self.gpu_stats if s["memory"] is not None]
|
54
|
+
avg_power = sum(powers) / len(powers) if powers else 0
|
55
|
+
max_memory = max(memories) if memories else 0
|
56
|
+
# power_unit = self.gpu_stats[0]["power_unit"] if self.gpu_stats else "W"
|
57
|
+
# memory_unit = self.gpu_stats[0]["memory_unit"] if self.gpu_stats else "MiB"
|
58
|
+
return {"gpu_avg_power": avg_power, "gpu_avg_max_memory": max_memory}
|
halib/utils/video.py
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
import os
|
2
|
+
import cv2
|
3
|
+
from ..filetype import csvfile
|
4
|
+
from ..system import filesys as fs
|
5
|
+
|
6
|
+
|
7
|
+
class VideoUtils:
|
8
|
+
@staticmethod
|
9
|
+
def get_video_meta_dict(video_path):
|
10
|
+
# Open the video file
|
11
|
+
cap = cv2.VideoCapture(video_path)
|
12
|
+
|
13
|
+
# Check if the video was opened successfully
|
14
|
+
if not cap.isOpened():
|
15
|
+
print(f"Error: Could not open video file {video_path}")
|
16
|
+
return None, None
|
17
|
+
|
18
|
+
# Get the frame count
|
19
|
+
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
|
20
|
+
|
21
|
+
# Get the FPS
|
22
|
+
fps = cap.get(cv2.CAP_PROP_FPS)
|
23
|
+
|
24
|
+
# Release the video capture object
|
25
|
+
cap.release()
|
26
|
+
meta_dict = {
|
27
|
+
"video_path": video_path,
|
28
|
+
"frame_count": frame_count,
|
29
|
+
"fps": fps
|
30
|
+
}
|
31
|
+
return meta_dict
|
32
|
+
|
33
|
+
@staticmethod
|
34
|
+
def get_video_dir_meta_df(video_dir, video_exts=['.mp4', '.avi', '.mov', '.mkv'], search_recursive=False, csv_outfile=None):
|
35
|
+
assert os.path.exists(video_dir), f"Video directory {video_dir} does not exist"
|
36
|
+
video_files = fs.filter_files_by_extension(video_dir, video_exts, recursive=search_recursive)
|
37
|
+
assert len(video_files) > 0, f"No video files found in {video_dir} with extensions {video_exts}"
|
38
|
+
video_meta_list = []
|
39
|
+
for vfile in video_files:
|
40
|
+
meta_dict = VideoUtils.get_video_meta_dict(vfile)
|
41
|
+
if meta_dict:
|
42
|
+
video_meta_list.append(meta_dict)
|
43
|
+
dfmk = csvfile.DFCreator()
|
44
|
+
columns = list(video_meta_list[0].keys())
|
45
|
+
assert len(columns) > 0, "No video metadata found"
|
46
|
+
assert 'video_path' in columns, "video_path column not found in video metadata"
|
47
|
+
# move video_path to the first column
|
48
|
+
columns.remove('video_path')
|
49
|
+
columns.insert(0, 'video_path')
|
50
|
+
dfmk.create_table("video_meta", columns)
|
51
|
+
rows = [[meta[col] for col in columns] for meta in video_meta_list]
|
52
|
+
dfmk.insert_rows("video_meta", rows)
|
53
|
+
dfmk.fill_table_from_row_pool("video_meta")
|
54
|
+
|
55
|
+
if csv_outfile:
|
56
|
+
dfmk["video_meta"].to_csv(csv_outfile, index=False, sep=";")
|
57
|
+
return dfmk["video_meta"].copy()
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: halib
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.61
|
4
4
|
Summary: Small library for common tasks
|
5
5
|
Author: Hoang Van Ha
|
6
6
|
Author-email: hoangvanhauit@gmail.com
|
@@ -45,6 +45,11 @@ Requires-Dist: dataclass-wizard
|
|
45
45
|
|
46
46
|
Helper package for coding and automation
|
47
47
|
|
48
|
+
**Version 0.1.61**
|
49
|
+
|
50
|
+
+ add `util/video`: add `VideoUtils` class to handle common video-related tasks
|
51
|
+
+ add `util/gpu_mon`: add `GPUMonitor` class to monitor GPU usage and performance
|
52
|
+
|
48
53
|
**Version 0.1.59**
|
49
54
|
|
50
55
|
+ add `util/perfcalc`: abstract class for performance calculation. This class need to be inherited and implemented with specific performance calculation logic.
|
@@ -42,12 +42,14 @@ halib/system/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
42
42
|
halib/system/cmd.py,sha256=b2x7JPcNnFjLGheIESVYvqAb-w2UwBM1PAwYxMZ5YjA,228
|
43
43
|
halib/system/filesys.py,sha256=ERpnELLDKJoTIIKf-AajgkY62nID4qmqmX5TkE95APU,2931
|
44
44
|
halib/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
45
|
-
halib/utils/dataclass_util.py,sha256=
|
45
|
+
halib/utils/dataclass_util.py,sha256=rj2IMLlUzbm2OlF5_B2dRTk9njZOaF7tTjYkOsq8uLY,1416
|
46
46
|
halib/utils/dict_op.py,sha256=wYE6Iw-_CnCWdMg9tpJ2Y2-e2ESkW9FxmdBkZkbUh80,299
|
47
|
+
halib/utils/gpu_mon.py,sha256=vD41_ZnmPLKguuq9X44SB_vwd9JrblO4BDzHLXZhhFY,2233
|
47
48
|
halib/utils/listop.py,sha256=Vpa8_2fI0wySpB2-8sfTBkyi_A4FhoFVVvFiuvW8N64,339
|
48
49
|
halib/utils/tele_noti.py,sha256=-4WXZelCA4W9BroapkRyIdUu9cUVrcJJhegnMs_WpGU,5928
|
49
|
-
halib
|
50
|
-
halib-0.1.
|
51
|
-
halib-0.1.
|
52
|
-
halib-0.1.
|
53
|
-
halib-0.1.
|
50
|
+
halib/utils/video.py,sha256=mJQFHFbijmu3lo0NZk4Ed64Tfa1u5KxNJpd_TuckpPU,2228
|
51
|
+
halib-0.1.61.dist-info/LICENSE.txt,sha256=qZssdna4aETiR8znYsShUjidu-U4jUT9Q-EWNlZ9yBQ,1100
|
52
|
+
halib-0.1.61.dist-info/METADATA,sha256=1s7ikn1n88Ix9c_rB4OqSY9hmQ12sJMM-LE_4aIDWNM,5039
|
53
|
+
halib-0.1.61.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
54
|
+
halib-0.1.61.dist-info/top_level.txt,sha256=7AD6PLaQTreE0Fn44mdZsoHBe_Zdd7GUmjsWPyQ7I-k,6
|
55
|
+
halib-0.1.61.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|