holobench 1.25.2__py3-none-any.whl → 1.27.0__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/bench_report.py +6 -109
- bencher/example/__init__.py +0 -0
- 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.27.0.data/data/share/ament_index/resource_index/packages/bencher +0 -0
- holobench-1.27.0.data/data/share/bencher/package.xml +33 -0
- {holobench-1.25.2.dist-info → holobench-1.27.0.dist-info}/METADATA +5 -5
- holobench-1.27.0.dist-info/RECORD +93 -0
- holobench-1.25.2.dist-info/RECORD +0 -18
- {holobench-1.25.2.dist-info → holobench-1.27.0.dist-info}/LICENSE +0 -0
- {holobench-1.25.2.dist-info → holobench-1.27.0.dist-info}/WHEEL +0 -0
- {holobench-1.25.2.dist-info → holobench-1.27.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,160 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
from PIL import Image, ImageDraw
|
3
|
+
from bencher.video_writer import VideoWriter
|
4
|
+
|
5
|
+
|
6
|
+
class BenchImageTest(bch.ParametrizedSweep):
|
7
|
+
character = bch.StringSweep(["a", "b", "c", "d", "e", "f"])
|
8
|
+
r = bch.IntSweep(default=255, bounds=[0, 255])
|
9
|
+
g = bch.IntSweep(default=255, bounds=[0, 255])
|
10
|
+
b = bch.IntSweep(default=255, bounds=[0, 255])
|
11
|
+
width = bch.IntSweep(default=100, bounds=[10, 100])
|
12
|
+
height = bch.IntSweep(default=100, bounds=[10, 100])
|
13
|
+
|
14
|
+
image = bch.ResultImage()
|
15
|
+
|
16
|
+
def __call__(self, **kwargs):
|
17
|
+
self.update_params_from_kwargs(**kwargs)
|
18
|
+
|
19
|
+
img = Image.new("RGB", (self.width, self.height), color=(self.r, self.g, self.b))
|
20
|
+
ImageDraw.Draw(img).text(
|
21
|
+
(self.width / 2.0, self.height / 2.0),
|
22
|
+
self.character,
|
23
|
+
(0, 0, 0),
|
24
|
+
anchor="mm",
|
25
|
+
font_size=self.height,
|
26
|
+
)
|
27
|
+
self.image = bch.gen_image_path()
|
28
|
+
img.save(self.image)
|
29
|
+
return super().__call__(**kwargs)
|
30
|
+
|
31
|
+
|
32
|
+
def bench_image(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
|
33
|
+
bench = BenchImageTest().to_bench(run_cfg, report)
|
34
|
+
bench.sweep_sequential(group_size=1)
|
35
|
+
return bench
|
36
|
+
|
37
|
+
|
38
|
+
class BenchComposableContainerImage(BenchImageTest):
|
39
|
+
compose_method = bch.EnumSweep(bch.ComposeType)
|
40
|
+
labels = bch.BoolSweep()
|
41
|
+
# num_frames = bch.IntSweep(default=5, bounds=[1, 10])
|
42
|
+
# character = bch.StringSweep(["a", "b"])
|
43
|
+
|
44
|
+
text_vid = bch.ResultVideo()
|
45
|
+
frame_width = bch.ResultVar("pixels")
|
46
|
+
frame_height = bch.ResultVar("pixels")
|
47
|
+
duration = bch.ResultVar("S")
|
48
|
+
|
49
|
+
def __call__(self, **kwargs):
|
50
|
+
self.update_params_from_kwargs(**kwargs)
|
51
|
+
# if self.labels:
|
52
|
+
# var_name = "sides"
|
53
|
+
# var_value = self.sides
|
54
|
+
vr = bch.ComposableContainerVideo()
|
55
|
+
|
56
|
+
for c in ["a", "b"]:
|
57
|
+
res = super().__call__(character=c)
|
58
|
+
vr.append(res["image"])
|
59
|
+
|
60
|
+
vid = vr.render(
|
61
|
+
bch.RenderCfg(
|
62
|
+
compose_method=self.compose_method,
|
63
|
+
# var_name=var_name,
|
64
|
+
# var_value=var_value,
|
65
|
+
max_frame_duration=2.0,
|
66
|
+
# max_frame_duration=1.,
|
67
|
+
# duration=1.
|
68
|
+
)
|
69
|
+
)
|
70
|
+
|
71
|
+
self.frame_width, self.frame_height = vid.size
|
72
|
+
self.duration = vid.duration
|
73
|
+
print("RES", self.frame_width, self.frame_height, self.duration)
|
74
|
+
|
75
|
+
self.text_vid = VideoWriter().write_video_raw(vid)
|
76
|
+
return self.get_results_values_as_dict()
|
77
|
+
|
78
|
+
|
79
|
+
# class BenchComposableContainerVideo(bch.ParametrizedSweep):
|
80
|
+
# unequal_length = bch.BoolSweep()
|
81
|
+
# compose_method = bch.EnumSweep(bch.ComposeType)
|
82
|
+
# labels = bch.BoolSweep()
|
83
|
+
# polygon_vid = bch.ResultVideo()
|
84
|
+
|
85
|
+
# def __call__(self, **kwargs):
|
86
|
+
# self.update_params_from_kwargs(**kwargs)
|
87
|
+
# vr = bch.ComposableContainerVideo()
|
88
|
+
# for i in range(3, 5):
|
89
|
+
# num_frames = i * 10 if self.unequal_length else 5
|
90
|
+
# res = BenchComposableContainerImage().__call__(
|
91
|
+
# compose_method=bch.ComposeType.sequence, sides=i, num_frames=num_frames
|
92
|
+
# )
|
93
|
+
# vr.append(res["polygon_vid"])
|
94
|
+
|
95
|
+
# self.polygon_vid = vr.to_video(bch.RenderCfg(compose_method=kwargs.get("compose_method")))
|
96
|
+
# return self.get_results_values_as_dict()
|
97
|
+
|
98
|
+
|
99
|
+
def example_composable_container_image(
|
100
|
+
run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
|
101
|
+
) -> bch.Bench:
|
102
|
+
bench = BenchComposableContainerImage().to_bench(run_cfg, report)
|
103
|
+
bench.result_vars = ["text_vid", "duration"]
|
104
|
+
# bench.result_vars = ["duration"]
|
105
|
+
# bench.add_plot_callback(bch.BenchResult.to_panes)
|
106
|
+
# bench.add_plot_callback(bch.BenchResult.to_table)
|
107
|
+
|
108
|
+
# bench.add_plot_callback(bch.BenchResult.to_video_grid, result_types=(bch.ResultVideo))
|
109
|
+
# bench.add_plot_callback(bch.BenchResult.to_video_summary, result_types=(bch.ResultVideo))
|
110
|
+
# bench.plot_sweep(input_vars=["compose_method", "labels"])
|
111
|
+
|
112
|
+
bench.plot_sweep(input_vars=["compose_method"])
|
113
|
+
|
114
|
+
# bench.compose_
|
115
|
+
# bench.plot_sweep(
|
116
|
+
# input_vars=[bch.p("num_frames", [2, 8, 20])],
|
117
|
+
# const_vars=dict(compose_method=bch.ComposeType.sequence),
|
118
|
+
# )
|
119
|
+
|
120
|
+
return bench
|
121
|
+
|
122
|
+
|
123
|
+
# def example_composable_container_video(
|
124
|
+
# run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
|
125
|
+
# ) -> bch.Bench:
|
126
|
+
# bench = BenchComposableContainerVideo().to_bench(run_cfg, report)
|
127
|
+
|
128
|
+
# bench.result_vars = ["polygon_vid"]
|
129
|
+
# bench.add_plot_callback(bch.BenchResult.to_panes)
|
130
|
+
# bench.add_plot_callback(bch.BenchResult.to_video_grid, result_types=(bch.ResultVideo))
|
131
|
+
# bench.add_plot_callback(bch.BenchResult.to_video_summary, result_types=(bch.ResultVideo))
|
132
|
+
# bench.plot_sweep(input_vars=["compose_method", "labels"], const_vars=dict(unequal_length=True))
|
133
|
+
|
134
|
+
# res = bench.plot_sweep(
|
135
|
+
# input_vars=[],
|
136
|
+
# const_vars=dict(unequal_length=False, compose_method=bch.ComposeType.sequence),
|
137
|
+
# plot_callbacks=False,
|
138
|
+
# )
|
139
|
+
|
140
|
+
# bench.report.append(res.to_video_grid())
|
141
|
+
|
142
|
+
# return bench
|
143
|
+
|
144
|
+
|
145
|
+
# if __name__ == "__main__":
|
146
|
+
# ex_run_cfg = bch.BenchRunCfg()
|
147
|
+
# ex_run_cfg.use_sample_cache = False
|
148
|
+
# # ex_run_cfg.level = 2
|
149
|
+
# ex_report = bch.BenchReport()
|
150
|
+
# example_composable_container_image(ex_run_cfg, report=ex_report)
|
151
|
+
# # example_composable_container_video(ex_run_cfg, report=ex_report)
|
152
|
+
# ex_report.show()
|
153
|
+
|
154
|
+
|
155
|
+
if __name__ == "__main__":
|
156
|
+
bench_runner = bch.BenchRunner("ImageChar")
|
157
|
+
# bench_runner.add_run(bench_image)
|
158
|
+
bench_runner.add_run(example_composable_container_image)
|
159
|
+
|
160
|
+
bench_runner.run(level=6, show=True, use_cache=False)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
"""This file contains examples for how to perform basic 2D benchmarking parameter sweeps"""
|
2
|
+
|
3
|
+
import math
|
4
|
+
import bencher as bch
|
5
|
+
|
6
|
+
|
7
|
+
class SimpleFloat(bch.ParametrizedSweep):
|
8
|
+
theta = bch.FloatSweep(
|
9
|
+
default=0, bounds=[0, math.pi], doc="Input angle", units="rad", samples=30
|
10
|
+
)
|
11
|
+
offset = bch.FloatSweep(default=0, bounds=[0, 1], doc="Input angle offset", units="rad")
|
12
|
+
noise = bch.FloatSweep(default=0, bounds=[0, 1], doc="noise", units="rad")
|
13
|
+
out_sin = bch.ResultVar(units="v", doc="sin of theta")
|
14
|
+
|
15
|
+
def __call__(self, **kwargs):
|
16
|
+
self.update_params_from_kwargs(**kwargs)
|
17
|
+
self.out_sin = math.sin(self.theta) + self.offset + self.noise
|
18
|
+
return super().__call__(**kwargs)
|
19
|
+
|
20
|
+
|
21
|
+
def example_2D_float_const(
|
22
|
+
run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
|
23
|
+
) -> bch.Bench:
|
24
|
+
"""This example shows how to sample a 1 dimensional float variable and plot the result of passing that parameter sweep to the benchmarking function"""
|
25
|
+
|
26
|
+
bench = SimpleFloat().to_bench(run_cfg, report)
|
27
|
+
const_vars = SimpleFloat().get_input_defaults_override(offset=0.5)
|
28
|
+
bench.plot_sweep(input_vars=["theta"], const_vars=const_vars)
|
29
|
+
|
30
|
+
const_vars = SimpleFloat().get_input_defaults_override(noise=0.2)
|
31
|
+
bench.plot_sweep(input_vars=["theta"], const_vars=const_vars)
|
32
|
+
|
33
|
+
bench.plot_sweep(input_vars=["theta"], const_vars=dict(offset=0.3))
|
34
|
+
|
35
|
+
return bench
|
36
|
+
|
37
|
+
|
38
|
+
if __name__ == "__main__":
|
39
|
+
example_2D_float_const().report.show()
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
|
3
|
+
|
4
|
+
class Square(bch.ParametrizedSweep):
|
5
|
+
"""An example of a datatype with an integer and float parameter"""
|
6
|
+
|
7
|
+
x = bch.FloatSweep(
|
8
|
+
sample_values=[2, 3, 4, 7, 8, 9],
|
9
|
+
doc="An example of a user defines set of sweep values",
|
10
|
+
)
|
11
|
+
y = bch.IntSweep(
|
12
|
+
sample_values=[1, 2, 6], doc="An example of a user defines set of sweep values"
|
13
|
+
)
|
14
|
+
|
15
|
+
result = bch.ResultVar("ul", doc="Square of x")
|
16
|
+
|
17
|
+
def __call__(self, **kwargs) -> dict:
|
18
|
+
self.update_params_from_kwargs(**kwargs)
|
19
|
+
self.result = self.x * self.x * self.y * 3
|
20
|
+
return self.get_results_values_as_dict()
|
21
|
+
|
22
|
+
|
23
|
+
def example_custom_sweep(
|
24
|
+
run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
|
25
|
+
) -> bch.Bench:
|
26
|
+
"""This example shows how to define a custom set of value to sample from intead of a uniform sweep
|
27
|
+
|
28
|
+
Args:
|
29
|
+
run_cfg (BenchRunCfg): configuration of how to perform the param sweep
|
30
|
+
|
31
|
+
Returns:
|
32
|
+
Bench: results of the parameter sweep
|
33
|
+
"""
|
34
|
+
|
35
|
+
bencher = bch.Bench(
|
36
|
+
"benchmarking_example_custom_sweep", Square(), run_cfg=run_cfg, report=report
|
37
|
+
)
|
38
|
+
# bencher = bch.Bench("benchmarking_example_custom_sweep", call,run_cfg=run_cfg)
|
39
|
+
|
40
|
+
# here we sample the input variable theta and plot the value of output1. The (noisy) function is sampled 20 times so you can see the distribution
|
41
|
+
|
42
|
+
bencher.plot_sweep(
|
43
|
+
title="Example User Defined Sweep 1D",
|
44
|
+
input_vars=[Square.param.x],
|
45
|
+
result_vars=[Square.param.result],
|
46
|
+
description="Sample the x parameter",
|
47
|
+
)
|
48
|
+
|
49
|
+
bencher.plot_sweep(
|
50
|
+
title="Example User Defined Sweep 2D",
|
51
|
+
description="By default bencher sweep all the variables in a class",
|
52
|
+
)
|
53
|
+
|
54
|
+
return bencher
|
55
|
+
|
56
|
+
|
57
|
+
if __name__ == "__main__":
|
58
|
+
ex_run_cfg = bch.BenchRunCfg(run_tag="example_tag1", print_meta=True)
|
59
|
+
example_custom_sweep(ex_run_cfg).report.show()
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
|
3
|
+
|
4
|
+
class Square(bch.ParametrizedSweep):
|
5
|
+
"""An example of a datatype with an integer and float parameter"""
|
6
|
+
|
7
|
+
x = bch.FloatSweep(default=0, bounds=[0, 6])
|
8
|
+
|
9
|
+
result = bch.ResultVar("ul", doc="Square of x")
|
10
|
+
|
11
|
+
def __call__(self, **kwargs) -> dict:
|
12
|
+
self.update_params_from_kwargs(**kwargs)
|
13
|
+
self.result = self.x * self.x
|
14
|
+
return self.get_results_values_as_dict()
|
15
|
+
|
16
|
+
|
17
|
+
def example_custom_sweep2(
|
18
|
+
run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
|
19
|
+
) -> bch.Bench:
|
20
|
+
"""This example shows how to define a custom set of value to sample from intead of a uniform sweep
|
21
|
+
|
22
|
+
Args:
|
23
|
+
run_cfg (BenchRunCfg): configuration of how to perform the param sweep
|
24
|
+
|
25
|
+
Returns:
|
26
|
+
Bench: results of the parameter sweep
|
27
|
+
"""
|
28
|
+
|
29
|
+
bench = Square().to_bench(run_cfg=run_cfg, report=report)
|
30
|
+
|
31
|
+
# These are all equivalent
|
32
|
+
bench.plot_sweep(input_vars=[Square.param.x.with_sample_values([0, 1, 2])])
|
33
|
+
bench.plot_sweep(input_vars=[bch.p("x", [4, 5, 6])])
|
34
|
+
|
35
|
+
bench.plot_sweep(input_vars=[bch.p("x", samples=5)])
|
36
|
+
bench.plot_sweep(input_vars=[bch.p("x", samples=6)])
|
37
|
+
|
38
|
+
return bench
|
39
|
+
|
40
|
+
|
41
|
+
if __name__ == "__main__":
|
42
|
+
example_custom_sweep2().report.show()
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
from bencher.example.example_video import example_video
|
3
|
+
from bencher.example.example_image import example_image
|
4
|
+
from bencher.example.meta.example_meta_levels import example_meta_levels
|
5
|
+
from bencher.example.meta.example_meta_cat import example_meta_cat
|
6
|
+
from bencher.example.meta.example_meta_float import example_meta_float
|
7
|
+
|
8
|
+
|
9
|
+
def example_docs(
|
10
|
+
run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
|
11
|
+
) -> bch.Bench:
|
12
|
+
# b_run = bch.BenchRunner("bench_runner_test", run_cfg=run_cfg)
|
13
|
+
# b_run.add_run(example_categorical)
|
14
|
+
# b_run.add_run(example_floats)
|
15
|
+
# b_run.add_run(example_image)
|
16
|
+
# b_run.add_run(example_video)
|
17
|
+
# b_run.add_run(example_meta_levels)
|
18
|
+
# b_run.add_run(run_levels)
|
19
|
+
# b_run.run(level=4, grouped=True, save=True)
|
20
|
+
# b_run.shutdown()
|
21
|
+
run_cfg.repeats = 1
|
22
|
+
run_cfg.level = 2
|
23
|
+
example_image(run_cfg, report)
|
24
|
+
example_video(run_cfg, report)
|
25
|
+
example_meta_cat(report=report)
|
26
|
+
example_meta_float(report=report)
|
27
|
+
example_meta_levels(report=report)
|
28
|
+
# example_meta(run_cfg,report)
|
29
|
+
|
30
|
+
return report
|
31
|
+
|
32
|
+
|
33
|
+
if __name__ == "__main__":
|
34
|
+
example_docs().show()
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
|
3
|
+
|
4
|
+
class ExampleFile(bch.ParametrizedSweep):
|
5
|
+
content = bch.StringSweep(["entry1", "entry2", "entry3"])
|
6
|
+
|
7
|
+
file_result = bch.ResultPath()
|
8
|
+
|
9
|
+
def __call__(self, **kwargs):
|
10
|
+
self.update_params_from_kwargs(**kwargs)
|
11
|
+
|
12
|
+
# this generates a unique filename and stores it in the cache directory
|
13
|
+
filename = bch.gen_path(self.content, suffix=".txt")
|
14
|
+
with open(filename, "w", encoding="utf-8") as text_file:
|
15
|
+
text_file.write(f"content:{self.content}")
|
16
|
+
self.file_result = filename
|
17
|
+
return super().__call__()
|
18
|
+
|
19
|
+
|
20
|
+
def example_filepath(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None):
|
21
|
+
bench = ExampleFile().to_bench(run_cfg, report)
|
22
|
+
bench.plot_sweep()
|
23
|
+
return bench
|
24
|
+
|
25
|
+
|
26
|
+
if __name__ == "__main__":
|
27
|
+
example_filepath().report.show()
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# pylint: disable=duplicate-code
|
2
|
+
|
3
|
+
import numpy as np
|
4
|
+
|
5
|
+
import bencher as bch
|
6
|
+
|
7
|
+
|
8
|
+
class VolumeSample(bch.ParametrizedSweep):
|
9
|
+
"""A class to represent a 3D point in space."""
|
10
|
+
|
11
|
+
x = bch.FloatSweep(
|
12
|
+
default=0, bounds=[-1.0, 1.0], doc="x coordinate of the sample volume", samples=4
|
13
|
+
)
|
14
|
+
y = bch.FloatSweep(
|
15
|
+
default=0, bounds=[-1.0, 1.0], doc="y coordinate of the sample volume", samples=5
|
16
|
+
)
|
17
|
+
z = bch.FloatSweep(
|
18
|
+
default=0, bounds=[-1.0, 1.0], doc="z coordinate of the sample volume", samples=6
|
19
|
+
)
|
20
|
+
|
21
|
+
|
22
|
+
class VolumeResult(bch.ParametrizedSweep):
|
23
|
+
"""A class to represent the properties of a volume sample."""
|
24
|
+
|
25
|
+
value = bch.ResultVar("ul", doc="The scalar value of the 3D volume field")
|
26
|
+
occupancy = bch.ResultVar(
|
27
|
+
"occupied", doc="If the value is > 0.5 this point is considered occupied"
|
28
|
+
)
|
29
|
+
interesting = bch.ResultVar("ul", doc="A more interesting scalar field")
|
30
|
+
interesting_vec = bch.ResultVec(3, "vec", doc="A vector field with an interesting shape")
|
31
|
+
interesting_vec_and_occ = bch.ResultVec(
|
32
|
+
3, "vec", doc="The same vector field but only showing values in a sphere of radius 0.5"
|
33
|
+
)
|
34
|
+
|
35
|
+
|
36
|
+
def bench_fn(point: VolumeSample) -> VolumeResult:
|
37
|
+
"""This function takes a 3D point as input and returns distance of that point to the origin.
|
38
|
+
|
39
|
+
Args:
|
40
|
+
point (VolumeSample): Sample point
|
41
|
+
|
42
|
+
Returns:
|
43
|
+
VolumeResult: Value at that point
|
44
|
+
"""
|
45
|
+
output = VolumeResult()
|
46
|
+
output.value = np.linalg.norm(np.array([point.x, point.y, point.z])) # distance to origin
|
47
|
+
output.occupancy = float(output.value < 0.5)
|
48
|
+
# from https://plotly.com/python/3d-volume-plots/
|
49
|
+
output.interesting = np.sin(np.pi * point.x) * np.cos(np.pi * point.z) * np.sin(np.pi * point.y)
|
50
|
+
output.interesting_vec = [
|
51
|
+
np.sin(np.pi * point.x),
|
52
|
+
np.cos(np.pi * point.z),
|
53
|
+
np.sin(np.pi * point.y),
|
54
|
+
]
|
55
|
+
|
56
|
+
if output.occupancy:
|
57
|
+
output.interesting_vec_and_occ = output.interesting_vec
|
58
|
+
else:
|
59
|
+
output.interesting_vec_and_occ = [0, 0, 0]
|
60
|
+
|
61
|
+
return output
|
62
|
+
|
63
|
+
|
64
|
+
def example_floats3D(
|
65
|
+
run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
|
66
|
+
) -> bch.Bench:
|
67
|
+
"""Example of how to perform a 3D floating point parameter sweep
|
68
|
+
|
69
|
+
Args:
|
70
|
+
run_cfg (BenchRunCfg): configuration of how to perform the param sweep
|
71
|
+
|
72
|
+
Returns:
|
73
|
+
Bench: results of the parameter sweep
|
74
|
+
"""
|
75
|
+
bench = bch.Bench(
|
76
|
+
"Bencher_Example_Floats",
|
77
|
+
bench_fn,
|
78
|
+
VolumeSample,
|
79
|
+
run_cfg=run_cfg,
|
80
|
+
report=report,
|
81
|
+
)
|
82
|
+
|
83
|
+
bench.plot_sweep(
|
84
|
+
title="Float 3D Example",
|
85
|
+
input_vars=[VolumeSample.param.x, VolumeSample.param.y, VolumeSample.param.z],
|
86
|
+
result_vars=[
|
87
|
+
VolumeResult.param.value,
|
88
|
+
VolumeResult.param.occupancy,
|
89
|
+
VolumeResult.param.interesting,
|
90
|
+
],
|
91
|
+
description="""This example shows how to sample 3 floating point variables and plot a volumetric representation of the results. The benchmark function returns the distance to the origin""",
|
92
|
+
post_description="Here you can see concentric shells as the value of the function increases with distance from the origin. The occupancy graph should show a sphere with radius=0.5",
|
93
|
+
)
|
94
|
+
|
95
|
+
return bench
|
96
|
+
|
97
|
+
|
98
|
+
if __name__ == "__main__":
|
99
|
+
ex_run_cfg = bch.BenchRunCfg()
|
100
|
+
ex_run_cfg.level = 3
|
101
|
+
example_floats3D(ex_run_cfg).report.show()
|
@@ -0,0 +1,99 @@
|
|
1
|
+
"""Example of how to perform a parameter sweep for categorical variables"""
|
2
|
+
|
3
|
+
import bencher as bch
|
4
|
+
|
5
|
+
|
6
|
+
# All the examples will be using the data structures and benchmark function defined in this file
|
7
|
+
from bencher.example.benchmark_data import ExampleBenchCfgIn, ExampleBenchCfgOut, bench_function
|
8
|
+
|
9
|
+
|
10
|
+
def example_float_cat(
|
11
|
+
run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
|
12
|
+
) -> bch.Bench:
|
13
|
+
"""Example of how to perform a parameter sweep for categorical variables
|
14
|
+
|
15
|
+
Args:
|
16
|
+
run_cfg (BenchRunCfg): configuration of how to perform the param sweep
|
17
|
+
|
18
|
+
Returns:
|
19
|
+
Bench: results of the parameter sweep
|
20
|
+
"""
|
21
|
+
bench = bch.Bench(
|
22
|
+
"Bencher_Example_Float_Cat",
|
23
|
+
bench_function,
|
24
|
+
ExampleBenchCfgIn,
|
25
|
+
run_cfg=run_cfg,
|
26
|
+
report=report,
|
27
|
+
)
|
28
|
+
|
29
|
+
bench.plot_sweep(
|
30
|
+
input_vars=[
|
31
|
+
ExampleBenchCfgIn.param.theta,
|
32
|
+
ExampleBenchCfgIn.param.offset,
|
33
|
+
ExampleBenchCfgIn.param.postprocess_fn,
|
34
|
+
],
|
35
|
+
result_vars=[ExampleBenchCfgOut.param.out_sin],
|
36
|
+
const_vars=[ExampleBenchCfgIn.param.noisy.with_const(True)],
|
37
|
+
title="Float 2D Cat 1D Example",
|
38
|
+
description="""Following from the previous example lets add another input parameter to see how that affects the output. We pass the boolean 'noisy' and keep the other parameters the same""",
|
39
|
+
post_description="Now the plot has two lines, one for each of the boolean values where noisy=true and noisy=false.",
|
40
|
+
)
|
41
|
+
|
42
|
+
bench.plot_sweep(
|
43
|
+
input_vars=[ExampleBenchCfgIn.param.theta],
|
44
|
+
result_vars=[ExampleBenchCfgOut.param.out_sin],
|
45
|
+
const_vars=[ExampleBenchCfgIn.param.noisy.with_const(True)],
|
46
|
+
title="Float 1D Cat 1D Example",
|
47
|
+
description="""Following from the previous example lets add another input parameter to see how that affects the output. We pass the boolean 'noisy' and keep the other parameters the same""",
|
48
|
+
post_description="Now the plot has two lines, one for each of the boolean values where noisy=true and noisy=false.",
|
49
|
+
plot_callbacks=False,
|
50
|
+
)
|
51
|
+
|
52
|
+
# report.append(bench.get_result().to_curve())
|
53
|
+
|
54
|
+
# # this does not work yet because it tries to find min and max of categorical values
|
55
|
+
# bench.plot_sweep(
|
56
|
+
# input_vars=[ExampleBenchCfgIn.param.theta, ExampleBenchCfgIn.param.postprocess_fn],
|
57
|
+
# result_vars=[ExampleBenchCfgOut.param.out_sin],
|
58
|
+
# const_vars=[ExampleBenchCfgIn.param.noisy.with_const(True)],
|
59
|
+
# title="Float 1D Cat 1D Example",
|
60
|
+
# description="""Following from the previous example lets add another input parameter to see how that affects the output. We pass the boolean 'noisy' and keep the other parameters the same""",
|
61
|
+
# post_description="Now the plot has two lines, one for each of the boolean values where noisy=true and noisy=false.",
|
62
|
+
# run_cfg=run_cfg,
|
63
|
+
# )
|
64
|
+
|
65
|
+
return bench
|
66
|
+
|
67
|
+
|
68
|
+
def run_example_float_cat(ex_run_cfg=bch.BenchRunCfg()) -> None:
|
69
|
+
ex_run_cfg.repeats = 2
|
70
|
+
ex_run_cfg.over_time = True
|
71
|
+
ex_run_cfg.clear_cache = True
|
72
|
+
ex_run_cfg.clear_history = True
|
73
|
+
ex_run_cfg.level = 3
|
74
|
+
# ex_run_cfg.time_event = "run 1"
|
75
|
+
# ex_run_cfg.use_optuna = True
|
76
|
+
|
77
|
+
example_float_cat(ex_run_cfg)
|
78
|
+
|
79
|
+
# ex_run_cfg.repeats = 2
|
80
|
+
# ex_run_cfg.over_time = True
|
81
|
+
ex_run_cfg.clear_cache = False
|
82
|
+
ex_run_cfg.clear_history = False
|
83
|
+
# ex_run_cfg.time_event = "run 2"
|
84
|
+
# ex_run_cfg.use_optuna = True
|
85
|
+
|
86
|
+
# example_float_cat(ex_run_cfg)
|
87
|
+
|
88
|
+
# ex_run_cfg.clear_cache = False
|
89
|
+
# ex_run_cfg.clear_history = False
|
90
|
+
# ex_run_cfg.time_event = "run 2"
|
91
|
+
|
92
|
+
# example_float_cat(ex_run_cfg)
|
93
|
+
|
94
|
+
# ex_run_cfg.time_event = "run 3"
|
95
|
+
return example_float_cat(ex_run_cfg)
|
96
|
+
|
97
|
+
|
98
|
+
if __name__ == "__main__":
|
99
|
+
run_example_float_cat().report.show()
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# pylint: disable=duplicate-code
|
2
|
+
|
3
|
+
|
4
|
+
import bencher as bch
|
5
|
+
|
6
|
+
# All the examples will be using the data structures and benchmark function defined in this file
|
7
|
+
from bencher.example.benchmark_data import ExampleBenchCfgIn, ExampleBenchCfgOut, ExampleBenchCfg
|
8
|
+
|
9
|
+
|
10
|
+
def example_floats(
|
11
|
+
run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
|
12
|
+
) -> bch.Bench:
|
13
|
+
"""Example of how to perform a parameter sweep for floating point variables
|
14
|
+
|
15
|
+
Args:
|
16
|
+
run_cfg (BenchRunCfg): configuration of how to perform the param sweep
|
17
|
+
|
18
|
+
Returns:
|
19
|
+
Bench: results of the parameter sweep
|
20
|
+
"""
|
21
|
+
bench = bch.Bench("Bencher_Example_Floats", ExampleBenchCfg(), report=report, run_cfg=run_cfg)
|
22
|
+
|
23
|
+
with open("README.md", "r", encoding="utf-8") as file:
|
24
|
+
readme = file.read()
|
25
|
+
|
26
|
+
bench.report.append(readme, "Intro")
|
27
|
+
|
28
|
+
bench.plot_sweep(
|
29
|
+
input_vars=[ExampleBenchCfgIn.param.theta],
|
30
|
+
result_vars=[ExampleBenchCfgOut.param.out_sin],
|
31
|
+
title="Float 1D Example",
|
32
|
+
description="""Bencher is a tool to make it easy to explore how input parameter affect a range of output metrics. In these examples we are going to benchmark an example function which has been selected to show the features of bencher.
|
33
|
+
The example function takes an input theta and returns the absolute value of sin(theta) and cos(theta) +- various types of noise.
|
34
|
+
|
35
|
+
def bench_function(cfg: ExampleBenchCfgIn) -> ExampleBenchCfgOut:
|
36
|
+
"Takes an ExampleBenchCfgIn and returns a ExampleBenchCfgOut output"
|
37
|
+
out = ExampleBenchCfgOut()
|
38
|
+
noise = calculate_noise(cfg)
|
39
|
+
offset = 0.0
|
40
|
+
|
41
|
+
postprocess_fn = abs if cfg.postprocess_fn == PostprocessFn.absolute else negate_fn
|
42
|
+
|
43
|
+
out.out_sin = postprocess_fn(offset + math.sin(cfg.theta) + noise)
|
44
|
+
out.out_cos = postprocess_fn(offset + math.cos(cfg.theta) + noise)
|
45
|
+
return out
|
46
|
+
|
47
|
+
The following examples will show how to perform parameter sweeps to characterise the behavior of the function. The idea is that the benchmarking can be used to gain understanding of an unknown function.
|
48
|
+
""",
|
49
|
+
post_description="Here you can see the output plot of sin theta between 0 and pi. In the tabs at the top you can also view 3 tabular representations of the data",
|
50
|
+
)
|
51
|
+
|
52
|
+
bench.plot_sweep(
|
53
|
+
input_vars=[ExampleBenchCfgIn.param.theta, ExampleBenchCfgIn.param.noisy],
|
54
|
+
result_vars=[ExampleBenchCfgOut.param.out_sin],
|
55
|
+
title="Float 1D and Bool Example",
|
56
|
+
description="""Following from the previous example lets add another input parameter to see how that affects the output. We pass the boolean 'noisy' and keep the other parameters the same""",
|
57
|
+
post_description="Now the plot has two lines, one for each of the boolean values where noisy=true and noisy=false.",
|
58
|
+
)
|
59
|
+
|
60
|
+
bench.plot_sweep(
|
61
|
+
input_vars=[ExampleBenchCfgIn.param.theta, ExampleBenchCfgIn.param.noisy],
|
62
|
+
result_vars=[ExampleBenchCfgOut.param.out_sin, ExampleBenchCfgOut.param.out_cos],
|
63
|
+
title="Float 1D and Bool Example with multiple outputs",
|
64
|
+
description="""Following from the previous example here the second output is added to the result variables""",
|
65
|
+
post_description="Another column is added for the result variable that shows cos(theta)",
|
66
|
+
)
|
67
|
+
|
68
|
+
bench.plot_sweep(
|
69
|
+
input_vars=[
|
70
|
+
ExampleBenchCfgIn.param.theta,
|
71
|
+
ExampleBenchCfgIn.param.noisy,
|
72
|
+
ExampleBenchCfgIn.param.postprocess_fn,
|
73
|
+
],
|
74
|
+
result_vars=[
|
75
|
+
ExampleBenchCfgOut.param.out_sin,
|
76
|
+
ExampleBenchCfgOut.param.out_cos,
|
77
|
+
],
|
78
|
+
title="Float 1D, Bool and Categorical Example",
|
79
|
+
description="""Following from the previous example lets add another input parameter to see how that affects the output. We add the 'postprocess_fn' categorical enum value which either takes the absolute value or negates the output of the function.""",
|
80
|
+
post_description="This generates two rows of results, one for each of the category options.",
|
81
|
+
)
|
82
|
+
|
83
|
+
return bench
|
84
|
+
|
85
|
+
|
86
|
+
if __name__ == "__main__":
|
87
|
+
bench_ex = example_floats(bch.BenchRunCfg(repeats=2))
|
88
|
+
bench_ex.report.save_index()
|
89
|
+
bench_ex.report.show()
|