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.
Files changed (81) hide show
  1. bencher/example/benchmark_data.py +196 -0
  2. bencher/example/example_all.py +45 -0
  3. bencher/example/example_categorical.py +99 -0
  4. bencher/example/example_composable_container.py +106 -0
  5. bencher/example/example_composable_container2.py +160 -0
  6. bencher/example/example_consts.py +39 -0
  7. bencher/example/example_custom_sweep.py +59 -0
  8. bencher/example/example_custom_sweep2.py +42 -0
  9. bencher/example/example_docs.py +34 -0
  10. bencher/example/example_filepath.py +27 -0
  11. bencher/example/example_float3D.py +101 -0
  12. bencher/example/example_float_cat.py +99 -0
  13. bencher/example/example_floats.py +89 -0
  14. bencher/example/example_floats2D.py +93 -0
  15. bencher/example/example_holosweep.py +98 -0
  16. bencher/example/example_holosweep_objects.py +111 -0
  17. bencher/example/example_holosweep_tap.py +144 -0
  18. bencher/example/example_image.py +155 -0
  19. bencher/example/example_levels.py +181 -0
  20. bencher/example/example_levels2.py +37 -0
  21. bencher/example/example_pareto.py +53 -0
  22. bencher/example/example_sample_cache.py +85 -0
  23. bencher/example/example_sample_cache_context.py +116 -0
  24. bencher/example/example_simple.py +134 -0
  25. bencher/example/example_simple_bool.py +35 -0
  26. bencher/example/example_simple_cat.py +48 -0
  27. bencher/example/example_simple_float.py +28 -0
  28. bencher/example/example_simple_float2d.py +29 -0
  29. bencher/example/example_strings.py +47 -0
  30. bencher/example/example_time_event.py +63 -0
  31. bencher/example/example_video.py +118 -0
  32. bencher/example/example_workflow.py +189 -0
  33. bencher/example/experimental/example_bokeh_plotly.py +38 -0
  34. bencher/example/experimental/example_hover_ex.py +45 -0
  35. bencher/example/experimental/example_hvplot_explorer.py +39 -0
  36. bencher/example/experimental/example_interactive.py +75 -0
  37. bencher/example/experimental/example_streamnd.py +49 -0
  38. bencher/example/experimental/example_streams.py +36 -0
  39. bencher/example/experimental/example_template.py +40 -0
  40. bencher/example/experimental/example_updates.py +84 -0
  41. bencher/example/experimental/example_vector.py +84 -0
  42. bencher/example/meta/example_meta.py +171 -0
  43. bencher/example/meta/example_meta_cat.py +25 -0
  44. bencher/example/meta/example_meta_float.py +23 -0
  45. bencher/example/meta/example_meta_levels.py +26 -0
  46. bencher/example/optuna/example_optuna.py +78 -0
  47. bencher/example/shelved/example_float2D_scatter.py +109 -0
  48. bencher/example/shelved/example_float3D_cone.py +96 -0
  49. bencher/example/shelved/example_kwargs.py +63 -0
  50. bencher/plotting/__init__.py +0 -0
  51. bencher/plotting/plot_filter.py +110 -0
  52. bencher/plotting/plt_cnt_cfg.py +75 -0
  53. bencher/results/__init__.py +0 -0
  54. bencher/results/bench_result.py +94 -0
  55. bencher/results/bench_result_base.py +476 -0
  56. bencher/results/composable_container/__init__.py +0 -0
  57. bencher/results/composable_container/composable_container_base.py +73 -0
  58. bencher/results/composable_container/composable_container_panel.py +39 -0
  59. bencher/results/composable_container/composable_container_video.py +184 -0
  60. bencher/results/float_formatter.py +44 -0
  61. bencher/results/holoview_result.py +753 -0
  62. bencher/results/optuna_result.py +354 -0
  63. bencher/results/panel_result.py +41 -0
  64. bencher/results/plotly_result.py +65 -0
  65. bencher/results/video_result.py +38 -0
  66. bencher/results/video_summary.py +222 -0
  67. bencher/variables/__init__.py +0 -0
  68. bencher/variables/inputs.py +202 -0
  69. bencher/variables/parametrised_sweep.py +208 -0
  70. bencher/variables/results.py +214 -0
  71. bencher/variables/sweep_base.py +162 -0
  72. bencher/variables/time.py +92 -0
  73. holobench-1.26.3.data/data/share/ament_index/resource_index/packages/bencher +0 -0
  74. {holobench-1.25.1.dist-info → holobench-1.26.3.dist-info}/METADATA +5 -7
  75. holobench-1.26.3.dist-info/RECORD +93 -0
  76. holobench-1.25.1.dist-info/RECORD +0 -20
  77. /holobench-1.25.1.data/data/share/ament_index/resource_index/packages/bencher → /bencher/example/__init__.py +0 -0
  78. {holobench-1.25.1.data → holobench-1.26.3.data}/data/share/bencher/package.xml +0 -0
  79. {holobench-1.25.1.dist-info → holobench-1.26.3.dist-info}/LICENSE +0 -0
  80. {holobench-1.25.1.dist-info → holobench-1.26.3.dist-info}/WHEEL +0 -0
  81. {holobench-1.25.1.dist-info → holobench-1.26.3.dist-info}/top_level.txt +0 -0
