|
| 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) |
0 commit comments