MATE-runtime 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. MATE/__init__.py +22 -0
  2. MATE/__main__.py +7 -0
  3. MATE/cli/__init__.py +181 -0
  4. MATE/cli/commands.py +573 -0
  5. MATE/cli/workdir.py +571 -0
  6. MATE/compat/__init__.py +1 -0
  7. MATE/compat/interface.py +248 -0
  8. MATE/compat/sizes.py +144 -0
  9. MATE/config/__init__.py +1 -0
  10. MATE/config/axes.py +310 -0
  11. MATE/config/builders.py +498 -0
  12. MATE/config/calendar.py +371 -0
  13. MATE/config/canonical.py +543 -0
  14. MATE/config/criteria.py +396 -0
  15. MATE/config/events.py +183 -0
  16. MATE/config/invariance.py +227 -0
  17. MATE/config/loader.py +498 -0
  18. MATE/config/model.py +883 -0
  19. MATE/config/resolve.py +943 -0
  20. MATE/config/runtable.py +342 -0
  21. MATE/config/seeds.py +344 -0
  22. MATE/config/stages.py +632 -0
  23. MATE/config/structure.py +635 -0
  24. MATE/config/toml.py +237 -0
  25. MATE/conformance/__init__.py +14 -0
  26. MATE/conformance/baseline.py +250 -0
  27. MATE/conformance/checks.py +1604 -0
  28. MATE/conformance/sampler.py +179 -0
  29. MATE/errors.py +236 -0
  30. MATE/evaluation/__init__.py +1 -0
  31. MATE/evaluation/budget.py +160 -0
  32. MATE/evaluation/invalids.py +181 -0
  33. MATE/evaluation/requests.py +148 -0
  34. MATE/execution/__init__.py +1 -0
  35. MATE/execution/accelerator.py +60 -0
  36. MATE/execution/base.py +643 -0
  37. MATE/execution/choose.py +152 -0
  38. MATE/execution/devices.py +108 -0
  39. MATE/execution/process.py +377 -0
  40. MATE/execution/serial.py +37 -0
  41. MATE/execution/thread.py +106 -0
  42. MATE/execution/vectorised.py +32 -0
  43. MATE/launch.py +267 -0
  44. MATE/loop/__init__.py +6 -0
  45. MATE/loop/continuous.py +172 -0
  46. MATE/loop/driver.py +783 -0
  47. MATE/loop/events.py +266 -0
  48. MATE/loop/generational.py +140 -0
  49. MATE/loop/owns_loop.py +333 -0
  50. MATE/loop/subpops.py +508 -0
  51. MATE/modules/__init__.py +1 -0
  52. MATE/modules/construct.py +198 -0
  53. MATE/modules/discovery.py +238 -0
  54. MATE/modules/registry.py +970 -0
  55. MATE/modules/software.py +593 -0
  56. MATE/modules/versions.py +72 -0
  57. MATE/numerics.py +159 -0
  58. MATE/observation/__init__.py +10 -0
  59. MATE/observation/control.py +199 -0
  60. MATE/observation/hub.py +451 -0
  61. MATE/observation/records.py +125 -0
  62. MATE/observation/sinks.py +313 -0
  63. MATE/provenance.py +396 -0
  64. MATE/readout/__init__.py +10 -0
  65. MATE/readout/catalogue.py +282 -0
  66. MATE/readout/front.py +151 -0
  67. MATE/readout/readout.py +927 -0
  68. MATE/readout/series.py +155 -0
  69. MATE/readout/statistics.py +202 -0
  70. MATE/run/__init__.py +1 -0
  71. MATE/run/checkpointing.py +266 -0
  72. MATE/run/contexts.py +553 -0
  73. MATE/run/declarations.py +240 -0
  74. MATE/run/plan.py +464 -0
  75. MATE/run/preconditions.py +165 -0
  76. MATE/run/run.py +991 -0
  77. MATE/run/specs.py +319 -0
  78. MATE/run/times.py +103 -0
  79. MATE/scheduling/__init__.py +214 -0
  80. MATE/scheduling/local.py +119 -0
  81. MATE/scheduling/slurm.py +380 -0
  82. MATE/storage/__init__.py +1 -0
  83. MATE/storage/checkpoint.py +414 -0
  84. MATE/storage/codec.py +315 -0
  85. MATE/storage/database.py +359 -0
  86. MATE/storage/lease.py +397 -0
  87. MATE/storage/rundir.py +248 -0
  88. mate_runtime-1.0.0.dist-info/METADATA +58 -0
  89. mate_runtime-1.0.0.dist-info/RECORD +93 -0
  90. mate_runtime-1.0.0.dist-info/WHEEL +4 -0
  91. mate_runtime-1.0.0.dist-info/entry_points.txt +2 -0
  92. mate_runtime-1.0.0.dist-info/licenses/COPYING +674 -0
  93. mate_runtime-1.0.0.dist-info/licenses/COPYING.LESSER +165 -0
