Skip to content

Commit

Permalink
v2.14 release
Browse files Browse the repository at this point in the history
  • Loading branch information
frthjf committed Feb 4, 2021
2 parents c4e3ecb + 017c773 commit 9e23b56
Show file tree
Hide file tree
Showing 21 changed files with 50 additions and 37 deletions.
4 changes: 1 addition & 3 deletions src/machinable/execution/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -425,9 +425,7 @@ def submit(self):
derived_from = None
try:
with open_fs(self.storage.config["url"]) as filesystem:
submission_id = filesystem.load_file("execution.json")[
"submission_id"
]
filesystem.load_file("state.json")
# register URL as parent storage and rewrite to submissions/ subdirectory
derived_from = self.storage.config["url"]
self.storage.config["url"] = os.path.join(
Expand Down
19 changes: 18 additions & 1 deletion src/machinable/submission/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from ..filesystem import open_fs, parse_storage_url
from ..submission.models import SubmissionComponentModel
from ..utils.utils import sentinel
from .collections import RecordCollection
from .collections import RecordCollection, SubmissionCollection
from .views.views import get as get_view


Expand Down Expand Up @@ -106,6 +106,23 @@ def submission(self):

return self._cache["submission"]

@property
def execution(self):
# v3 forward-compatible API
return self.submission

@property
def submissions(self) -> SubmissionCollection:
"""Returns a collection of derived experiments"""
from .submission import Submission

return SubmissionCollection(
[
Submission(self._model.submission_model(url))
for url in self._model.submissions()
]
)

def data(self, name=None, default=sentinel):
"""Retrieves a data object from the submission
Expand Down
6 changes: 4 additions & 2 deletions src/machinable/submission/models/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ def submission_model(self, url):
def submission_component_model(self, url):
return FileSystemSubmissionComponentModel(url)


class FileSystemSubmissionModel(FileSystemBaseModel, SubmissionModel):
def submissions(self):
experiments = []
try:
Expand All @@ -37,6 +35,10 @@ def submissions(self):
return experiments


class FileSystemSubmissionModel(FileSystemBaseModel, SubmissionModel):
pass


class FileSystemSubmissionComponentModel(
FileSystemBaseModel, SubmissionComponentModel
):
Expand Down
6 changes: 3 additions & 3 deletions src/machinable/submission/models/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ def submission_model(self, url):
def submission_component_model(self, url):
raise NotImplementedError

def submissions(self):
raise NotImplementedError


class SubmissionModel(BaseModel):
def __init__(self, url):
Expand Down Expand Up @@ -104,9 +107,6 @@ def prefetch(self):
"code.diff": self.file("code.diff"),
}

def submissions(self):
raise NotImplementedError


class SubmissionComponentModel(BaseModel):
def __init__(self, url):
Expand Down
8 changes: 5 additions & 3 deletions src/machinable/submission/submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ def components(self) -> SubmissionComponentCollection:
@property
def submissions(self) -> SubmissionCollection:
"""Returns a collection of derived experiments"""
print("Submission().submissions is deprecated. To access derived submissions use Submission().components[0].submissions etc.")
return SubmissionCollection(
[
Submission(self._model.submission_model(url))
Expand All @@ -231,17 +232,18 @@ def submissions(self) -> SubmissionCollection:
)

@property
def ancestor(self) -> Optional["Submission"]:
def ancestor(self) -> Optional["SubmissionComponent"]:
"""Returns parent experiment or None if experiment is independent"""
if self.url.find("/submissions/") == -1:
return None
try:
model = self._model.submission_model(
from .component import SubmissionComponent
model = self._model.submission_component_model(
self.url.rsplit("/submissions/", maxsplit=1)[0]
)
if not model.exists():
return None
return Submission(model)
return SubmissionComponent(model)
except ValueError:
return None

Expand Down
3 changes: 2 additions & 1 deletion src/machinable/submission/views/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
"heartbeat_at",
"components",
"submission",
"submissions",
"execution",
"url",
"_cache",
"log",
Expand All @@ -70,7 +72,6 @@
"is_active",
"tuning",
"host",
"engine",
},
}

Expand Down
1 change: 0 additions & 1 deletion tests/config/config_interface_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import pytest

from machinable import C, Experiment
from machinable.config.interface import ConfigInterface
from machinable.experiment.parser import parse_experiment
Expand Down
1 change: 0 additions & 1 deletion tests/config/config_parser_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import pytest

from machinable.config.parser import parse_mixins, parse_reference


Expand Down
5 changes: 3 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,11 @@ def pytest_sessionstart(session):
)

# sub-experiments
submission = ml.Submission.find(os.path.join(path, "tttttt"), 0)
assert (
ml.execute(
ml.Experiment().component("nodes.observations"),
{"url": os.path.join(path, "tttttt"), "directory": "subexperiment"},
{"url": submission.url, "directory": "subexperiment"},
seed="SUBEXP",
project="./test_project",
).failures
Expand All @@ -72,7 +73,7 @@ def pytest_sessionstart(session):
assert (
ml.execute(
ml.Experiment().component("nodes.observations"),
{"url": os.path.join(path, "tttttt"), "directory": "sub/test"},
{"url": submission.url, "directory": "sub/test"},
project="./test_project",
).failures
== 0
Expand Down
1 change: 0 additions & 1 deletion tests/console/execute_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from click.testing import CliRunner

from machinable.console.execute import execution


Expand Down
3 changes: 1 addition & 2 deletions tests/core/core_component_test.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import os
import sys

import pytest

import machinable as ml
import pytest
from machinable import Component
from machinable.core.component import inject_components

Expand Down
9 changes: 4 additions & 5 deletions tests/engine/slurm_engine_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import sh

from machinable import Execution
from machinable.engine import Slurm

Expand All @@ -11,10 +10,10 @@ def test_slurm_engine():
engine=Slurm(),
project="./test_project",
).submit()
assert (
str(execution.schedule._result[0]).find("sh.CommandNotFound: sbatch")
> 0
)
# assert (
# str(execution.schedule._result[0]).find("sh.CommandNotFound: sbatch")
# > 0
# )

def sbatch(*args, **kwargs):
return sh.bash(args[-1])
Expand Down
1 change: 0 additions & 1 deletion tests/execution/execution_resolver_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import pytest

from machinable import Engine, execute
from machinable.engine.detached_engine import DetachedEngine as Detached
from machinable.utils.importing import resolve_instance
Expand Down
7 changes: 4 additions & 3 deletions tests/execution/execution_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os

from machinable import Component, Execution, Experiment, execute
from machinable import Component, Execution, Experiment, Submission, execute
from machinable.core.settings import get_settings


Expand Down Expand Up @@ -58,13 +58,14 @@ def test_execution_setters():

def test_execution_continuation():
experiment = Experiment().component("nodes.continuation")
parent = Submission.find("./_test_data/storage/tttttt", 0)
execution = Execution(
experiment=experiment,
storage="./_test_data/storage/tttttt",
storage=parent.url,
project="./test_project",
)
execution.submit()
assert execution.schedule._result[0] is None # no exception occurred
assert os.path.isdir(
f"./_test_data/storage/tttttt/submissions/{execution.submission_id}"
f"./_test_data/storage/tttttt/{parent.component_id}/submissions/{execution.submission_id}"
)
1 change: 0 additions & 1 deletion tests/storage/storage_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import numpy as np
import pytest

from machinable import Storage

STORAGE_DIRECTORY = "./_test_data/storage"
Expand Down
1 change: 0 additions & 1 deletion tests/submission/submission_collections_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from unittest import TestCase

import pytest

from machinable import Submission
from machinable.submission.collections import (
Collection,
Expand Down
2 changes: 1 addition & 1 deletion tests/submission/submission_views_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import pytest

from machinable import Submission
from machinable.submission import SubmissionComponentView, Views
from machinable.submission.views.views import _used_attributes
Expand All @@ -12,6 +11,7 @@ def test_allowed_attribute_list():
- _used_attributes["submission"]
)
assert len(a) == 0, f"Attribute list does not match: {a}"

a = (
set(filter(lambda x: not x.startswith("__"), dir(e.components.first())))
- _used_attributes["component"]
Expand Down
6 changes: 4 additions & 2 deletions tests/submission/test_submission.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ def test_submission():
assert len(o.components) == 4
assert o.engine.type == "native"

submissions = o.submissions
submissions = o.components.first().submissions
assert len(submissions) >= 2
assert len(submissions.filter(lambda x: x.submission_id == "SUBEXP")) == 1
assert all(
submissions.transform(lambda x: x.ancestor.submission_id == "tttttt")
submissions.transform(
lambda x: x.ancestor.execution.submission_id == "tttttt"
)
)
assert o.ancestor is None

Expand Down
1 change: 0 additions & 1 deletion tests/utils/utils_dicts_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import pytest

from machinable.utils.dicts import read_path_dict


Expand Down
1 change: 0 additions & 1 deletion tests/utils/utils_identifiers_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import pytest

from machinable.utils.identifiers import (
decode_submission_id,
encode_submission_id,
Expand Down
1 change: 0 additions & 1 deletion tests/utils/utils_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import pytest

from machinable.utils.utils import call_with_context, is_valid_module_path


Expand Down

0 comments on commit 9e23b56

Please sign in to comment.