holobench 1.25.1__py3-none-any.whl → 1.26.3__py3-none-any.whl
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.
- bencher/example/benchmark_data.py +196 -0
- bencher/example/example_all.py +45 -0
- bencher/example/example_categorical.py +99 -0
- bencher/example/example_composable_container.py +106 -0
- bencher/example/example_composable_container2.py +160 -0
- bencher/example/example_consts.py +39 -0
- bencher/example/example_custom_sweep.py +59 -0
- bencher/example/example_custom_sweep2.py +42 -0
- bencher/example/example_docs.py +34 -0
- bencher/example/example_filepath.py +27 -0
- bencher/example/example_float3D.py +101 -0
- bencher/example/example_float_cat.py +99 -0
- bencher/example/example_floats.py +89 -0
- bencher/example/example_floats2D.py +93 -0
- bencher/example/example_holosweep.py +98 -0
- bencher/example/example_holosweep_objects.py +111 -0
- bencher/example/example_holosweep_tap.py +144 -0
- bencher/example/example_image.py +155 -0
- bencher/example/example_levels.py +181 -0
- bencher/example/example_levels2.py +37 -0
- bencher/example/example_pareto.py +53 -0
- bencher/example/example_sample_cache.py +85 -0
- bencher/example/example_sample_cache_context.py +116 -0
- bencher/example/example_simple.py +134 -0
- bencher/example/example_simple_bool.py +35 -0
- bencher/example/example_simple_cat.py +48 -0
- bencher/example/example_simple_float.py +28 -0
- bencher/example/example_simple_float2d.py +29 -0
- bencher/example/example_strings.py +47 -0
- bencher/example/example_time_event.py +63 -0
- bencher/example/example_video.py +118 -0
- bencher/example/example_workflow.py +189 -0
- bencher/example/experimental/example_bokeh_plotly.py +38 -0
- bencher/example/experimental/example_hover_ex.py +45 -0
- bencher/example/experimental/example_hvplot_explorer.py +39 -0
- bencher/example/experimental/example_interactive.py +75 -0
- bencher/example/experimental/example_streamnd.py +49 -0
- bencher/example/experimental/example_streams.py +36 -0
- bencher/example/experimental/example_template.py +40 -0
- bencher/example/experimental/example_updates.py +84 -0
- bencher/example/experimental/example_vector.py +84 -0
- bencher/example/meta/example_meta.py +171 -0
- bencher/example/meta/example_meta_cat.py +25 -0
- bencher/example/meta/example_meta_float.py +23 -0
- bencher/example/meta/example_meta_levels.py +26 -0
- bencher/example/optuna/example_optuna.py +78 -0
- bencher/example/shelved/example_float2D_scatter.py +109 -0
- bencher/example/shelved/example_float3D_cone.py +96 -0
- bencher/example/shelved/example_kwargs.py +63 -0
- bencher/plotting/__init__.py +0 -0
- bencher/plotting/plot_filter.py +110 -0
- bencher/plotting/plt_cnt_cfg.py +75 -0
- bencher/results/__init__.py +0 -0
- bencher/results/bench_result.py +94 -0
- bencher/results/bench_result_base.py +476 -0
- bencher/results/composable_container/__init__.py +0 -0
- bencher/results/composable_container/composable_container_base.py +73 -0
- bencher/results/composable_container/composable_container_panel.py +39 -0
- bencher/results/composable_container/composable_container_video.py +184 -0
- bencher/results/float_formatter.py +44 -0
- bencher/results/holoview_result.py +753 -0
- bencher/results/optuna_result.py +354 -0
- bencher/results/panel_result.py +41 -0
- bencher/results/plotly_result.py +65 -0
- bencher/results/video_result.py +38 -0
- bencher/results/video_summary.py +222 -0
- bencher/variables/__init__.py +0 -0
- bencher/variables/inputs.py +202 -0
- bencher/variables/parametrised_sweep.py +208 -0
- bencher/variables/results.py +214 -0
- bencher/variables/sweep_base.py +162 -0
- bencher/variables/time.py +92 -0
- holobench-1.26.3.data/data/share/ament_index/resource_index/packages/bencher +0 -0
- {holobench-1.25.1.dist-info → holobench-1.26.3.dist-info}/METADATA +5 -7
- holobench-1.26.3.dist-info/RECORD +93 -0
- holobench-1.25.1.dist-info/RECORD +0 -20
- /holobench-1.25.1.data/data/share/ament_index/resource_index/packages/bencher → /bencher/example/__init__.py +0 -0
- {holobench-1.25.1.data → holobench-1.26.3.data}/data/share/bencher/package.xml +0 -0
- {holobench-1.25.1.dist-info → holobench-1.26.3.dist-info}/LICENSE +0 -0
- {holobench-1.25.1.dist-info → holobench-1.26.3.dist-info}/WHEEL +0 -0
- {holobench-1.25.1.dist-info → holobench-1.26.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
# pylint: skip-file #this is experimental still
|
2
|
+
|
3
|
+
|
4
|
+
import numpy as np
|
5
|
+
import pandas as pd
|
6
|
+
import holoviews as hv
|
7
|
+
import panel as pn
|
8
|
+
|
9
|
+
# import streamz
|
10
|
+
# import streamz.dataframe
|
11
|
+
|
12
|
+
from holoviews import opts
|
13
|
+
from holoviews.streams import Buffer
|
14
|
+
|
15
|
+
from tornado.ioloop import PeriodicCallback
|
16
|
+
from tornado import gen
|
17
|
+
|
18
|
+
|
19
|
+
hv.extension("bokeh")
|
20
|
+
|
21
|
+
|
22
|
+
count = 0
|
23
|
+
buffer = Buffer(np.zeros((0, 2)), length=50)
|
24
|
+
|
25
|
+
dataType = pd.DataFrame()
|
26
|
+
|
27
|
+
|
28
|
+
@gen.coroutine
|
29
|
+
def f():
|
30
|
+
global count
|
31
|
+
count += 1
|
32
|
+
buffer.send(np.array([[count, np.random.rand()]]))
|
33
|
+
|
34
|
+
|
35
|
+
def plot(**kwargs):
|
36
|
+
# print(dat)
|
37
|
+
return hv.Curve(**kwargs)
|
38
|
+
|
39
|
+
|
40
|
+
cb = PeriodicCallback(f, 1)
|
41
|
+
cb.start()
|
42
|
+
|
43
|
+
# dmap = hv.DynamicMap(hv.Curve, streams=[buffer]).opts(padding=0.1, width=600)
|
44
|
+
dmap = hv.DynamicMap(plot, streams=[buffer]).opts(padding=0.1, width=600)
|
45
|
+
|
46
|
+
pn.Row(dmap).show()
|
47
|
+
|
48
|
+
|
49
|
+
example = pd.DataFrame({"x": [], "y": [], "count": []}, columns=["x", "y", "count"])
|
50
|
+
dfstream = Buffer(example, length=100, index=False)
|
51
|
+
|
52
|
+
|
53
|
+
def plot():
|
54
|
+
curve_dmap = hv.DynamicMap(hv.Curve, streams=[dfstream])
|
55
|
+
point_dmap = hv.DynamicMap(hv.Points, streams=[dfstream])
|
56
|
+
(curve_dmap * point_dmap).opts(
|
57
|
+
opts.Points(color="count", line_color="black", size=5, padding=0.1, xaxis=None, yaxis=None),
|
58
|
+
opts.Curve(line_width=1, color="black"),
|
59
|
+
)
|
60
|
+
|
61
|
+
|
62
|
+
def gen_brownian():
|
63
|
+
x, y, count = 0, 0, 0
|
64
|
+
while True:
|
65
|
+
x += np.random.randn()
|
66
|
+
y += np.random.randn()
|
67
|
+
count += 1
|
68
|
+
yield pd.DataFrame([(x, y, count)], columns=["x", "y", "count"])
|
69
|
+
|
70
|
+
|
71
|
+
@gen.coroutine
|
72
|
+
def update_callback():
|
73
|
+
brownian = gen_brownian()
|
74
|
+
for i in range(2):
|
75
|
+
dfstream.send(next(brownian))
|
76
|
+
|
77
|
+
|
78
|
+
cb = PeriodicCallback(update_callback, 1)
|
79
|
+
cb.start()
|
80
|
+
|
81
|
+
# update_button = pn.widgets.Button(name="Update Grid", button_type="primary")
|
82
|
+
# update_button.on_click(update_callback)
|
83
|
+
|
84
|
+
pn.Row(plot()).show()
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# """Example on how to sweep over function with vector outputs"""
|
2
|
+
|
3
|
+
# from math import cos, sin
|
4
|
+
|
5
|
+
# import numpy as np
|
6
|
+
|
7
|
+
# import bencher as bch
|
8
|
+
|
9
|
+
|
10
|
+
# class OffsetCfg(bch.ParametrizedSweep):
|
11
|
+
# """A class for describing which parameters to sweep"""
|
12
|
+
|
13
|
+
# dc_offset = bch.FloatSweep(
|
14
|
+
# default=0,
|
15
|
+
# bounds=[0.0, 2.0],
|
16
|
+
# samples=4,
|
17
|
+
# units="v",
|
18
|
+
# doc="DC offset to add to the result of the signal",
|
19
|
+
# )
|
20
|
+
# phase_offset = bch.FloatSweep(
|
21
|
+
# default=0,
|
22
|
+
# bounds=[0.0, 3.14],
|
23
|
+
# samples=4,
|
24
|
+
# units="rad",
|
25
|
+
# doc="phase offset that is added to the input before passing to the trig function",
|
26
|
+
# )
|
27
|
+
|
28
|
+
|
29
|
+
# class SweepResult(bch.ParametrizedSweep):
|
30
|
+
# """A class to describe the vector outputs of the benchmark function"""
|
31
|
+
|
32
|
+
# sin_sweep = bch.ResultList(
|
33
|
+
# index_name="time", index_units="s", units="v", doc="A list of values from a sin function"
|
34
|
+
# )
|
35
|
+
# cos_sweep = bch.ResultList(
|
36
|
+
# index_name="time", index_units="s", units="v", doc="A list of values from a cos function"
|
37
|
+
# )
|
38
|
+
|
39
|
+
|
40
|
+
# def sin_sweep(cfg: OffsetCfg) -> SweepResult:
|
41
|
+
# """A function that returns vector outputs of the sin and cos functions
|
42
|
+
|
43
|
+
# Args:
|
44
|
+
# cfg (OffsetCfg): Options for phase and dc offset
|
45
|
+
|
46
|
+
# Returns:
|
47
|
+
# SweepResult: vectors with sin and cos results
|
48
|
+
# """
|
49
|
+
# res = SweepResult()
|
50
|
+
# print(type(res.sin_sweep))
|
51
|
+
# for i in np.arange(0, 6.28, 0.02):
|
52
|
+
# res.sin_sweep.append(sin(i + cfg.phase_offset) + cfg.dc_offset, i)
|
53
|
+
# # res.sin_sweep.indices.append(i)
|
54
|
+
# for i in np.arange(0, 3.28, 0.02):
|
55
|
+
# res.cos_sweep.append(cos(i + cfg.phase_offset) + cfg.dc_offset, i)
|
56
|
+
# # res.cos_sweep.indices.append(i)
|
57
|
+
# return res
|
58
|
+
|
59
|
+
|
60
|
+
# def example_vector() -> bch.Bench:
|
61
|
+
# """Example on how to sweep over function with vector outputs"""
|
62
|
+
# bencher = bch.Bench("vector output example", sin_sweep, OffsetCfg)
|
63
|
+
|
64
|
+
# bencher.plot_sweep(
|
65
|
+
# title="Sweep DC offset",
|
66
|
+
# input_vars=[OffsetCfg.param.dc_offset],
|
67
|
+
# result_vars=[SweepResult.param.sin_sweep, SweepResult.param.cos_sweep],
|
68
|
+
# description="""This is an example of how to sample function that return a vector of unknown or varying size. In this example it returns the output of the sin and cos function for varying angles and a range of dc offsets""",
|
69
|
+
# post_description="""The output shows stack of sin and cos functions as the dc offset increases""",
|
70
|
+
# )
|
71
|
+
|
72
|
+
# bencher.plot_sweep(
|
73
|
+
# title="Sweep phase offset",
|
74
|
+
# input_vars=[OffsetCfg.param.phase_offset],
|
75
|
+
# result_vars=[SweepResult.param.sin_sweep, SweepResult.param.cos_sweep],
|
76
|
+
# description="""This is an example of how to sample function that return a vector of unknown or varying size. In this example it returns the output of the sin and cos function for varying angles and a range of phase offsets""",
|
77
|
+
# post_description="""The output shows different phases of the sin and cos functions""",
|
78
|
+
# )
|
79
|
+
|
80
|
+
# return bencher
|
81
|
+
|
82
|
+
|
83
|
+
# if __name__ == "__main__":
|
84
|
+
# example_vector().plot()
|
@@ -0,0 +1,171 @@
|
|
1
|
+
from typing import Any
|
2
|
+
import bencher as bch
|
3
|
+
import numpy as np
|
4
|
+
|
5
|
+
from enum import auto
|
6
|
+
from strenum import StrEnum
|
7
|
+
import random
|
8
|
+
import holoviews as hv
|
9
|
+
import math
|
10
|
+
|
11
|
+
|
12
|
+
class NoiseDistribution(StrEnum):
|
13
|
+
"""A categorical variable describing the types of random noise"""
|
14
|
+
|
15
|
+
uniform = auto() # uniform random noiase
|
16
|
+
gaussian = auto() # gaussian noise
|
17
|
+
|
18
|
+
@staticmethod
|
19
|
+
def calculate_noise(noisy, noise_distribution, sigma) -> float:
|
20
|
+
if noisy:
|
21
|
+
match noise_distribution:
|
22
|
+
case NoiseDistribution.uniform:
|
23
|
+
return random.uniform(0, sigma)
|
24
|
+
case NoiseDistribution.gaussian:
|
25
|
+
return random.gauss(0, sigma)
|
26
|
+
return 0.0
|
27
|
+
|
28
|
+
|
29
|
+
class BenchableObject(bch.ParametrizedSweep):
|
30
|
+
"""A class to represent a 3D point in space."""
|
31
|
+
|
32
|
+
# floating point variables
|
33
|
+
float1 = bch.FloatSweep(default=0, bounds=[0, 1.0], doc="x coordinate of the sample volume")
|
34
|
+
float2 = bch.FloatSweep(default=0, bounds=[0, 1.0], doc="y coordinate of the sample volume")
|
35
|
+
float3 = bch.FloatSweep(default=0, bounds=[0, 1.0], doc="z coordinate of the sample volume")
|
36
|
+
|
37
|
+
sigma = bch.FloatSweep(default=1, bounds=[1, 10], doc="standard deviation of the added noise")
|
38
|
+
|
39
|
+
# categorial variables
|
40
|
+
noisy = bch.BoolSweep(
|
41
|
+
default=False, doc="Optionally add random noise to the output of the function"
|
42
|
+
)
|
43
|
+
noise_distribution = bch.EnumSweep(NoiseDistribution, doc=NoiseDistribution.__doc__)
|
44
|
+
|
45
|
+
negate_output = bch.StringSweep(["positive", "negative"])
|
46
|
+
|
47
|
+
distance = bch.ResultVar("m", doc="The distance from the sample point to the origin")
|
48
|
+
sample_noise = bch.ResultVar("m", doc="The amount of noise added to the distance sample")
|
49
|
+
|
50
|
+
result_hmap = bch.ResultHmap()
|
51
|
+
# result_im
|
52
|
+
##todo all var types
|
53
|
+
|
54
|
+
def __call__(self, **kwargs):
|
55
|
+
self.update_params_from_kwargs(**kwargs)
|
56
|
+
|
57
|
+
# distance to origin
|
58
|
+
self.distance = math.pow(
|
59
|
+
np.linalg.norm(np.array([self.float1, self.float2, self.float3])), 2
|
60
|
+
)
|
61
|
+
self.sample_noise = NoiseDistribution.calculate_noise(
|
62
|
+
self.noisy, self.noise_distribution, self.sigma
|
63
|
+
)
|
64
|
+
|
65
|
+
self.distance += self.sample_noise
|
66
|
+
|
67
|
+
if self.negate_output == "negative":
|
68
|
+
self.distance *= -1
|
69
|
+
|
70
|
+
self.result_hmap = hv.Text(
|
71
|
+
x=0, y=0, text=f"distance:{self.distance}\nnoise:{self.sample_noise}"
|
72
|
+
)
|
73
|
+
|
74
|
+
return super().__call__()
|
75
|
+
|
76
|
+
|
77
|
+
class BenchMeta(bch.ParametrizedSweep):
|
78
|
+
"""This class uses bencher to display the multidimensional types bencher can represent"""
|
79
|
+
|
80
|
+
float_vars = bch.IntSweep(
|
81
|
+
default=1, bounds=(0, 4), doc="The number of floating point variables that are swept"
|
82
|
+
)
|
83
|
+
categorical_vars = bch.IntSweep(
|
84
|
+
default=1, bounds=(0, 3), doc="The number of categorical variables that are swept"
|
85
|
+
)
|
86
|
+
sample_with_repeats = bch.IntSweep(default=1, bounds=(1, 10))
|
87
|
+
|
88
|
+
sample_over_time = bch.BoolSweep(default=False)
|
89
|
+
|
90
|
+
level = bch.IntSweep(default=2, units="level", bounds=(2, 5))
|
91
|
+
|
92
|
+
# plots = bch.ResultHmap()
|
93
|
+
# plots = bch.ResultContainer()
|
94
|
+
plots = bch.ResultReference(units="int")
|
95
|
+
|
96
|
+
def __call__(self, **kwargs: Any) -> Any:
|
97
|
+
self.update_params_from_kwargs(**kwargs)
|
98
|
+
|
99
|
+
run_cfg = bch.BenchRunCfg()
|
100
|
+
run_cfg.level = self.level
|
101
|
+
run_cfg.repeats = self.sample_with_repeats
|
102
|
+
run_cfg.over_time = self.sample_over_time
|
103
|
+
run_cfg.plot_size = 500
|
104
|
+
|
105
|
+
bench = bch.Bench("benchable", BenchableObject(), run_cfg=run_cfg)
|
106
|
+
|
107
|
+
inputs_vars_float = [
|
108
|
+
"float1",
|
109
|
+
"float2",
|
110
|
+
"float3",
|
111
|
+
"sigma",
|
112
|
+
]
|
113
|
+
|
114
|
+
inputs_vars_cat = [
|
115
|
+
"noisy",
|
116
|
+
"noise_distribution",
|
117
|
+
"negate_output",
|
118
|
+
]
|
119
|
+
|
120
|
+
input_vars = (
|
121
|
+
inputs_vars_float[0 : self.float_vars] + inputs_vars_cat[0 : self.categorical_vars]
|
122
|
+
)
|
123
|
+
|
124
|
+
res = bench.plot_sweep(
|
125
|
+
"test",
|
126
|
+
input_vars=input_vars,
|
127
|
+
result_vars=[BenchableObject.param.distance],
|
128
|
+
# result_vars=[BenchableObject.param.distance, BenchableObject.param.sample_noise],
|
129
|
+
# result_vars=[ BenchableObject.param.sample_noise],
|
130
|
+
# result_vars=[BenchableObject.param.result_hmap],
|
131
|
+
plot_callbacks=False,
|
132
|
+
)
|
133
|
+
|
134
|
+
self.plots = bch.ResultReference()
|
135
|
+
self.plots.obj = res.to_auto()
|
136
|
+
|
137
|
+
# self.plots.obj = res.to_heatmap_multi()
|
138
|
+
|
139
|
+
# self.plots.obj = res.to_line_multi(width=500, height=300)
|
140
|
+
|
141
|
+
return super().__call__()
|
142
|
+
|
143
|
+
|
144
|
+
def example_meta(
|
145
|
+
run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
|
146
|
+
) -> bch.Bench:
|
147
|
+
bench = BenchMeta().to_bench(run_cfg, report)
|
148
|
+
|
149
|
+
bench.plot_sweep(
|
150
|
+
title="Meta Bench",
|
151
|
+
description="""## All Combinations of Variable Sweeps and Resulting Plots
|
152
|
+
This uses bencher to display all the combinatios of plots bencher is able to produce""",
|
153
|
+
input_vars=[
|
154
|
+
bch.p("float_vars", [0, 1, 2, 3]),
|
155
|
+
BenchMeta.param.categorical_vars,
|
156
|
+
bch.p("sample_with_repeats", [1, 2]),
|
157
|
+
# BenchMeta.param.sample_over_time,
|
158
|
+
],
|
159
|
+
const_vars=[
|
160
|
+
# BenchMeta.param.float_vars.with_const(1),
|
161
|
+
# BenchMeta.param.sample_with_repeats.with_const(2),
|
162
|
+
# BenchMeta.param.categorical_vars.with_const(2),
|
163
|
+
# BenchMeta.param.sample_over_time.with_const(True),
|
164
|
+
],
|
165
|
+
)
|
166
|
+
|
167
|
+
return bench
|
168
|
+
|
169
|
+
|
170
|
+
if __name__ == "__main__":
|
171
|
+
example_meta().report.show()
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
from bencher.example.meta.example_meta import BenchMeta
|
3
|
+
|
4
|
+
|
5
|
+
def example_meta_cat(
|
6
|
+
run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
|
7
|
+
) -> bch.Bench:
|
8
|
+
bench = BenchMeta().to_bench(run_cfg, report)
|
9
|
+
|
10
|
+
bench.plot_sweep(
|
11
|
+
title="Sweeping Categorical Variables",
|
12
|
+
input_vars=[
|
13
|
+
bch.p("categorical_vars", [1, 2, 3]),
|
14
|
+
bch.p("sample_with_repeats", [1, 2]),
|
15
|
+
],
|
16
|
+
const_vars=[
|
17
|
+
BenchMeta.param.float_vars.with_const(0),
|
18
|
+
],
|
19
|
+
)
|
20
|
+
|
21
|
+
return bench
|
22
|
+
|
23
|
+
|
24
|
+
if __name__ == "__main__":
|
25
|
+
example_meta_cat().report.show()
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
from bencher.example.meta.example_meta import BenchMeta
|
3
|
+
|
4
|
+
|
5
|
+
def example_meta_float(
|
6
|
+
run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
|
7
|
+
) -> bch.Bench:
|
8
|
+
bench = BenchMeta().to_bench(run_cfg, report)
|
9
|
+
|
10
|
+
bench.plot_sweep(
|
11
|
+
title="Sweeping Floating Point Variables",
|
12
|
+
input_vars=[bch.p("float_vars", [1, 2, 3])],
|
13
|
+
const_vars=[
|
14
|
+
BenchMeta.param.categorical_vars.with_const(0),
|
15
|
+
BenchMeta.param.level.with_const(3),
|
16
|
+
],
|
17
|
+
)
|
18
|
+
|
19
|
+
return bench
|
20
|
+
|
21
|
+
|
22
|
+
if __name__ == "__main__":
|
23
|
+
example_meta_float().report.show()
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
from bencher.example.meta.example_meta import BenchMeta
|
3
|
+
|
4
|
+
|
5
|
+
def example_meta_levels(
|
6
|
+
run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
|
7
|
+
) -> bch.Bench:
|
8
|
+
bench = BenchMeta().to_bench(run_cfg, report)
|
9
|
+
|
10
|
+
bench.plot_sweep(
|
11
|
+
title="Using Levels to define sample density",
|
12
|
+
description="Sample levels let you perform parameter sweeps without having to decide how many samples to take when defining the class. If you perform a sweep at level 2, then all the points are reused when sampling at level 3. The higher levels reuse the points from lower levels to avoid having to recompute potentially expensive samples. The other advantage is that it enables a workflow where you can quickly see the results of the sweep at a low resolution to sense check the code, and then run it at a high level to get the fidelity you want. When calling a sweep at a high level, you can publish the intermediate lower level results as the computiation continues so that you can track the progress of the computation and end the sweep early when you have sufficient resolution",
|
13
|
+
input_vars=[
|
14
|
+
bch.p("float_vars", [1, 2]),
|
15
|
+
bch.p("level", [2, 3, 4]),
|
16
|
+
],
|
17
|
+
const_vars=[
|
18
|
+
BenchMeta.param.categorical_vars.with_const(0),
|
19
|
+
],
|
20
|
+
)
|
21
|
+
|
22
|
+
return bench
|
23
|
+
|
24
|
+
|
25
|
+
if __name__ == "__main__":
|
26
|
+
example_meta_levels().report.show()
|
@@ -0,0 +1,78 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
import numpy as np
|
3
|
+
import optuna
|
4
|
+
from optuna.samplers import TPESampler
|
5
|
+
|
6
|
+
|
7
|
+
def objective(trial):
|
8
|
+
x = trial.suggest_float("x", -10, 10)
|
9
|
+
return x**2
|
10
|
+
|
11
|
+
|
12
|
+
study = optuna.create_study(sampler=TPESampler())
|
13
|
+
study.optimize(objective, n_trials=10)
|
14
|
+
|
15
|
+
rast_range = 1.5
|
16
|
+
|
17
|
+
optimal_value = 0.1234
|
18
|
+
|
19
|
+
|
20
|
+
class ToyOptimisationProblem(bch.ParametrizedSweep):
|
21
|
+
input1 = bch.FloatSweep(default=0, bounds=[-rast_range, rast_range], samples=10)
|
22
|
+
input2 = bch.FloatSweep(default=0, bounds=[-rast_range, rast_range], samples=10)
|
23
|
+
offset = bch.FloatSweep(default=0, bounds=[-rast_range, rast_range])
|
24
|
+
|
25
|
+
bump_scale = bch.FloatSweep(default=1.5, bounds=[1, 10])
|
26
|
+
|
27
|
+
# RESULTS
|
28
|
+
output = bch.ResultVar("ul", bch.OptDir.minimize)
|
29
|
+
|
30
|
+
def rastrigin(self, **kwargs) -> dict:
|
31
|
+
"""A modified version of the rastrigin function which is very difficult to find the global optimum
|
32
|
+
https://en.wikipedia.org/wiki/Rastrigin_function
|
33
|
+
|
34
|
+
Returns:
|
35
|
+
dict: dictionary of return values
|
36
|
+
"""
|
37
|
+
self.update_params_from_kwargs(**kwargs)
|
38
|
+
x = np.array([self.input1 + optimal_value, self.input2 + optimal_value])
|
39
|
+
|
40
|
+
self.output = (
|
41
|
+
np.sum(x * x - self.bump_scale * np.cos(self.bump_scale * np.pi * x))
|
42
|
+
+ self.bump_scale * np.size(x)
|
43
|
+
+ self.offset
|
44
|
+
)
|
45
|
+
return self.get_results_values_as_dict()
|
46
|
+
|
47
|
+
|
48
|
+
def optuna_rastrigin(
|
49
|
+
run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
|
50
|
+
):
|
51
|
+
explorer = ToyOptimisationProblem()
|
52
|
+
|
53
|
+
bench = bch.Bench("Rastrigin", explorer.rastrigin, run_cfg=run_cfg, report=report)
|
54
|
+
|
55
|
+
# res = bench.to_optuna(
|
56
|
+
# input_vars=[explorer.param.input1, explorer.param.input2],
|
57
|
+
# result_vars=[explorer.param.output],
|
58
|
+
# n_trials=30
|
59
|
+
# )
|
60
|
+
|
61
|
+
# run_cfg.use_optuna = True
|
62
|
+
res = bench.plot_sweep(
|
63
|
+
"Rastrigin",
|
64
|
+
input_vars=[explorer.param.input1, explorer.param.input2],
|
65
|
+
result_vars=[explorer.param.output],
|
66
|
+
run_cfg=run_cfg,
|
67
|
+
)
|
68
|
+
|
69
|
+
bench.report.append(res.to_optuna_plots())
|
70
|
+
bench.report.append(res.to_optuna_from_sweep(bench))
|
71
|
+
bench.report.append_markdown(
|
72
|
+
f"The optimal value should be input1:{-optimal_value},input2:{-optimal_value} with a value of 0"
|
73
|
+
)
|
74
|
+
return bench
|
75
|
+
|
76
|
+
|
77
|
+
if __name__ == "__main__":
|
78
|
+
optuna_rastrigin().report.show()
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# import random
|
2
|
+
|
3
|
+
# import bencher as bch
|
4
|
+
|
5
|
+
|
6
|
+
# class GaussianDist(bch.ParametrizedSweep):
|
7
|
+
# """A class to represent a gaussian distribution."""
|
8
|
+
|
9
|
+
# mean = bch.FloatSweep(
|
10
|
+
# default=0, bounds=[-1.0, 1.0], doc="mean of the gaussian distribution", samples=3
|
11
|
+
# )
|
12
|
+
# sigma = bch.FloatSweep(
|
13
|
+
# default=1, bounds=[0, 1.0], doc="standard deviation of gaussian distribution", samples=4
|
14
|
+
# )
|
15
|
+
|
16
|
+
|
17
|
+
# class Example2DGaussianResult(bch.ParametrizedSweep):
|
18
|
+
# """A class to represent the properties of a volume sample."""
|
19
|
+
|
20
|
+
# gauss_x = bch.ResultVar("m", doc="x value of the 2D gaussian")
|
21
|
+
# gauss_y = bch.ResultVar("m", doc="y value of the 2D gaussian")
|
22
|
+
|
23
|
+
# point2D = bch.ResultVec(2, "m", doc="2D vector of the point")
|
24
|
+
|
25
|
+
|
26
|
+
# def bench_fn(dist: GaussianDist) -> Example2DGaussianResult:
|
27
|
+
# """This function samples a point from a gaussian distribution.
|
28
|
+
|
29
|
+
# Args:
|
30
|
+
# dist (GaussianDist): Sample point
|
31
|
+
|
32
|
+
# Returns:
|
33
|
+
# Example2DGaussianResult: Value at that point
|
34
|
+
# """
|
35
|
+
# output = Example2DGaussianResult()
|
36
|
+
|
37
|
+
# output.gauss_x = random.gauss(dist.mean, dist.sigma)
|
38
|
+
# output.gauss_y = random.gauss(dist.mean, dist.sigma)
|
39
|
+
# output.point2D = [output.gauss_x, output.gauss_y]
|
40
|
+
|
41
|
+
# return output
|
42
|
+
|
43
|
+
|
44
|
+
# def example_floats2D_scatter(run_cfg: bch.BenchRunCfg) -> bch.Bench:
|
45
|
+
# """Example of how to perform a 3D floating point parameter sweep
|
46
|
+
|
47
|
+
# Args:
|
48
|
+
# run_cfg (BenchRunCfg): configuration of how to perform the param sweep
|
49
|
+
|
50
|
+
# Returns:
|
51
|
+
# Bench: results of the parameter sweep
|
52
|
+
# """
|
53
|
+
# bench = bch.Bench(
|
54
|
+
# "Bencher_Example_Floats_Scatter", bench_fn, GaussianDist, plot_lib=bch.PlotLibrary.default()
|
55
|
+
# )
|
56
|
+
|
57
|
+
# bench.plot_sweep(
|
58
|
+
# result_vars=[
|
59
|
+
# Example2DGaussianResult.param.point2D,
|
60
|
+
# Example2DGaussianResult.param.gauss_x,
|
61
|
+
# Example2DGaussianResult.param.gauss_y,
|
62
|
+
# ],
|
63
|
+
# title="Float 2D Scatter Example",
|
64
|
+
# run_cfg=run_cfg,
|
65
|
+
# )
|
66
|
+
|
67
|
+
# bench.plot_sweep(
|
68
|
+
# input_vars=[GaussianDist.param.mean],
|
69
|
+
# result_vars=[
|
70
|
+
# Example2DGaussianResult.param.point2D,
|
71
|
+
# Example2DGaussianResult.param.gauss_x,
|
72
|
+
# Example2DGaussianResult.param.gauss_y,
|
73
|
+
# ],
|
74
|
+
# title="Float 2D Scatter With Changing Mean",
|
75
|
+
# run_cfg=run_cfg,
|
76
|
+
# )
|
77
|
+
|
78
|
+
# bench.plot_sweep(
|
79
|
+
# input_vars=[GaussianDist.param.sigma],
|
80
|
+
# result_vars=[
|
81
|
+
# Example2DGaussianResult.param.point2D,
|
82
|
+
# Example2DGaussianResult.param.gauss_x,
|
83
|
+
# Example2DGaussianResult.param.gauss_y,
|
84
|
+
# ],
|
85
|
+
# title="Float 2D Scatter With Changing Sigma",
|
86
|
+
# run_cfg=run_cfg,
|
87
|
+
# )
|
88
|
+
|
89
|
+
# # future work
|
90
|
+
# # bench.plot_sweep(
|
91
|
+
# # input_vars=[GaussianDist.param.mean, GaussianDist.param.sigma],
|
92
|
+
# # result_vars=[
|
93
|
+
# # GaussianResult.param.point2D,
|
94
|
+
# # GaussianResult.param.gauss_x,
|
95
|
+
# # GaussianResult.param.gauss_y,
|
96
|
+
# # ],
|
97
|
+
# # title="Float 2D Scatter With Changing Sigma",
|
98
|
+
# # run_cfg=run_cfg,
|
99
|
+
# # )
|
100
|
+
|
101
|
+
# return bench
|
102
|
+
|
103
|
+
|
104
|
+
# if __name__ == "__main__":
|
105
|
+
# ex_run_cfg = bch.BenchRunCfg()
|
106
|
+
# ex_run_cfg.repeats = 50
|
107
|
+
# ex_run_cfg.over_time = True
|
108
|
+
# # ex_run_cfg.clear_history = True
|
109
|
+
# example_floats2D_scatter(ex_run_cfg).report.show()
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# import numpy as np
|
2
|
+
|
3
|
+
# import bencher as bch
|
4
|
+
|
5
|
+
|
6
|
+
# class VolumeSample(bch.ParametrizedSweep):
|
7
|
+
# """A class to represent a 3D point in space."""
|
8
|
+
|
9
|
+
# pos_samples = 1
|
10
|
+
|
11
|
+
# x = bch.FloatSweep(
|
12
|
+
# default=0, bounds=[-1.0, 1.0], samples=pos_samples, doc="x coordinate of the sample volume"
|
13
|
+
# )
|
14
|
+
# y = bch.FloatSweep(
|
15
|
+
# default=0, bounds=[-1.0, 1.0], samples=pos_samples, doc="y coordinate of the sample volume"
|
16
|
+
# )
|
17
|
+
# z = bch.FloatSweep(
|
18
|
+
# default=0, bounds=[-1.0, 1.0], samples=pos_samples, doc="z coordinate of the sample volume"
|
19
|
+
# )
|
20
|
+
|
21
|
+
# vec_samples = 5
|
22
|
+
|
23
|
+
# vec_x = bch.FloatSweep(
|
24
|
+
# default=0, bounds=[-1.0, 1.0], samples=vec_samples, doc="x coordinate of the sample volume"
|
25
|
+
# )
|
26
|
+
# vec_y = bch.FloatSweep(
|
27
|
+
# default=0, bounds=[-1.0, 1.0], samples=vec_samples, doc="y coordinate of the sample volume"
|
28
|
+
# )
|
29
|
+
# vec_z = bch.FloatSweep(
|
30
|
+
# default=0, bounds=[-1.0, 1.0], samples=vec_samples, doc="z coordinate of the sample volume"
|
31
|
+
# )
|
32
|
+
|
33
|
+
|
34
|
+
# class VolumeResult(bch.ParametrizedSweep):
|
35
|
+
# """A class to represent the properties of a volume sample."""
|
36
|
+
|
37
|
+
# vec_dir = bch.ResultVec(3, "vec", doc="A vector field with an interesting shape")
|
38
|
+
|
39
|
+
|
40
|
+
# def bench_fn(point: VolumeSample, normalise=False) -> VolumeResult:
|
41
|
+
# """This function takes a 3D point as input and returns distance of that point to the origin.
|
42
|
+
|
43
|
+
# Args:
|
44
|
+
# point (VolumeSample): Sample point
|
45
|
+
|
46
|
+
# Returns:
|
47
|
+
# VolumeResult: Value at that point
|
48
|
+
# """
|
49
|
+
# output = VolumeResult()
|
50
|
+
|
51
|
+
# vec = np.array([point.vec_x, point.vec_y, point.vec_z])
|
52
|
+
|
53
|
+
# if normalise:
|
54
|
+
# norm = np.linalg.norm(vec)
|
55
|
+
# if norm > 0:
|
56
|
+
# vec /= norm
|
57
|
+
|
58
|
+
# output.vec_dir = list(vec)
|
59
|
+
# return output
|
60
|
+
|
61
|
+
|
62
|
+
# def example_cone(run_cfg: bch.BenchRunCfg) -> bch.Bench:
|
63
|
+
# """Example of how to perform a 3D floating point parameter sweep
|
64
|
+
|
65
|
+
# Args:
|
66
|
+
# run_cfg (BenchRunCfg): configuration of how to perform the param sweep
|
67
|
+
|
68
|
+
# Returns:
|
69
|
+
# Bench: results of the parameter sweep
|
70
|
+
# """
|
71
|
+
# bench = bch.Bench("Bencher_Example_Cone", bench_fn, VolumeSample)
|
72
|
+
|
73
|
+
# bench.plot_sweep(
|
74
|
+
# input_vars=[
|
75
|
+
# VolumeSample.param.x,
|
76
|
+
# VolumeSample.param.y,
|
77
|
+
# VolumeSample.param.z,
|
78
|
+
# VolumeSample.param.vec_x,
|
79
|
+
# VolumeSample.param.vec_y,
|
80
|
+
# VolumeSample.param.vec_z,
|
81
|
+
# ],
|
82
|
+
# result_vars=[
|
83
|
+
# VolumeResult.param.vec_dir,
|
84
|
+
# ],
|
85
|
+
# title="Float 3D cone Example",
|
86
|
+
# description="""This example shows how to sample 3 floating point variables and plot a vector field representation of the results. The benchmark function returns the distance to the origin""",
|
87
|
+
# run_cfg=run_cfg,
|
88
|
+
# )
|
89
|
+
|
90
|
+
# return bench
|
91
|
+
|
92
|
+
|
93
|
+
# if __name__ == "__main__":
|
94
|
+
# ex_run_cfg = bch.BenchRunCfg()
|
95
|
+
# ex_run_cfg.use_cache = True
|
96
|
+
# example_cone(ex_run_cfg).report.show()
|