holobench 1.3.6__py2.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 (74) hide show
  1. bencher/__init__.py +41 -0
  2. bencher/bench_cfg.py +462 -0
  3. bencher/bench_plot_server.py +100 -0
  4. bencher/bench_report.py +268 -0
  5. bencher/bench_runner.py +136 -0
  6. bencher/bencher.py +805 -0
  7. bencher/caching.py +51 -0
  8. bencher/example/__init__.py +0 -0
  9. bencher/example/benchmark_data.py +200 -0
  10. bencher/example/example_all.py +45 -0
  11. bencher/example/example_categorical.py +99 -0
  12. bencher/example/example_custom_sweep.py +59 -0
  13. bencher/example/example_docs.py +34 -0
  14. bencher/example/example_float3D.py +101 -0
  15. bencher/example/example_float_cat.py +98 -0
  16. bencher/example/example_floats.py +89 -0
  17. bencher/example/example_floats2D.py +93 -0
  18. bencher/example/example_holosweep.py +104 -0
  19. bencher/example/example_holosweep_objects.py +111 -0
  20. bencher/example/example_holosweep_tap.py +144 -0
  21. bencher/example/example_image.py +82 -0
  22. bencher/example/example_levels.py +181 -0
  23. bencher/example/example_pareto.py +53 -0
  24. bencher/example/example_sample_cache.py +85 -0
  25. bencher/example/example_sample_cache_context.py +116 -0
  26. bencher/example/example_simple.py +134 -0
  27. bencher/example/example_simple_bool.py +34 -0
  28. bencher/example/example_simple_cat.py +47 -0
  29. bencher/example/example_simple_float.py +38 -0
  30. bencher/example/example_strings.py +46 -0
  31. bencher/example/example_time_event.py +62 -0
  32. bencher/example/example_video.py +124 -0
  33. bencher/example/example_workflow.py +189 -0
  34. bencher/example/experimental/example_bokeh_plotly.py +38 -0
  35. bencher/example/experimental/example_hover_ex.py +45 -0
  36. bencher/example/experimental/example_hvplot_explorer.py +39 -0
  37. bencher/example/experimental/example_interactive.py +75 -0
  38. bencher/example/experimental/example_streamnd.py +49 -0
  39. bencher/example/experimental/example_streams.py +36 -0
  40. bencher/example/experimental/example_template.py +40 -0
  41. bencher/example/experimental/example_updates.py +84 -0
  42. bencher/example/experimental/example_vector.py +84 -0
  43. bencher/example/meta/example_meta.py +171 -0
  44. bencher/example/meta/example_meta_cat.py +25 -0
  45. bencher/example/meta/example_meta_float.py +23 -0
  46. bencher/example/meta/example_meta_levels.py +26 -0
  47. bencher/example/optuna/example_optuna.py +78 -0
  48. bencher/example/shelved/example_float2D_scatter.py +109 -0
  49. bencher/example/shelved/example_float3D_cone.py +96 -0
  50. bencher/example/shelved/example_kwargs.py +63 -0
  51. bencher/job.py +184 -0
  52. bencher/optuna_conversions.py +168 -0
  53. bencher/plotting/__init__.py +0 -0
  54. bencher/plotting/plot_filter.py +110 -0
  55. bencher/plotting/plt_cnt_cfg.py +74 -0
  56. bencher/results/__init__.py +0 -0
  57. bencher/results/bench_result.py +80 -0
  58. bencher/results/bench_result_base.py +405 -0
  59. bencher/results/float_formatter.py +44 -0
  60. bencher/results/holoview_result.py +592 -0
  61. bencher/results/optuna_result.py +354 -0
  62. bencher/results/panel_result.py +113 -0
  63. bencher/results/plotly_result.py +65 -0
  64. bencher/utils.py +148 -0
  65. bencher/variables/inputs.py +193 -0
  66. bencher/variables/parametrised_sweep.py +206 -0
  67. bencher/variables/results.py +176 -0
  68. bencher/variables/sweep_base.py +167 -0
  69. bencher/variables/time.py +74 -0
  70. bencher/video_writer.py +30 -0
  71. bencher/worker_job.py +40 -0
  72. holobench-1.3.6.dist-info/METADATA +85 -0
  73. holobench-1.3.6.dist-info/RECORD +74 -0
  74. holobench-1.3.6.dist-info/WHEEL +5 -0