@@ -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()
@@ -0,0 +1,93 @@
1
+ # pylint: disable=duplicate-code
2
+ import bencher as bch
3
+
4
+ # All the examples will be using the data structures and benchmark function defined in this file
5
+ from bencher.example.benchmark_data import (
6
+ ExampleBenchCfgOut,
7
+ NoiseDistribution,
8
+ ExampleBenchCfg,
9
+ call,
10
+ )
11
+
12
+
13
+ def example_floats2D(
14
+ run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
15
+ ) -> bch.Bench:
16
+ """Example of how to perform a 2D floating point parameter sweep
17
+
18
+ Args:
19
+ run_cfg (BenchRunCfg): configuration of how to perform the param sweep
20
+
21
+ Returns:
22
+ Bench: results of the parameter sweep
23
+ """
24
+ bench = bch.Bench(
25
+ "Bencher_Example_Floats",
26
+ call,
27
+ run_cfg=run_cfg,
28
+ report=report,
29
+ )
30
+ run_cfg.use_optuna = True
31
+
32
+ bench.plot_sweep(
33
+ input_vars=[ExampleBenchCfg.param.theta, ExampleBenchCfg.param.offset],
34
+ result_vars=[ExampleBenchCfgOut.param.out_sin, ExampleBenchCfgOut.param.out_cos],
35
+ const_vars=[
36
+ ExampleBenchCfg.param.sigma.with_const(0.1),
37
+ ExampleBenchCfg.param.noise_distribution.with_const(NoiseDistribution.gaussian),
38
+ ExampleBenchCfg.param.noisy.with_const(True),
39
+ ],
40
+ title="Float 2D Example",
41
+ 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.
42
+ The example function takes an input theta and returns the absolute value of sin(theta) and cos(theta) +- various types of noise.
43
+
44
+ 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.
45
+ """,
46
+ 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",
47
+ )
48
+
49
+ bench.report.append(bench.get_result().to_surface())
50
+
51
+ bench.plot_sweep(
52
+ input_vars=[
53
+ ExampleBenchCfg.param.theta,
54
+ ExampleBenchCfg.param.offset,
55
+ ExampleBenchCfg.param.postprocess_fn,
56
+ ],
57
+ result_vars=[ExampleBenchCfgOut.param.out_sin, ExampleBenchCfgOut.param.out_cos],
58
+ const_vars=[
59
+ (ExampleBenchCfg.param.sigma, 0.1),
60
+ (ExampleBenchCfg.param.noise_distribution, NoiseDistribution.gaussian),
61
+ (ExampleBenchCfg.param.noisy, True),
62
+ ],
63
+ title="Float 2D with categorical Example",
64
+ description="""Here we add plot a 2d surface and facet over a categorical variable
65
+ """,
66
+ )
67
+ bench.report.append(bench.get_result().to_surface())
68
+
69
+ bench.plot_sweep(
70
+ input_vars=[
71
+ ExampleBenchCfg.param.theta,
72
+ ExampleBenchCfg.param.offset,
73
+ ExampleBenchCfg.param.postprocess_fn,
74
+ ExampleBenchCfg.param.noise_distribution,
75
+ ],
76
+ result_vars=[ExampleBenchCfgOut.param.out_sin, ExampleBenchCfgOut.param.out_cos],
77
+ const_vars=[
78
+ (ExampleBenchCfg.param.sigma, 0.1),
79
+ (ExampleBenchCfg.param.noise_distribution, NoiseDistribution.gaussian),
80
+ (ExampleBenchCfg.param.noisy, True),
81
+ ],
82
+ title="Float 2D with categorical x2 Example",
83
+ description="""Here we add plot a 2d surface and facet over two categorical variable
84
+ """,
85
+ )
86
+
87
+ bench.report.append(bench.get_result().to_surface())
88
+
89
+ return bench
90
+
91
+
92
+ if __name__ == "__main__":
93
+ example_floats2D(bch.BenchRunCfg(repeats=2, level=3)).report.show()
@@ -0,0 +1,98 @@
1
+ # THIS IS NOT A WORKING EXAMPLE YET
2
+
3
+ # pylint: disable=duplicate-code,unused-argument
4
+
5
+
6
+ import bencher as bch
7
+ import math
8
+ import random
9
+ import numpy as np
10
+ import holoviews as hv
11
+
12
+ from strenum import StrEnum
13
+ from enum import auto
14
+
15
+
16
+ class Function(StrEnum):
17
+ fn_cos = auto()
18
+ fn_sin = auto()
19
+ fn_log = auto()
20
+ fn_arctan = auto()
21
+
22
+ def call(self, arg) -> float:
23
+ """Calls the function defined by the name of the enum
24
+
25
+ Returns:
26
+ float: The result of calling the function defined by the enum
27
+ """
28
+ return getattr(np, self.removeprefix("fn_"))(arg)
29
+
30
+
31
+ class PlotFunctions(bch.ParametrizedSweep):
32
+ phase = bch.FloatSweep(
33
+ default=0, bounds=[0, math.pi], doc="Input angle", units="rad", samples=5
34
+ )
35
+
36
+ freq = bch.FloatSweep(default=1, bounds=[0, math.pi], doc="Input angle", units="rad", samples=5)
37
+
38
+ theta = bch.FloatSweep(
39
+ default=0, bounds=[0, math.pi], doc="Input angle", units="rad", samples=10
40
+ )
41
+
42
+ compute_fn = bch.EnumSweep(Function)
43
+
44
+ # RESULT VARS
45
+ fn_output = bch.ResultVar(units="v", doc="sin of theta with some noise")
46
+ out_sum = bch.ResultVar(units="v", doc="The sum")
47
+ ref = bch.ResultReference()
48
+ holomap = bch.ResultHmap()
49
+
50
+ def __call__(self, plot=True, **kwargs) -> dict:
51
+ self.update_params_from_kwargs(**kwargs)
52
+ noise = 0.1
53
+
54
+ self.fn_output = self.compute_fn.call(self.phase + self.freq * self.theta) + random.uniform(
55
+ 0, noise
56
+ )
57
+
58
+ self.holomap = self.plot_holo(plot)
59
+ self.ref = bch.ResultReference(self.ref)
60
+
61
+ return self.get_results_values_as_dict()
62
+
63
+ def plot_holo(self, plot=True) -> hv.core.ViewableElement:
64
+ """Plots a generic representation of the object that is not a basic hv datatype. In this case its an image of the values of the object, but it could be any representation of the object, e.g. a screenshot of the object state"""
65
+ if plot:
66
+ pt = hv.Text(0, 0, f"{self.phase}\n{self.freq}\n {self.theta}")
67
+ pt *= hv.Ellipse(0, 0, 1)
68
+ return pt
69
+ return None
70
+
71
+
72
+ def example_holosweep(
73
+ run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
74
+ ) -> bch.Bench:
75
+ bench = PlotFunctions().to_bench(run_cfg, report)
76
+
77
+ bench.plot_sweep(
78
+ input_vars=["theta", "freq"],
79
+ result_vars=["fn_output", "holomap"],
80
+ )
81
+
82
+ # print("best", res.get_best_trial_params(True))
83
+ # print(res.hmap_kdims)
84
+ # bench.report.append(res.describe_sweep())
85
+ # bench.report.append(res.to_optuna_plots())
86
+ # bench.report.append(res.get_best_holomap())
87
+ # bench.report.append(res.to_curve(), "Slider view")
88
+ # bench.report.append(res.to_holomap())
89
+
90
+ # bench.report.append(res.to_holomap().layout())
91
+ return bench
92
+
93
+
94
+ if __name__ == "__main__":
95
+ PlotFunctions().to_gui()
96
+ bench_run = bch.BenchRunner("bench_runner_test")
97
+ bench_run.add_run(example_holosweep)
98
+ bench_run.run(level=6, show=True, use_cache=False)