Skip to content

Commit f6ece16

Browse files
committed
Use donfig to control default spec
1 parent adb802d commit f6ece16

File tree

7 files changed

+43
-7
lines changed

7 files changed

+43
-7
lines changed

cubed/__init__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@
1212
except Exception: # pragma: no cover
1313
__version__ = "unknown"
1414

15+
from donfig import Config
16+
17+
config = Config(
18+
"cubed",
19+
# default spec is local temp dir and a modest amount of memory (200MB, of which 100MB is reserved)
20+
defaults=[{"spec": {"allowed_mem": 200_000_000, "reserved_mem": 100_000_000}}],
21+
)
22+
1523
from .array_api import Array
1624
from .core.array import compute, measure_reserved_mem, visualize
1725
from .core.gufunc import apply_gufunc
@@ -28,6 +36,7 @@
2836
"TaskEndEvent",
2937
"apply_gufunc",
3038
"compute",
39+
"config",
3140
"from_array",
3241
"from_zarr",
3342
"map_blocks",

cubed/core/array.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
import numpy as np
55
from toolz import map, reduce
66

7+
from cubed import config
78
from cubed.runtime.types import Callback, Executor
8-
from cubed.spec import Spec
9+
from cubed.spec import Spec, spec_from_config
910
from cubed.storage.zarr import open_if_lazy_zarr_array
1011
from cubed.utils import chunk_memory
1112
from cubed.vendor.dask.array.core import normalize_chunks
@@ -41,11 +42,8 @@ def __init__(self, name, zarray, spec, plan):
4142
self._chunks = normalize_chunks(
4243
zarray.chunks, shape=self.shape, dtype=self.dtype
4344
)
44-
# if no spec is supplied, use a default with local temp dir,
45-
# and a modest amount of memory (200MB, of which 100MB is reserved)
46-
self.spec = spec or Spec(
47-
None, allowed_mem=200_000_000, reserved_mem=100_000_000
48-
)
45+
# get spec from config if not supplied
46+
self.spec = spec or spec_from_config(config)
4947
self.plan = plan
5048

5149
@property

cubed/runtime/executors/modal.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
aws_image = modal.Image.debian_slim().pip_install(
3333
[
3434
"array-api-compat",
35+
"donfig",
3536
"fsspec",
3637
"mypy_extensions", # for rechunker
3738
"networkx",
@@ -46,6 +47,7 @@
4647
gcp_image = modal.Image.debian_slim().pip_install(
4748
[
4849
"array-api-compat",
50+
"donfig",
4951
"fsspec",
5052
"mypy_extensions", # for rechunker
5153
"networkx",

cubed/spec.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
from functools import lru_cache
12
from typing import Optional, Union
23

4+
import donfig
5+
from donfig.config_obj import expand_environment_variables
6+
37
from cubed.runtime.create import create_executor
48
from cubed.runtime.types import Executor
59
from cubed.utils import convert_to_bytes
@@ -109,3 +113,14 @@ def __eq__(self, other):
109113
)
110114
else:
111115
return False
116+
117+
118+
def spec_from_config(config):
119+
return _spec_from_serialized_config(config.serialize())
120+
121+
122+
@lru_cache # ensure arrays have the same Spec object for a given config
123+
def _spec_from_serialized_config(ser: str):
124+
config = donfig.deserialize(ser)
125+
spec_dict = expand_environment_variables(config["spec"])
126+
return Spec(**spec_dict)

cubed/tests/runtime/test_modal_async.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
image = modal.Image.debian_slim().pip_install(
2121
[
2222
"array-api-compat",
23+
"donfig",
2324
"fsspec",
2425
"mypy_extensions", # for rechunker
2526
"networkx",

cubed/tests/test_core.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,11 +280,21 @@ def test_default_spec(executor):
280280

281281
def test_default_spec_allowed_mem_exceeded():
282282
# default spec fails for large computations
283-
a = xp.ones((100000, 100000), chunks=(10000, 10000))
283+
a = xp.ones((20000, 1000), chunks=(10000, 1000))
284284
with pytest.raises(ValueError):
285285
xp.negative(a)
286286

287287

288+
def test_default_spec_config_override():
289+
# override default spec to increase allowed_mem
290+
from cubed import config
291+
292+
with config.set({"spec.allowed_mem": "500MB"}):
293+
a = xp.ones((20000, 1000), chunks=(10000, 1000))
294+
b = xp.negative(a)
295+
assert_array_equal(b.compute(), -np.ones((20000, 1000)))
296+
297+
288298
def test_different_specs(tmp_path):
289299
spec1 = cubed.Spec(tmp_path, allowed_mem=100000)
290300
spec2 = cubed.Spec(tmp_path, allowed_mem=200000)

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ requires-python = ">=3.9"
2323
dependencies = [
2424
"aiostream",
2525
"array-api-compat",
26+
"donfig",
2627
"fsspec",
2728
"mypy_extensions", # for rechunker
2829
"networkx < 2.8.3",

0 commit comments

Comments
 (0)