bencher/caching.py ADDED
@@ -0,0 +1,51 @@
1
+ from diskcache import Cache
2
+
3
+ from bencher.variables.parametrised_sweep import ParametrizedSweep
4
+ from bencher.utils import hash_sha1
5
+ import logging
6
+ from sortedcontainers import SortedDict
7
+
8
+ # from job import job,JobCache,JobFunctionCache
9
+
10
+
11
+ class CachedParams(ParametrizedSweep):
12
+ def __init__(self, clear_cache=True, cache_name="fcache", **params):
13
+ super().__init__(**params)
14
+
15
+ self.cache = Cache(f"cachedir/{cache_name}/sample_cache")
16
+ logging.info(f"cache dir{self.cache.directory}")
17
+ print(f"cache dir{self.cache.directory}")
18
+
19
+ if clear_cache:
20
+ self.cache.clear()
21
+
22
+ def kwargs_to_hash_key(self, **kwargs):
23
+ return tuple(SortedDict(kwargs).items())
24
+
25
+ def in_cache(self, **kwargs):
26
+ self.update_params_from_kwargs(**kwargs)
27
+ # print(self.get_inputs_as_dict())
28
+ inputs_key = self.kwargs_to_hash_key(**self.get_inputs_as_dict())
29
+ key = hash_sha1(inputs_key)
30
+ print(f"key:{key},value: {inputs_key}")
31
+ value = None
32
+ if key in self.cache:
33
+ value = self.cache[key]
34
+ return key, value
35
+
36
+ def cache_wrap(self, func, **kwargs):
37
+ key, value = self.in_cache(**kwargs)
38
+ if value is None:
39
+ value = func(**kwargs)
40
+ self.cache[key] = value
41
+ return value
42
+
43
+ # def cache_mem(self, function):
44
+ # def cache_wrap1(self, func, **kwargs):
45
+ # key, value = self.in_cache(**kwargs)
46
+ # if value is None:
47
+ # value = function(**kwargs)
48
+ # self.cache[key] = value
49
+ # return value
50
+
51
+ # return cache_wrap1
File without changes
@@ -0,0 +1,200 @@
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
+
10
+ from strenum import StrEnum
11
+
12
+
13
+ from bencher.variables.inputs import IntSweep, FloatSweep, StringSweep, EnumSweep, BoolSweep
14
+ from bencher.variables.results import ResultVar, OptDir
15
+
16
+ from bencher.variables.parametrised_sweep import ParametrizedSweep
17
+
18
+
19
+ class PostprocessFn(StrEnum):
20
+ """Apply a postprocessing step to the data"""
21
+
22
+ absolute = auto() # return the abs of the output data
23
+ negate = auto() # return the negative of the output data
24
+
25
+
26
+ class NoiseDistribution(StrEnum):
27
+ """A categorical variable describing the types of random noise"""
28
+
29
+ uniform = auto() # uniform random noiase
30
+ gaussian = auto() # gaussian noise
31
+ lognorm = auto() # lognorm noise
32
+
33
+
34
+ class NoiseCfg(ParametrizedSweep):
35
+ """A class for storing the parameters for generating various types of noise"""
36
+
37
+ noisy = BoolSweep(
38
+ default=False, doc="Optionally add random noise to the output of the function"
39
+ )
40
+
41
+ noise_distribution = EnumSweep(NoiseDistribution, doc=NoiseDistribution.__doc__)
42
+
43
+ sigma = FloatSweep(
44
+ default=1,
45
+ bounds=[0, 10],
46
+ doc="The standard deviation of the noise",
47
+ units="v",
48
+ )
49
+
50
+
51
+ def calculate_noise(config: NoiseCfg) -> float:
52
+ """Generate a float value based on a noise distribution and scale
53
+
54
+ Args:
55
+ config (NoiseCfg): see NoiseCfg type
56
+
57
+ Returns:
58
+ float: a noisy float value
59
+ """
60
+
61
+ noise = 0.0
62
+ if config.noisy:
63
+ match config.noise_distribution:
64
+ case NoiseDistribution.uniform:
65
+ noise = random.uniform(0, config.sigma)
66
+ case NoiseDistribution.gaussian:
67
+ noise = random.gauss(0, config.sigma)
68
+ case NoiseDistribution.lognorm:
69
+ noise = random.lognormvariate(0, config.sigma)
70
+
71
+ return noise
72
+
73
+
74
+ class ExampleBenchCfgIn(NoiseCfg):
75
+ """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."""
76
+
77
+ theta = FloatSweep(default=0, bounds=[0, math.pi], doc="Input angle", units="rad", samples=30)
78
+ offset = FloatSweep(default=0, bounds=[0, 0.3], doc="dc offset", units="v", samples=30)
79
+ postprocess_fn = EnumSweep(PostprocessFn)
80
+
81
+
82
+ class ExampleBenchCfgOut(ParametrizedSweep):
83
+ out_sin = ResultVar(units="v", direction=OptDir.minimize, doc="sin of theta with some noise")
84
+ out_cos = ResultVar(units="v", direction=OptDir.minimize, doc="cos of theta with some noise")
85
+ out_bool = ResultVar(units="%", doc="sin > 0.5")
86
+
87
+
88
+ def negate_fn(fn_input: float):
89
+ """returns the negative of the input
90
+
91
+ Args:
92
+ fn_input (float): any float value
93
+
94
+ Returns:
95
+ float: negative of the input
96
+ """
97
+ return -fn_input
98
+
99
+
100
+ def bench_function(cfg: ExampleBenchCfgIn) -> ExampleBenchCfgOut:
101
+ """Takes an ExampleBenchCfgIn and returns a ExampleBenchCfgOut output"""
102
+ out = ExampleBenchCfgOut()
103
+ noise = calculate_noise(cfg)
104
+
105
+ postprocess_fn = abs if cfg.postprocess_fn == PostprocessFn.absolute else negate_fn
106
+
107
+ out.out_sin = postprocess_fn(cfg.offset + math.sin(cfg.theta) + noise)
108
+ out.out_cos = postprocess_fn(cfg.offset + math.cos(cfg.theta) + noise)
109
+
110
+ out.out_bool = out.out_sin > 0.5
111
+ return out
112
+
113
+
114
+ class ExampleBenchCfg(ParametrizedSweep):
115
+ theta = FloatSweep(default=0, bounds=[0, math.pi], doc="Input angle", units="rad", samples=30)
116
+ offset = FloatSweep(default=0, bounds=[0, 0.3], doc="dc offset", units="v", samples=30)
117
+ postprocess_fn = EnumSweep(PostprocessFn)
118
+
119
+ noisy = BoolSweep(
120
+ default=False, doc="Optionally add random noise to the output of the function"
121
+ )
122
+ noise_distribution = EnumSweep(NoiseDistribution, doc=NoiseDistribution.__doc__)
123
+ sigma = FloatSweep(
124
+ default=1,
125
+ bounds=[0, 10],
126
+ doc="The standard deviation of the noise",
127
+ units="v",
128
+ )
129
+
130
+ out_sin = ResultVar(units="v", direction=OptDir.minimize, doc="sin of theta with some noise")
131
+ out_cos = ResultVar(units="v", direction=OptDir.minimize, doc="cos of theta with some noise")
132
+ out_bool = ResultVar(units="%", doc="sin > 0.5")
133
+
134
+ def __call__(self, **kwwargs) -> dict:
135
+ self.update_params_from_kwargs(**kwwargs)
136
+
137
+ noise = self.calculate_noise()
138
+ postprocess_fn = abs if self.postprocess_fn == PostprocessFn.absolute else negate_fn
139
+
140
+ self.out_sin = postprocess_fn(self.offset + math.sin(self.theta) + noise)
141
+ self.out_cos = postprocess_fn(self.offset + math.cos(self.theta) + noise)
142
+ self.out_bool = self.out_sin > 0.5
143
+ return self.get_results_values_as_dict()
144
+
145
+ def calculate_noise(self):
146
+ noise = 0.0
147
+ if self.noisy:
148
+ match self.noise_distribution:
149
+ case NoiseDistribution.uniform:
150
+ noise = random.uniform(0, self.sigma)
151
+ case NoiseDistribution.gaussian:
152
+ noise = random.gauss(0, self.sigma)
153
+ case NoiseDistribution.lognorm:
154
+ noise = random.lognormvariate(0, self.sigma)
155
+
156
+ return noise
157
+
158
+
159
+ def call(**kwargs) -> dict:
160
+ return ExampleBenchCfg().__call__(**kwargs)
161
+
162
+
163
+ class AllSweepVars(ParametrizedSweep):
164
+ """A class containing all the sweep types, This class is used for unit testing how the configuration classes are serialised and hashed"""
165
+
166
+ var_float = FloatSweep(default=5, bounds=(0, 10), units="m/s")
167
+ var_int = IntSweep(default=3, bounds=[0, 4])
168
+ var_int_big = IntSweep(default=0, bounds=[0, 100], samples=3)
169
+ var_bool = BoolSweep()
170
+ var_string = StringSweep(["string1", "string2"])
171
+ var_enum = EnumSweep(PostprocessFn)
172
+
173
+ result = ResultVar()
174
+
175
+ def __call__(self, **kwargs) -> dict:
176
+ self.update_params_from_kwargs(**kwargs)
177
+ self.result = self.var_float + self.var_int
178
+ return self.get_results_values_as_dict()
179
+
180
+
181
+ class SimpleBenchClass(ParametrizedSweep):
182
+ var1 = IntSweep(default=0, bounds=[0, 2])
183
+
184
+ result = ResultVar()
185
+
186
+ def __call__(self, **kwargs) -> dict:
187
+ self.update_params_from_kwargs(**kwargs)
188
+ self.result = self.var1
189
+ return self.get_results_values_as_dict()
190
+
191
+
192
+ class SimpleBenchClassFloat(ParametrizedSweep):
193
+ var1 = FloatSweep(bounds=[0, 100])
194
+
195
+ result = ResultVar()
196
+
197
+ def __call__(self, **kwargs) -> dict:
198
+ self.update_params_from_kwargs(**kwargs)
199
+ self.result = self.var1
200
+ 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,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,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,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,98 @@
1
+ """Example of how to perform a parameter sweep for categorical variables"""
2
+ import bencher as bch
3
+
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_float_cat(
10
+ run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
11
+ ) -> bch.Bench:
12
+ """Example of how to perform a parameter sweep for categorical variables
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
+ bench = bch.Bench(
21
+ "Bencher_Example_Float_Cat",
22
+ bench_function,
23
+ ExampleBenchCfgIn,
24
+ run_cfg=run_cfg,
25
+ report=report,
26
+ )
27
+
28
+ bench.plot_sweep(
29
+ input_vars=[
30
+ ExampleBenchCfgIn.param.theta,
31
+ ExampleBenchCfgIn.param.offset,
32
+ ExampleBenchCfgIn.param.postprocess_fn,
33
+ ],
34
+ result_vars=[ExampleBenchCfgOut.param.out_sin],
35
+ const_vars=[ExampleBenchCfgIn.param.noisy.with_const(True)],
36
+ title="Float 2D Cat 1D Example",
37
+ 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""",
38
+ post_description="Now the plot has two lines, one for each of the boolean values where noisy=true and noisy=false.",
39
+ )
40
+
41
+ bench.plot_sweep(
42
+ input_vars=[ExampleBenchCfgIn.param.theta],
43
+ result_vars=[ExampleBenchCfgOut.param.out_sin],
44
+ const_vars=[ExampleBenchCfgIn.param.noisy.with_const(True)],
45
+ title="Float 1D Cat 1D Example",
46
+ 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""",
47
+ post_description="Now the plot has two lines, one for each of the boolean values where noisy=true and noisy=false.",
48
+ plot=False,
49
+ )
50
+
51
+ # report.append(bench.get_result().to_curve())
52
+
53
+ # # this does not work yet because it tries to find min and max of categorical values
54
+ # bench.plot_sweep(
55
+ # input_vars=[ExampleBenchCfgIn.param.theta, ExampleBenchCfgIn.param.postprocess_fn],
56
+ # result_vars=[ExampleBenchCfgOut.param.out_sin],
57
+ # const_vars=[ExampleBenchCfgIn.param.noisy.with_const(True)],
58
+ # title="Float 1D Cat 1D Example",
59
+ # 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""",
60
+ # post_description="Now the plot has two lines, one for each of the boolean values where noisy=true and noisy=false.",
61
+ # run_cfg=run_cfg,
62
+ # )
63
+
64
+ return bench
65
+
66
+
67
+ def run_example_float_cat(ex_run_cfg=bch.BenchRunCfg()) -> None:
68
+ ex_run_cfg.repeats = 2
69
+ ex_run_cfg.over_time = True
70
+ ex_run_cfg.clear_cache = True
71
+ ex_run_cfg.clear_history = True
72
+ ex_run_cfg.level = 3
73
+ # ex_run_cfg.time_event = "run 1"
74
+ # ex_run_cfg.use_optuna = True
75
+
76
+ example_float_cat(ex_run_cfg)
77
+
78
+ # ex_run_cfg.repeats = 2
79
+ # ex_run_cfg.over_time = True
80
+ ex_run_cfg.clear_cache = False
81
+ ex_run_cfg.clear_history = False
82
+ # ex_run_cfg.time_event = "run 2"
83
+ # ex_run_cfg.use_optuna = True
84
+
85
+ # example_float_cat(ex_run_cfg)
86
+
87
+ # ex_run_cfg.clear_cache = False
88
+ # ex_run_cfg.clear_history = False
89
+ # ex_run_cfg.time_event = "run 2"
90
+
91
+ # example_float_cat(ex_run_cfg)
92
+
93
+ # ex_run_cfg.time_event = "run 3"
94
+ return example_float_cat(ex_run_cfg)
95
+
96
+
97
+ if __name__ == "__main__":
98
+ run_example_float_cat().report.show()