Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiment Preview #447

Merged
merged 34 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5e32788
experiment preview method and tests
juliaputko Dec 19, 2023
6ab3dc7
mypy fix
juliaputko Dec 21, 2023
09285d2
lint error fix
juliaputko Dec 21, 2023
cf4adbc
experiment preview with jinja
juliaputko Jan 3, 2024
c4046c1
added jinja as dependency
juliaputko Jan 4, 2024
d9cf92b
addressing comments, and adding tests
juliaputko Jan 11, 2024
a2eace9
type change
juliaputko Jan 11, 2024
0d04640
ccreation of html templates and refactor of checking nto render function
juliaputko Jan 12, 2024
446bf98
Merge branch 'exppreview' of https://github.com/juliaputko/SmartSim i…
Jan 16, 2024
6323c7a
defining literals,changing loggin fmt, and docstring update
Jan 17, 2024
cb7691d
whitespace fix
Jan 17, 2024
745594e
Merge branch 'develop' of https://github.com/CrayLabs/SmartSim into e…
Jan 18, 2024
84e48e7
added doc strings, and check verbosity_level change
Jan 19, 2024
0ad027f
render and review updates, linting
juliaputko Jan 23, 2024
2449c0f
synch with develop
juliaputko Jan 23, 2024
2c97276
template fixes
Jan 30, 2024
757eea1
Merge branch 'develop' of https://github.com/CrayLabs/SmartSim into e…
Jan 31, 2024
c789f8e
isort fix
Feb 1, 2024
23f633a
black error fix
Feb 1, 2024
85ac57b
output forrmat doc + error handling
Feb 1, 2024
0662f0c
added previewformaterror to test-preview
Feb 1, 2024
8604992
mypy fix
Feb 1, 2024
27aef4c
entities in manifest addition for template check
Feb 6, 2024
0eb2442
mypy fix in manifest
Feb 6, 2024
a0a54f7
mypy fix
Feb 6, 2024
3595bd4
sync with develop
Feb 9, 2024
1577f39
added jinja to setup.py
Feb 9, 2024
56e852d
remove html from this branch
Feb 10, 2024
d261f20
mypy fix
Feb 12, 2024
4108181
Merge branch 'develop' into exppreview
Feb 12, 2024
10d7f89
added enums for verbosity
Feb 12, 2024
c42ac83
fixed wording on error message
Feb 12, 2024
ca84b72
black fix
Feb 12, 2024
7d48a1e
Merge branch 'develop' of https://github.com/CrayLabs/SmartSim into e…
Feb 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions smartsim/_core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from .control import Controller, Manifest
from .control import Controller, Manifest, Viewexp
from .generation import Generator

__all__ = ["Controller", "Manifest", "Generator"]
__all__ = ["Controller", "Manifest", "Generator", "Viewexp"]
1 change: 1 addition & 0 deletions smartsim/_core/control/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@

from .controller import Controller
from .manifest import Manifest
from .view import Viewexp
43 changes: 43 additions & 0 deletions smartsim/_core/control/view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# BSD 2-Clause License
#
# Copyright (c) 2021-2023, Hewlett Packard Enterprise
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import typing as t
import jinja2


class Viewexp:
def __init__(self, exp_entity: t.Any) -> None:
self.exp_entity = exp_entity

def render(self) -> str:
"""
Render the template from the supplied entity
"""
loader = jinja2.PackageLoader("templates")
env = jinja2.Environment(loader=loader, autoescape=True)
tpl = env.get_template("master.pytpl")
template = tpl.render(exp_entity=self.exp_entity)

return template
55 changes: 52 additions & 3 deletions smartsim/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,13 @@
from os import getcwd

from tabulate import tabulate

from ._core import Controller, Generator, Manifest
from ._core import Controller, Generator, Manifest, Viewexp
from ._core.utils import init_default
from .database import Orchestrator
from .entity import Ensemble, Model, SmartSimEntity
from .error import SmartSimError
from .log import get_logger
from .settings import Container, base, settings
from .settings import settings, base, Container
from .wlm import detect_launcher

