Skip to content

Commit 154ab69

Browse files
committed
Merge remote-tracking branch 'origin/develop' into feature/IMAS-4918-dd3to4
2 parents 15272a7 + 757516a commit 154ab69

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3178
-173
lines changed

asv.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
// Customizable commands for building, installing, and
2222
// uninstalling the project. See asv.conf.json documentation.
2323
//
24-
// "install_command": ["in-dir={env_dir} python -mpip install {wheel_file}"],
24+
"install_command": ["in-dir={env_dir} python -mpip install {wheel_file}[netcdf]"],
2525
// "uninstall_command": ["return-code=any python -mpip uninstall -y {project}"],
2626
"build_command": [
2727
// link data-dictionary and build folder so the DD source files remain cached

benchmarks/core_profiles.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,6 @@ def fill_slices(core_profiles, times):
6262
profiles_1d.neutral[i].density = np.zeros(N_GRID)
6363

6464

65-
def setup_dbentry(hli, backend):
66-
dbentry = create_dbentry(hli, backend, "w")
67-
core_profiles = factory[hli].core_profiles()
68-
fill_slices(core_profiles, TIME)
69-
dbentry.put(core_profiles)
70-
dbentry.close()
71-
72-
7365
class GetSlice:
7466
params = [hlis, available_slicing_backends]
7567
param_names = ["hli", "backend"]
@@ -84,11 +76,16 @@ def time_get_slice(self, hli, backend):
8476
for t in TIME:
8577
self.dbentry.get_slice("core_profiles", t, imaspy.ids_defs.CLOSEST_INTERP)
8678

79+
def teardown(self, hli, backend):
80+
if hasattr(self, "dbentry"): # imas + netCDF has no dbentry
81+
self.dbentry.close()
82+
8783

8884
class Get:
8985
params = [hlis, available_backends]
9086
param_names = ["hli", "backend"]
9187
setup = GetSlice.setup
88+
teardown = GetSlice.teardown
9289

9390
def time_get(self, hli, backend):
9491
self.dbentry.get("core_profiles")
@@ -108,6 +105,10 @@ def time_lazy_get(self, lazy, backend):
108105
cp = self.dbentry.get("core_profiles", lazy=lazy)
109106
np.array([prof_1d.electrons.temperature for prof_1d in cp.profiles_1d])
110107

108+
def teardown(self, lazy, backend):
109+
if hasattr(self, "dbentry"): # imas + netCDF has no dbentry
110+
self.dbentry.close()
111+
111112

112113
class Generate:
113114
params = [hlis]
@@ -132,28 +133,30 @@ class Put:
132133
param_names = ["disable_validate", "hli", "backend"]
133134

134135
def setup(self, disable_validate, hli, backend):
135-
self.dbentry = create_dbentry(hli, backend)
136+
create_dbentry(hli, backend).close() # catch unsupported combinations
136137
self.core_profiles = factory[hli].core_profiles()
137138
fill_slices(self.core_profiles, TIME)
138139
os.environ["IMAS_AL_DISABLE_VALIDATE"] = disable_validate
139140

140141
def time_put(self, disable_validate, hli, backend):
141-
self.dbentry.put(self.core_profiles)
142+
with create_dbentry(hli, backend) as dbentry:
143+
dbentry.put(self.core_profiles)
142144

143145

144146
class PutSlice:
145147
params = [["0", "1"], hlis, available_slicing_backends]
146148
param_names = ["disable_validate", "hli", "backend"]
147149

148150
def setup(self, disable_validate, hli, backend):
149-
self.dbentry = create_dbentry(hli, backend)
151+
create_dbentry(hli, backend).close() # catch unsupported combinations
150152
self.core_profiles = factory[hli].core_profiles()
151153
os.environ["IMAS_AL_DISABLE_VALIDATE"] = disable_validate
152154

153155
def time_put_slice(self, disable_validate, hli, backend):
154-
for t in TIME:
155-
fill_slices(self.core_profiles, [t])
156-
self.dbentry.put_slice(self.core_profiles)
156+
with create_dbentry(hli, backend) as dbentry:
157+
for t in TIME:
158+
fill_slices(self.core_profiles, [t])
159+
dbentry.put_slice(self.core_profiles)
157160

158161

159162
class Serialize:

benchmarks/edge_profiles.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ def setup(self, hli, backend):
124124
def time_get(self, hli, backend):
125125
self.dbentry.get("edge_profiles")
126126

127+
def teardown(self, hli, backend):
128+
if hasattr(self, "dbentry"): # imas + netCDF has no dbentry
129+
self.dbentry.close()
130+
127131

128132
class Generate:
129133
params = [hlis]
@@ -142,10 +146,11 @@ class Put:
142146
param_names = ["disable_validate", "hli", "backend"]
143147

144148
def setup(self, disable_validate, hli, backend):
145-
self.dbentry = create_dbentry(hli, backend)
149+
create_dbentry(hli, backend).close() # catch unsupported combinations
146150
self.edge_profiles = factory[hli].edge_profiles()
147151
fill_ggd(self.edge_profiles, TIME)
148152
os.environ["IMAS_AL_DISABLE_VALIDATE"] = disable_validate
149153

150154
def time_put(self, disable_validate, hli, backend):
151-
self.dbentry.put(self.edge_profiles)
155+
with create_dbentry(hli, backend) as dbentry:
156+
dbentry.put(self.edge_profiles)

benchmarks/utils.py

Lines changed: 48 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,52 +3,50 @@
33
import uuid
44
from pathlib import Path
55

6-
from packaging.version import Version
7-
86
import imaspy
9-
from imaspy.backends.imas_core.imas_interface import ll_interface, lowlevel
7+
import imaspy.exception
108

119
# Don't directly import imas: code analyzers break on the huge code base
1210
imas = importlib.import_module("imas")
1311

1412

13+
# Backend constants
14+
HDF5 = "HDF5"
15+
MDSPLUS = "MDSplus"
16+
MEMORY = "memory"
17+
ASCII = "ASCII"
18+
NETCDF = "netCDF"
19+
20+
21+
def create_uri(backend, path):
22+
if backend == NETCDF:
23+
return f"{path}.nc"
24+
return f"imas:{backend.lower()}?path={path}"
25+
26+
1527
def backend_exists(backend):
1628
"""Tries to detect if the lowlevel has support for the given backend."""
17-
random_db = str(uuid.uuid4())
18-
if ll_interface._al_version < Version("5"):
19-
dbentry = imas.DBEntry(backend, random_db, 1, 1)
20-
try:
21-
# open() raises an exception when there is no support for the backend
22-
# when there is support, but the entry cannot be opened, it only gives a
23-
# negative return value.
24-
# A bit weird (and subject to change per
25-
# https://jira.iter.org/browse/IMAS-4671), but we can use it nicely here
26-
dbentry.open()
27-
except Exception as exc:
28-
if "Error calling ual_begin_pulse_action" in str(exc):
29-
return False
30-
raise
31-
return True
32-
33-
else:
34-
dbentry = imaspy.DBEntry(backend, random_db, 1, 1)
35-
try:
36-
dbentry.open()
37-
except Exception as exc:
38-
if "backend is not available" in str(exc):
39-
return False
40-
elif isinstance(exc, lowlevel.ImasCoreBackendException):
41-
return True
42-
raise
29+
uri = create_uri(backend, str(uuid.uuid4()))
30+
try:
31+
entry = imaspy.DBEntry(uri, "r")
32+
except Exception as exc:
33+
if "backend is not available" in str(exc):
34+
return False
35+
elif isinstance(exc, (imaspy.exception.ALException, FileNotFoundError)):
36+
return True
4337
return True
38+
# Highly unlikely, but it could succeed without error
39+
entry.close()
40+
return True
4441

4542

4643
# Note: UDA backend is not used for benchmarking
4744
all_backends = [
48-
imaspy.ids_defs.HDF5_BACKEND,
49-
imaspy.ids_defs.MDSPLUS_BACKEND,
50-
imaspy.ids_defs.MEMORY_BACKEND,
51-
imaspy.ids_defs.ASCII_BACKEND,
45+
HDF5,
46+
MDSPLUS,
47+
MEMORY,
48+
ASCII,
49+
NETCDF,
5250
]
5351

5452
# Suppress error logs for testing backend availabitily:
@@ -59,9 +57,7 @@ def backend_exists(backend):
5957
available_backends = list(filter(backend_exists, all_backends))
6058
logging.getLogger().setLevel(logging.INFO)
6159
available_slicing_backends = [
62-
backend
63-
for backend in available_backends
64-
if backend != imaspy.ids_defs.ASCII_BACKEND
60+
backend for backend in available_backends if backend not in [ASCII, NETCDF]
6561
]
6662

6763
hlis = ["imas", "imaspy"]
@@ -77,12 +73,20 @@ def backend_exists(backend):
7773

7874

7975
def create_dbentry(hli, backend):
76+
if backend == NETCDF:
77+
if hli == "imas":
78+
# Raising NotImplementedError will skip the benchmarks for this combination
79+
raise NotImplementedError("AL-Python HLI doesn't implement netCDF.")
80+
if hli == "imaspy": # check if netcdf backend is available
81+
try:
82+
assert (
83+
imaspy.DBEntry._select_implementation("x.nc").__name__
84+
== "NCDBEntryImpl"
85+
)
86+
except (AttributeError, AssertionError):
87+
raise NotImplementedError(
88+
"This version of IMASPy doesn't implement netCDF."
89+
) from None
90+
8091
path = Path.cwd() / f"DB-{hli}-{backend}"
81-
path.mkdir(exist_ok=True)
82-
if backend == imas.imasdef.MDSPLUS_BACKEND:
83-
# Need to ensure that the MDS+ data folder exists:
84-
(path / "benchmark" / "3" / "0").mkdir(parents=True, exist_ok=True)
85-
dbentry = DBEntry[hli](backend, "benchmark", 1, 1, str(path))
86-
options = f"-prefix {path}/" if backend == imas.imasdef.ASCII_BACKEND else None
87-
dbentry.create(options=options)
88-
return dbentry
92+
return DBEntry[hli](create_uri(backend, path), "w")

ci/build_docs_and_dist.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ rm -rf dist
2828
python -m build .
2929

3030
# Install imaspy and documentation dependencies from the just-built wheel
31-
pip install "`readlink -f dist/*.whl`[docs]"
31+
pip install "`readlink -f dist/*.whl`[docs,netcdf]"
3232

3333
# Debugging:
3434
pip freeze

ci/run_pytest.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ source venv/bin/activate
2424

2525
# Install imaspy and test dependencies
2626
pip install --upgrade pip setuptools wheel
27-
pip install .[test]
27+
pip install .[h5py,netcdf,test]
2828

2929
# Debugging:
3030
pip freeze

docs/source/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
apidoc/*
2+
netcdf4.objects.inv

0 commit comments

Comments
 (0)