Newer
Older
def __call__(self):
return self.log_manager.t_log
class EventCounter(PostLogQuantity):
def __init__(self, name="interval", description=None):
PostLogQuantity.__init__(self, name, "1", description)
self.events = 0
def add(self, n=1):
self.events += n
def transfer(self, counter):
self.events += counter.pop()
def prepare_for_tick(self):
self.events = 0
def __call__(self):
result = self.events
return result
def time_and_count_function(f, timer, counter=None, increment=1):
def inner_f(*args, **kwargs):
if counter is not None:
counter.add(increment)
sub_timer = timer.start_sub_timer()
try:
return f(*args, **kwargs)
finally:
sub_timer.stop().submit()
return inner_f
"""Counts the number of times :meth:`LogManager.tick` is called."""
def __init__(self, name="step"):
LogQuantity.__init__(self, name, "1", "Timesteps")
self.steps = 0
def __call__(self):
result = self.steps
self.steps += 1
return result
class StepToStepDuration(PostLogQuantity):
"""Records the CPU time between invocations of
:meth:`LogManager.tick_before` and
:meth:`LogManager.tick_after`.
"""
def __init__(self, name="t_2step"):
PostLogQuantity.__init__(self, name, "s", "Step-to-step duration")
self.last_start_time = None
self.last2_start_time = None
def prepare_for_tick(self):
self.last2_start_time = self.last_start_time
self.last_start_time = time()
def __call__(self):
if self.last2_start_time is None:
return None
else:
return self.last_start_time - self.last2_start_time
class TimestepDuration(PostLogQuantity):
"""Records the CPU time between the starts of time steps.
:meth:`LogManager.tick_before` and
:meth:`LogManager.tick_after`.
"""
# We would like to run last, so that if log gathering takes any
# significant time, we catch that, too. (CUDA sync-on-time-taking,
# I'm looking at you.)
sort_weight = 1000
PostLogQuantity.__init__(self, name, "s", "Time step duration")
def prepare_for_tick(self):
self.last_start = time()
def __call__(self):
now = time()
result = now - self.last_start
del self.last_start
class CPUTime(LogQuantity):
"""Records (monotonically increasing) CPU time."""
def __init__(self, name="t_cpu"):
LogQuantity.__init__(self, name, "s", "Wall time")
self.start = time()
def __call__(self):
return time()-self.start
class ETA(LogQuantity):
"""Records an estimate of how long the computation will still take."""
def __init__(self, total_steps, name="t_eta"):
LogQuantity.__init__(self, name, "s", "Estimated remaining duration")
self.steps = 0
self.total_steps = total_steps
self.start = time()
def __call__(self):
fraction_done = self.steps/self.total_steps
self.steps += 1
time_spent = time()-self.start
if fraction_done > 1e-9:
return time_spent/fraction_done-time_spent
else:
return 0
"""Add generally applicable :class:`LogQuantity` objects to C{mgr}."""
mgr.add_quantity(TimestepDuration())
mgr.add_quantity(StepToStepDuration())
mgr.add_quantity(CPUTime())
mgr.add_quantity(LogUpdateDuration(mgr))
mgr.add_quantity(TimestepCounter())
class SimulationTime(TimeTracker, LogQuantity):
"""Record (monotonically increasing) simulation time."""
def __init__(self, dt, name="t_sim", start=0):
LogQuantity.__init__(self, name, "s", "Simulation Time")
TimeTracker.__init__(self, dt)
return self.t
class Timestep(SimulationLogQuantity):
"""Record the magnitude of the simulated time step."""
def __init__(self, dt, name="dt", unit="s"):
SimulationLogQuantity.__init__(self, dt, name, unit, "Simulation Timestep")
Andreas Klöckner
committed
def __call__(self):
return self.dt
def set_dt(mgr, dt):
"""Set the simulation timestep on :class:`LogManager` C{mgr} to C{dt}."""
for gd_lst in [mgr.before_gather_descriptors,
mgr.after_gather_descriptors]:
for gd in gd_lst:
if isinstance(gd.quantity, DtConsumer):
gd.quantity.set_dt(dt)
Andreas Klöckner
committed
def add_simulation_quantities(mgr, dt=None):
"""Add :class:`LogQuantity` objects relating to simulation time."""
if dt is not None:
from warnings import warn
warn("Specifying dt ahead of time is a deprecated practice. "
"Use pytools.log.set_dt() instead.")
Andreas Klöckner
committed
mgr.add_quantity(Timestep(dt))
def add_run_info(mgr):
"""Add generic run metadata, such as command line, host, and time."""
import sys
mgr.set_constant("cmdline", " ".join(sys.argv))
from socket import gethostname
mgr.set_constant("machine", gethostname())
from time import localtime, strftime, time
mgr.set_constant("date", strftime("%a, %d %b %Y %H:%M:%S %Z", localtime()))