Skip to content

Commit

Permalink
remove remaining dependence on UniformSequence; define max_time_preci…
Browse files Browse the repository at this point in the history
…sion, the maximum number of digits of precision in a time value & use it to determine the number of digits of precision in checkpoint flenames; remove 'second' from docstrings and variable names, as the simulator doesn't care about time units
  • Loading branch information
artgoldberg committed Mar 10, 2020
1 parent 8d97688 commit 8649f52
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 13 deletions.
15 changes: 9 additions & 6 deletions de_sim/checkpoint.py
Expand Up @@ -14,12 +14,12 @@
import pickle
import re

from de_sim.config import core
from de_sim.errors import SimulatorError
from wc_utils.config.core import get_config
from wc_utils.util.misc import obj_to_str
from wc_utils.util.uniform_seq import UniformSequence

uniform_seq_precision = get_config()['wc_utils']['misc']['uniform_seq_precision']
MAX_TIME_PRECISION = core.get_config()['de_sim']['max_time_precision']


class Checkpoint(object):
Expand Down Expand Up @@ -61,7 +61,7 @@ def get_checkpoint(dirname, time=None):
Args:
dirname (:obj:`str`): directory to read/write checkpoint data
time (:obj:`float`, optional): time in seconds of desired checkpoint; if not provided,
time (:obj:`float`, optional): time in simulated time units of desired checkpoint; if not provided,
the most recent checkpoint is returned
Returns:
Expand Down Expand Up @@ -101,7 +101,7 @@ def list_checkpoints(dirname, error_if_empty=True):
"""
# find checkpoint times
checkpoint_times = []
pattern = r'^(\d+\.\d{' + f'{uniform_seq_precision},{uniform_seq_precision}' + r'})\.pickle$'
pattern = r'^(\d+\.\d{' + f'{MAX_TIME_PRECISION},{MAX_TIME_PRECISION}' + r'})\.pickle$'
for file_name in os.listdir(dirname):
match = re.match(pattern, file_name)
if os.path.isfile(os.path.join(dirname, file_name)) and match:
Expand All @@ -123,12 +123,15 @@ def get_file_name(dirname, time):
Args:
dirname (:obj:`str`): directory to read/write checkpoint data
time (:obj:`float`): time in seconds
time (:obj:`float`): time
Returns:
:obj:`str`: file name for checkpoint at time `time`
"""
return os.path.join(dirname, f'{UniformSequence.truncate(time)}.pickle')
filename_time = f'{time:.{MAX_TIME_PRECISION}f}'
if not math.isclose(float(filename_time), time):
raise SimulatorError(f"filename time {filename_time} is not close to time {time}")
return os.path.join(dirname, f'{filename_time}.pickle')

def __str__(self):
""" Provide a human readable representation of this `Checkpoint`
Expand Down
1 change: 1 addition & 0 deletions de_sim/config/core.default.cfg
@@ -1,3 +1,4 @@
[de_sim]
copy_event_bodies = False
log_events = False
max_time_precision = 6
3 changes: 3 additions & 0 deletions de_sim/config/core.schema.cfg
Expand Up @@ -6,3 +6,6 @@

# whether to log each event; logging to 'de_sim.plot.file' must also be on
log_events = boolean(default=False)

# maximum number of digits of precision in a time value
max_time_precision = integer(default=6)
2 changes: 1 addition & 1 deletion de_sim/simulation_checkpoint_object.py
Expand Up @@ -18,7 +18,7 @@ class AbstractCheckpointSimulationObject(TemplatePeriodicSimulationObject):
""" Abstract class that creates periodic checkpoints
Attributes:
period (:obj:`float`): interval between checkpoints, in simulated seconds
period (:obj:`float`): interval between checkpoints in simulated time units
"""

def __init__(self, name, period):
Expand Down
4 changes: 2 additions & 2 deletions de_sim/template_sim_objs.py
Expand Up @@ -24,7 +24,7 @@ class TemplatePeriodicSimulationObject(ApplicationSimulationObject):
to determine event times.
Attributes:
period (:obj:`float`): interval between events, in simulated seconds
period (:obj:`float`): interval between events, in simulated time units
num_periods (:obj:`int`): number of periods executed
"""

