-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add time clock to runtime #170
Changes from 39 commits
2955bca
770d1ec
7b0326e
7384b47
d8165be
d2a3030
bc26be9
95a4b4d
76033e8
2214139
570489e
800f2b8
6f38346
13f0045
6aa4f37
5f1f6a8
6c5a223
605594d
a9dabac
1589466
cceed31
10673e9
1d11793
60127a7
5e0f75c
404cddd
482c1f9
16330bd
0abba09
2b05f12
9be2a50
90b0463
097a9aa
a0d80c0
5bc5b6e
d8a1fa9
c9139ca
5f84d67
08a17e8
fc4d3dd
6d9ffa7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"python.pythonPath": "/home/joempie/miniconda3/envs/simlab-dev/bin/python" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,7 @@ | |
import zarr | ||
|
||
from . import Model | ||
from .utils import get_batch_size, normalize_encoding | ||
from .utils import get_batch_size, normalize_encoding, MAIN_CLOCK | ||
from .variable import VarType | ||
|
||
|
||
|
@@ -241,6 +241,14 @@ def _create_zarr_dataset( | |
f"its accepted dimension(s): {var_info['metadata']['dims']}" | ||
) | ||
|
||
# set MAIN_CLOCK placeholder to main_clock dimension | ||
if self.mclock_dim in dim_labels and MAIN_CLOCK in dim_labels: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we don't allow declaring input variables with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can still happen: when a user declares a variabke with dims There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yes! Hmm then we would probably want to check in For convenience we could add a property in Let's fix that in another PR.. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not sure if that is the right place though: Am I right that a user may add a process after updating clocks, thus not catching it? |
||
raise ValueError( | ||
f"Main clock: '{self.mclock_dim}' has a duplicate in {dim_labels}." | ||
"Please change the name of 'main_clock' in `create_setup`" | ||
) | ||
dim_labels = [self.mclock_dim if d is MAIN_CLOCK else d for d in dim_labels] | ||
|
||
if clock is not None: | ||
dim_labels.insert(0, clock) | ||
if add_batch_dim: | ||
|
@@ -320,7 +328,6 @@ def write_output_vars(self, batch: int, step: int, model: Optional[Model] = None | |
|
||
else: | ||
idx_dims = [clock_inc] + [slice(0, n) for n in np.shape(value)] | ||
|
||
if batch != -1: | ||
idx_dims.insert(0, batch) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -452,3 +452,68 @@ def initialize(self): | |
model.execute("initialize", {}) | ||
|
||
assert model.state[("baz", "actual")] == Frozen({("foo", "a"): 1, ("bar", "b"): 2}) | ||
|
||
|
||
def test_main_clock_access(): | ||
@xs.process | ||
class Foo: | ||
a = xs.variable(intent="out", dims=xs.MAIN_CLOCK) | ||
b = xs.variable(intent="out", dims=xs.MAIN_CLOCK) | ||
|
||
@xs.runtime(args=["main_clock_values", "main_clock_dataarray"]) | ||
def initialize(self, clock_values, clock_array): | ||
self.a = clock_values * 2 | ||
np.testing.assert_equal(self.a, [0, 2, 4, 6]) | ||
self.b = clock_array * 2 | ||
assert clock_array.dims[0] == "clock" | ||
assert all(clock_array[clock_array.dims[0]].data == [0, 1, 2, 3]) | ||
|
||
@xs.runtime(args=["step_delta", "step"]) | ||
def run_step(self, dt, n): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could remove |
||
assert self.a[n] == 2 * n | ||
self.a[n] += 1 | ||
|
||
model = xs.Model({"foo": Foo}) | ||
ds_in = xs.create_setup( | ||
model=model, | ||
clocks={"clock": range(4)}, | ||
input_vars={}, | ||
output_vars={"foo__a": None}, | ||
) | ||
ds_out = ds_in.xsimlab.run(model=model) | ||
assert all(ds_out.foo__a.data == [1, 3, 5, 6]) | ||
|
||
# test for error when another dim has the same name as xs.MAIN_CLOCK | ||
@xs.process | ||
class DoubleMainClockDim: | ||
a = xs.variable(intent="out", dims=("clock", xs.MAIN_CLOCK)) | ||
|
||
def initialize(self): | ||
self.a = [[1, 2, 3], [3, 4, 5]] | ||
|
||
def run_step(self): | ||
self.a += self.a | ||
|
||
model = xs.Model({"foo": DoubleMainClockDim}) | ||
with pytest.raises(ValueError, match=r"Main clock:*"): | ||
xs.create_setup( | ||
model=model, | ||
clocks={"clock": [0, 1, 2, 3]}, | ||
input_vars={}, | ||
output_vars={"foo__a": None}, | ||
).xsimlab.run(model) | ||
|
||
# test for error when trying to put xs.MAIN_CLOCK as a dim in an input var | ||
with pytest.raises( | ||
ValueError, match="Do not pass xs.MAIN_CLOCK into input vars dimensions" | ||
): | ||
a = xs.variable(intent="in", dims=xs.MAIN_CLOCK) | ||
|
||
with pytest.raises( | ||
ValueError, match="Do not pass xs.MAIN_CLOCK into input vars dimensions" | ||
): | ||
b = xs.variable(intent="in", dims=(xs.MAIN_CLOCK,)) | ||
with pytest.raises( | ||
ValueError, match="Do not pass xs.MAIN_CLOCK into input vars dimensions" | ||
): | ||
c = xs.variable(intent="in", dims=["a", ("a", xs.MAIN_CLOCK)]) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,34 @@ | |
V = TypeVar("V") | ||
|
||
|
||
class _MainClockDim: | ||
"""Singleton class to be used as a placeholder of the main clock | ||
dimension. | ||
|
||
It will be replaced by the actual dimension label set during simulation setup | ||
(i.e., ``main_clock`` argument). | ||
|
||
""" | ||
|
||
_singleton = None | ||
|
||
def __new__(cls): | ||
if _MainClockDim._singleton is None: | ||
# if there is no instance of it yet, create a class instance | ||
_MainClockDim._singleton = super(_MainClockDim, cls).__new__(cls) | ||
return _MainClockDim._singleton | ||
|
||
def __repr__(self): | ||
return "MAIN_CLOCK (undefined)" | ||
|
||
|
||
MAIN_CLOCK = _MainClockDim() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice to add some docstrings for this attribute, e.g., MAIN_CLOCK = _MainClockDim()
"""
Sentinel to indicate simulation's main clock dimension, to be
replaced by the actual dimension label set in input/output datasets.
""" and add it in the docs (probably in API references in the variables section, since we would use it when declaring variables).
|
||
""" | ||
Sentinel to indicate simulation's main clock dimension, to be | ||
replaced by the actual dimension label set in input/output datasets. | ||
""" | ||
|
||
|
||
def variables_dict(process_cls): | ||
"""Get all xsimlab variables declared in a process. | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you remove this file, please? It should be ignored in the next PRs (#169).