Skip to content

Commit 2ce124b

Browse files
authored
Merge pull request #61 from MoseleyBioinformaticsLab/granular
Introduces the SubTracker
2 parents 51302b6 + e8eb333 commit 2ce124b

13 files changed

+193
-17
lines changed

src/gpu_tracker/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
__version__ = _gv(_path.join(_path.dirname(__file__), _path.pardir))
1111

1212
from .tracker import Tracker
13+
from .sub_tracker import SubTracker

src/gpu_tracker/_helper_classes.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import dataclasses as dclass
99
import sqlalchemy as sqlalc
1010
import sqlalchemy.orm as sqlorm
11+
import enum
1112

1213

1314
class _GPUQuerier(abc.ABC):
@@ -111,7 +112,7 @@ def ram_and_utilization(cls) -> pd.DataFrame:
111112

112113

113114
@dclass.dataclass
114-
class TimepointUsage:
115+
class _TimepointUsage:
115116
main_ram: float = 0.0
116117
descendants_ram: float = 0.0
117118
combined_ram: float = 0.0
@@ -136,6 +137,16 @@ class TimepointUsage:
136137
timestamp: float = 0.0
137138

138139

140+
@dclass.dataclass
141+
class _SubTrackerLog:
142+
class CodeBlockPosition(enum.Enum):
143+
START = 'START'
144+
END = 'END'
145+
code_block_name: str
146+
position: CodeBlockPosition
147+
timestamp: float
148+
149+
139150
class _TrackingFile(abc.ABC):
140151
@staticmethod
141152
def create(file: str | None) -> _TrackingFile | None:
@@ -153,7 +164,7 @@ def create(file: str | None) -> _TrackingFile | None:
153164
def __init__(self, file: str):
154165
self._file = file
155166

156-
def write_row(self, values: TimepointUsage):
167+
def write_row(self, values: _TimepointUsage | _SubTrackerLog):
157168
values = dclass.asdict(values)
158169
if not os.path.isfile(self._file):
159170
self._create_file(values)
@@ -206,5 +217,5 @@ def _create_file(self, values: dict):
206217
for column_name, data_type in schema.items():
207218
sqlalchemy_type = type_mapping[data_type]
208219
columns.append(sqlalc.Column(column_name, sqlalchemy_type))
209-
tracking_table = sqlalc.Table(_SQLiteTrackingFile._SQLITE_TABLE_NAME, metadata, *columns)
220+
sqlalc.Table(_SQLiteTrackingFile._SQLITE_TABLE_NAME, metadata, *columns)
210221
metadata.create_all(engine)

src/gpu_tracker/sub_tracker.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""The ``sub_tracker`` module contains the ``SubTracker`` class which can alternatively be imported directly from the ``gpu_tracker`` package."""
2+
import inspect
3+
import os
4+
import time
5+
from ._helper_classes import _TrackingFile, _SubTrackerLog
6+
7+
8+
class SubTracker:
9+
"""
10+
Context manager that logs to a file for the purposes of sub tracking a code block using the timestamps at which the codeblock begins and ends.
11+
Entering the context manager marks the beginning of the code block and exiting the context manager marks the end of the code block.
12+
At the beginning of the codeblock, the ``SubTracker`` logs a row to a tablular file (".csv" or ".sqlite") that includes the timestamp along with a name for the code block and an indication of whether it is the start or end of the code bock.
13+
This resulting file can be used alongside a tracking file created by a ``Tracker`` object for more granular analysis of specific code blocks.
14+
15+
:ivar str code_block_name: The name of the code block being sub-tracked.
16+
:ivar str sub_tracking_file: The path to the file where the sub-tracking info is logged.
17+
"""
18+
def __init__(self, code_block_name: str | None = None, sub_tracking_file: str | None = None):
19+
"""
20+
:param code_block_name: The name of the code block within a ``Tracker`` context that is being sub-tracked. Defaults to the file path and line number where the SubTracker context is started.
21+
:param sub_tracking_file: The path to the file to log the time stamps of the code block being sub-tracked Defaults to the ID of the process where the SubTracker context is created and in CSV format.
22+
"""
23+
if code_block_name is not None:
24+
self.code_block_name = code_block_name
25+
else:
26+
stack = inspect.stack()
27+
caller_frame = stack[1]
28+
file_path = os.path.abspath(caller_frame.filename)
29+
line_number = caller_frame.lineno
30+
self.code_block_name = f'{file_path}:{line_number}'
31+
if sub_tracking_file is None:
32+
sub_tracking_file = f'{os.getpid()}.csv'
33+
self.sub_tracking_file = sub_tracking_file
34+
self._sub_tracking_file = _TrackingFile.create(self.sub_tracking_file)
35+
36+
def _log(self, code_block_position: _SubTrackerLog.CodeBlockPosition):
37+
sub_tracker_log = _SubTrackerLog(
38+
code_block_name=self.code_block_name, position=code_block_position.value, timestamp=time.time())
39+
self._sub_tracking_file.write_row(sub_tracker_log)
40+
41+
def __enter__(self):
42+
self._log(_SubTrackerLog.CodeBlockPosition.START)
43+
return self
44+
45+
def __exit__(self, *_):
46+
self._log(_SubTrackerLog.CodeBlockPosition.END)

src/gpu_tracker/tracker.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import pickle as pkl
1414
import uuid
1515
import pandas as pd
16-
from ._helper_classes import _NvidiaQuerier, _AMDQuerier, _TrackingFile, TimepointUsage
16+
from ._helper_classes import _NvidiaQuerier, _AMDQuerier, _TrackingFile, _TimepointUsage
1717

1818

1919
class _TrackingProcess(mproc.Process):
@@ -140,7 +140,7 @@ def run(self):
140140
self._stop_event.set()
141141
# Simulate a do-while loop so that the tracking is executed at least once.
142142
while True:
143-
timepoint_usage = TimepointUsage()
143+
timepoint_usage = _TimepointUsage()
144144
with open(self._resource_usage_file, 'wb') as file:
145145
pkl.dump(self._resource_usage, file)
146146
if self._stop_event.is_set():

tests/data/None_None.csv

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
position,timestamp
2+
START,0
3+
END,1
4+
START,2
5+
END,3
6+
START,4
7+
END,5
8+
START,6
9+
END,7
10+
START,8
11+
END,9
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
position,timestamp
2+
START,0
3+
END,1
4+
START,2
5+
END,3
6+
START,4
7+
END,5
8+
START,6
9+
END,7
10+
START,8
11+
END,9
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
position,timestamp
2+
START,0
3+
END,1
4+
START,2
5+
END,3
6+
START,4
7+
END,5
8+
START,6
9+
END,7
10+
START,8
11+
END,9

tests/data/my-code-block_None.csv

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
position,timestamp
2+
START,0
3+
END,1
4+
START,2
5+
END,3
6+
START,4
7+
END,5
8+
START,6
9+
END,7
10+
START,8
11+
END,9
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
position,timestamp
2+
START,0
3+
END,1
4+
START,2
5+
END,3
6+
START,4
7+
END,5
8+
START,6
9+
END,7
10+
START,8
11+
END,9
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
position,timestamp
2+
START,0
3+
END,1
4+
START,2
5+
END,3
6+
START,4
7+
END,5
8+
START,6
9+
END,7
10+
START,8
11+
END,9

0 commit comments

Comments
 (0)