Expand All @@ -36,7 +36,7 @@ def __init__(self, name, period):
super().__init__(name)

def schedule_next_event(self):
""" Schedule the next event in `self.period` simulated seconds
""" Schedule the next event in `self.period` simulated time units
"""
next_event_time = self.num_periods * self.period
self.num_periods += 1
Expand Down
2 changes: 1 addition & 1 deletion examples/random_state_variable.py
Expand Up @@ -21,7 +21,7 @@ class RandomStateVariableSimulationObject(ApplicationSimulationObject):
""" The random state variable model
* State: a number
* Event scheduling: schedule events randomly 1 or 4 seconds ahead
* Event scheduling: schedule events randomly
* Event execution: randomly increment or decrement the state
"""

Expand Down
27 changes: 27 additions & 0 deletions tests/results/perf_results/de_sim_performance_log.txt
Expand Up @@ -70,3 +70,30 @@ Performance summary on 2020-03-10
1024 102400 6.437 15908
4096 409600 43.492 9418

Performance summary on 2020-03-10
#sim obs # events run time (s) events/s
4 400 0.048 8324
16 1600 0.179 8943
64 6400 0.809 7908
256 25600 3.249 7880
1024 102400 8.352 12261
4096 409600 36.974 11078

Performance summary on 2020-03-10
#sim obs # events run time (s) events/s
4 400 0.051 7867
16 1600 0.170 9415
64 6400 0.742 8624
256 25600 2.372 10793
1024 102400 6.912 14814
4096 409600 29.428 13919

Performance summary on 2020-03-10
#sim obs # events run time (s) events/s
4 400 0.019 20611
16 1600 0.101 15844
64 6400 0.337 19008
256 25600 1.550 16519
1024 102400 7.250 14125
4096 409600 60.128 6812

13 changes: 11 additions & 2 deletions tests/test_checkpoint.py
Expand Up @@ -17,10 +17,13 @@
import copy

from de_sim.checkpoint import Checkpoint
from de_sim.config import core
from de_sim.errors import SimulatorError
from wc_utils.util.uniform_seq import UniformSequence
import wc_utils.util.types

MAX_TIME_PRECISION = core.get_config()['de_sim']['max_time_precision']


class TestCheckpoint(unittest.TestCase):

Expand Down Expand Up @@ -61,6 +64,12 @@ def test_equality(self):
for ckpt in self.diff_checkpoints:
self.assertNotEqual(self.non_empty_checkpoint1, ckpt)

def test_get_file_name(self):
self.assertIn(f'{3.0:.{MAX_TIME_PRECISION}f}', Checkpoint.get_file_name('', 3))
for time in [1.00000001, 1E-7]:
with self.assertRaises(SimulatorError):
Checkpoint.get_file_name('', time)


class CheckpointLogTest(unittest.TestCase):

Expand Down Expand Up @@ -154,14 +163,14 @@ class MockCheckpointLogger(object):
Attributes:
dirname (:obj:`str`): directory to write checkpoint data
event_time_sequence (:obj:`UniformSequence`):
_next_checkpoint (:obj:`float`): time in seconds of next checkpoint
_next_checkpoint (:obj:`float`): time in simulated time units of next checkpoint
"""

def __init__(self, dirname, step, initial_time):
"""
Args:
dirname (:obj:`str`): directory to write checkpoint data
step (:obj:`float`): simulation time between checkpoints in seconds
step (:obj:`float`): simulation time between checkpoints in simulated time units
initial_time (:obj:`float`): starting simulation time
"""
self.event_time_sequence = UniformSequence(initial_time, step)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_simulation_engine.py
Expand Up @@ -115,7 +115,7 @@ class PeriodicSimulationObject(TemplatePeriodicSimulationObject):
""" Self-clocking ApplicationSimulationObject
Attributes:
period (:obj:`float`): interval between events, in simulated seconds
period (:obj:`float`): interval between events, in simulated time units
"""

def __init__(self, name, period):
Expand Down

0 comments on commit 8649f52

Please sign in to comment.