holobench 1.3.4__tar.gz → 1.3.6__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.
- {holobench-1.3.4 → holobench-1.3.6}/PKG-INFO +3 -4
- {holobench-1.3.4 → holobench-1.3.6}/bencher/__init__.py +1 -1
- {holobench-1.3.4 → holobench-1.3.6}/bencher/bench_cfg.py +9 -3
- {holobench-1.3.4 → holobench-1.3.6}/bencher/bencher.py +19 -7
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_video.py +40 -14
- {holobench-1.3.4 → holobench-1.3.6}/bencher/results/bench_result.py +3 -6
- {holobench-1.3.4 → holobench-1.3.6}/bencher/results/bench_result_base.py +6 -2
- {holobench-1.3.4 → holobench-1.3.6}/bencher/results/holoview_result.py +65 -8
- {holobench-1.3.4 → holobench-1.3.6}/bencher/results/optuna_result.py +22 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/utils.py +17 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/variables/inputs.py +1 -1
- holobench-1.3.6/bencher/video_writer.py +30 -0
- {holobench-1.3.4 → holobench-1.3.6}/pyproject.toml +10 -5
- holobench-1.3.4/bencher/video_writer.py +0 -17
- {holobench-1.3.4 → holobench-1.3.6}/README.md +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/bench_plot_server.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/bench_report.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/bench_runner.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/caching.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/__init__.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/benchmark_data.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_all.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_categorical.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_custom_sweep.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_docs.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_float3D.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_float_cat.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_floats.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_floats2D.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_holosweep.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_holosweep_objects.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_holosweep_tap.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_image.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_levels.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_pareto.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_sample_cache.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_sample_cache_context.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_simple.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_simple_bool.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_simple_cat.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_simple_float.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_strings.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_time_event.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/example_workflow.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/experimental/example_bokeh_plotly.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/experimental/example_hover_ex.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/experimental/example_hvplot_explorer.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/experimental/example_interactive.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/experimental/example_streamnd.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/experimental/example_streams.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/experimental/example_template.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/experimental/example_updates.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/experimental/example_vector.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/meta/example_meta.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/meta/example_meta_cat.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/meta/example_meta_float.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/meta/example_meta_levels.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/optuna/example_optuna.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/shelved/example_float2D_scatter.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/shelved/example_float3D_cone.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/example/shelved/example_kwargs.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/job.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/optuna_conversions.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/plotting/__init__.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/plotting/plot_filter.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/plotting/plt_cnt_cfg.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/results/__init__.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/results/float_formatter.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/results/panel_result.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/results/plotly_result.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/variables/parametrised_sweep.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/variables/results.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/variables/sweep_base.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/variables/time.py +0 -0
- {holobench-1.3.4 → holobench-1.3.6}/bencher/worker_job.py +0 -0
@@ -1,9 +1,8 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: holobench
|
3
|
-
Version: 1.3.
|
3
|
+
Version: 1.3.6
|
4
4
|
Summary: A package for benchmarking the performance of arbitrary functions
|
5
5
|
Author-email: Austin Gregg-Smith <blooop@gmail.com>
|
6
|
-
Requires-Python: >=3.10
|
7
6
|
Description-Content-Type: text/markdown
|
8
7
|
Requires-Dist: holoviews>=1.15,<=1.18.1
|
9
8
|
Requires-Dist: numpy>=1.0,<=1.26.2
|
@@ -21,7 +20,6 @@ Requires-Dist: strenum>=0.4.0,<=0.4.15
|
|
21
20
|
Requires-Dist: scikit-learn>=1.2,<=1.3.2
|
22
21
|
Requires-Dist: str2bool>=1.1,<=1.1
|
23
22
|
Requires-Dist: scoop>=0.7.0,<=0.7.2.0
|
24
|
-
Requires-Dist: ffmpeg-downloader>=0.3.0,<=0.3.0
|
25
23
|
Requires-Dist: moviepy>=1.0.3,<=1.0.3
|
26
24
|
Requires-Dist: black>=23,<=23.12.1 ; extra == "test"
|
27
25
|
Requires-Dist: pylint>=2.16,<=3.0.3 ; extra == "test"
|
@@ -30,8 +28,9 @@ Requires-Dist: pytest>=7.4,<=7.4.4 ; extra == "test"
|
|
30
28
|
Requires-Dist: hypothesis>=6.82,<=6.92.2 ; extra == "test"
|
31
29
|
Requires-Dist: ruff>=0.0.280,<=0.1.9 ; extra == "test"
|
32
30
|
Requires-Dist: coverage>=7.2.7,<=7.4.0 ; extra == "test"
|
31
|
+
Project-URL: Documentation, https://bencher.readthedocs.io/en/latest/
|
33
32
|
Project-URL: Home, https://github.com/dyson-ai/bencher
|
34
|
-
Project-URL:
|
33
|
+
Project-URL: Repository, https://github.com/dyson-ai/bencher
|
35
34
|
Provides-Extra: test
|
36
35
|
|
37
36
|
# Bencher
|
@@ -38,4 +38,4 @@ from .results.panel_result import PanelResult
|
|
38
38
|
from .results.holoview_result import ReduceType, HoloviewResult
|
39
39
|
from .bench_report import BenchReport
|
40
40
|
from .job import Executors
|
41
|
-
from .video_writer import VideoWriter
|
41
|
+
from .video_writer import VideoWriter, add_image
|
@@ -164,7 +164,14 @@ class BenchRunCfg(BenchPlotSrvCfg):
|
|
164
164
|
doc="The function can be run serially or in parallel with different futures executors",
|
165
165
|
)
|
166
166
|
|
167
|
-
plot_size = param.Integer(default=None)
|
167
|
+
plot_size = param.Integer(default=None, doc="Sets the width and height of the plot")
|
168
|
+
plot_width = param.Integer(
|
169
|
+
default=None,
|
170
|
+
doc="Sets with width of the plots, this will ovverride the plot_size parameter",
|
171
|
+
)
|
172
|
+
plot_height = param.Integer(
|
173
|
+
default=None, doc="Sets the height of the plot, this will ovverride the plot_size parameter"
|
174
|
+
)
|
168
175
|
|
169
176
|
@staticmethod
|
170
177
|
def from_cmd_line() -> BenchRunCfg: # pragma: no cover
|
@@ -420,8 +427,7 @@ class BenchCfg(BenchRunCfg):
|
|
420
427
|
if self.description is not None and description:
|
421
428
|
col.append(self.to_description())
|
422
429
|
if describe_sweep:
|
423
|
-
col.append(pn.
|
424
|
-
col.append(self.describe_sweep())
|
430
|
+
col.append(pn.Accordion(("Data Collection Parameters", self.describe_sweep())))
|
425
431
|
if results_suffix:
|
426
432
|
col.append(pn.pane.Markdown("## Results:"))
|
427
433
|
return col
|
@@ -200,7 +200,7 @@ class Bench(BenchPlotServer):
|
|
200
200
|
run_cfg: BenchRunCfg = None,
|
201
201
|
plot: bool = False,
|
202
202
|
) -> BenchResult:
|
203
|
-
title = "Sweeping " + " vs ".join([i
|
203
|
+
title = "Sweeping " + " vs ".join([self.get_name(i) for i in input_vars])
|
204
204
|
return self.plot_sweep(
|
205
205
|
title,
|
206
206
|
input_vars=input_vars,
|
@@ -217,6 +217,7 @@ class Bench(BenchPlotServer):
|
|
217
217
|
|
218
218
|
def sweep_sequential(
|
219
219
|
self,
|
220
|
+
title="",
|
220
221
|
input_vars: List[ParametrizedSweep] = None,
|
221
222
|
result_vars: List[ParametrizedSweep] = None,
|
222
223
|
const_vars: List[ParametrizedSweep] = None,
|
@@ -231,12 +232,14 @@ class Bench(BenchPlotServer):
|
|
231
232
|
relationship_cb = combinations
|
232
233
|
for it in range(iterations):
|
233
234
|
for input_group in relationship_cb(input_vars, group_size):
|
234
|
-
|
235
|
+
title_gen = (
|
236
|
+
title + "Sweeping " + " vs ".join([self.get_name(i) for i in input_group])
|
237
|
+
)
|
235
238
|
if iterations > 1:
|
236
|
-
|
239
|
+
title_gen += f" iteration:{it}"
|
237
240
|
res = self.plot_sweep(
|
238
|
-
title=
|
239
|
-
input_vars=input_group,
|
241
|
+
title=title_gen,
|
242
|
+
input_vars=list(input_group),
|
240
243
|
result_vars=result_vars,
|
241
244
|
const_vars=const_vars,
|
242
245
|
run_cfg=run_cfg,
|
@@ -313,6 +316,10 @@ class Bench(BenchPlotServer):
|
|
313
316
|
input_vars[i] = self.convert_vars_to_params(input_vars[i], "input")
|
314
317
|
for i in range(len(result_vars)):
|
315
318
|
result_vars[i] = self.convert_vars_to_params(result_vars[i], "result")
|
319
|
+
|
320
|
+
if isinstance(const_vars, dict):
|
321
|
+
const_vars = list(const_vars.items())
|
322
|
+
|
316
323
|
for i in range(len(const_vars)):
|
317
324
|
# consts come as tuple pairs
|
318
325
|
cv_list = list(const_vars[i])
|
@@ -338,8 +345,8 @@ class Bench(BenchPlotServer):
|
|
338
345
|
elif len(const_vars) > 0:
|
339
346
|
title = "Constant Value"
|
340
347
|
if len(const_vars) > 1:
|
341
|
-
title += "
|
342
|
-
title += ": " + " ".join([f"{c[0].name}={c[1]}" for c in const_vars])
|
348
|
+
title += "s"
|
349
|
+
title += ": " + ", ".join([f"{c[0].name}={c[1]}" for c in const_vars])
|
343
350
|
else:
|
344
351
|
raise RuntimeError("you must pass a title, or define inputs or consts")
|
345
352
|
|
@@ -444,6 +451,11 @@ class Bench(BenchPlotServer):
|
|
444
451
|
self.results.append(bench_res)
|
445
452
|
return bench_res
|
446
453
|
|
454
|
+
def get_name(self, var):
|
455
|
+
if isinstance(var, param.Parameter):
|
456
|
+
return var.name
|
457
|
+
return var
|
458
|
+
|
447
459
|
def convert_vars_to_params(self, variable: param.Parameter, var_type: str):
|
448
460
|
"""check that a variable is a subclass of param
|
449
461
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import bencher as bch
|
2
2
|
import numpy as np
|
3
3
|
import matplotlib.pyplot as plt
|
4
|
-
|
4
|
+
import panel as pn
|
5
5
|
|
6
6
|
|
7
7
|
# code from https://ipython-books.github.io/124-simulating-a-partial-differential-equation-reaction-diffusion-systems-and-turing-patterns/
|
@@ -11,11 +11,12 @@ class TuringPattern(bch.ParametrizedSweep):
|
|
11
11
|
tau = bch.FloatSweep(default=0.1, bounds=(0.01, 0.5))
|
12
12
|
k = bch.FloatSweep(default=-0.005, bounds=(-0.01, 0.01))
|
13
13
|
|
14
|
-
size = bch.IntSweep(default=
|
14
|
+
size = bch.IntSweep(default=30, bounds=(30, 200), doc="size of the 2D grid")
|
15
15
|
time = bch.FloatSweep(default=20.0, bounds=(1, 100), doc="total time of simulation")
|
16
16
|
dt = bch.FloatSweep(default=0.001, doc="simulation time step")
|
17
17
|
|
18
18
|
video = bch.ResultVideo()
|
19
|
+
score = bch.ResultVar()
|
19
20
|
|
20
21
|
def laplacian(self, Z, dx):
|
21
22
|
Ztop = Z[0:-2, 1:-1]
|
@@ -57,20 +58,18 @@ class TuringPattern(bch.ParametrizedSweep):
|
|
57
58
|
fig, ax = plt.subplots(frameon=False, figsize=(2, 2))
|
58
59
|
fig.set_tight_layout(True)
|
59
60
|
ax.set_axis_off()
|
60
|
-
|
61
|
-
artists = []
|
62
|
-
|
61
|
+
vid_writer = bch.VideoWriter()
|
63
62
|
for i in range(n):
|
64
63
|
self.update(U, V, dx)
|
65
64
|
if i % 500 == 0:
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
self.
|
65
|
+
ax.imshow(U)
|
66
|
+
fig.canvas.draw()
|
67
|
+
rgb = np.array(fig.canvas.renderer.buffer_rgba())
|
68
|
+
vid_writer.append(rgb)
|
69
|
+
|
70
|
+
self.video = vid_writer.write()
|
71
|
+
|
72
|
+
self.score = self.alpha + self.beta
|
74
73
|
return super().__call__()
|
75
74
|
|
76
75
|
|
@@ -91,8 +90,35 @@ def example_video(
|
|
91
90
|
return bench
|
92
91
|
|
93
92
|
|
93
|
+
def example_video_tap(
|
94
|
+
run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
|
95
|
+
) -> bch.Bench: # pragma: no cover
|
96
|
+
tp = TuringPattern()
|
97
|
+
|
98
|
+
run_cfg.use_sample_cache = False
|
99
|
+
# run_cfg.use_optuna = True
|
100
|
+
run_cfg.auto_plot = False
|
101
|
+
run_cfg.run_tag = "3"
|
102
|
+
bench = tp.to_bench(run_cfg=run_cfg, report=report)
|
103
|
+
|
104
|
+
res = bench.plot_sweep(
|
105
|
+
"phase",
|
106
|
+
input_vars=["alpha", "beta"],
|
107
|
+
# result_vars=["video","score"],
|
108
|
+
run_cfg=run_cfg,
|
109
|
+
)
|
110
|
+
|
111
|
+
bench.report.append(res.describe_sweep())
|
112
|
+
bench.report.append(
|
113
|
+
res.to_heatmap(tp.param.score, tap_var=tp.param.video, tap_container=pn.pane.Video)
|
114
|
+
)
|
115
|
+
|
116
|
+
return bench
|
117
|
+
|
118
|
+
|
94
119
|
if __name__ == "__main__":
|
95
120
|
run_cfg_ex = bch.BenchRunCfg()
|
96
121
|
run_cfg_ex.level = 2
|
97
122
|
|
98
|
-
example_video(run_cfg_ex).report.show()
|
123
|
+
# example_video(run_cfg_ex).report.show()
|
124
|
+
example_video_tap(run_cfg_ex).report.show()
|
@@ -47,6 +47,8 @@ class BenchResult(PlotlyResult, HoloviewResult):
|
|
47
47
|
for p in remove_plots:
|
48
48
|
plot_list.remove(p)
|
49
49
|
|
50
|
+
kwargs = self.set_plot_size(**kwargs)
|
51
|
+
|
50
52
|
row = EmptyContainer(pn.Row())
|
51
53
|
for plot_callback in plot_list:
|
52
54
|
if self.plt_cnt_cfg.print_debug:
|
@@ -61,9 +63,6 @@ class BenchResult(PlotlyResult, HoloviewResult):
|
|
61
63
|
)
|
62
64
|
return row.pane
|
63
65
|
|
64
|
-
def to_auto_da(self):
|
65
|
-
pass
|
66
|
-
|
67
66
|
def to_auto_plots(self, **kwargs) -> List[pn.panel]:
|
68
67
|
"""Given the dataset result of a benchmark run, automatically dedeuce how to plot the data based on the types of variables that were sampled
|
69
68
|
|
@@ -73,9 +72,7 @@ class BenchResult(PlotlyResult, HoloviewResult):
|
|
73
72
|
Returns:
|
74
73
|
pn.pane: A panel containing plot results
|
75
74
|
"""
|
76
|
-
|
77
|
-
kwargs["width"] = self.bench_cfg.plot_size
|
78
|
-
kwargs["height"] = self.bench_cfg.plot_size
|
75
|
+
|
79
76
|
plot_cols = pn.Column()
|
80
77
|
plot_cols.append(self.to_sweep_summary(name="Plots View"))
|
81
78
|
plot_cols.append(self.to_auto(**kwargs))
|
@@ -5,7 +5,7 @@ import xarray as xr
|
|
5
5
|
from param import Parameter
|
6
6
|
import holoviews as hv
|
7
7
|
from functools import partial
|
8
|
-
from bencher.utils import int_to_col, color_tuple_to_css
|
8
|
+
from bencher.utils import int_to_col, color_tuple_to_css, callable_name
|
9
9
|
|
10
10
|
from bencher.variables.parametrised_sweep import ParametrizedSweep
|
11
11
|
from bencher.variables.results import OptDir
|
@@ -241,6 +241,8 @@ class BenchResultBase(OptunaResult):
|
|
241
241
|
if hv_dataset is None:
|
242
242
|
hv_dataset = self.to_hv_dataset()
|
243
243
|
row = EmptyContainer(pn.Row())
|
244
|
+
|
245
|
+
# kwargs= self.set_plot_size(**kwargs)
|
244
246
|
for rv in self.get_results_var_list(result_var):
|
245
247
|
if result_types is None or isinstance(rv, result_types):
|
246
248
|
row.append(
|
@@ -279,7 +281,7 @@ class BenchResultBase(OptunaResult):
|
|
279
281
|
repeats_range=repeats_range,
|
280
282
|
input_range=input_range,
|
281
283
|
)
|
282
|
-
matches_res = plot_filter.matches_result(self.plt_cnt_cfg, plot_callback
|
284
|
+
matches_res = plot_filter.matches_result(self.plt_cnt_cfg, callable_name(plot_callback))
|
283
285
|
if matches_res.overall:
|
284
286
|
return self.map_plot_panes(
|
285
287
|
plot_callback=plot_callback,
|
@@ -300,6 +302,8 @@ class BenchResultBase(OptunaResult):
|
|
300
302
|
**kwargs,
|
301
303
|
):
|
302
304
|
dims = len(hv_dataset.dimensions())
|
305
|
+
if target_dimension is None:
|
306
|
+
target_dimension = dims
|
303
307
|
return self._to_panes_da(
|
304
308
|
hv_dataset.data,
|
305
309
|
plot_callback=plot_callback,
|
@@ -8,7 +8,7 @@ from functools import partial
|
|
8
8
|
import hvplot.xarray # noqa pylint: disable=duplicate-code,unused-import
|
9
9
|
import xarray as xr
|
10
10
|
|
11
|
-
from bencher.utils import hmap_canonical_input, get_nearest_coords
|
11
|
+
from bencher.utils import hmap_canonical_input, get_nearest_coords, get_nearest_coords1D
|
12
12
|
from bencher.results.panel_result import PanelResult
|
13
13
|
from bencher.results.bench_result_base import ReduceType
|
14
14
|
|
@@ -173,13 +173,27 @@ class HoloviewResult(PanelResult):
|
|
173
173
|
return pt.opts(legend_position="right").overlay()
|
174
174
|
return pt.opts(legend_position="right")
|
175
175
|
|
176
|
-
def to_heatmap(
|
176
|
+
def to_heatmap(
|
177
|
+
self,
|
178
|
+
result_var: Parameter = None,
|
179
|
+
tap_var=None,
|
180
|
+
tap_container=None,
|
181
|
+
target_dimension=2,
|
182
|
+
**kwargs,
|
183
|
+
) -> Optional[pn.panel]:
|
184
|
+
if tap_var is None:
|
185
|
+
heatmap_cb = self.to_heatmap_ds
|
186
|
+
else:
|
187
|
+
heatmap_cb = partial(
|
188
|
+
self.to_heatmap_container_tap_ds, result_var_plot=tap_var, container=tap_container
|
189
|
+
)
|
190
|
+
|
177
191
|
return self.filter(
|
178
|
-
|
192
|
+
heatmap_cb,
|
179
193
|
float_range=VarRange(2, None),
|
180
194
|
cat_range=VarRange(0, None),
|
181
195
|
input_range=VarRange(1, None),
|
182
|
-
target_dimension=
|
196
|
+
target_dimension=target_dimension,
|
183
197
|
result_var=result_var,
|
184
198
|
result_types=(ResultVar),
|
185
199
|
**kwargs,
|
@@ -189,9 +203,6 @@ class HoloviewResult(PanelResult):
|
|
189
203
|
self, dataset: xr.Dataset, result_var: Parameter, **kwargs
|
190
204
|
) -> Optional[hv.HeatMap]:
|
191
205
|
if len(dataset.dims) >= 2:
|
192
|
-
# dims = [d for d in da.sizes]
|
193
|
-
# x = dims[0]
|
194
|
-
# y = dims[1]
|
195
206
|
x = self.plt_cnt_cfg.float_vars[0].name
|
196
207
|
y = self.plt_cnt_cfg.float_vars[1].name
|
197
208
|
C = result_var.name
|
@@ -200,6 +211,50 @@ class HoloviewResult(PanelResult):
|
|
200
211
|
return dataset.hvplot.heatmap(x=x, y=y, C=C, cmap="plasma", **time_args, **kwargs)
|
201
212
|
return None
|
202
213
|
|
214
|
+
def to_heatmap_container_tap_ds(
|
215
|
+
self,
|
216
|
+
dataset: xr.Dataset,
|
217
|
+
result_var: Parameter,
|
218
|
+
result_var_plot: Parameter,
|
219
|
+
container: pn.pane.panel = pn.pane.panel,
|
220
|
+
**kwargs,
|
221
|
+
) -> pn.Row:
|
222
|
+
htmap = self.to_heatmap_ds(dataset, result_var).opts(tools=["hover", "tap"], **kwargs)
|
223
|
+
htmap_posxy = hv.streams.Tap(source=htmap, x=0, y=0)
|
224
|
+
|
225
|
+
container_instance = container(**kwargs)
|
226
|
+
title = pn.pane.Markdown("Selected: None")
|
227
|
+
|
228
|
+
def tap_plot(x, y): # pragma: no cover
|
229
|
+
x_nearest = get_nearest_coords1D(
|
230
|
+
x, dataset.coords[self.bench_cfg.input_vars[0].name].data
|
231
|
+
)
|
232
|
+
y_nearest = get_nearest_coords1D(
|
233
|
+
y, dataset.coords[self.bench_cfg.input_vars[1].name].data
|
234
|
+
)
|
235
|
+
kdims = {}
|
236
|
+
kdims[self.bench_cfg.input_vars[0].name] = x_nearest
|
237
|
+
kdims[self.bench_cfg.input_vars[1].name] = y_nearest
|
238
|
+
|
239
|
+
if hasattr(htmap, "current_key"):
|
240
|
+
for d, k in zip(htmap.kdims, htmap.current_key):
|
241
|
+
kdims[d.name] = k
|
242
|
+
|
243
|
+
ds = dataset[result_var_plot.name]
|
244
|
+
val = ds.sel(**kdims)
|
245
|
+
item = self.zero_dim_da_to_val(val)
|
246
|
+
title.object = "Selected: " + ", ".join([f"{k}:{v}" for k, v in kdims.items()])
|
247
|
+
container_instance.object = item
|
248
|
+
if hasattr(container, "autoplay"): # container is a video, set to autoplay
|
249
|
+
container_instance.paused = False
|
250
|
+
container_instance.time = 0
|
251
|
+
container_instance.loop = True
|
252
|
+
container_instance.autoplay = True
|
253
|
+
|
254
|
+
htmap_posxy.add_subscriber(tap_plot)
|
255
|
+
bound_plot = pn.Column(title, container_instance)
|
256
|
+
return pn.Row(htmap, bound_plot)
|
257
|
+
|
203
258
|
def to_error_bar(self) -> hv.Bars:
|
204
259
|
return self.to_hv_dataset(ReduceType.REDUCE).to(hv.ErrorBars)
|
205
260
|
|
@@ -312,7 +367,9 @@ class HoloviewResult(PanelResult):
|
|
312
367
|
# return matches.to_panel()
|
313
368
|
|
314
369
|
def to_scatter_jitter(
|
315
|
-
self,
|
370
|
+
self,
|
371
|
+
result_var: Parameter = None,
|
372
|
+
**kwargs, # pylint: disable=unused-argument
|
316
373
|
) -> List[hv.Scatter]:
|
317
374
|
return self.overlay_plots(partial(self.to_scatter_jitter_single, **kwargs))
|
318
375
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
from typing import List
|
3
|
+
from copy import deepcopy
|
4
|
+
|
3
5
|
import numpy as np
|
4
6
|
import optuna
|
5
7
|
import panel as pn
|
@@ -330,3 +332,23 @@ class OptunaResult:
|
|
330
332
|
# for it, rv in enumerate(bench_cfg.result_vars):
|
331
333
|
# bench_cfg.ds[rv.name].loc[t.params] = t.values[it]
|
332
334
|
# return bench_cfg
|
335
|
+
|
336
|
+
def deep(self) -> OptunaResult: # pragma: no cover
|
337
|
+
"""Return a deep copy of these results"""
|
338
|
+
return deepcopy(self)
|
339
|
+
|
340
|
+
def set_plot_size(self, **kwargs) -> dict:
|
341
|
+
if "width" not in kwargs:
|
342
|
+
if self.bench_cfg.plot_size is not None:
|
343
|
+
kwargs["width"] = self.bench_cfg.plot_size
|
344
|
+
# specific width overrrides general size
|
345
|
+
if self.bench_cfg.plot_width is not None:
|
346
|
+
kwargs["width"] = self.bench_cfg.plot_width
|
347
|
+
|
348
|
+
if "height" not in kwargs:
|
349
|
+
if self.bench_cfg.plot_size is not None:
|
350
|
+
kwargs["height"] = self.bench_cfg.plot_size
|
351
|
+
# specific height overrrides general size
|
352
|
+
if self.bench_cfg.plot_height is not None:
|
353
|
+
kwargs["height"] = self.bench_cfg.plot_height
|
354
|
+
return kwargs
|
@@ -7,6 +7,8 @@ import math
|
|
7
7
|
from colorsys import hsv_to_rgb
|
8
8
|
from pathlib import Path
|
9
9
|
from uuid import uuid4
|
10
|
+
from functools import partial
|
11
|
+
from typing import Callable, Any
|
10
12
|
|
11
13
|
|
12
14
|
def hmap_canonical_input(dic: dict) -> tuple:
|
@@ -55,6 +57,12 @@ def get_nearest_coords(dataset: xr.Dataset, collapse_list=False, **kwargs) -> di
|
|
55
57
|
return cd2
|
56
58
|
|
57
59
|
|
60
|
+
def get_nearest_coords1D(val: Any, coords) -> Any:
|
61
|
+
if isinstance(val, (int, float)):
|
62
|
+
return min(coords, key=lambda x_: abs(x_ - val))
|
63
|
+
return val
|
64
|
+
|
65
|
+
|
58
66
|
def hash_sha1(var: any) -> str:
|
59
67
|
"""A hash function that avoids the PYTHONHASHSEED 'feature' which returns a different hash value each time the program is run"""
|
60
68
|
return hashlib.sha1(str(var).encode("ASCII")).hexdigest()
|
@@ -129,3 +137,12 @@ def gen_video_path(video_name: str, extension: str = ".webm") -> str:
|
|
129
137
|
|
130
138
|
def gen_image_path(image_name: str, filetype=".png") -> str:
|
131
139
|
return gen_path(image_name, "img", filetype)
|
140
|
+
|
141
|
+
|
142
|
+
def callable_name(any_callable: Callable[..., Any]) -> str:
|
143
|
+
if isinstance(any_callable, partial):
|
144
|
+
return any_callable.func.__name__
|
145
|
+
try:
|
146
|
+
return any_callable.__name__
|
147
|
+
except AttributeError:
|
148
|
+
return str(any_callable)
|
@@ -72,7 +72,7 @@ class EnumSweep(SweepSelector):
|
|
72
72
|
__slots__ = shared_slots
|
73
73
|
|
74
74
|
def __init__(
|
75
|
-
self, enum_type: Enum | List[Enum], units="", samples=None, samples_debug=2, **params
|
75
|
+
self, enum_type: Enum | List[Enum], units=" ", samples=None, samples_debug=2, **params
|
76
76
|
):
|
77
77
|
# The enum can either be an Enum type or a list of enums
|
78
78
|
list_of_enums = isinstance(enum_type, list)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
from bencher import gen_video_path, gen_image_path
|
2
|
+
from PIL import Image
|
3
|
+
import numpy as np
|
4
|
+
|
5
|
+
|
6
|
+
class VideoWriter:
|
7
|
+
def __init__(self, filename: str = "vid") -> None:
|
8
|
+
self.images = []
|
9
|
+
self.filename = gen_video_path(filename)
|
10
|
+
|
11
|
+
def append(self, img):
|
12
|
+
self.images.append(img)
|
13
|
+
|
14
|
+
def write(self, bitrate: int = 1500) -> str:
|
15
|
+
import moviepy.video.io.ImageSequenceClip
|
16
|
+
|
17
|
+
# todo
|
18
|
+
# if len(self.images[0.shape) == 2:
|
19
|
+
# for i in range(len(self.images)):
|
20
|
+
# self.images[i] = np.expand_dims(self.images[i], 2)
|
21
|
+
|
22
|
+
clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(self.images, fps=30)
|
23
|
+
clip.write_videofile(self.filename, bitrate=f"{bitrate}k", logger=None)
|
24
|
+
return self.filename
|
25
|
+
|
26
|
+
|
27
|
+
def add_image(np_array: np.ndarray, name: str = "img"):
|
28
|
+
filename = gen_image_path(name)
|
29
|
+
Image.fromarray(np_array).save(filename)
|
30
|
+
return filename
|
@@ -1,13 +1,14 @@
|
|
1
1
|
[project]
|
2
2
|
name = "holobench"
|
3
|
-
version = "1.3.
|
3
|
+
version = "1.3.6"
|
4
4
|
|
5
5
|
authors = [{ name = "Austin Gregg-Smith", email = "blooop@gmail.com" }]
|
6
6
|
description = "A package for benchmarking the performance of arbitrary functions"
|
7
7
|
readme = "README.md"
|
8
|
-
documentation = "https://bencher.readthedocs.io/en/latest/"
|
9
8
|
|
10
|
-
|
9
|
+
#incompatible with setuptools
|
10
|
+
# requires-python = ">= 3.10"
|
11
|
+
|
11
12
|
|
12
13
|
dependencies = [
|
13
14
|
"holoviews>=1.15,<=1.18.1",
|
@@ -26,7 +27,6 @@ dependencies = [
|
|
26
27
|
"scikit-learn>=1.2,<=1.3.2",
|
27
28
|
"str2bool>=1.1,<=1.1",
|
28
29
|
"scoop>=0.7.0,<=0.7.2.0",
|
29
|
-
"ffmpeg-downloader>=0.3.0,<=0.3.0",
|
30
30
|
"moviepy>=1.0.3,<=1.0.3",
|
31
31
|
]
|
32
32
|
|
@@ -42,18 +42,23 @@ test = [
|
|
42
42
|
]
|
43
43
|
|
44
44
|
[project.urls]
|
45
|
-
|
45
|
+
Repository = "https://github.com/dyson-ai/bencher"
|
46
46
|
Home = "https://github.com/dyson-ai/bencher"
|
47
|
+
Documentation = "https://bencher.readthedocs.io/en/latest/"
|
47
48
|
|
48
49
|
|
49
50
|
[tool.flit.module]
|
50
51
|
name = "bencher"
|
51
52
|
|
53
|
+
|
52
54
|
[build-system]
|
53
55
|
requires = ["flit_core >=3.2,<4"]
|
54
56
|
build-backend = "flit_core.buildapi"
|
55
57
|
|
56
58
|
|
59
|
+
[tool.setuptools_scm]
|
60
|
+
# lol just to keep colcon happy
|
61
|
+
|
57
62
|
[tool.pylint]
|
58
63
|
extension-pkg-whitelist = ["numpy", "scipy"]
|
59
64
|
jobs = 16 #detect number of cores
|
@@ -1,17 +0,0 @@
|
|
1
|
-
from bencher import gen_video_path
|
2
|
-
|
3
|
-
|
4
|
-
class VideoWriter:
|
5
|
-
def __init__(self, filename: str) -> None:
|
6
|
-
self.images = []
|
7
|
-
self.filename = gen_video_path(filename)
|
8
|
-
|
9
|
-
def append(self, img):
|
10
|
-
self.images.append(img)
|
11
|
-
|
12
|
-
def write(self, bitrate: int = 1500) -> str:
|
13
|
-
import moviepy.video.io.ImageSequenceClip
|
14
|
-
|
15
|
-
clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(self.images, fps=30)
|
16
|
-
clip.write_videofile(self.filename, bitrate=f"{bitrate}k")
|
17
|
-
return self.filename
|
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
|
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
|