Skip to content

Commit

Permalink
Merge pull request #364 from dyson-ai/feature/fileresult
Browse files Browse the repository at this point in the history
Feature/fileresult
  • Loading branch information
blooop committed May 24, 2024
2 parents be14edb + 3891975 commit 6660d0f
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 40 deletions.
1 change: 1 addition & 0 deletions bencher/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
ResultVar,
ResultVec,
ResultHmap,
ResultPath,
ResultVideo,
ResultImage,
ResultString,
Expand Down
2 changes: 1 addition & 1 deletion bencher/bench_cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ def describe_benchmark(self) -> str:
benchmark_sampling_str.append(f" use_cache: {self.use_cache}")
benchmark_sampling_str.append(f" use_sample_cache: {self.use_sample_cache}")
benchmark_sampling_str.append(f" only_hash_tag: {self.only_hash_tag}")
benchmark_sampling_str.append(f" parallel: {self.executor}")
benchmark_sampling_str.append(f" executor: {self.executor}")

for mv in self.meta_vars:
benchmark_sampling_str.extend(describe_variable(mv, True))
Expand Down
19 changes: 14 additions & 5 deletions bencher/bencher.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
ResultVar,
ResultVec,
ResultHmap,
ResultPath,
ResultVideo,
ResultImage,
ResultString,
Expand Down Expand Up @@ -557,17 +558,15 @@ def setup_dataset(
time_src (datetime | str): a representation of the sample time
Returns:
_type_: _description_
tuple[BenchResult, List, List]: bench_result, function intputs, dimension names
"""

if time_src is None:
time_src = datetime.now()
bench_cfg.meta_vars = self.define_extra_vars(bench_cfg, bench_cfg.repeats, time_src)

bench_cfg.all_vars = bench_cfg.input_vars + bench_cfg.meta_vars

# bench_cfg.all_vars = bench_cfg.iv_time + bench_cfg.input_vars +[ bench_cfg.iv_repeat]

# bench_cfg.all_vars = [ bench_cfg.iv_repeat] +bench_cfg.input_vars + bench_cfg.iv_time

for i in bench_cfg.all_vars:
Expand All @@ -587,7 +586,9 @@ def setup_dataset(
if isinstance(rv, ResultReference):
result_data = np.full(dims_cfg.dims_size, -1, dtype=int)
data_vars[rv.name] = (dims_cfg.dims_name, result_data)
if isinstance(rv, (ResultVideo, ResultImage, ResultString, ResultContainer)):
if isinstance(
rv, (ResultPath, ResultVideo, ResultImage, ResultString, ResultContainer)
):
result_data = np.full(dims_cfg.dims_size, "NAN", dtype=object)
data_vars[rv.name] = (dims_cfg.dims_name, result_data)
elif type(rv) == ResultVec:
Expand Down Expand Up @@ -724,7 +725,15 @@ def store_results(
logging.info(f"{rv.name}: {result_value}")

if isinstance(
rv, (ResultVar, ResultVideo, ResultImage, ResultString, ResultContainer)
rv,
(
ResultVar,
ResultVideo,
ResultImage,
ResultString,
ResultContainer,
ResultPath,
),
):
set_xarray_multidim(bench_res.ds[rv.name], worker_job.index_tuple, result_value)
elif isinstance(rv, ResultReference):
Expand Down
27 changes: 27 additions & 0 deletions bencher/example/example_filepath.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import bencher as bch


class ExampleFile(bch.ParametrizedSweep):
content = bch.StringSweep(["entry1", "entry2", "entry3"])

file_result = bch.ResultPath()

def __call__(self, **kwargs):
self.update_params_from_kwargs(**kwargs)

# this generates a unique filename and stores it in the cache directory
filename = bch.gen_path(self.content, suffix=".txt")
with open(filename, "w", encoding="utf-8") as text_file:
text_file.write(f"content:{self.content}")
self.file_result = filename
return super().__call__()


def example_filepath(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None):
bench = ExampleFile().to_bench(run_cfg, report)
bench.plot_sweep()
return bench


if __name__ == "__main__":
example_filepath().report.show()
2 changes: 1 addition & 1 deletion bencher/example/example_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def example_image_vid_sequential(
# ex_run_cfg.debug = True
# ex_run_cfg.repeats = 2
ex_run_cfg.level = 4
# example_image_vid(ex_run_cfg).report.show()
example_image_vid(ex_run_cfg).report.show()
simple().report.show()

# example_image_vid_sequential(ex_run_cfg).report.show()
Expand Down
7 changes: 7 additions & 0 deletions bencher/results/bench_result_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,13 @@ def ds_to_container(
return ref.container(val, **kwargs)
if container is not None:
return container(val, styles={"background": "white"}, **kwargs)
try:
container = result_var.to_container()
if container is not None:
return container(val)
except AttributeError as _:
# TODO make sure all vars have to_container method
pass
return val

@staticmethod
Expand Down
2 changes: 0 additions & 2 deletions bencher/results/panel_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ def to_panes(
level: int = None,
**kwargs
) -> Optional[pn.pane.panel]:
if container is None:
container = pn.pane.panel
if hv_dataset is None:
hv_dataset = self.to_hv_dataset(ReduceType.SQUEEZE, level=level)
elif not isinstance(hv_dataset, hv.Dataset):
Expand Down
2 changes: 1 addition & 1 deletion bencher/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def color_tuple_to_css(color: tuple[float, float, float]) -> str:
return f"rgb{(color[0] * 255, color[1] * 255, color[2] * 255)}"


def gen_path(filename, folder, suffix):
def gen_path(filename, folder="generic", suffix=".dat"):
path = Path(f"cachedir/{folder}/{filename}/")
path.mkdir(parents=True, exist_ok=True)
return f"{path.absolute().as_posix()}/{filename}_{uuid4()}{suffix}"
Expand Down
22 changes: 2 additions & 20 deletions bencher/variables/parametrised_sweep.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,7 @@


from bencher.utils import make_namedtuple, hash_sha1
from bencher.variables.results import (
ResultVar,
ResultVec,
ResultHmap,
ResultVideo,
ResultImage,
ResultString,
ResultContainer,
ResultReference,
)
from bencher.variables.results import ALL_RESULT_TYPES, ResultHmap


class ParametrizedSweep(Parameterized):
Expand Down Expand Up @@ -78,16 +69,7 @@ def get_input_and_results(cls, include_name: bool = False) -> Tuple[dict, dict]:
for k, v in cls.param.objects().items():
if isinstance(
v,
(
ResultVar,
ResultVec,
ResultHmap,
ResultVideo,
ResultImage,
ResultString,
ResultContainer,
ResultReference,
),
ALL_RESULT_TYPES,
):
results[k] = v
else:
Expand Down
48 changes: 39 additions & 9 deletions bencher/variables/results.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from enum import auto
from typing import List, Callable, Any, Optional

from functools import partial
import panel as pn
import param
from param import Number
Expand Down Expand Up @@ -99,7 +99,7 @@ def curve(
return hv.Curve(zip(x_vals, y_vals), kdims=[x_name], vdims=[y_name], label=label, **kwargs)


class PathResult(param.Filename):
class ResultPath(param.Filename):
__slots__ = ["units"]

def __init__(self, default=None, units="path", **params):
Expand All @@ -110,15 +110,33 @@ def hash_persistent(self) -> str:
"""A hash function that avoids the PYTHONHASHSEED 'feature' which returns a different hash value each time the program is run"""
return hash_sha1(self)

def to_container(self):
"""Returns a partial function for creating a FileDownload widget with embedding enabled. This function is used to create a panel container to represent the ResultPath object"""
return partial(pn.widgets.FileDownload, embed=True)

class ResultVideo(PathResult):
def __init__(self, default=None, units="video", **params):
super().__init__(default=default, units=units, **params)

class ResultVideo(param.Filename):
__slots__ = ["units"]

class ResultImage(PathResult):
def __init__(self, default=None, units="image", **params):
super().__init__(default=default, units=units, **params)
def __init__(self, default=None, units="path", **params):
super().__init__(default=default, check_exists=False, **params)
self.units = units

def hash_persistent(self) -> str:
"""A hash function that avoids the PYTHONHASHSEED 'feature' which returns a different hash value each time the program is run"""
return hash_sha1(self)


class ResultImage(param.Filename):
__slots__ = ["units"]

def __init__(self, default=None, units="path", **params):
super().__init__(default=default, check_exists=False, **params)
self.units = units

def hash_persistent(self) -> str:
"""A hash function that avoids the PYTHONHASHSEED 'feature' which returns a different hash value each time the program is run"""
return hash_sha1(self)


class ResultString(param.String):
Expand Down Expand Up @@ -181,4 +199,16 @@ def hash_persistent(self) -> str:
return hash_sha1(self)


PANEL_TYPES = (ResultImage, ResultVideo, ResultContainer, ResultString, ResultReference)
PANEL_TYPES = (ResultPath, ResultImage, ResultVideo, ResultContainer, ResultString, ResultReference)

ALL_RESULT_TYPES = (
ResultVar,
ResultVec,
ResultHmap,
ResultPath,
ResultVideo,
ResultImage,
ResultString,
ResultContainer,
ResultReference,
)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "holobench"
version = "1.18.0"
version = "1.19.0"

authors = [{ name = "Austin Gregg-Smith", email = "blooop@gmail.com" }]
description = "A package for benchmarking the performance of arbitrary functions"
Expand Down
4 changes: 4 additions & 0 deletions test/test_bench_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from bencher.example.example_strings import example_strings
from bencher.example.example_image import example_image, example_image_vid
from bencher.example.example_video import example_video
from bencher.example.example_filepath import example_filepath
from bencher.example.meta.example_meta import example_meta
from bencher.example.example_docs import example_docs

Expand Down Expand Up @@ -112,6 +113,9 @@ def test_example_image(self) -> None:
def test_example_video(self) -> None:
self.examples_asserts(example_video(self.create_run_cfg()))

def test_example_filepath(self) -> None:
self.examples_asserts(example_filepath(self.create_run_cfg()))

def test_example_meta(self) -> None:
self.examples_asserts(example_meta(self.create_run_cfg()))

Expand Down

0 comments on commit 6660d0f

Please sign in to comment.