experimaestro 1.7.1__tar.gz → 1.8.0rc0__tar.gz
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.
Potentially problematic release.
This version of experimaestro might be problematic. Click here for more details.
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/PKG-INFO +1 -1
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/pyproject.toml +2 -2
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/__init__.py +2 -1
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/core/context.py +3 -9
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/core/objects.py +2 -2
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/core/serialization.py +9 -6
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/experiments/cli.py +31 -9
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/scheduler/base.py +9 -0
- experimaestro-1.8.0rc0/src/experimaestro/scheduler/state.py +75 -0
- experimaestro-1.8.0rc0/src/experimaestro/tests/test_experiment.py +50 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/typingutils.py +1 -8
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/LICENSE +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/README.md +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/__main__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/annotations.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/checkers.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/cli/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/cli/filter.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/cli/jobs.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/click.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/commandline.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/compat.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/connectors/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/connectors/local.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/connectors/ssh.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/core/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/core/arguments.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/core/objects.pyi +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/core/serializers.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/core/types.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/core/utils.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/exceptions.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/experiments/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/experiments/configuration.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/generators.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/huggingface.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/ipc.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/launcherfinder/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/launcherfinder/base.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/launcherfinder/parser.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/launcherfinder/registry.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/launcherfinder/specs.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/launchers/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/launchers/direct.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/launchers/oar.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/launchers/slurm/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/launchers/slurm/base.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/locking.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/mkdocs/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/mkdocs/annotations.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/mkdocs/base.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/mkdocs/metaloader.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/mkdocs/style.css +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/mypy.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/notifications.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/py.typed +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/rpyc.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/run.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/scheduler/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/scheduler/dependencies.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/scheduler/dynamic_outputs.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/scheduler/services.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/scheduler/workspace.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/scriptbuilder.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/016b4a6cdced82ab3aa1.ttf +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/0c35d18bf06992036b69.woff2 +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/1815e00441357e01619e.ttf +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/219aa9140e099e6c72ed.woff2 +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/2463b90d9a316e4e5294.woff2 +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/2582b0e4bcf85eceead0.ttf +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/3a4004a46a653d4b2166.woff +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/3baa5b8f3469222b822d.woff +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/4d73cb90e394b34b7670.woff +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/4ef4218c522f1eb6b5b1.woff2 +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/50701fbb8177c2dde530.ttf +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/5d681e2edae8c60630db.woff +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/6f420cf17cc0d7676fad.woff2 +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/878f31251d960bd6266f.woff2 +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/89999bdf5d835c012025.woff2 +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/914997e1bdfc990d0897.ttf +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/b041b1fa4fe241b23445.woff2 +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/b6879d41b0852f01ed5b.woff2 +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/c210719e60948b211a12.woff2 +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/c380809fd3677d7d6903.woff2 +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/d75e3fd1eb12e9bd6655.ttf +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/f882956fd323fd322f31.woff +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/favicon.ico +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/index.css +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/index.css.map +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/index.html +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/index.js +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/index.js.map +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/login.html +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/server/data/manifest.json +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/settings.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/sphinx/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/sphinx/static/experimaestro.css +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/taskglobals.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/conftest.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/connectors/bin/executable.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/connectors/test_local.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/connectors/utils.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/definitions_types.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/bin/sacct +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/bin/sbatch +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/bin/srun +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/bin/test.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/common.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/config_slurm/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/config_slurm/launchers.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/test_local.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/test_slurm.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/restart.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/restart_main.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/scripts/notifyandwait.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/scripts/waitforfile.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/task_tokens.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/tasks/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/tasks/all.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/tasks/foreign.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_checkers.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_dependencies.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_findlauncher.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_forward.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_identifier.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_instance.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_objects.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_outputs.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_param.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_progress.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_serializers.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_snippets.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_ssh.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_tags.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_tasks.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_tokens.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_types.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/test_validation.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/token_reschedule.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/utils.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tokens.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tools/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tools/diff.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tools/documentation.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tools/jobs.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/utils/__init__.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/utils/asyncio.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/utils/jobs.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/utils/jupyter.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/utils/resources.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/utils/settings.py +0 -0
- {experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/xpmutils.py +0 -0
|
@@ -20,7 +20,7 @@ include = [
|
|
|
20
20
|
"src/experimaestro/mkdocs/style.css",
|
|
21
21
|
{ path="src/experimaestro/server/data/*", format=['sdist', 'wheel']}
|
|
22
22
|
]
|
|
23
|
-
version = "1.
|
|
23
|
+
version = "1.8.0-rc0"
|
|
24
24
|
repository = "https://github.com/experimaestro/experimaestro-python"
|
|
25
25
|
documentation = "https://experimaestro-python.readthedocs.io/"
|
|
26
26
|
|
|
@@ -122,7 +122,7 @@ warn_unused_ignores = true
|
|
|
122
122
|
|
|
123
123
|
[tool.commitizen]
|
|
124
124
|
name = "cz_conventional_commits"
|
|
125
|
-
version = "1.
|
|
125
|
+
version = "1.8.0rc0"
|
|
126
126
|
changelog_start_rev = "v1.0.0"
|
|
127
127
|
tag_format = "v$major.$minor.$patch$prerelease"
|
|
128
128
|
# update_changelog_on_bump = true
|
|
@@ -55,8 +55,9 @@ from .core.context import SerializationContext
|
|
|
55
55
|
from .core.serializers import SerializationLWTask, PathSerializationLWTask
|
|
56
56
|
from .core.types import Any, SubmitHook
|
|
57
57
|
from .launchers import Launcher
|
|
58
|
-
from .scheduler.workspace import Workspace, RunMode
|
|
59
58
|
from .scheduler import Scheduler, experiment, FailedExperiment
|
|
59
|
+
from .scheduler.workspace import Workspace, RunMode
|
|
60
|
+
from .scheduler.state import get_experiment
|
|
60
61
|
from .notifications import progress, tqdm
|
|
61
62
|
from .checkers import Choices
|
|
62
63
|
from .xpmutils import DirectoryContext
|
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
from contextlib import contextmanager
|
|
2
|
-
from pathlib import Path
|
|
2
|
+
from pathlib import Path, UnsupportedOperation
|
|
3
3
|
import shutil
|
|
4
4
|
from typing import List, Optional, Protocol, Set, Union
|
|
5
5
|
import os
|
|
6
|
-
import sys
|
|
7
|
-
|
|
8
|
-
has_hardlink_to = sys.version_info.major == 3 and sys.version_info.minor >= 10
|
|
9
6
|
|
|
10
7
|
|
|
11
8
|
def shallow_copy(src_path: Path, dest_path: Path):
|
|
12
9
|
"""Copy a directory or file, trying to use hard links if possible"""
|
|
13
10
|
if src_path.is_file():
|
|
14
11
|
try:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
else:
|
|
18
|
-
dest_path.link_to(src_path)
|
|
19
|
-
except OSError:
|
|
12
|
+
dest_path.hardlink_to(src_path)
|
|
13
|
+
except (NotImplementedError, UnsupportedOperation, OSError):
|
|
20
14
|
shutil.copy(src_path, dest_path)
|
|
21
15
|
else:
|
|
22
16
|
if dest_path.exists():
|
|
@@ -1079,7 +1079,7 @@ class ConfigInformation:
|
|
|
1079
1079
|
if value is None:
|
|
1080
1080
|
return None
|
|
1081
1081
|
|
|
1082
|
-
elif isinstance(value, list):
|
|
1082
|
+
elif isinstance(value, (list, tuple)):
|
|
1083
1083
|
return [ConfigInformation._outputjsonvalue(el, context) for el in value]
|
|
1084
1084
|
|
|
1085
1085
|
elif isinstance(value, dict):
|
|
@@ -1196,7 +1196,7 @@ class ConfigInformation:
|
|
|
1196
1196
|
configurations if necessary"""
|
|
1197
1197
|
if isinstance(value, Config):
|
|
1198
1198
|
value.__xpm__.__get_objects__(objects, context)
|
|
1199
|
-
elif isinstance(value, list):
|
|
1199
|
+
elif isinstance(value, (list, tuple)):
|
|
1200
1200
|
for el in value:
|
|
1201
1201
|
ConfigInformation.__collect_objects__(el, objects, context)
|
|
1202
1202
|
elif isinstance(value, dict):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from pathlib import Path
|
|
3
|
-
from typing import Any, Dict, List, Tuple, Union, TYPE_CHECKING
|
|
3
|
+
from typing import Any, Dict, List, Optional, Tuple, Union, TYPE_CHECKING
|
|
4
4
|
from experimaestro.core.context import (
|
|
5
5
|
SerializationContext,
|
|
6
6
|
SerializedPath,
|
|
@@ -41,17 +41,20 @@ def state_dict(context: SerializationContext, obj: Any):
|
|
|
41
41
|
return {"objects": objects, "data": data}
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
def
|
|
44
|
+
def save_definition(obj: Any, context: SerializationContext, path: Path):
|
|
45
|
+
data = state_dict(context, obj)
|
|
46
|
+
with path.open("wt") as out:
|
|
47
|
+
json.dump(data, out)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def save(obj: Any, save_directory: Optional[Path]):
|
|
45
51
|
"""Saves an object into a disk file
|
|
46
52
|
|
|
47
53
|
:param save_directory: The directory in which the object and its data will
|
|
48
54
|
be saved (by default, the object is saved in "definition.json")
|
|
49
55
|
"""
|
|
50
56
|
context = SerializationContext(save_directory=save_directory)
|
|
51
|
-
|
|
52
|
-
data = state_dict(context, obj)
|
|
53
|
-
with (save_directory / "definition.json").open("wt") as out:
|
|
54
|
-
json.dump(data, out)
|
|
57
|
+
save_definition(obj, context, save_directory / "definition.json")
|
|
55
58
|
|
|
56
59
|
|
|
57
60
|
def get_data_loader(path: Union[str, Path, SerializedPathLoader]):
|
|
@@ -59,6 +59,7 @@ class ConfigurationLoader:
|
|
|
59
59
|
def __init__(self):
|
|
60
60
|
self.yamls = []
|
|
61
61
|
self.python_path = set()
|
|
62
|
+
self.yaml_module_file: None | Path = None
|
|
62
63
|
|
|
63
64
|
def load(self, yaml_file: Path):
|
|
64
65
|
"""Loads a YAML file, and parents one if they exist"""
|
|
@@ -73,6 +74,10 @@ class ConfigurationLoader:
|
|
|
73
74
|
if not path.is_absolute():
|
|
74
75
|
_data["file"] = str((yaml_file.parent / path).resolve())
|
|
75
76
|
|
|
77
|
+
if "module" in _data:
|
|
78
|
+
# Keeps track of the YAML file where the module was defined
|
|
79
|
+
self.yaml_module_file = yaml_file
|
|
80
|
+
|
|
76
81
|
if parent := _data.get("parent", None):
|
|
77
82
|
self.load(yaml_file.parent / parent)
|
|
78
83
|
|
|
@@ -121,7 +126,10 @@ class ConfigurationLoader:
|
|
|
121
126
|
help="Port for monitoring (can be defined in the settings.yaml file)",
|
|
122
127
|
)
|
|
123
128
|
@click.option(
|
|
124
|
-
"--file",
|
|
129
|
+
"--file",
|
|
130
|
+
"xp_file",
|
|
131
|
+
type=Path,
|
|
132
|
+
help="The file containing the main experimental code",
|
|
125
133
|
)
|
|
126
134
|
@click.option(
|
|
127
135
|
"--module-name", "module_name", help="Module containing the experimental code"
|
|
@@ -202,8 +210,6 @@ def experiments_cli( # noqa: C901
|
|
|
202
210
|
logging.info(
|
|
203
211
|
"Using python path: %s", ", ".join(str(s) for s in python_path)
|
|
204
212
|
)
|
|
205
|
-
else:
|
|
206
|
-
xp_file = Path(xp_file)
|
|
207
213
|
|
|
208
214
|
assert (
|
|
209
215
|
module_name or xp_file
|
|
@@ -221,6 +227,19 @@ def experiments_cli( # noqa: C901
|
|
|
221
227
|
for path in python_path:
|
|
222
228
|
sys.path.append(str(path))
|
|
223
229
|
|
|
230
|
+
# --- Adds automatically the experiment module if not found
|
|
231
|
+
if module_name and conf_loader.yaml_module_file:
|
|
232
|
+
try:
|
|
233
|
+
importlib.import_module(module_name)
|
|
234
|
+
except ModuleNotFoundError:
|
|
235
|
+
# Try to setup a path
|
|
236
|
+
path = conf_loader.yaml_module_file.resolve()
|
|
237
|
+
for _ in range(len(module_name.split("."))):
|
|
238
|
+
path = path.parent
|
|
239
|
+
|
|
240
|
+
logging.info("Appending %s to python path", path)
|
|
241
|
+
sys.path.append(str(path))
|
|
242
|
+
|
|
224
243
|
if xp_file:
|
|
225
244
|
if not xp_file.exists() and xp_file.suffix != ".py":
|
|
226
245
|
xp_file = xp_file.with_suffix(".py")
|
|
@@ -243,17 +262,20 @@ def experiments_cli( # noqa: C901
|
|
|
243
262
|
|
|
244
263
|
# --- ... and runs it
|
|
245
264
|
if helper is None:
|
|
246
|
-
raise
|
|
265
|
+
raise click.ClickException(
|
|
266
|
+
f"Could not find run function in {xp_file if xp_file else module_name}"
|
|
267
|
+
)
|
|
247
268
|
|
|
248
269
|
if not isinstance(helper, ExperimentHelper):
|
|
249
270
|
helper = ExperimentHelper(helper)
|
|
250
271
|
|
|
251
272
|
parameters = inspect.signature(helper.callable).parameters
|
|
252
273
|
list_parameters = list(parameters.values())
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
274
|
+
if len(list_parameters) != 2:
|
|
275
|
+
raise click.ClickException(
|
|
276
|
+
f"run in {xp_file if xp_file else module_name} function should only "
|
|
277
|
+
f"have two arguments (got {len(list_parameters)}), "
|
|
278
|
+
)
|
|
257
279
|
|
|
258
280
|
schema = list_parameters[1].annotation
|
|
259
281
|
omegaconf_schema = OmegaConf.structured(schema())
|
|
@@ -263,7 +285,7 @@ def experiments_cli( # noqa: C901
|
|
|
263
285
|
configuration = OmegaConf.merge(omegaconf_schema, configuration)
|
|
264
286
|
except omegaconf.errors.ConfigKeyError as e:
|
|
265
287
|
cprint(f"Error in configuration:\n\n{e}", "red", file=sys.stderr)
|
|
266
|
-
|
|
288
|
+
raise click.ClickException("Error in configuration")
|
|
267
289
|
|
|
268
290
|
if show:
|
|
269
291
|
print(json.dumps(OmegaConf.to_container(configuration))) # noqa: T201
|
|
@@ -1057,6 +1057,15 @@ class experiment:
|
|
|
1057
1057
|
logger.info("Stopping web server")
|
|
1058
1058
|
self.server.stop()
|
|
1059
1059
|
|
|
1060
|
+
if self.workspace.run_mode == RunMode.NORMAL:
|
|
1061
|
+
# Write the state
|
|
1062
|
+
logging.info("Saving the experiment state")
|
|
1063
|
+
from experimaestro.scheduler.state import ExperimentState
|
|
1064
|
+
|
|
1065
|
+
ExperimentState.save(
|
|
1066
|
+
self.workdir / "state.json", self.scheduler.jobs.values()
|
|
1067
|
+
)
|
|
1068
|
+
|
|
1060
1069
|
async def update_task_output_count(self, delta: int):
|
|
1061
1070
|
"""Change in the number of task outputs to process"""
|
|
1062
1071
|
async with self.central.exitCondition:
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
import json
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Iterable, Optional, Type
|
|
5
|
+
from experimaestro import Task
|
|
6
|
+
|
|
7
|
+
from experimaestro.core.context import SerializationContext
|
|
8
|
+
from experimaestro.scheduler.base import Job, JobDependency
|
|
9
|
+
from experimaestro.settings import find_workspace
|
|
10
|
+
from experimaestro.core.serialization import from_state_dict, save_definition
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class JobInformation:
|
|
15
|
+
id: str
|
|
16
|
+
path: Path
|
|
17
|
+
task: Task
|
|
18
|
+
tags: dict[str, str]
|
|
19
|
+
depends_on: list["JobInformation"] = field(default_factory=list)
|
|
20
|
+
|
|
21
|
+
def __post_init__(self):
|
|
22
|
+
self.path = Path(self.path)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ExperimentState:
|
|
26
|
+
def __init__(self, workdir: Path, name: str):
|
|
27
|
+
path = workdir / "xp" / name / "state.json"
|
|
28
|
+
with path.open("rt") as fh:
|
|
29
|
+
content = json.load(fh)
|
|
30
|
+
|
|
31
|
+
self.states: dict[str, JobInformation] = {
|
|
32
|
+
state_dict["id"]: JobInformation(**state_dict)
|
|
33
|
+
for state_dict in from_state_dict(content, as_instance=False)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
for state in self.states.values():
|
|
37
|
+
state.depends_on = [self.states[key] for key in state.depends_on]
|
|
38
|
+
|
|
39
|
+
def get_jobs(self, task_class: Type[Task]) -> list[JobInformation]:
|
|
40
|
+
if task_class is None:
|
|
41
|
+
return list(self.data.values())
|
|
42
|
+
|
|
43
|
+
tasks = []
|
|
44
|
+
for job_state in self.states.values():
|
|
45
|
+
if isinstance(job_state.task, task_class):
|
|
46
|
+
tasks.append(job_state)
|
|
47
|
+
return tasks
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def save(path: Path, jobs: Iterable[Job]):
|
|
51
|
+
save_definition(
|
|
52
|
+
[
|
|
53
|
+
{
|
|
54
|
+
"id": job.identifier,
|
|
55
|
+
"path": str(job.path),
|
|
56
|
+
"task": job.config,
|
|
57
|
+
"tags": job.config.__xpm__.tags(),
|
|
58
|
+
"depends_on": list(
|
|
59
|
+
dep.origin.identifier
|
|
60
|
+
for dep in job.dependencies
|
|
61
|
+
if isinstance(dep, JobDependency)
|
|
62
|
+
),
|
|
63
|
+
}
|
|
64
|
+
for job in jobs
|
|
65
|
+
],
|
|
66
|
+
SerializationContext(),
|
|
67
|
+
path,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def get_experiment(
|
|
72
|
+
name: str, *, workspace: Optional[str] = None, workdir: Optional[Path] = None
|
|
73
|
+
) -> ExperimentState:
|
|
74
|
+
ws = find_workspace(workspace=workspace, workdir=workdir)
|
|
75
|
+
return ExperimentState(ws.path, name)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from experimaestro import Task, Param, get_experiment, tag
|
|
2
|
+
from experimaestro.tests.utils import TemporaryDirectory, TemporaryExperiment
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class TaskA(Task):
|
|
6
|
+
def execute(self):
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TaskB(Task):
|
|
11
|
+
task_a: Param[TaskA]
|
|
12
|
+
x: Param[int]
|
|
13
|
+
|
|
14
|
+
def execute(self):
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# xp = get_experiment(id="my-xp-1")
|
|
19
|
+
|
|
20
|
+
# # Returns a list of tasks which were submitted and successful
|
|
21
|
+
# tasks = xp.get_tasks(myxps.evaluation.Evaluation, status=Job.DONE)
|
|
22
|
+
|
|
23
|
+
# for task in tasks:
|
|
24
|
+
# # Look at the tags
|
|
25
|
+
# print(task.tags)
|
|
26
|
+
|
|
27
|
+
# # Get some information
|
|
28
|
+
# print("Task ran in {task.workdir}")
|
|
29
|
+
|
|
30
|
+
# # Look at the parent jobs
|
|
31
|
+
# print(task.depends_on)
|
|
32
|
+
|
|
33
|
+
# # Look at the dependant
|
|
34
|
+
# print(task.dependents)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def test_experiment_history():
|
|
38
|
+
"""Test retrieving experiment history"""
|
|
39
|
+
with TemporaryDirectory() as workdir:
|
|
40
|
+
with TemporaryExperiment("experiment", workdir=workdir):
|
|
41
|
+
task_a = TaskA().submit()
|
|
42
|
+
TaskB(task_a=task_a, x=tag(1)).submit()
|
|
43
|
+
|
|
44
|
+
# Look at the experiment
|
|
45
|
+
xp = get_experiment("experiment", workdir=workdir)
|
|
46
|
+
|
|
47
|
+
(task_a_info,) = xp.get_jobs(TaskA)
|
|
48
|
+
(task_b_info,) = xp.get_jobs(TaskB)
|
|
49
|
+
assert task_b_info.tags == {"x": 1}
|
|
50
|
+
assert task_b_info.depends_on == [task_a_info]
|
|
@@ -8,14 +8,7 @@ if sys.version_info.major == 3:
|
|
|
8
8
|
else:
|
|
9
9
|
from typing import _collect_parameters
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
from typing_extensions import (
|
|
13
|
-
_AnnotatedAlias as AnnotatedAlias,
|
|
14
|
-
get_args,
|
|
15
|
-
get_origin,
|
|
16
|
-
)
|
|
17
|
-
else:
|
|
18
|
-
from typing import _AnnotatedAlias as AnnotatedAlias, get_args, get_origin
|
|
11
|
+
from typing import _AnnotatedAlias as AnnotatedAlias, get_args, get_origin
|
|
19
12
|
|
|
20
13
|
GenericAlias = typing._GenericAlias
|
|
21
14
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/experiments/configuration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/launchers/slurm/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/scheduler/dynamic_outputs.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/sphinx/static/experimaestro.css
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/connectors/bin/executable.py
RENAMED
|
File without changes
|
{experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/connectors/test_local.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/bin/test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/test_local.py
RENAMED
|
File without changes
|
{experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/launchers/test_slurm.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/scripts/notifyandwait.py
RENAMED
|
File without changes
|
{experimaestro-1.7.1 → experimaestro-1.8.0rc0}/src/experimaestro/tests/scripts/waitforfile.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|