Browse Source

Timer improvements, log in yaml

devel
Stefan Holst 2 years ago
parent
commit
753ce566e4
  1. 46
      src/kyupy/__init__.py

46
src/kyupy/__init__.py

@ -6,6 +6,7 @@ if they are available and otherwise point to mocks. @@ -6,6 +6,7 @@ if they are available and otherwise point to mocks.
"""
import time
import sys
from collections import defaultdict
import importlib.util
import gzip
@ -76,21 +77,27 @@ def hr_time(seconds): @@ -76,21 +77,27 @@ def hr_time(seconds):
class Timer:
def __init__(self): self.s = 0
def __enter__(self): self.start_time = time.perf_counter()
def __init__(self, s=0): self.s = s
def __enter__(self): self.start_time = time.perf_counter(); return self
def __exit__(self, *args): self.s += time.perf_counter() - self.start_time
@property
def ms(self): return self.s*1e3
@property
def us(self): return self.s*1e6
def __repr__(self): return f'{self.s:.3f}s' if self.s >= 1 else f'{self.ms:.3f}ms'
def __repr__(self): return f'{self.s:.3f}'
def __add__(self, t):
return Timer(self.s + t.s)
class Timers:
def __init__(self): self.timers = defaultdict(Timer)
def __init__(self, t={}): self.timers = defaultdict(Timer) | t
def __getitem__(self, name): return self.timers[name]
def __getattr__(self, name): return self.timers[name]
def __repr__(self): return ''.join([f'{k}={v} ' for k, v in self.timers.items()])
def __repr__(self): return '{' + ', '.join([f'{k}: {v}' for k, v in self.timers.items()]) + '}'
def __add__(self, t):
tmr = Timers(self.timers)
for k, v in t.timers.items(): tmr.timers[k] += v
return tmr
class Log:
@ -100,25 +107,36 @@ class Log: @@ -100,25 +107,36 @@ class Log:
def __init__(self):
self.start = time.perf_counter()
self.logfile = None
self.logfile = sys.stdout
"""When set to a file handle, log messages are written to it instead to standard output.
After each write, ``flush()`` is called as well.
"""
self.indent = 0
def __getstate__(self):
return {'elapsed': time.perf_counter() - self.start}
def __setstate__(self, state):
self.logfile = None
self.logfile = sys.stdout
self.indent = 0
self.start = time.perf_counter() - state['elapsed']
def write(self, s, indent=0):
self.logfile.write(' '*indent + s + '\n')
self.logfile.flush()
def li(self, item): self.write('- ' + str(item).replace('\n', '\n'+' '*(self.indent+1)), self.indent)
def lib(self): self.write('-', self.indent); self.indent += 1
def lin(self): self.write('-', self.indent-1)
def di(self, key, value): self.write(str(key) + ': ' + str(value).replace('\n', '\n'+' '*(self.indent+1)), self.indent)
def dib(self, key): self.write(str(key) + ':', self.indent); self.indent += 1
def din(self, key): self.write(str(key) + ':', self.indent-1)
def ie(self, n=1): self.indent -= n
def log(self, level, message):
t = time.perf_counter() - self.start
if self.logfile is None:
print(f'{t:011.3f} {level} {message}')
else:
self.logfile.write(f'{t:011.3f} {level} {message}\n')
self.logfile.flush()
self.logfile.write(f'# {t:011.3f} {level} {message}\n')
self.logfile.flush()
def info(self, message):
"""Log an informational message."""
@ -227,11 +245,11 @@ if importlib.util.find_spec('numba') is not None: @@ -227,11 +245,11 @@ if importlib.util.find_spec('numba') is not None:
try:
list(numba.cuda.gpus)
from numba import cuda
from numba.core import config
config.CUDA_LOW_OCCUPANCY_WARNINGS = False
except CudaSupportError:
log.warn('Cuda unavailable. Falling back to pure Python.')
cuda = MockCuda()
from numba.core import config
config.CUDA_LOW_OCCUPANCY_WARNINGS = False
else:
numba = MockNumba()
"""If Numba is available on the system, it is the actual ``numba`` package.

Loading…
Cancel
Save