holobench 1.25.2__tar.gz → 1.27.0__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.27.0/MANIFEST.in +1 -0
- {holobench-1.25.2/holobench.egg-info → holobench-1.27.0}/PKG-INFO +5 -5
- {holobench-1.25.2 → holobench-1.27.0}/bencher/bench_report.py +6 -109
- holobench-1.27.0/bencher/example/__init__.py +0 -0
- holobench-1.27.0/bencher/example/benchmark_data.py +196 -0
- holobench-1.27.0/bencher/example/example_all.py +45 -0
- holobench-1.27.0/bencher/example/example_categorical.py +99 -0
- holobench-1.27.0/bencher/example/example_composable_container.py +106 -0
- holobench-1.27.0/bencher/example/example_composable_container2.py +160 -0
- holobench-1.27.0/bencher/example/example_consts.py +39 -0
- holobench-1.27.0/bencher/example/example_custom_sweep.py +59 -0
- holobench-1.27.0/bencher/example/example_custom_sweep2.py +42 -0
- holobench-1.27.0/bencher/example/example_docs.py +34 -0
- holobench-1.27.0/bencher/example/example_filepath.py +27 -0
- holobench-1.27.0/bencher/example/example_float3D.py +101 -0
- holobench-1.27.0/bencher/example/example_float_cat.py +99 -0
- holobench-1.27.0/bencher/example/example_floats.py +89 -0
- holobench-1.27.0/bencher/example/example_floats2D.py +93 -0
- holobench-1.27.0/bencher/example/example_holosweep.py +98 -0
- holobench-1.27.0/bencher/example/example_holosweep_objects.py +111 -0
- holobench-1.27.0/bencher/example/example_holosweep_tap.py +144 -0
- holobench-1.27.0/bencher/example/example_image.py +155 -0
- holobench-1.27.0/bencher/example/example_levels.py +181 -0
- holobench-1.27.0/bencher/example/example_levels2.py +37 -0
- holobench-1.27.0/bencher/example/example_pareto.py +53 -0
- holobench-1.27.0/bencher/example/example_sample_cache.py +85 -0
- holobench-1.27.0/bencher/example/example_sample_cache_context.py +116 -0
- holobench-1.27.0/bencher/example/example_simple.py +134 -0
- holobench-1.27.0/bencher/example/example_simple_bool.py +35 -0
- holobench-1.27.0/bencher/example/example_simple_cat.py +48 -0
- holobench-1.27.0/bencher/example/example_simple_float.py +28 -0
- holobench-1.27.0/bencher/example/example_simple_float2d.py +29 -0
- holobench-1.27.0/bencher/example/example_strings.py +47 -0
- holobench-1.27.0/bencher/example/example_time_event.py +63 -0
- holobench-1.27.0/bencher/example/example_video.py +118 -0
- holobench-1.27.0/bencher/example/example_workflow.py +189 -0
- holobench-1.27.0/bencher/example/experimental/example_bokeh_plotly.py +38 -0
- holobench-1.27.0/bencher/example/experimental/example_hover_ex.py +45 -0
- holobench-1.27.0/bencher/example/experimental/example_hvplot_explorer.py +39 -0
- holobench-1.27.0/bencher/example/experimental/example_interactive.py +75 -0
- holobench-1.27.0/bencher/example/experimental/example_streamnd.py +49 -0
- holobench-1.27.0/bencher/example/experimental/example_streams.py +36 -0
- holobench-1.27.0/bencher/example/experimental/example_template.py +40 -0
- holobench-1.27.0/bencher/example/experimental/example_updates.py +84 -0
- holobench-1.27.0/bencher/example/experimental/example_vector.py +84 -0
- holobench-1.27.0/bencher/example/meta/example_meta.py +171 -0
- holobench-1.27.0/bencher/example/meta/example_meta_cat.py +25 -0
- holobench-1.27.0/bencher/example/meta/example_meta_float.py +23 -0
- holobench-1.27.0/bencher/example/meta/example_meta_levels.py +26 -0
- holobench-1.27.0/bencher/example/optuna/example_optuna.py +78 -0
- holobench-1.27.0/bencher/example/shelved/example_float2D_scatter.py +109 -0
- holobench-1.27.0/bencher/example/shelved/example_float3D_cone.py +96 -0
- holobench-1.27.0/bencher/example/shelved/example_kwargs.py +63 -0
- holobench-1.27.0/bencher/plotting/__init__.py +0 -0
- holobench-1.27.0/bencher/plotting/plot_filter.py +110 -0
- holobench-1.27.0/bencher/plotting/plt_cnt_cfg.py +75 -0
- holobench-1.27.0/bencher/results/__init__.py +0 -0
- holobench-1.27.0/bencher/results/bench_result.py +94 -0
- holobench-1.27.0/bencher/results/bench_result_base.py +476 -0
- holobench-1.27.0/bencher/results/composable_container/__init__.py +0 -0
- holobench-1.27.0/bencher/results/composable_container/composable_container_base.py +73 -0
- holobench-1.27.0/bencher/results/composable_container/composable_container_panel.py +39 -0
- holobench-1.27.0/bencher/results/composable_container/composable_container_video.py +184 -0
- holobench-1.27.0/bencher/results/float_formatter.py +44 -0
- holobench-1.27.0/bencher/results/holoview_result.py +753 -0
- holobench-1.27.0/bencher/results/optuna_result.py +354 -0
- holobench-1.27.0/bencher/results/panel_result.py +41 -0
- holobench-1.27.0/bencher/results/plotly_result.py +65 -0
- holobench-1.27.0/bencher/results/video_result.py +38 -0
- holobench-1.27.0/bencher/results/video_summary.py +222 -0
- holobench-1.27.0/bencher/variables/__init__.py +0 -0
- holobench-1.27.0/bencher/variables/inputs.py +202 -0
- holobench-1.27.0/bencher/variables/parametrised_sweep.py +208 -0
- holobench-1.27.0/bencher/variables/results.py +214 -0
- holobench-1.27.0/bencher/variables/sweep_base.py +162 -0
- holobench-1.27.0/bencher/variables/time.py +92 -0
- {holobench-1.25.2 → holobench-1.27.0/holobench.egg-info}/PKG-INFO +5 -5
- holobench-1.27.0/holobench.egg-info/SOURCES.txt +122 -0
- holobench-1.27.0/holobench.egg-info/not-zip-safe +1 -0
- {holobench-1.25.2 → holobench-1.27.0}/holobench.egg-info/requires.txt +4 -4
- holobench-1.27.0/package.xml +33 -0
- {holobench-1.25.2 → holobench-1.27.0}/pyproject.toml +9 -17
- holobench-1.27.0/resource/bencher +0 -0
- holobench-1.27.0/setup.cfg +10 -0
- holobench-1.27.0/setup.py +18 -0
- holobench-1.25.2/holobench.egg-info/SOURCES.txt +0 -43
- holobench-1.25.2/setup.cfg +0 -4
- {holobench-1.25.2 → holobench-1.27.0}/LICENSE +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/README.md +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/bencher/__init__.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/bencher/bench_cfg.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/bencher/bench_plot_server.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/bencher/bench_runner.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/bencher/bencher.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/bencher/caching.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/bencher/class_enum.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/bencher/job.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/bencher/optuna_conversions.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/bencher/utils.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/bencher/video_writer.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/bencher/worker_job.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/holobench.egg-info/dependency_links.txt +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/holobench.egg-info/top_level.txt +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_bch_p.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_bench_examples.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_bench_report.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_bench_result_base.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_bench_runner.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_bencher.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_cache.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_class_enum.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_combinations.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_composable_container_base.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_composable_container_video.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_float_formatter.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_job.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_meta_tests.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_parametrized_sweep.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_plot_filter.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_plot_server.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_sample_cache.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_sweep_base.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_sweep_vars.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_utils.py +0 -0
- {holobench-1.25.2 → holobench-1.27.0}/test/test_vars.py +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
recursive-include bencher/ *.py
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: holobench
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.27.0
|
4
4
|
Summary: A package for benchmarking the performance of arbitrary functions
|
5
5
|
Author-email: Austin Gregg-Smith <blooop@gmail.com>
|
6
6
|
Project-URL: Repository, https://github.com/dyson-ai/bencher
|
@@ -8,7 +8,7 @@ Project-URL: Home, https://github.com/dyson-ai/bencher
|
|
8
8
|
Project-URL: Documentation, https://bencher.readthedocs.io/en/latest/
|
9
9
|
Description-Content-Type: text/markdown
|
10
10
|
License-File: LICENSE
|
11
|
-
Requires-Dist: holoviews<=1.
|
11
|
+
Requires-Dist: holoviews<=1.19.0,>=1.15
|
12
12
|
Requires-Dist: numpy<=1.26.4,>=1.0
|
13
13
|
Requires-Dist: param<=2.1.0,>=1.13.0
|
14
14
|
Requires-Dist: hvplot<=0.10.0,>=0.8
|
@@ -16,7 +16,7 @@ Requires-Dist: matplotlib<=3.9.0,>=3.6.3
|
|
16
16
|
Requires-Dist: panel<=1.4.4,>=1.3.6
|
17
17
|
Requires-Dist: diskcache<=5.6.3,>=5.6
|
18
18
|
Requires-Dist: optuna<=3.6.1,>=3.2
|
19
|
-
Requires-Dist: xarray<=2024.
|
19
|
+
Requires-Dist: xarray<=2024.6.0,>=2023.7
|
20
20
|
Requires-Dist: plotly<=5.22.0,>=5.15
|
21
21
|
Requires-Dist: sortedcontainers<=2.4,>=2.4
|
22
22
|
Requires-Dist: pandas<=2.2.2,>=2.0
|
@@ -30,8 +30,8 @@ Requires-Dist: black<=24.4.2,>=23; extra == "test"
|
|
30
30
|
Requires-Dist: pylint<=3.2.3,>=2.17.7; extra == "test"
|
31
31
|
Requires-Dist: pytest-cov<=5.0.0,>=4.1; extra == "test"
|
32
32
|
Requires-Dist: pytest<=8.2.2,>=7.4; extra == "test"
|
33
|
-
Requires-Dist: hypothesis<=6.103.
|
34
|
-
Requires-Dist: ruff<=0.4.
|
33
|
+
Requires-Dist: hypothesis<=6.103.2,>=6.82; extra == "test"
|
34
|
+
Requires-Dist: ruff<=0.4.9,>=0.0.280; extra == "test"
|
35
35
|
Requires-Dist: coverage<=7.5.3,>=7.2.7; extra == "test"
|
36
36
|
|
37
37
|
# Bencher
|
@@ -157,112 +157,9 @@ class BenchReport(BenchPlotServer):
|
|
157
157
|
|
158
158
|
return publish_url
|
159
159
|
|
160
|
-
|
161
|
-
# def
|
162
|
-
#
|
163
|
-
|
164
|
-
#
|
165
|
-
#
|
166
|
-
# # Don't pickle baz
|
167
|
-
# del state["pane"]
|
168
|
-
# return state
|
169
|
-
|
170
|
-
# def __setstate__(self, state):
|
171
|
-
# self.__dict__.update(state)
|
172
|
-
# # Add baz back since it doesn't exist in the pickle
|
173
|
-
# self.report = []
|
174
|
-
|
175
|
-
# def publish_old(
|
176
|
-
# self,
|
177
|
-
# directory: str = "bench_results",
|
178
|
-
# branch_name: str = "bench_results",
|
179
|
-
# url_postprocess: Callable = None,
|
180
|
-
# **kwargs,
|
181
|
-
# ) -> str:
|
182
|
-
# """Publish the results as an html file by committing it to the bench_results branch in the current repo. If you have set up your repo with github pages or equivalent then the html file will be served as a viewable webpage.
|
183
|
-
|
184
|
-
# Args:
|
185
|
-
# directory (str, optional): Directory to save the results. Defaults to "bench_results".
|
186
|
-
# branch_name (str, optional): Branch to publish on. Defaults to "bench_results".
|
187
|
-
# url_postprocess (Callable, optional): A function that maps the origin url to a github pages url. Pass your own function if you are using another git providers. Defaults to None.
|
188
|
-
|
189
|
-
# Returns:
|
190
|
-
# str: _description_
|
191
|
-
# """
|
192
|
-
|
193
|
-
# def get_output(cmd: str) -> str:
|
194
|
-
# return (
|
195
|
-
# subprocess.run(cmd.split(" "), stdout=subprocess.PIPE, check=False)
|
196
|
-
# .stdout.decode("utf=8")
|
197
|
-
# .strip()
|
198
|
-
# )
|
199
|
-
|
200
|
-
# def postprocess_url(publish_url: str, branch_name: str, report_path: str, **kwargs) -> str:
|
201
|
-
# # import re
|
202
|
-
|
203
|
-
# # return re.sub(
|
204
|
-
# # """((git|ssh|http(s)?)|(git@[\w\.-]+))(:(//)?)([\w\.@\:/\-~]+)(\.git)(/)?""",
|
205
|
-
# # """https://$7/""",
|
206
|
-
# # publish_url,
|
207
|
-
# # )
|
208
|
-
# # git@github.com:user/project.git
|
209
|
-
# # https://github.com/user/project.git
|
210
|
-
# # http://github.com/user/project.git
|
211
|
-
# # git@192.168.101.127:user/project.git
|
212
|
-
# # https://192.168.101.127/user/project.git
|
213
|
-
# # http://192.168.101.127/user/project.git
|
214
|
-
# # ssh://user@host.xz:port/path/to/repo.git/
|
215
|
-
# # ssh://user@host.xz/path/to/repo.git/
|
216
|
-
# # ssh://host.xz:port/path/to/repo.git/
|
217
|
-
# # ssh://host.xz/path/to/repo.git/
|
218
|
-
# # ssh://user@host.xz/path/to/repo.git/
|
219
|
-
# # ssh://host.xz/path/to/repo.git/
|
220
|
-
# # ssh://user@host.xz/~user/path/to/repo.git/
|
221
|
-
# # ssh://host.xz/~user/path/to/repo.git/
|
222
|
-
# # ssh://user@host.xz/~/path/to/repo.git
|
223
|
-
# # ssh://host.xz/~/path/to/repo.git
|
224
|
-
# # git://host.xz/path/to/repo.git/
|
225
|
-
# # git://host.xz/~user/path/to/repo.git/
|
226
|
-
# # http://host.xz/path/to/repo.git/
|
227
|
-
# # https://host.xz/path/to/repo.git/
|
228
|
-
# # https://regex101.com/r/qT7NP0/3
|
229
|
-
|
230
|
-
# return publish_url.replace(".git", f"/blob/{directory}/{report_path}")
|
231
|
-
|
232
|
-
# if url_postprocess is None:
|
233
|
-
# url_postprocess = postprocess_url
|
234
|
-
# current_branch = get_output("git symbolic-ref --short HEAD")
|
235
|
-
# logging.info(f"on branch: {current_branch}")
|
236
|
-
# stash_msg = get_output("git stash")
|
237
|
-
# logging.info(f"stashing current work :{stash_msg}")
|
238
|
-
# checkout_msg = get_output(f"git checkout -b {branch_name}")
|
239
|
-
# checkout_msg = get_output(f"git checkout {branch_name}")
|
240
|
-
# get_output("git pull")
|
241
|
-
|
242
|
-
# logging.info(f"checking out branch: {checkout_msg}")
|
243
|
-
# report_path = self.save(directory, in_html_folder=False)
|
244
|
-
# logging.info(f"created report at: {report_path.absolute()}")
|
245
|
-
# # commit_msg = f""
|
246
|
-
# logging.info("adding report to git")
|
247
|
-
# get_output(f"git add {report_path.absolute()}")
|
248
|
-
# get_output("git status")
|
249
|
-
# logging.info("committing report")
|
250
|
-
# cmd = f'git commit -m "generate_report:{self.bench_name}"'
|
251
|
-
# logging.info(cmd)
|
252
|
-
# get_output(cmd)
|
253
|
-
# logging.info("pushing report to origin")
|
254
|
-
# get_output(f"git push --set-upstream origin {branch_name}")
|
255
|
-
# logging.info("checking out original branch")
|
256
|
-
# get_output(f"git checkout {current_branch}")
|
257
|
-
# if "No local changes" not in stash_msg:
|
258
|
-
# logging.info("restoring work with git stash pop")
|
259
|
-
# get_output("git stash pop")
|
260
|
-
|
261
|
-
# publish_url = get_output("git remote get-url --push origin")
|
262
|
-
# logging.info(f"raw url:{publish_url}")
|
263
|
-
# publish_url = url_postprocess(
|
264
|
-
# publish_url, branch_name=branch_name, report_path=report_path, **kwargs
|
265
|
-
# )
|
266
|
-
# logging.info("Published report @")
|
267
|
-
# logging.info(publish_url)
|
268
|
-
# return publish_url
|
160
|
+
# @staticmethod
|
161
|
+
# def publish_github(github_user: str, repo_name: str, branch_name: str) -> Tuple[str, str]:
|
162
|
+
# return (
|
163
|
+
# f"https://github.com/{github_user}/{repo_name}.git",
|
164
|
+
# f"https://github.com/{github_user}/{repo_name}/blob/{branch_name}",
|
165
|
+
# )
|
File without changes
|
@@ -0,0 +1,196 @@
|
|
1
|
+
"""This file contains an example of how to define benchmarking parameters sweeps. Categorical values are defined as enums and passed to EnumSweep classes, other types of sweeps are defined by their respective classes.
|
2
|
+
|
3
|
+
You can define a subclass which contains an input configuration which can be passed to a function in a type safe way. You can combine the subclass with a higher level class which contains more configuation parameters. This is to help manage the complexity of large configuration/parameter spaces.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import math
|
7
|
+
import random
|
8
|
+
from enum import auto
|
9
|
+
from strenum import StrEnum
|
10
|
+
from bencher.variables.inputs import IntSweep, FloatSweep, StringSweep, EnumSweep, BoolSweep
|
11
|
+
from bencher.variables.results import ResultVar, OptDir
|
12
|
+
from bencher.variables.parametrised_sweep import ParametrizedSweep
|
13
|
+
|
14
|
+
|
15
|
+
class PostprocessFn(StrEnum):
|
16
|
+
"""Apply a postprocessing step to the data"""
|
17
|
+
|
18
|
+
absolute = auto() # return the abs of the output data
|
19
|
+
negate = auto() # return the negative of the output data
|
20
|
+
|
21
|
+
|
22
|
+
class NoiseDistribution(StrEnum):
|
23
|
+
"""A categorical variable describing the types of random noise"""
|
24
|
+
|
25
|
+
uniform = auto() # uniform random noiase
|
26
|
+
gaussian = auto() # gaussian noise
|
27
|
+
lognorm = auto() # lognorm noise
|
28
|
+
|
29
|
+
|
30
|
+
class NoiseCfg(ParametrizedSweep):
|
31
|
+
"""A class for storing the parameters for generating various types of noise"""
|
32
|
+
|
33
|
+
noisy = BoolSweep(
|
34
|
+
default=False, doc="Optionally add random noise to the output of the function"
|
35
|
+
)
|
36
|
+
|
37
|
+
noise_distribution = EnumSweep(NoiseDistribution, doc=NoiseDistribution.__doc__)
|
38
|
+
|
39
|
+
sigma = FloatSweep(
|
40
|
+
default=1,
|
41
|
+
bounds=[0, 10],
|
42
|
+
doc="The standard deviation of the noise",
|
43
|
+
units="v",
|
44
|
+
)
|
45
|
+
|
46
|
+
|
47
|
+
def calculate_noise(config: NoiseCfg) -> float:
|
48
|
+
"""Generate a float value based on a noise distribution and scale
|
49
|
+
|
50
|
+
Args:
|
51
|
+
config (NoiseCfg): see NoiseCfg type
|
52
|
+
|
53
|
+
Returns:
|
54
|
+
float: a noisy float value
|
55
|
+
"""
|
56
|
+
|
57
|
+
noise = 0.0
|
58
|
+
if config.noisy:
|
59
|
+
match config.noise_distribution:
|
60
|
+
case NoiseDistribution.uniform:
|
61
|
+
noise = random.uniform(0, config.sigma)
|
62
|
+
case NoiseDistribution.gaussian:
|
63
|
+
noise = random.gauss(0, config.sigma)
|
64
|
+
case NoiseDistribution.lognorm:
|
65
|
+
noise = random.lognormvariate(0, config.sigma)
|
66
|
+
|
67
|
+
return noise
|
68
|
+
|
69
|
+
|
70
|
+
class ExampleBenchCfgIn(NoiseCfg):
|
71
|
+
"""A class for representing a set of configuration options for the example worker. This class inherits from NoiseCfg so it also stores all its values as well."""
|
72
|
+
|
73
|
+
theta = FloatSweep(default=0, bounds=[0, math.pi], doc="Input angle", units="rad", samples=30)
|
74
|
+
offset = FloatSweep(default=0, bounds=[0, 0.3], doc="dc offset", units="v", samples=30)
|
75
|
+
postprocess_fn = EnumSweep(PostprocessFn)
|
76
|
+
|
77
|
+
|
78
|
+
class ExampleBenchCfgOut(ParametrizedSweep):
|
79
|
+
out_sin = ResultVar(units="v", direction=OptDir.minimize, doc="sin of theta with some noise")
|
80
|
+
out_cos = ResultVar(units="v", direction=OptDir.minimize, doc="cos of theta with some noise")
|
81
|
+
out_bool = ResultVar(units="%", doc="sin > 0.5")
|
82
|
+
|
83
|
+
|
84
|
+
def negate_fn(fn_input: float):
|
85
|
+
"""returns the negative of the input
|
86
|
+
|
87
|
+
Args:
|
88
|
+
fn_input (float): any float value
|
89
|
+
|
90
|
+
Returns:
|
91
|
+
float: negative of the input
|
92
|
+
"""
|
93
|
+
return -fn_input
|
94
|
+
|
95
|
+
|
96
|
+
def bench_function(cfg: ExampleBenchCfgIn) -> ExampleBenchCfgOut:
|
97
|
+
"""Takes an ExampleBenchCfgIn and returns a ExampleBenchCfgOut output"""
|
98
|
+
out = ExampleBenchCfgOut()
|
99
|
+
noise = calculate_noise(cfg)
|
100
|
+
|
101
|
+
postprocess_fn = abs if cfg.postprocess_fn == PostprocessFn.absolute else negate_fn
|
102
|
+
|
103
|
+
out.out_sin = postprocess_fn(cfg.offset + math.sin(cfg.theta) + noise)
|
104
|
+
out.out_cos = postprocess_fn(cfg.offset + math.cos(cfg.theta) + noise)
|
105
|
+
|
106
|
+
out.out_bool = out.out_sin > 0.5
|
107
|
+
return out
|
108
|
+
|
109
|
+
|
110
|
+
class ExampleBenchCfg(ParametrizedSweep):
|
111
|
+
theta = FloatSweep(default=0, bounds=[0, math.pi], doc="Input angle", units="rad", samples=30)
|
112
|
+
offset = FloatSweep(default=0, bounds=[0, 0.3], doc="dc offset", units="v", samples=30)
|
113
|
+
postprocess_fn = EnumSweep(PostprocessFn)
|
114
|
+
|
115
|
+
noisy = BoolSweep(
|
116
|
+
default=False, doc="Optionally add random noise to the output of the function"
|
117
|
+
)
|
118
|
+
noise_distribution = EnumSweep(NoiseDistribution, doc=NoiseDistribution.__doc__)
|
119
|
+
sigma = FloatSweep(
|
120
|
+
default=1,
|
121
|
+
bounds=[0, 10],
|
122
|
+
doc="The standard deviation of the noise",
|
123
|
+
units="v",
|
124
|
+
)
|
125
|
+
|
126
|
+
out_sin = ResultVar(units="v", direction=OptDir.minimize, doc="sin of theta with some noise")
|
127
|
+
out_cos = ResultVar(units="v", direction=OptDir.minimize, doc="cos of theta with some noise")
|
128
|
+
out_bool = ResultVar(units="%", doc="sin > 0.5")
|
129
|
+
|
130
|
+
def __call__(self, **kwwargs) -> dict:
|
131
|
+
self.update_params_from_kwargs(**kwwargs)
|
132
|
+
|
133
|
+
noise = self.calculate_noise()
|
134
|
+
postprocess_fn = abs if self.postprocess_fn == PostprocessFn.absolute else negate_fn
|
135
|
+
|
136
|
+
self.out_sin = postprocess_fn(self.offset + math.sin(self.theta) + noise)
|
137
|
+
self.out_cos = postprocess_fn(self.offset + math.cos(self.theta) + noise)
|
138
|
+
self.out_bool = self.out_sin > 0.5
|
139
|
+
return self.get_results_values_as_dict()
|
140
|
+
|
141
|
+
def calculate_noise(self):
|
142
|
+
noise = 0.0
|
143
|
+
if self.noisy:
|
144
|
+
match self.noise_distribution:
|
145
|
+
case NoiseDistribution.uniform:
|
146
|
+
noise = random.uniform(0, self.sigma)
|
147
|
+
case NoiseDistribution.gaussian:
|
148
|
+
noise = random.gauss(0, self.sigma)
|
149
|
+
case NoiseDistribution.lognorm:
|
150
|
+
noise = random.lognormvariate(0, self.sigma)
|
151
|
+
|
152
|
+
return noise
|
153
|
+
|
154
|
+
|
155
|
+
def call(**kwargs) -> dict:
|
156
|
+
return ExampleBenchCfg().__call__(**kwargs)
|
157
|
+
|
158
|
+
|
159
|
+
class AllSweepVars(ParametrizedSweep):
|
160
|
+
"""A class containing all the sweep types, This class is used for unit testing how the configuration classes are serialised and hashed"""
|
161
|
+
|
162
|
+
var_float = FloatSweep(default=5, bounds=(0, 10), units="m/s")
|
163
|
+
var_int = IntSweep(default=3, bounds=[0, 4])
|
164
|
+
var_int_big = IntSweep(default=0, bounds=[0, 100], samples=3)
|
165
|
+
var_bool = BoolSweep()
|
166
|
+
var_string = StringSweep(["string1", "string2"])
|
167
|
+
var_enum = EnumSweep(PostprocessFn)
|
168
|
+
|
169
|
+
result = ResultVar()
|
170
|
+
|
171
|
+
def __call__(self, **kwargs) -> dict:
|
172
|
+
self.update_params_from_kwargs(**kwargs)
|
173
|
+
self.result = self.var_float + self.var_int
|
174
|
+
return self.get_results_values_as_dict()
|
175
|
+
|
176
|
+
|
177
|
+
class SimpleBenchClass(ParametrizedSweep):
|
178
|
+
var1 = IntSweep(default=0, bounds=[0, 2])
|
179
|
+
|
180
|
+
result = ResultVar()
|
181
|
+
|
182
|
+
def __call__(self, **kwargs) -> dict:
|
183
|
+
self.update_params_from_kwargs(**kwargs)
|
184
|
+
self.result = self.var1
|
185
|
+
return self.get_results_values_as_dict()
|
186
|
+
|
187
|
+
|
188
|
+
class SimpleBenchClassFloat(ParametrizedSweep):
|
189
|
+
var1 = FloatSweep(bounds=[0, 100])
|
190
|
+
|
191
|
+
result = ResultVar()
|
192
|
+
|
193
|
+
def __call__(self, **kwargs) -> dict:
|
194
|
+
self.update_params_from_kwargs(**kwargs)
|
195
|
+
self.result = self.var1
|
196
|
+
return self.get_results_values_as_dict()
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
|
3
|
+
from bencher.example.example_categorical import example_categorical
|
4
|
+
from bencher.example.example_floats import example_floats
|
5
|
+
from bencher.example.example_floats2D import example_floats2D
|
6
|
+
from bencher.example.example_pareto import example_pareto
|
7
|
+
from bencher.example.example_simple_cat import example_1D_cat
|
8
|
+
from bencher.example.example_simple_float import example_1D_float
|
9
|
+
from bencher.example.example_float_cat import example_float_cat
|
10
|
+
from bencher.example.example_time_event import example_time_event
|
11
|
+
from bencher.example.example_float3D import example_floats3D
|
12
|
+
|
13
|
+
from bencher.example.example_custom_sweep import example_custom_sweep
|
14
|
+
from bencher.example.example_holosweep import example_holosweep
|
15
|
+
from bencher.example.example_holosweep_tap import example_holosweep_tap
|
16
|
+
|
17
|
+
from bencher.example.optuna.example_optuna import optuna_rastrigin
|
18
|
+
from bencher.example.example_sample_cache import example_sample_cache
|
19
|
+
|
20
|
+
# from bencher.example.example_workflow import example_floats2D_workflow, example_floats3D_workflow
|
21
|
+
|
22
|
+
|
23
|
+
if __name__ == "__main__":
|
24
|
+
run_cfg = bch.BenchRunCfg()
|
25
|
+
run_cfg.overwrite_sample_cache = True
|
26
|
+
bench_runner = bch.BenchRunner("bencher_examples", run_cfg=run_cfg)
|
27
|
+
|
28
|
+
bench_runner.add_run(example_categorical)
|
29
|
+
bench_runner.add_run(example_floats)
|
30
|
+
bench_runner.add_run(example_floats2D)
|
31
|
+
bench_runner.add_run(example_floats3D)
|
32
|
+
bench_runner.add_run(example_1D_cat)
|
33
|
+
bench_runner.add_run(example_1D_float)
|
34
|
+
bench_runner.add_run(example_pareto)
|
35
|
+
bench_runner.add_run(example_float_cat)
|
36
|
+
bench_runner.add_run(example_time_event)
|
37
|
+
bench_runner.add_run(example_custom_sweep)
|
38
|
+
bench_runner.add_run(example_holosweep)
|
39
|
+
bench_runner.add_run(example_holosweep_tap)
|
40
|
+
bench_runner.add_run(optuna_rastrigin)
|
41
|
+
bench_runner.add_run(example_sample_cache)
|
42
|
+
|
43
|
+
# bench_runner.run(level=2, show=True, grouped=True)
|
44
|
+
|
45
|
+
bench_runner.run(level=4, show=True, grouped=True, save=False)
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# pylint: disable=duplicate-code
|
2
|
+
|
3
|
+
import bencher as bch
|
4
|
+
|
5
|
+
# All the examples will be using the data structures and benchmark function defined in this file
|
6
|
+
from bencher.example.benchmark_data import ExampleBenchCfgIn, ExampleBenchCfgOut, bench_function
|
7
|
+
|
8
|
+
|
9
|
+
def example_categorical(
|
10
|
+
run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
|
11
|
+
) -> bch.Bench:
|
12
|
+
"""Example of how to perform a categorical parameter sweep
|
13
|
+
|
14
|
+
Args:
|
15
|
+
run_cfg (BenchRunCfg): configuration of how to perform the param sweep
|
16
|
+
|
17
|
+
Returns:
|
18
|
+
Bench: results of the parameter sweep
|
19
|
+
"""
|
20
|
+
|
21
|
+
with open("README.md", "r", encoding="utf-8") as file:
|
22
|
+
readme = file.read()
|
23
|
+
|
24
|
+
# run_cfg.over_time = True
|
25
|
+
|
26
|
+
bench = bch.Bench(
|
27
|
+
"Bencher_Example_Categorical",
|
28
|
+
bench_function,
|
29
|
+
ExampleBenchCfgIn,
|
30
|
+
run_cfg=run_cfg,
|
31
|
+
report=report,
|
32
|
+
)
|
33
|
+
|
34
|
+
bench.report.append(readme, "Intro")
|
35
|
+
|
36
|
+
bench.plot_sweep(
|
37
|
+
input_vars=[ExampleBenchCfgIn.param.noisy],
|
38
|
+
result_vars=[ExampleBenchCfgOut.param.out_sin],
|
39
|
+
title="Categorical 1D Example",
|
40
|
+
description="""This example shows how to sample categorical values. The same objective from the float examples is used but theta is kept constant with a value of 0 (as described in the ExampleBenchCfgIn class definition).
|
41
|
+
|
42
|
+
|
43
|
+
```
|
44
|
+
def bench_function(cfg: ExampleBenchCfgIn) -> ExampleBenchCfgOut:
|
45
|
+
"Takes an ExampleBenchCfgIn and returns a ExampleBenchCfgOut output"
|
46
|
+
out = ExampleBenchCfgOut()
|
47
|
+
noise = calculate_noise(cfg)
|
48
|
+
offset = 0.0
|
49
|
+
|
50
|
+
postprocess_fn = abs if cfg.postprocess_fn == PostprocessFn.absolute else negate_fn
|
51
|
+
|
52
|
+
out.out_sin = postprocess_fn(offset + math.sin(cfg.theta) + noise)
|
53
|
+
return out
|
54
|
+
```
|
55
|
+
|
56
|
+
""",
|
57
|
+
post_description="The plot shows when noise=True the output has uniform random noise.",
|
58
|
+
)
|
59
|
+
|
60
|
+
bench.plot_sweep(
|
61
|
+
input_vars=[ExampleBenchCfgIn.param.noisy, ExampleBenchCfgIn.param.noise_distribution],
|
62
|
+
result_vars=[ExampleBenchCfgOut.param.out_sin],
|
63
|
+
title="Categorical 2D Example",
|
64
|
+
description="""Adding another categorical value creates a facet plot over that dimension""",
|
65
|
+
post_description="The output shows swarm plots of different noise distributions",
|
66
|
+
)
|
67
|
+
|
68
|
+
bench.plot_sweep(
|
69
|
+
input_vars=[
|
70
|
+
ExampleBenchCfgIn.param.noisy,
|
71
|
+
ExampleBenchCfgIn.param.noise_distribution,
|
72
|
+
ExampleBenchCfgIn.param.postprocess_fn,
|
73
|
+
],
|
74
|
+
result_vars=[ExampleBenchCfgOut.param.out_sin],
|
75
|
+
title="Categorical 3D Example",
|
76
|
+
description="""Adding another categorical value extends the facets to the right""",
|
77
|
+
post_description="The output shows swarm plots of different noise distributions",
|
78
|
+
)
|
79
|
+
|
80
|
+
run_cfg.over_time = True
|
81
|
+
bench.plot_sweep(
|
82
|
+
input_vars=[
|
83
|
+
ExampleBenchCfgIn.param.noisy,
|
84
|
+
ExampleBenchCfgIn.param.noise_distribution,
|
85
|
+
ExampleBenchCfgIn.param.postprocess_fn,
|
86
|
+
],
|
87
|
+
title="Categorical 3D Example Over Time",
|
88
|
+
result_vars=[ExampleBenchCfgOut.param.out_sin],
|
89
|
+
description="""Lastly, what if you want to track these distributions over time? Set over_time=True and bencher will cache and display historical resuts alongside the latest result. Use clear_history=True to clear that cache.""",
|
90
|
+
post_description="The output shows faceted line plot with confidence intervals for the mean value over time.",
|
91
|
+
run_cfg=run_cfg,
|
92
|
+
)
|
93
|
+
|
94
|
+
return bench
|
95
|
+
|
96
|
+
|
97
|
+
if __name__ == "__main__":
|
98
|
+
ex_run_cfg = bch.BenchRunCfg()
|
99
|
+
example_categorical(ex_run_cfg).report.show()
|
@@ -0,0 +1,106 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
|
3
|
+
from bencher.example.example_image import BenchPolygons
|
4
|
+
|
5
|
+
|
6
|
+
class BenchComposableContainerImage(BenchPolygons):
|
7
|
+
compose_method = bch.EnumSweep(bch.ComposeType)
|
8
|
+
labels = bch.BoolSweep()
|
9
|
+
num_frames = bch.IntSweep(default=5, bounds=[1, 100])
|
10
|
+
polygon_vid = bch.ResultVideo()
|
11
|
+
|
12
|
+
def __call__(self, **kwargs):
|
13
|
+
self.update_params_from_kwargs(**kwargs)
|
14
|
+
var_name = None
|
15
|
+
var_value = None
|
16
|
+
|
17
|
+
if self.labels:
|
18
|
+
var_name = "sides"
|
19
|
+
var_value = self.sides
|
20
|
+
vr = bch.ComposableContainerVideo()
|
21
|
+
for i in range(self.num_frames):
|
22
|
+
res = super().__call__(start_angle=i)
|
23
|
+
print(res)
|
24
|
+
vr.append(res["polygon"])
|
25
|
+
self.polygon_vid = vr.to_video(
|
26
|
+
bch.RenderCfg(
|
27
|
+
compose_method=self.compose_method,
|
28
|
+
var_name=var_name,
|
29
|
+
var_value=var_value,
|
30
|
+
max_frame_duration=1.0 / 20.0,
|
31
|
+
)
|
32
|
+
)
|
33
|
+
return self.get_results_values_as_dict()
|
34
|
+
|
35
|
+
|
36
|
+
class BenchComposableContainerVideo(bch.ParametrizedSweep):
|
37
|
+
unequal_length = bch.BoolSweep()
|
38
|
+
compose_method = bch.EnumSweep(bch.ComposeType)
|
39
|
+
labels = bch.BoolSweep()
|
40
|
+
polygon_vid = bch.ResultVideo()
|
41
|
+
|
42
|
+
def __call__(self, **kwargs):
|
43
|
+
self.update_params_from_kwargs(**kwargs)
|
44
|
+
vr = bch.ComposableContainerVideo()
|
45
|
+
for i in range(3, 5):
|
46
|
+
num_frames = i * 10 if self.unequal_length else 5
|
47
|
+
res = BenchComposableContainerImage().__call__(
|
48
|
+
compose_method=bch.ComposeType.sequence, sides=i, num_frames=num_frames
|
49
|
+
)
|
50
|
+
vr.append(res["polygon_vid"])
|
51
|
+
|
52
|
+
self.polygon_vid = vr.to_video(bch.RenderCfg(compose_method=kwargs.get("compose_method")))
|
53
|
+
return self.get_results_values_as_dict()
|
54
|
+
|
55
|
+
|
56
|
+
def example_composable_container_image(
|
57
|
+
run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
|
58
|
+
) -> bch.Bench:
|
59
|
+
bench = BenchComposableContainerImage().to_bench(run_cfg, report)
|
60
|
+
bench.result_vars = ["polygon_vid"]
|
61
|
+
# bench.add_plot_callback(bch.BenchResult.to_panes)
|
62
|
+
# bench.add_plot_callback(bch.BenchResult.to_video_grid, result_types=(bch.ResultVideo))
|
63
|
+
# bench.add_plot_callback(bch.BenchResult.to_video_summary, result_types=(bch.ResultVideo))
|
64
|
+
# bench.plot_sweep(input_vars=["compose_method", "labels"])
|
65
|
+
|
66
|
+
bench.plot_sweep(input_vars=["compose_method"])
|
67
|
+
|
68
|
+
# bench.compose_
|
69
|
+
# bench.plot_sweep(
|
70
|
+
# input_vars=[bch.p("num_frames", [2, 8, 20])],
|
71
|
+
# const_vars=dict(compose_method=bch.ComposeType.sequence),
|
72
|
+
# )
|
73
|
+
|
74
|
+
return bench
|
75
|
+
|
76
|
+
|
77
|
+
def example_composable_container_video(
|
78
|
+
run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
|
79
|
+
) -> bch.Bench:
|
80
|
+
bench = BenchComposableContainerVideo().to_bench(run_cfg, report)
|
81
|
+
|
82
|
+
bench.result_vars = ["polygon_vid"]
|
83
|
+
bench.add_plot_callback(bch.BenchResult.to_panes)
|
84
|
+
bench.add_plot_callback(bch.BenchResult.to_video_grid, result_types=(bch.ResultVideo))
|
85
|
+
bench.add_plot_callback(bch.BenchResult.to_video_summary, result_types=(bch.ResultVideo))
|
86
|
+
bench.plot_sweep(input_vars=["compose_method", "labels"], const_vars=dict(unequal_length=True))
|
87
|
+
|
88
|
+
res = bench.plot_sweep(
|
89
|
+
input_vars=[],
|
90
|
+
const_vars=dict(unequal_length=False, compose_method=bch.ComposeType.sequence),
|
91
|
+
plot_callbacks=False,
|
92
|
+
)
|
93
|
+
|
94
|
+
bench.report.append(res.to_video_grid())
|
95
|
+
|
96
|
+
return bench
|
97
|
+
|
98
|
+
|
99
|
+
if __name__ == "__main__":
|
100
|
+
ex_run_cfg = bch.BenchRunCfg()
|
101
|
+
ex_run_cfg.use_sample_cache = False
|
102
|
+
# ex_run_cfg.level = 2
|
103
|
+
ex_report = bch.BenchReport()
|
104
|
+
example_composable_container_image(ex_run_cfg, report=ex_report)
|
105
|
+
# example_composable_container_video(ex_run_cfg, report=ex_report)
|
106
|
+
ex_report.show()
|