@@ -0,0 +1,240 @@
1
+ """Load-time checks of what a module declares about itself.
2
+
3
+ These are the checks of [K] §10 that need only the constructed module: its capabilities, the
4
+ methods its flags announce, its reserved names and the names of its observables. Each refusal
5
+ code is produced here by one function.
6
+ """
7
+
8
+ from collections.abc import Mapping
9
+ from dataclasses import fields
10
+
11
+ from MATE_contract import Capabilities, Method, System
12
+
13
+ from MATE.errors import Refusal
14
+ from MATE.run.specs import NormalisedSpecs
15
+
16
+ __all__ = ["check_system", "check_method", "check_observable_names"]
17
+
18
+ _DEFAULT = Capabilities()
19
+ _EXECUTION = ("batched", "threadsafe", "picklable", "backends", "deterministic_given_seed")
20
+ _SYSTEM_ONLY = ("interruptible", "cost_hint", "owns_loop", "clock", "stateful")
21
+ _METHOD_ONLY = tuple(
22
+ f.name for f in fields(Capabilities) if f.name not in _EXECUTION + _SYSTEM_ONLY
23
+ )
24
+ _LOOP_KINDS = ("generational", "continuous")
25
+ # Level-2 flags that announce the method of the same name ([K] CP3).
26
+ _FLAG_METHODS = ("recommend", "parents", "distance", "split", "generation")
27
+ _METHOD_LEVEL_1 = (
28
+ "configure", "init", "ask", "decode", "tell", "genome_id",
29
+ "genome_to_data", "genome_from_data", "state_to_data", "state_from_data",
30
+ ) # fmt: skip
31
+ # Prefixes of the series and summaries MATE publishes itself ([K] OB7).
32
+ _SYSTEM_PREFIXES = ("method.", "performance.", "genome.", "invalid.", "time.")
33
+ _METHOD_PREFIXES = ("method.",)
34
+
35
+
36
+ def _implements(module: object, base: type, method: str) -> bool:
37
+ """Tell whether a module's class overrides a base method ([K] §9.5)."""
38
+ found = getattr(type(module), method, None)
39
+ return found is not None and found is not getattr(base, method)
40
+
41
+
42
+ def _foreign_fields(
43
+ caps: Capabilities, foreign: tuple[str, ...], kind: str, name: str
44
+ ) -> list[Refusal]:
45
+ """``P-CAPABILITY-FIELD`` for each foreign field that differs from its default ([K] CP1)."""
46
+ other = "method" if kind == "system" else "system"
47
+ return [
48
+ Refusal("P-CAPABILITY-FIELD", f"{kind} '{name}'",
49
+ f"{kind} '{name}': Capabilities field '{f}' does not concern a {kind}",
50
+ fix=f"remove '{f}' from the capabilities (it is a {other} field)")
51
+ for f in foreign
52
+ if getattr(caps, f) != getattr(_DEFAULT, f)
53
+ ]
54
+
55
+
56
+ def _backends(caps: Capabilities, kind: str, name: str) -> list[Refusal]:
57
+ """``P-CAPABILITIES`` for an empty backend list or an empty backend name ([K] CP4)."""
58
+ if caps.backends and all(caps.backends):
59
+ return []
60
+ return [Refusal("P-CAPABILITIES", f"{kind} '{name}'",
61
+ f"{kind} '{name}': Capabilities.backends = {caps.backends!r} must be a "
62
+ "non-empty tuple of non-empty names")]
63
+
64
+
65
+ def _reserved(
66
+ declared: Mapping[str, object], reserved: tuple[str, ...], kind: str, name: str, what: str
67
+ ) -> list[Refusal]:
68
+ """``P-RESERVED-NAME`` for each declared name MATE reserves ([C] R6.12)."""
69
+ return [
70
+ Refusal("P-RESERVED-NAME", f"{kind} '{name}'",
71
+ f"{kind} '{name}': {what} '{key}' uses a name reserved by MATE "
72
+ f"({', '.join(reserved)})")
73
+ for key in declared
74
+ if key in reserved
75
+ ]
76
+
77
+
78
+ def _prefixed(
79
+ declared: Mapping[str, object], prefixes: tuple[str, ...], kind: str, name: str
80
+ ) -> list[Refusal]:
81
+ """``P-RESERVED-PREFIX`` for each observable name under a reserved prefix ([K] OB7)."""
82
+ out = []
83
+ for s in declared:
84
+ for p in prefixes:
85
+ if s.startswith(p):
86
+ out.append(Refusal("P-RESERVED-PREFIX", f"{kind} '{name}'",
87
+ f"{kind} '{name}': observable name '{s}' uses the reserved "
88
+ f"prefix '{p}'"))
89
+ break
90
+ return out
91
+
92
+
93
+ def check_system(system: System, *, name: str) -> list[Refusal]:
94
+ """Check what a system declares about itself.
95
+
96
+ Parameters
97
+ ----------
98
+ system : System
99
+ The constructed system.
100
+ name : str
101
+ Its entry-point name.
102
+
103
+ Returns
104
+ -------
105
+ list of Refusal
106
+ ``P-CAPABILITIES-MISSING`` without a ``Capabilities``; ``P-CAPABILITY-FIELD`` for a
107
+ method-only field set; ``P-CAPABILITIES`` for a [K] CP4 failure (backends,
108
+ ``cost_hint``, ``owns_loop`` without ``clock`` or the reverse, ``stateful`` without
109
+ ``save_state``/``load_state``, ``owns_loop`` without ``evolve``);
110
+ ``P-RESERVED-NAME`` for a setting named ``module``; ``P-CAPABILITY-METHOD`` for
111
+ ``spec()`` or ``evaluate()`` not implemented by a system that does not own its loop.
112
+
113
+ Notes
114
+ -----
115
+ [K] SY2, CP1, CP4, §10 R3, R16, R18; [C] R6.12.
116
+ """
117
+ where = f"system '{name}'"
118
+ out = _reserved(getattr(system, "settings", {}) or {}, ("module",), "system", name,
119
+ "setting")
120
+ caps = getattr(system, "capabilities", None)
121
+ if not isinstance(caps, Capabilities):
122
+ out.insert(0, Refusal("P-CAPABILITIES-MISSING", where,
123
+ f"system '{name}' declares no Capabilities",
124
+ fix="set the class attribute capabilities = Capabilities(...)"))
125
+ return out
126
+ out[:0] = _foreign_fields(caps, _METHOD_ONLY, "system", name) + _backends(caps, "system", name)
127
+ if caps.cost_hint <= 0:
128
+ out.append(Refusal("P-CAPABILITIES", where,
129
+ f"system '{name}': Capabilities.cost_hint = {caps.cost_hint} must be "
130
+ "> 0"))
131
+ if caps.owns_loop and not caps.clock:
132
+ out.append(Refusal("P-CAPABILITIES", where,
133
+ f"system '{name}': Capabilities.owns_loop is True but clock is empty; "
134
+ "a system that owns its loop names the unit of its dates"))
135
+ if caps.clock and not caps.owns_loop:
136
+ out.append(Refusal("P-CAPABILITIES", where,
137
+ f"system '{name}': Capabilities.clock = '{caps.clock}' but owns_loop "
138
+ "is False; only a system that owns its loop has a clock"))
139
+ if caps.stateful:
140
+ missing = [m for m in ("save_state", "load_state") if not _implements(system, System, m)]
141
+ if missing:
142
+ out.append(Refusal("P-CAPABILITIES", where,
143
+ f"system '{name}': Capabilities.stateful is True but "
144
+ f"{' and '.join(m + '()' for m in missing)} not implemented"))
145
+ if caps.owns_loop and not _implements(system, System, "evolve"):
146
+ out.append(Refusal("P-CAPABILITIES", where,
147
+ f"system '{name}': Capabilities.owns_loop is True but evolve() is not "
148
+ "implemented"))
149
+ if not caps.owns_loop:
150
+ for m in ("spec", "evaluate"):
151
+ if not _implements(system, System, m):
152
+ out.append(Refusal("P-CAPABILITY-METHOD", where,
153
+ f"system '{name}': {m}() is not implemented; it is required "
154
+ "of a system that does not own its loop"))
155
+ return out
156
+
157
+
158
+ def check_method(method: Method, *, name: str) -> list[Refusal]:
159
+ """Check what a method declares about itself.
160
+
161
+ Parameters
162
+ ----------
163
+ method : Method
164
+ The constructed method.
165
+ name : str
166
+ Its entry-point name.
167
+
168
+ Returns
169
+ -------
170
+ list of Refusal
171
+ ``P-CAPABILITY-FIELD`` for a system-only field set; ``P-CAPABILITIES`` for a [K] CP4
172
+ failure (``loop_kinds``, backends, ``rereadable`` outside a declared ``meta``);
173
+ ``P-CAPABILITY-METHOD`` for a level-2 flag without its method, or a level-1 method not
174
+ implemented; ``P-ALLOCATION`` for ``allocation = True``; ``P-RESERVED-NAME`` for a
175
+ meta-parameter named ``module`` or ``role``; ``P-RESERVED-PREFIX`` for a series or
176
+ summary named ``method.<...>``.
177
+
178
+ Notes
179
+ -----
180
+ [K] CP1, CP3, CP4, CP5, OB7, §10 R3, R14, R16, R17; [C] R6.12. ``P-ALLOCATION`` is
181
+ produced here only (design §3.5).
182
+ """
183
+ where = f"method '{name}'"
184
+ caps = getattr(method, "capabilities", _DEFAULT)
185
+ meta = getattr(method, "meta", {}) or {}
186
+ out = _foreign_fields(caps, _SYSTEM_ONLY, "method", name) + _backends(caps, "method", name)
187
+ kinds = caps.loop_kinds
188
+ if not kinds or any(k not in _LOOP_KINDS for k in kinds):
189
+ out.append(Refusal("P-CAPABILITIES", where,
190
+ f"method '{name}': Capabilities.loop_kinds = {kinds!r} must be a "
191
+ f"non-empty subset of {_LOOP_KINDS!r}"))
192
+ stray = [r for r in caps.rereadable if r not in meta]
193
+ if meta and stray:
194
+ out.append(Refusal("P-CAPABILITIES", where,
195
+ f"method '{name}': Capabilities.rereadable names {', '.join(stray)}, "
196
+ f"which are not meta-parameters (meta: {', '.join(meta)})"))
197
+ for flag in _FLAG_METHODS:
198
+ if getattr(caps, flag) and not _implements(method, Method, flag):
199
+ out.append(Refusal("P-CAPABILITY-METHOD", where,
200
+ f"method '{name}': Capabilities.{flag} is True but {flag}() is "
201
+ "not implemented"))
202
+ for m in _METHOD_LEVEL_1:
203
+ if not _implements(method, Method, m):
204
+ out.append(Refusal("P-CAPABILITY-METHOD", where,
205
+ f"method '{name}': {m}() is not implemented; every method "
206
+ "implements it (level 1)"))
207
+ if caps.allocation:
208
+ out.append(Refusal("P-ALLOCATION", where,
209
+ f"method '{name}' declares Capabilities.allocation; budget allocation "
210
+ "by the method is not available in MATE 1.0.0: its interface is not "
211
+ "yet specified"))
212
+ out += _reserved(meta, ("module", "role"), "method", name, "meta-parameter")
213
+ out += _prefixed(getattr(method, "series", {}) or {}, _METHOD_PREFIXES, "method", name)
214
+ out += _prefixed(getattr(method, "summaries", {}) or {}, _METHOD_PREFIXES, "method", name)
215
+ return out
216
+
217
+
218
+ def check_observable_names(specs: NormalisedSpecs, *, system: str) -> list[Refusal]:
219
+ """Check the names of a system's series and summaries.
220
+
221
+ Parameters
222
+ ----------
223
+ specs : NormalisedSpecs
224
+ The system's normalised specs.
225
+ system : str
226
+ The system's entry-point name.
227
+
228
+ Returns
229
+ -------
230
+ list of Refusal
231
+ ``P-RESERVED-PREFIX`` for each name starting with ``method.``, ``performance.``,
232
+ ``genome.``, ``invalid.`` or ``time.``.
233
+
234
+ Notes
235
+ -----
236
+ [K] OB7, §10 R17.
237
+ """
238
+ obs = specs.observables
239
+ return (_prefixed(obs.series, _SYSTEM_PREFIXES, "system", system)
240
+ + _prefixed(obs.summaries, _SYSTEM_PREFIXES, "system", system))