wolfgpu.sampled_timer ===================== .. py:module:: wolfgpu.sampled_timer .. autoapi-nested-parse:: Author: HECE - University of Liege, Stéphane Champailler, Pierre Archambeau Date: 2024 Copyright (c) 2024 University of Liege. All rights reserved. This script and its content are protected by copyright law. Unauthorized copying or distribution of this file, via any medium, is strictly prohibited. Module Contents --------------- .. py:class:: TimeSamplingStrategy(*args, **kwds) Bases: :py:obj:`enum.Enum` .. autoapi-inheritance-diagram:: wolfgpu.sampled_timer.TimeSamplingStrategy :parts: 1 :private-bases: When a simulation is run, interrogating the GPU is costly. Therefore we interrogate it not at each step but on a regular basis. This enumeration describes the various strategies of interrogation. When reporting, the sync time is a multiple of .. py:attribute:: ONE_SHOT :value: 1 Interrogate at fixed intervals .. py:attribute:: DYNAMIC :value: 2 Interrogate at a changing intervals .. py:attribute:: WALL_CLOCK_DYNAMIC :value: 3 .. py:attribute:: PERIODIC :value: 4 .. py:class:: TimeSampler(strategy: TimeSamplingStrategy, name: str = None) Example: - read GPU every 100 iterations - report every 111 iterations - update bathymetry every 3 seconds +/-. To solve this we make three timelines: - read at 100, 200, 300,... - read at 111, 222, 333,... - read at 3s, 6.25, 8,75,... For the first two time lines, knowing the current iteration allows to know when the next stop is. For the third one, only a planner knows. .. py:attribute:: _strategy .. py:attribute:: _period :value: None .. py:attribute:: _query_function :value: None .. py:attribute:: name :value: None .. py:method:: make_one_shot_timer(period: wolfgpu.glsimulation.SimulationDuration, name=None) -> TimeSampler :classmethod: A one-shot timer which have a fixed period. Fixed means you can't change it over time. :param period: If `int` then the period is expressed as a number of iterations. If `timedelta` then the period is expressed as a number of seconds. .. py:method:: make_dynamic_timer(query_function: Callable, duration_type: wolfgpu.glsimulation.SimulationDurationType, name=None) -> TimeSampler :classmethod: A timer which has a varying period. To know the time to next timer trigger time, the caller must provide a query function that will tell us how long to wait before the next trigger in function of the current time/iteration. :param duration_type: The type of duration used by this timer. This must be constant over time (so you can't go from steps to time or vice versa). .. py:method:: make_periodic_wall_clock_timer(period, triggers_on_zero=False, name: str = None) :classmethod: A timer which triggers every `period` seconds (seconds are wall clock seconds, not simulation seconds). :param period: Either a `timedelta` or a `SimulationDuration`. .. py:method:: make_periodic_timer(period: wolfgpu.glsimulation.SimulationDuration, name=None) -> TimeSampler :classmethod: A recurring timer which have a fixed period. :param period: If `int` then the period is expressed as a number of iterations. If `timedelta` then the period is expressed as a number of seconds. .. py:property:: strategy :type: TimeSamplingStrategy .. py:method:: get_next_duration(current_iteration: int, current_time: datetime.timedelta) -> wolfgpu.glsimulation.SimulationDuration :return: If `int` then it is a number of iterations. If `timedelta` then it is a duration. .. py:class:: TimerManager(sampling_period: int) .. py:attribute:: _sampling_period .. py:method:: reset() Reset the manager but keeps the initial sampling period. .. py:method:: ticker() -> TimeSampler .. py:method:: _remove_strategy(strategy: TimeSampler) .. py:method:: add_strategy(time_sampler: TimeSampler) .. py:method:: set_simulation_time_steps(steps) Set the simulation times steps database that can be used to estimate the next iteration upon which a time sampler must be triggered. :param steps: A collection of simulation step durations (in seconds). .. py:method:: _record(current_iteration, current_time) .. py:method:: _estimate_iterations_for_duration(seconds) Try to convert a time into a number of iterations using past knowledge. We use two databases to do that. The first one is built in this manager based on the iteration/times provided to it when querying/updating its state. It's not very accurate. The second one is a list of time steps which is provided by the caller whenever it has up to date data. It's meant to be more accurate. .. py:method:: update_one_shot_timer(timer: TimeSampler, new_period: wolfgpu.glsimulation.SimulationDuration, current_iteration, current_time) .. py:method:: _plan_next_stop_for_timer(ndx: int, current_iteration: int, current_time) .. py:method:: _can_estimate_time() Do we have enough data to estimate iteration number out of a time ? .. py:method:: _compute_next_timer_trigger() when will the next timer trigger ? .. py:method:: _reevaluate_time_samplers(current_iteration, current_time) Reevaluate the iteration that is planned for the trigger of each "time" (instead of "iterations") timers. We do that systematically, that is as often as possible. .. py:method:: update_clock_wall_timers() Update the wall clock timers. The wall clock timers being based on the real passage of time, they must be checked more often than the timers inside a simulation to be accurate. Since querying timers inside simulation is very expensive, we moved the clock wall timer update here, outside the more general timers update mechanism (in the update() method). This way, they can be updated as fast as needed without updating the more expensive simulation timers. :return: The set of wall clock timers that have triggered. .. py:method:: update(current_iteration: int, current_time) -> set[TimeSampler] Update all timers. :return: The set of timers that have triggered.