logger = get_logger(__name__)
Expand Down Expand Up @@ -797,6 +796,56 @@ def reconnect_orchestrator(self, checkpoint: str) -> Orchestrator:
logger.error(e)
raise

def preview(
self,
output_format: t.Optional[str] = None,
output_filename: t.Optional[str] = None,
verbosity_level: t.Optional[str] = None,
) -> str:
"""Preview entity information prior to launch. This method
aggregates multiple pieces of information to give users insight
into what and how entities will be launched. Any instance of
``Model``, ``Ensemble`` or ``Orchestrator`` created by the
Experiment can be passed as an argument to the preview method.
param output_format: Set output destination. The possible accepted
output formats are `json`, `xml`, `html`, `plain_text`, `color_text`.
A filename is required if an output format is specified. If no output
format is set, the preview will be output to stdout. Defaults to None.
type output_type: str
param output_filename: Specify name of path to write preview data to.
Only needed when an output format has been specified. Defaults to None.
type output_filename: str
param verbosity level: the verbosity level.
info: Display User defined fields and entities
debug: Display user defined field and entities and auto generated
fields.
developer: Display user defined field and entities, auto generated
fields, and run commands.
Defaults to info.
type verbosity_level: str
"""

if output_format:
raise NotImplementedError
if output_filename:
raise NotImplementedError
if verbosity_level:
raise NotImplementedError

return self._preview()

def _preview(self) -> str:
"""String formatting"""

preview = Viewexp(self).render()
logger.info(preview)

return preview

def get_launcher(self) -> str:
"""Get launcher"""
return self._launcher

def summary(self, style: str = "github") -> str:
"""Return a summary of the ``Experiment``

Expand Down
4 changes: 4 additions & 0 deletions templates/templates/experiment.pytpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
=== Experiment Overview ===
Experiment: {{ exp_entity.name }}
Experiment Path: {{ exp_entity.exp_path }}
Launcher: {{ exp_entity.get_launcher() }}
2 changes: 2 additions & 0 deletions templates/templates/master.pytpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

{% extends "experiment.pytpl" %}
82 changes: 82 additions & 0 deletions tests/test_preview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# BSD 2-Clause License
#
# Copyright (c) 2021-2023, Hewlett Packard Enterprise
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import pytest

from smartsim import Experiment


def test_experiment_preview(test_dir, wlmutils):
"""Test correct preview output items for Experiment preview"""
test_launcher = wlmutils.get_test_launcher()
exp_name = "test_prefix"
exp = Experiment(exp_name, exp_path=test_dir, launcher=test_launcher)
# Call method for string formatting for testing
output = exp._preview().strip()
summary_lines = output.split("\n")
summary_lines = [item.replace("\t", "") for item in summary_lines[-3:]]
assert 3 == len(summary_lines)
summary_dict = dict(row.split(": ") for row in summary_lines)
assert set(["Experiment", "Experiment Path", "Launcher"]).issubset(summary_dict)


def test_experiment_preview_properties(test_dir, wlmutils):
"""Test correct preview output properties for Experiment preview"""
test_launcher = wlmutils.get_test_launcher()
exp_name = "test_experiment_preview_properties"
exp = Experiment(exp_name, exp_path=test_dir, launcher=test_launcher)
# Call method for string formatting for testing
output = exp._preview().strip()
summary_lines = output.split("\n")
summary_lines = [item.replace("\t", "") for item in summary_lines[-3:]]
assert 3 == len(summary_lines)
summary_dict = dict(row.split(": ") for row in summary_lines)
assert exp.name == summary_dict["Experiment"]
assert exp.exp_path == summary_dict["Experiment Path"]
assert exp.get_launcher() == summary_dict["Launcher"]

def test_output_format_error():
exp_name = "test_output_format"
exp = Experiment(exp_name)

with pytest.raises(NotImplementedError):
exp.preview(output_format="hello")


def test_output_filename_error():
exp_name = "test_output_filename"
exp = Experiment(exp_name)

with pytest.raises(NotImplementedError):
exp.preview(output_filename="hello")


def test_verbosity_level_error():
exp_name = "test_verbosity_level"
exp = Experiment(exp_name)

with pytest.raises(NotImplementedError):
exp.preview(verbosity_level="hello")