holobench 1.36.2__py3-none-any.whl → 1.39.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. bencher/bench_runner.py +15 -0
  2. bencher/example/example_all.py +2 -2
  3. bencher/example/example_categorical.py +1 -1
  4. bencher/example/example_custom_sweep.py +1 -1
  5. bencher/example/example_docs.py +3 -3
  6. bencher/example/example_float3D.py +1 -3
  7. bencher/example/example_float_cat.py +1 -3
  8. bencher/example/example_floats.py +1 -3
  9. bencher/example/example_floats2D.py +1 -3
  10. bencher/example/example_holosweep.py +1 -3
  11. bencher/example/example_holosweep_objects.py +1 -3
  12. bencher/example/example_holosweep_tap.py +2 -2
  13. bencher/example/example_image.py +2 -4
  14. bencher/example/example_levels.py +1 -3
  15. bencher/example/example_pareto.py +1 -3
  16. bencher/example/example_sample_cache.py +2 -2
  17. bencher/example/example_simple_cat.py +1 -3
  18. bencher/example/example_simple_float.py +4 -3
  19. bencher/example/example_strings.py +1 -3
  20. bencher/example/example_time_event.py +1 -1
  21. bencher/example/example_video.py +2 -4
  22. bencher/example/inputs_0D/example_0_in_1_out.py +54 -0
  23. bencher/example/inputs_0D/{example_0D.py → example_0_in_2_out.py} +9 -5
  24. bencher/example/inputs_1D/example1d_common.py +69 -0
  25. bencher/example/inputs_1D/{example_1D.py → example_1_in_1_out.py} +26 -8
  26. bencher/example/inputs_1D/example_1_in_2_out.py +63 -0
  27. bencher/example/inputs_1D/example_1_in_2_out_repeats.py +61 -0
  28. bencher/example/meta/__init__.py +0 -0
  29. bencher/example/meta/example_meta.py +5 -7
  30. bencher/example/meta/example_meta_cat.py +1 -3
  31. bencher/example/meta/example_meta_float.py +1 -1
  32. bencher/example/meta/example_meta_levels.py +1 -1
  33. bencher/example/meta/generate_examples.py +54 -0
  34. bencher/example/meta/generate_meta.py +127 -0
  35. bencher/example/optuna/example_optuna.py +1 -3
  36. bencher/job.py +4 -4
  37. bencher/results/bench_result_base.py +5 -3
  38. bencher/results/holoview_result.py +12 -4
  39. bencher/variables/inputs.py +2 -4
  40. {holobench-1.36.2.dist-info → holobench-1.39.0.dist-info}/METADATA +12 -7
  41. {holobench-1.36.2.dist-info → holobench-1.39.0.dist-info}/RECORD +43 -36
  42. {holobench-1.36.2.dist-info → holobench-1.39.0.dist-info}/WHEEL +0 -0
  43. {holobench-1.36.2.dist-info → holobench-1.39.0.dist-info}/licenses/LICENSE +0 -0
bencher/bench_runner.py CHANGED
@@ -138,6 +138,21 @@ class BenchRunner:
138
138
  if show:
139
139
  self.servers.append(report.show(self.run_cfg))
140
140
 
141
+ def show(
142
+ self,
143
+ report: BenchReport = None,
144
+ show: bool = True,
145
+ publish: bool = False,
146
+ save: bool = False,
147
+ debug: bool = False,
148
+ ):
149
+ if report is None:
150
+ if len(self.results) > 0:
151
+ report = self.results[-1].report
152
+ else:
153
+ raise RuntimeError("no reports to show")
154
+ self.show_publish(report=report, show=show, publish=publish, save=save, debug=debug)
155
+
141
156
  def shutdown(self):
142
157
  while self.servers:
143
158
  self.servers.pop().stop()
@@ -5,7 +5,7 @@ from bencher.example.example_floats import example_floats
5
5
  from bencher.example.example_floats2D import example_floats2D
6
6
  from bencher.example.example_pareto import example_pareto
7
7
  from bencher.example.example_simple_cat import example_1D_cat
8
- from bencher.example.example_simple_float import example_1D_float
8
+ from bencher.example.example_simple_float import example_simple_float
9
9
  from bencher.example.example_float_cat import example_float_cat
10
10
  from bencher.example.example_time_event import example_time_event
11
11
  from bencher.example.example_float3D import example_floats3D
@@ -30,7 +30,7 @@ if __name__ == "__main__":
30
30
  bench_runner.add_run(example_floats2D)
31
31
  bench_runner.add_run(example_floats3D)
32
32
  bench_runner.add_run(example_1D_cat)
33
- bench_runner.add_run(example_1D_float)
33
+ bench_runner.add_run(example_simple_float)
34
34
  bench_runner.add_run(example_pareto)
35
35
  bench_runner.add_run(example_float_cat)
36
36
  bench_runner.add_run(example_time_event)
@@ -7,7 +7,7 @@ from bencher.example.benchmark_data import ExampleBenchCfgIn, ExampleBenchCfgOut
7
7
 
8
8
 
9
9
  def example_categorical(
10
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
10
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
11
11
  ) -> bch.Bench:
12
12
  """Example of how to perform a categorical parameter sweep
13
13
 
@@ -21,7 +21,7 @@ class Square(bch.ParametrizedSweep):
21
21
 
22
22
 
23
23
  def example_custom_sweep(
24
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
24
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
25
25
  ) -> bch.Bench:
26
26
  """This example shows how to define a custom set of value to sample from instead of a uniform sweep
27
27
 
@@ -6,9 +6,9 @@ from bencher.example.meta.example_meta_cat import example_meta_cat
6
6
  from bencher.example.meta.example_meta_float import example_meta_float
7
7
 
8
8
 
9
- def example_docs(
10
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
11
- ) -> bch.Bench:
9
+ def example_docs(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
10
+ if report is None:
11
+ report = bch.BenchReport()
12
12
  # b_run = bch.BenchRunner("bench_runner_test", run_cfg=run_cfg)
13
13
  # b_run.add_run(example_categorical)
14
14
  # b_run.add_run(example_floats)
@@ -47,9 +47,7 @@ class VolumeSweep(bch.ParametrizedSweep):
47
47
  return super().__call__()
48
48
 
49
49
 
50
- def example_floats3D(
51
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
52
- ) -> bch.Bench:
50
+ def example_floats3D(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
53
51
  """Example of how to perform a 3D floating point parameter sweep
54
52
 
55
53
  Args:
@@ -7,9 +7,7 @@ import bencher as bch
7
7
  from bencher.example.benchmark_data import ExampleBenchCfgIn, ExampleBenchCfgOut, bench_function
8
8
 
9
9
 
10
- def example_float_cat(
11
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
12
- ) -> bch.Bench:
10
+ def example_float_cat(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
13
11
  """Example of how to perform a parameter sweep for categorical variables
14
12
 
15
13
  Args:
@@ -7,9 +7,7 @@ import bencher as bch
7
7
  from bencher.example.benchmark_data import ExampleBenchCfgIn, ExampleBenchCfgOut, ExampleBenchCfg
8
8
 
9
9
 
10
- def example_floats(
11
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
12
- ) -> bch.Bench:
10
+ def example_floats(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
13
11
  """Example of how to perform a parameter sweep for floating point variables
14
12
 
15
13
  Args:
@@ -10,9 +10,7 @@ from bencher.example.benchmark_data import (
10
10
  )
11
11
 
12
12
 
13
- def example_floats2D(
14
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
15
- ) -> bch.Bench:
13
+ def example_floats2D(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
16
14
  """Example of how to perform a 2D floating point parameter sweep
17
15
 
18
16
  Args:
@@ -69,9 +69,7 @@ class PlotFunctions(bch.ParametrizedSweep):
69
69
  return None
70
70
 
71
71
 
72
- def example_holosweep(
73
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
74
- ) -> bch.Bench:
72
+ def example_holosweep(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
75
73
  bench = PlotFunctions().to_bench(run_cfg, report)
76
74
 
77
75
  bench.plot_sweep(
@@ -73,9 +73,7 @@ def plot_holo(self, plot=True) -> hv.core.ViewableElement:
73
73
  return None
74
74
 
75
75
 
76
- def example_holosweep(
77
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
78
- ) -> bch.Bench:
76
+ def example_holosweep(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
79
77
  # wv = PlotFunctions()
80
78
 
81
79
  bench = bch.Bench(
@@ -79,7 +79,7 @@ class PlotFunctions(bch.ParametrizedSweep):
79
79
 
80
80
 
81
81
  def example_holosweep_tap(
82
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
82
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
83
83
  ) -> bch.Bench:
84
84
  wv = PlotFunctions()
85
85
 
@@ -101,7 +101,7 @@ def example_holosweep_tap(
101
101
 
102
102
 
103
103
  def example_holosweep_tap_slider(
104
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
104
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
105
105
  ) -> bch.Bench: # pragma: no cover
106
106
  wv = PlotFunctions()
107
107
 
@@ -55,9 +55,7 @@ class BenchPolygons(bch.ParametrizedSweep):
55
55
  return filename
56
56
 
57
57
 
58
- def example_image(
59
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
60
- ) -> bch.Bench:
58
+ def example_image(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
61
59
  run_cfg.cache_results = False
62
60
  bench = bch.Bench("polygons", BenchPolygons(), run_cfg=run_cfg, report=report)
63
61
 
@@ -131,7 +129,7 @@ if __name__ == "__main__":
131
129
  return bench
132
130
 
133
131
  def example_image_vid_sequential(
134
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
132
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
135
133
  ) -> bch.Bench:
136
134
  bench = BenchPolygons().to_bench(run_cfg, report)
137
135
  bench.add_plot_callback(bch.BenchResult.to_title)
@@ -161,9 +161,7 @@ def run_levels_2D(bench: bch.Bench) -> bch.Bench:
161
161
  return bench
162
162
 
163
163
 
164
- def run_levels(
165
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
166
- ) -> bch.Bench:
164
+ def run_levels(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
167
165
  hv.extension("bokeh")
168
166
  opts.defaults(
169
167
  opts.Curve(show_legend=False),
@@ -6,9 +6,7 @@ import bencher as bch
6
6
  from bencher.example.benchmark_data import ExampleBenchCfgIn, ExampleBenchCfgOut, bench_function
7
7
 
8
8
 
9
- def example_pareto(
10
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
11
- ) -> bch.Bench:
9
+ def example_pareto(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
12
10
  """Example of how to calculate the pareto front of a parameter sweep
13
11
 
14
12
  Args:
@@ -27,8 +27,8 @@ class UnreliableClass(bch.ParametrizedSweep):
27
27
 
28
28
 
29
29
  def example_sample_cache(
30
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(),
31
- report: bch.BenchReport = bch.BenchReport(),
30
+ run_cfg: bch.BenchRunCfg = None,
31
+ report: bch.BenchReport = None,
32
32
  trigger_crash: bool = False,
33
33
  ) -> bch.Bench:
34
34
  """This example shows how to use the cache_samples option to deal with unreliable functions and to continue benchmarking using previously calculated results even if the code crashed during the run
@@ -8,9 +8,7 @@ import bencher as bch
8
8
  from bencher.example.benchmark_data import ExampleBenchCfgIn, ExampleBenchCfgOut, bench_function
9
9
 
10
10
 
11
- def example_1D_cat(
12
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
13
- ) -> bch.Bench:
11
+ def example_1D_cat(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
14
12
  """This example shows how to sample a 1 dimensional categorical variable and plot the result of passing that parameter sweep to the benchmarking function
15
13
 
16
14
  Args:
@@ -16,14 +16,15 @@ class SimpleFloat(bch.ParametrizedSweep):
16
16
  return super().__call__(**kwargs)
17
17
 
18
18
 
19
- def example_1D_float(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
19
+ def example_simple_float(
20
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
21
+ ) -> bch.Bench:
20
22
  """This example shows how to sample a 1 dimensional float variable and plot the result of passing that parameter sweep to the benchmarking function"""
21
23
 
22
24
  bench = SimpleFloat().to_bench(run_cfg, report)
23
25
  bench.plot_sweep()
24
- bench.report.append(bench.get_result().to_explorer())
25
26
  return bench
26
27
 
27
28
 
28
29
  if __name__ == "__main__":
29
- example_1D_float().report.show()
30
+ example_simple_float().report.show()
@@ -27,9 +27,7 @@ class TestPrinting(bch.ParametrizedSweep):
27
27
  return super().__call__()
28
28
 
29
29
 
30
- def example_strings(
31
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
32
- ) -> bch.Bench:
30
+ def example_strings(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
33
31
  bench = bch.Bench("strings", TestPrinting(), run_cfg=run_cfg, report=report)
34
32
 
35
33
  for s in [
@@ -9,7 +9,7 @@ from bencher.example.benchmark_data import ExampleBenchCfgIn, ExampleBenchCfgOut
9
9
 
10
10
 
11
11
  def example_time_event(
12
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
12
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
13
13
  ) -> bch.Bench:
14
14
  """This example shows how to manually set time events as a string so that progress can be monitored over time"""
15
15
 
@@ -75,9 +75,7 @@ class TuringPattern(bch.ParametrizedSweep):
75
75
  return super().__call__()
76
76
 
77
77
 
78
- def example_video(
79
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
80
- ) -> bch.Bench:
78
+ def example_video(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
81
79
  bench = TuringPattern().to_bench(run_cfg, report)
82
80
 
83
81
  bench.plot_sweep(
@@ -90,7 +88,7 @@ def example_video(
90
88
 
91
89
 
92
90
  def example_video_tap(
93
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
91
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
94
92
  ) -> bch.Bench: # pragma: no cover
95
93
  bench = TuringPattern().to_bench(run_cfg=run_cfg, report=report)
96
94
  res = bench.plot_sweep(input_vars=["alpha", "beta"])
@@ -0,0 +1,54 @@
1
+ """This file has some examples for how to perform basic benchmarking parameter sweeps"""
2
+
3
+ import bencher as bch
4
+ import random
5
+
6
+
7
+ class SimpleFloat0D(bch.ParametrizedSweep):
8
+ """This class has 0 input dimensions and 1 output dimensions. It samples from a gaussian distribution"""
9
+
10
+ # This defines a variable that we want to plot
11
+ output = bch.ResultVar(units="ul", doc="a sample from a gaussian distribution")
12
+
13
+ def __call__(self, **kwargs) -> dict:
14
+ """Generate a sample from a uniform distribution
15
+
16
+ Returns:
17
+ dict: a dictionary with all the result variables in the ParametrisedSweep class as named key value pairs.
18
+ """
19
+
20
+ self.output = random.gauss(mu=0.0, sigma=1.0)
21
+ return super().__call__(**kwargs)
22
+
23
+
24
+ def example_0_in_1_out(
25
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
26
+ ) -> bch.Bench:
27
+ """This example shows how to sample a 1 dimensional float variable and plot the result of passing that parameter sweep to the benchmarking function"""
28
+
29
+ bench = SimpleFloat0D().to_bench(run_cfg, report)
30
+ bench.plot_sweep()
31
+
32
+ bench.report.append(bench.get_result().to_table())
33
+ return bench
34
+
35
+
36
+ if __name__ == "__main__":
37
+ run_config = bch.BenchRunCfg(repeats=100)
38
+ reprt = bch.BenchReport()
39
+ # example_0_in_1_out(run_cfg, report).report.show()
40
+
41
+ # run_cfg.over_time = True
42
+ # run_cfg.cache_samples = True
43
+ # for i in range(4):
44
+ # example_0_in_1_out(run_cfg, report)
45
+
46
+ run_config.over_time = True
47
+ run_config.auto_plot = False
48
+ for _ in range(4):
49
+ example_0_in_1_out(run_config, reprt)
50
+
51
+ run_config.auto_plot = True
52
+ example_0_in_1_out(run_config, reprt)
53
+
54
+ reprt.show()
@@ -8,7 +8,8 @@ class SimpleFloat0D(bch.ParametrizedSweep):
8
8
  """This class has 0 input dimensions and 1 output dimensions. It samples from a gaussian distribution"""
9
9
 
10
10
  # This defines a variable that we want to plot
11
- output = bch.ResultVar(units="ul", doc="a sample from a gaussian distribution")
11
+ output1 = bch.ResultVar(units="ul", doc="a sample from a gaussian distribution")
12
+ output2 = bch.ResultVar(units="ul", doc="a sample from a gaussian distribution")
12
13
 
13
14
  def __call__(self, **kwargs) -> dict:
14
15
  """Generate a sample from a uniform distribution
@@ -17,11 +18,14 @@ class SimpleFloat0D(bch.ParametrizedSweep):
17
18
  dict: a dictionary with all the result variables in the ParametrisedSweep class as named key value pairs.
18
19
  """
19
20
 
20
- self.output = random.gauss(mu=0.0, sigma=1.0)
21
+ self.output1 = random.gauss(mu=0.0, sigma=1.0)
22
+ self.output2 = random.gauss(mu=2.0, sigma=5.0)
21
23
  return super().__call__(**kwargs)
22
24
 
23
25
 
24
- def example_0D(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
26
+ def example_0_in_2_out(
27
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
28
+ ) -> bch.Bench:
25
29
  """This example shows how to sample a 1 dimensional float variable and plot the result of passing that parameter sweep to the benchmarking function"""
26
30
 
27
31
  bench = SimpleFloat0D().to_bench(run_cfg, report)
@@ -30,5 +34,5 @@ def example_0D(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None)
30
34
 
31
35
 
32
36
  if __name__ == "__main__":
33
- run_config = bch.BenchRunCfg(repeats=100)
34
- example_0D(run_config).report.show()
37
+ run_config = bch.BenchRunCfg(repeats=500)
38
+ example_0_in_2_out(run_config).report.show()
@@ -0,0 +1,69 @@
1
+ """This file has some examples for how to perform basic benchmarking parameter sweeps"""
2
+
3
+ import bencher as bch
4
+
5
+
6
+ class DataSource:
7
+ def __init__(self):
8
+ self.data = [
9
+ [0, 0, 0, 0],
10
+ [1, 1, 1, 1],
11
+ [1, 1, 1, 1],
12
+ [2, 1, 1, 0],
13
+ [2, 2, 0, 0],
14
+ [2, 2, 1, 1],
15
+ ]
16
+
17
+ self.call_count = [0] * len(self.data)
18
+
19
+ def call(self, index, repeat=None):
20
+ if repeat is None:
21
+ self.call_count[index] += 1
22
+ repeat = self.call_count[index]
23
+ return self.data[index][repeat - 1]
24
+
25
+
26
+ class Example1D(bch.ParametrizedSweep):
27
+ index = bch.IntSweep(default=0, bounds=[0, 5], doc="Input angle", units="rad", samples=30)
28
+ output = bch.ResultVar(units="v", doc="sin of theta")
29
+ output2 = bch.ResultVar(units="v", doc="-sin of theta")
30
+
31
+ def __init__(self, **params):
32
+ super().__init__(**params)
33
+ self.data1 = DataSource()
34
+ self.data2 = DataSource()
35
+
36
+ def __call__(self, **kwargs):
37
+ self.update_params_from_kwargs(**kwargs)
38
+ self.output = self.data1.call(self.index)
39
+ self.output2 = -self.data2.call(self.index)
40
+ return super().__call__(**kwargs)
41
+
42
+
43
+ def example_1_in_2_out(
44
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
45
+ ) -> bch.Bench:
46
+ """This example shows how to sample a 1 dimensional float variable and plot the result of passing that parameter sweep to the benchmarking function"""
47
+ bench = Example1D().to_bench(run_cfg, report)
48
+ bench.plot_sweep()
49
+
50
+ # bench.report.append(bench.get_result().to_heatmap())
51
+ return bench
52
+
53
+
54
+ if __name__ == "__main__":
55
+ run_config = bch.BenchRunCfg()
56
+ reprt = bch.BenchReport()
57
+ example_1_in_2_out(run_config, reprt)
58
+
59
+ run_config.repeats = 4
60
+ example_1_in_2_out(run_config, reprt)
61
+
62
+ # run_config.over_time = True
63
+ # run_config.auto_plot = False
64
+ # for i in range(4):
65
+ # example_1_in_2_out(run_config, reprt)
66
+
67
+ # run_config.auto_plot = True
68
+ # example_1_in_2_out(run_config, reprt)
69
+ reprt.show()
@@ -14,7 +14,13 @@ class DataSource:
14
14
  [2, 2, 1, 1],
15
15
  ]
16
16
 
17
- def call(self, index, repeat):
17
+ self.call_count = [0] * len(self.data)
18
+
19
+ def call(self, index, repeat=None):
20
+ if repeat is None:
21
+ self.call_count[index] += 1
22
+ repeat = self.call_count[index]
23
+ print(index, repeat)
18
24
  return self.data[index][repeat - 1]
19
25
 
20
26
 
@@ -22,23 +28,35 @@ class Example1D(bch.ParametrizedSweep):
22
28
  index = bch.IntSweep(default=0, bounds=[0, 5], doc="Input angle", units="rad", samples=30)
23
29
  output = bch.ResultVar(units="v", doc="sin of theta")
24
30
 
31
+ def __init__(self, **params):
32
+ super().__init__(**params)
33
+ self.data1 = DataSource()
34
+
25
35
  def __call__(self, **kwargs):
26
36
  self.update_params_from_kwargs(**kwargs)
27
- self.output = DataSource().call(self.index, kwargs["repeat"])
37
+ self.output = self.data1.call(self.index)
28
38
  return super().__call__(**kwargs)
29
39
 
30
40
 
31
- def example_1D_float_repeats(
41
+ def example_1_in_1_out(
32
42
  run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
33
43
  ) -> bch.Bench:
34
44
  """This example shows how to sample a 1 dimensional float variable and plot the result of passing that parameter sweep to the benchmarking function"""
35
-
36
45
  bench = Example1D().to_bench(run_cfg, report)
37
- bench.run_cfg = bch.BenchRunCfg(repeats=4)
38
- bench.plot_sweep(pass_repeat=True)
39
-
46
+ bench.plot_sweep()
40
47
  return bench
41
48
 
42
49
 
43
50
  if __name__ == "__main__":
44
- example_1D_float_repeats().report.show()
51
+ run_config = bch.BenchRunCfg()
52
+ reprt = bch.BenchReport()
53
+ example_1_in_1_out(run_config, reprt)
54
+
55
+ run_config.repeats = 4
56
+ example_1_in_1_out(run_config, reprt)
57
+
58
+ # run_cfg.over_time = True
59
+ # for i in range(4):
60
+ # example_1_in_2_out(run_cfg, report)
61
+
62
+ reprt.show()
@@ -0,0 +1,63 @@
1
+ import bencher as bch
2
+
3
+
4
+ class DataSource:
5
+ def __init__(self):
6
+ self.data = [
7
+ [0, 0, 0, 0],
8
+ [1, 1, 1, 1],
9
+ [1, 1, 1, 1],
10
+ [2, 1, 1, 0],
11
+ [2, 2, 0, 0],
12
+ [2, 2, 1, 1],
13
+ ]
14
+
15
+ self.call_count = [0] * len(self.data)
16
+
17
+ def call(self, index, repeat=None):
18
+ if repeat is None:
19
+ self.call_count[index] += 1
20
+ repeat = self.call_count[index]
21
+ return self.data[index][repeat - 1]
22
+
23
+
24
+ class Example1D(bch.ParametrizedSweep):
25
+ index = bch.IntSweep(default=0, bounds=[0, 5], doc="Input angle", units="rad", samples=30)
26
+ output = bch.ResultVar(units="v", doc="sin of theta")
27
+ output2 = bch.ResultVar(units="v", doc="-sin of theta")
28
+
29
+ def __init__(self, **params):
30
+ super().__init__(**params)
31
+ self.data1 = DataSource()
32
+ self.data2 = DataSource()
33
+
34
+ def __call__(self, **kwargs):
35
+ self.update_params_from_kwargs(**kwargs)
36
+ self.output = self.data1.call(self.index)
37
+ self.output2 = -self.data2.call(self.index)
38
+ return super().__call__(**kwargs)
39
+
40
+
41
+ def example_1_in_2_out(
42
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
43
+ ) -> bch.Bench:
44
+ """This example shows how to sample a 1 dimensional float variable and plot the result of passing that parameter sweep to the benchmarking function"""
45
+ bench = Example1D().to_bench(run_cfg, report)
46
+ bench.plot_sweep()
47
+
48
+ # bench.report.append(bench.get_result().to_heatmap())
49
+ return bench
50
+
51
+
52
+ if __name__ == "__main__":
53
+ run_config = bch.BenchRunCfg()
54
+ reprt = bch.BenchReport()
55
+ example_1_in_2_out(run_config, reprt)
56
+ # run_config.over_time = True
57
+ # run_config.auto_plot = False
58
+ # for i in range(4):
59
+ # example_1_in_2_out(run_config, reprt)
60
+
61
+ # run_config.auto_plot = True
62
+ # example_1_in_2_out(run_config, reprt)
63
+ reprt.show()
@@ -0,0 +1,61 @@
1
+ import bencher as bch
2
+
3
+
4
+ class DataSource:
5
+ def __init__(self):
6
+ self.data = [
7
+ [0, 0, 0, 0],
8
+ [1, 1, 1, 1],
9
+ [1, 1, 1, 1],
10
+ [2, 1, 1, 0],
11
+ [2, 2, 0, 0],
12
+ [2, 2, 1, 1],
13
+ ]
14
+
15
+ self.call_count = [0] * len(self.data)
16
+
17
+ def call(self, index, repeat=None):
18
+ if repeat is None:
19
+ self.call_count[index] += 1
20
+ repeat = self.call_count[index]
21
+ return self.data[index][repeat - 1]
22
+
23
+
24
+ class Example1D(bch.ParametrizedSweep):
25
+ index = bch.IntSweep(default=0, bounds=[0, 5], doc="Input angle", units="rad", samples=30)
26
+ output = bch.ResultVar(units="v", doc="sin of theta")
27
+ output2 = bch.ResultVar(units="v", doc="-sin of theta")
28
+
29
+ def __init__(self, **params):
30
+ super().__init__(**params)
31
+ self.data1 = DataSource()
32
+ self.data2 = DataSource()
33
+
34
+ def __call__(self, **kwargs):
35
+ self.update_params_from_kwargs(**kwargs)
36
+ self.output = self.data1.call(self.index)
37
+ self.output2 = -self.data2.call(self.index)
38
+ return super().__call__(**kwargs)
39
+
40
+
41
+ def example_1_in_2_out_repeats(
42
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
43
+ ) -> bch.Bench:
44
+ """This example shows how to sample a 1 dimensional float variable and plot the result of passing that parameter sweep to the benchmarking function"""
45
+
46
+ from importlib.metadata import version
47
+
48
+ print(version("holobench"))
49
+ if run_cfg is None:
50
+ run_cfg = bch.BenchRunCfg()
51
+ run_cfg.repeats = 4
52
+ bench = Example1D().to_bench(run_cfg, report)
53
+ bench.plot_sweep()
54
+ return bench
55
+
56
+
57
+ if __name__ == "__main__":
58
+ run_config = bch.BenchRunCfg()
59
+ reprt = bch.BenchReport()
60
+ example_1_in_2_out_repeats(run_config, reprt)
61
+ reprt.show()
File without changes
@@ -20,7 +20,7 @@ class NoiseDistribution(StrEnum):
20
20
  if noisy:
21
21
  match noise_distribution:
22
22
  case NoiseDistribution.uniform:
23
- return random.uniform(0, sigma)
23
+ return random.uniform(-sigma / 2.0, sigma / 2)
24
24
  case NoiseDistribution.gaussian:
25
25
  return random.gauss(0, sigma)
26
26
  return 0.0
@@ -34,7 +34,7 @@ class BenchableObject(bch.ParametrizedSweep):
34
34
  float2 = bch.FloatSweep(default=0, bounds=[0, 1.0], doc="y coordinate of the sample volume")
35
35
  float3 = bch.FloatSweep(default=0, bounds=[0, 1.0], doc="z coordinate of the sample volume")
36
36
 
37
- sigma = bch.FloatSweep(default=1, bounds=[1, 10], doc="standard deviation of the added noise")
37
+ sigma = bch.FloatSweep(default=0.2, bounds=[0, 10], doc="standard deviation of the added noise")
38
38
 
39
39
  # categorial variables
40
40
  noisy = bch.BoolSweep(
@@ -78,10 +78,10 @@ class BenchMeta(bch.ParametrizedSweep):
78
78
  """This class uses bencher to display the multidimensional types bencher can represent"""
79
79
 
80
80
  float_vars = bch.IntSweep(
81
- default=1, bounds=(0, 4), doc="The number of floating point variables that are swept"
81
+ default=0, bounds=(0, 4), doc="The number of floating point variables that are swept"
82
82
  )
83
83
  categorical_vars = bch.IntSweep(
84
- default=1, bounds=(0, 3), doc="The number of categorical variables that are swept"
84
+ default=0, bounds=(0, 3), doc="The number of categorical variables that are swept"
85
85
  )
86
86
  sample_with_repeats = bch.IntSweep(default=1, bounds=(1, 10))
87
87
 
@@ -141,9 +141,7 @@ class BenchMeta(bch.ParametrizedSweep):
141
141
  return super().__call__()
142
142
 
143
143
 
144
- def example_meta(
145
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
146
- ) -> bch.Bench:
144
+ def example_meta(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
147
145
  bench = BenchMeta().to_bench(run_cfg, report)
148
146
 
149
147
  bench.plot_sweep(
@@ -2,9 +2,7 @@ import bencher as bch
2
2
  from bencher.example.meta.example_meta import BenchMeta
3
3
 
4
4
 
5
- def example_meta_cat(
6
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
7
- ) -> bch.Bench:
5
+ def example_meta_cat(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
8
6
  bench = BenchMeta().to_bench(run_cfg, report)
9
7
 
10
8
  bench.plot_sweep(
@@ -3,7 +3,7 @@ from bencher.example.meta.example_meta import BenchMeta
3
3
 
4
4
 
5
5
  def example_meta_float(
6
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
6
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
7
7
  ) -> bch.Bench:
8
8
  bench = BenchMeta().to_bench(run_cfg, report)
9
9
 
@@ -3,7 +3,7 @@ from bencher.example.meta.example_meta import BenchMeta
3
3
 
4
4
 
5
5
  def example_meta_levels(
6
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
6
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
7
7
  ) -> bch.Bench:
8
8
  bench = BenchMeta().to_bench(run_cfg, report)
9
9
 
@@ -0,0 +1,54 @@
1
+ import nbformat as nbf
2
+ from pathlib import Path
3
+
4
+
5
+ def convert_example_to_jupyter_notebook(filename: str, output_path: str):
6
+ # print
7
+ source_path = Path(filename)
8
+
9
+ nb = nbf.v4.new_notebook()
10
+ title = source_path.stem
11
+ function_name = f"{source_path.stem}()"
12
+ text = f"""# {title}"""
13
+
14
+ code = "%%capture\n"
15
+
16
+ example_code = source_path.read_text(encoding="utf-8")
17
+ split_code = example_code.split("""if __name__ == "__main__":""")
18
+ code += split_code[0]
19
+
20
+ code += f"""
21
+ bench={function_name}
22
+ """
23
+
24
+ code_results = """
25
+ from bokeh.io import output_notebook
26
+ output_notebook()
27
+ bench.get_result().to_auto_plots()
28
+ """
29
+
30
+ nb["cells"] = [
31
+ nbf.v4.new_markdown_cell(text),
32
+ nbf.v4.new_code_cell(code),
33
+ nbf.v4.new_code_cell(code_results),
34
+ ]
35
+ output_path = Path(f"docs/reference/{output_path}/ex_{title}.ipynb")
36
+ output_path.parent.mkdir(parents=True, exist_ok=True)
37
+ output_path.write_text(nbf.writes(nb), encoding="utf-8")
38
+
39
+
40
+ if __name__ == "__main__":
41
+ convert_example_to_jupyter_notebook(
42
+ "/workspaces/bencher/bencher/example/inputs_1D/example_1_in_1_out.py", "1D"
43
+ )
44
+ convert_example_to_jupyter_notebook(
45
+ "/workspaces/bencher/bencher/example/inputs_1D/example_1_in_2_out.py", "1D"
46
+ )
47
+
48
+ convert_example_to_jupyter_notebook(
49
+ "/workspaces/bencher/bencher/example/inputs_1D/example_1_in_2_out_repeats.py", "1D"
50
+ )
51
+
52
+ convert_example_to_jupyter_notebook(
53
+ "/workspaces/bencher/bencher/example/example_simple_float.py", "1D"
54
+ )
@@ -0,0 +1,127 @@
1
+ import nbformat as nbf
2
+ from typing import Any
3
+ import bencher as bch
4
+
5
+
6
+ from bencher.example.meta.example_meta import BenchableObject
7
+
8
+
9
+ class BenchMetaGen(bch.ParametrizedSweep):
10
+ """This class uses bencher to display the multidimensional types bencher can represent"""
11
+
12
+ float_vars = bch.IntSweep(
13
+ default=0, bounds=(0, 4), doc="The number of floating point variables that are swept"
14
+ )
15
+ categorical_vars = bch.IntSweep(
16
+ default=0, bounds=(0, 3), doc="The number of categorical variables that are swept"
17
+ )
18
+ sample_with_repeats = bch.IntSweep(default=1, bounds=(1, 100))
19
+
20
+ sample_over_time = bch.BoolSweep(default=False)
21
+
22
+ level = bch.IntSweep(default=2, units="level", bounds=(2, 5))
23
+
24
+ run_bench = False
25
+
26
+ plots = bch.ResultReference(units="int")
27
+
28
+ def __call__(self, **kwargs: Any) -> Any:
29
+ self.update_params_from_kwargs(**kwargs)
30
+
31
+ run_cfg = bch.BenchRunCfg()
32
+ run_cfg.level = self.level
33
+ run_cfg.repeats = self.sample_with_repeats
34
+ run_cfg.over_time = self.sample_over_time
35
+ run_cfg.plot_size = 500
36
+
37
+ # bench = bch.Bench("benchable", BenchableObject(), run_cfg=run_cfg)
38
+
39
+ inputs_vars_float = [
40
+ "float1",
41
+ "float2",
42
+ "float3",
43
+ "sigma",
44
+ ]
45
+
46
+ inputs_vars_cat = [
47
+ "noisy",
48
+ "noise_distribution",
49
+ "negate_output",
50
+ ]
51
+
52
+ input_vars = inputs_vars_float[: self.float_vars] + inputs_vars_cat[: self.categorical_vars]
53
+
54
+ if self.run_bench:
55
+ bench = BenchableObject().to_bench(run_cfg)
56
+ res = bench.plot_sweep(
57
+ "test",
58
+ input_vars=input_vars,
59
+ result_vars=["distance", "sample_noise"],
60
+ plot_callbacks=False,
61
+ )
62
+ self.plots = bch.ResultReference()
63
+ self.plots.obj = res.to_auto()
64
+
65
+ title = f"{self.float_vars}_float_{self.categorical_vars}_cat"
66
+
67
+ nb = nbf.v4.new_notebook()
68
+ text = f"""# {title}"""
69
+
70
+ code_gen = f"""
71
+ %%capture
72
+ import bencher as bch
73
+ from bencher.example.meta.example_meta import BenchableObject
74
+
75
+ run_cfg = bch.BenchRunCfg()
76
+ run_cfg.repeats = {self.sample_with_repeats}
77
+ run_cfg.level = 4
78
+ bench = BenchableObject().to_bench(run_cfg)
79
+ res=bench.plot_sweep(input_vars={input_vars},
80
+ result_vars=["distance","sample_noise"])
81
+ """
82
+ code_results = """
83
+ from bokeh.io import output_notebook
84
+ output_notebook()
85
+ res.to_auto_plots()
86
+ """
87
+
88
+ nb["cells"] = [
89
+ nbf.v4.new_markdown_cell(text),
90
+ nbf.v4.new_code_cell(code_gen),
91
+ nbf.v4.new_code_cell(code_results),
92
+ ]
93
+ from pathlib import Path
94
+
95
+ fname = Path(f"docs/reference/Meta/ex_{title}.ipynb")
96
+ fname.parent.mkdir(parents=True, exist_ok=True)
97
+ fname.write_text(nbf.writes(nb), encoding="utf-8")
98
+
99
+ return super().__call__()
100
+
101
+
102
+ def example_meta(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
103
+ bench = BenchMetaGen().to_bench(run_cfg, report)
104
+
105
+ bench.plot_sweep(
106
+ title="Meta Bench",
107
+ description="""## All Combinations of Variable Sweeps and Resulting Plots
108
+ This uses bencher to display all the combinations of plots bencher is able to produce""",
109
+ input_vars=[
110
+ bch.p("float_vars", [0, 1, 2, 3]),
111
+ "categorical_vars",
112
+ bch.p("sample_with_repeats", [1, 20]),
113
+ # "sample_over_time",
114
+ ],
115
+ const_vars=[
116
+ # BenchMeta.param.float_vars.with_const(1),
117
+ # BenchMeta.param.sample_with_repeats.with_const(2),
118
+ # BenchMeta.param.categorical_vars.with_const(2),
119
+ # BenchMeta.param.sample_over_time.with_const(True),
120
+ ],
121
+ )
122
+
123
+ return bench
124
+
125
+
126
+ if __name__ == "__main__":
127
+ example_meta().report.show()
@@ -45,9 +45,7 @@ class ToyOptimisationProblem(bch.ParametrizedSweep):
45
45
  return self.get_results_values_as_dict()
46
46
 
47
47
 
48
- def optuna_rastrigin(
49
- run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
50
- ):
48
+ def optuna_rastrigin(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None):
51
49
  explorer = ToyOptimisationProblem()
52
50
 
53
51
  bench = bch.Bench("Rastrigin", explorer.rastrigin, run_cfg=run_cfg, report=report)
bencher/job.py CHANGED
@@ -36,9 +36,9 @@ class JobFuture:
36
36
  self.res = res
37
37
  self.future = future
38
38
  # either a result or a future needs to be passed
39
- assert (
40
- self.res is not None or self.future is not None
41
- ), "make sure you are returning a dict or super().__call__(**kwargs) from your __call__ function"
39
+ assert self.res is not None or self.future is not None, (
40
+ "make sure you are returning a dict or super().__call__(**kwargs) from your __call__ function"
41
+ )
42
42
 
43
43
  self.cache = cache
44
44
 
@@ -162,7 +162,7 @@ class FutureCache:
162
162
  logging.info(f"cache calls: {self.worker_cache_call_count}")
163
163
  logging.info(f"worker calls: {self.worker_fn_call_count}")
164
164
  if self.cache:
165
- return f"cache size :{int(self.cache.volume() / 1000000)}MB / {int(self.size_limit/1000000)}MB"
165
+ return f"cache size :{int(self.cache.volume() / 1000000)}MB / {int(self.size_limit / 1000000)}MB"
166
166
  return ""
167
167
 
168
168
 
@@ -97,7 +97,7 @@ class BenchResultBase(OptunaResult):
97
97
  ds_out = self.ds.copy()
98
98
 
99
99
  if result_var is not None:
100
- ds_out = ds_out[result_var.name]
100
+ ds_out = ds_out[result_var.name].to_dataset(name=result_var.name)
101
101
 
102
102
  def rename_ds(dataset: xr.Dataset, suffix: str):
103
103
  # var_name =
@@ -317,6 +317,7 @@ class BenchResultBase(OptunaResult):
317
317
  result_types=None,
318
318
  pane_collection: pn.pane = None,
319
319
  zip_results=False,
320
+ reduce: ReduceType = None,
320
321
  **kwargs,
321
322
  ) -> Optional[pn.Row]:
322
323
  if hv_dataset is None:
@@ -332,7 +333,7 @@ class BenchResultBase(OptunaResult):
332
333
  if result_types is None or isinstance(rv, result_types):
333
334
  row.append(
334
335
  self.to_panes_multi_panel(
335
- hv_dataset,
336
+ self.to_hv_dataset(reduce=reduce, result_var=rv),
336
337
  rv,
337
338
  plot_callback=partial(plot_callback, **kwargs),
338
339
  target_dimension=target_dimension,
@@ -377,11 +378,12 @@ class BenchResultBase(OptunaResult):
377
378
  if matches_res.overall:
378
379
  return self.map_plot_panes(
379
380
  plot_callback=plot_callback,
380
- hv_dataset=self.to_hv_dataset(reduce=reduce),
381
+ hv_dataset=None,
381
382
  target_dimension=target_dimension,
382
383
  result_var=result_var,
383
384
  result_types=result_types,
384
385
  pane_collection=pane_collection,
386
+ reduce=reduce,
385
387
  **kwargs,
386
388
  )
387
389
  return matches_res.to_panel()
@@ -202,10 +202,18 @@ class HoloviewResult(PanelResult):
202
202
  ) -> Optional[hv.Curve]:
203
203
  hvds = hv.Dataset(dataset)
204
204
  title = self.title_from_ds(dataset, result_var, **kwargs)
205
- pt = hvds.to(hv.Curve).opts(title=title, **kwargs)
206
- pt *= hvds.to(hv.Spread).opts(alpha=0.2)
207
- if len(dataset.sizes) > 1:
208
- return pt.opts(legend_position="right").overlay()
205
+
206
+ # print(result_var.name, dataset)
207
+ pt = hv.Overlay()
208
+ # find pairs of {var_name} {var_name}_std to plot the line and their spreads.
209
+ for var in dataset.data_vars:
210
+ if not var.endswith("_std"):
211
+ std_var = f"{var}_std"
212
+ pt *= hvds.to(hv.Curve, vdims=var, label=var).opts(title=title, **kwargs)
213
+ # Only create a Spread if the matching _std variable exists
214
+ if std_var in dataset.data_vars:
215
+ pt *= hvds.to(hv.Spread, vdims=[var, std_var])
216
+
209
217
  return pt.opts(legend_position="right")
210
218
 
211
219
  def to_heatmap(
@@ -126,15 +126,13 @@ class IntSweep(Integer, SweepBase):
126
126
 
127
127
  if not isinstance(val, (int, np.integer)):
128
128
  raise ValueError(
129
- "Integer parameter %r must be an integer, " "not type %r." % (self.name, type(val))
129
+ "Integer parameter %r must be an integer, not type %r." % (self.name, type(val))
130
130
  )
131
131
 
132
132
  ###THESE ARE COPIES OF INTEGER VALIDATION BUT ALSO ALLOW NUMPY INT TYPES
133
133
  def _validate_step(self, val, step):
134
134
  if step is not None and not isinstance(step, (int, np.integer)):
135
- raise ValueError(
136
- "Step can only be None or an " "integer value, not type %r" % type(step)
137
- )
135
+ raise ValueError("Step can only be None or an integer value, not type %r" % type(step))
138
136
 
139
137
 
140
138
  class FloatSweep(Number, SweepBase):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: holobench
3
- Version: 1.36.2
3
+ Version: 1.39.0
4
4
  Summary: A package for benchmarking the performance of arbitrary functions
5
5
  Project-URL: Repository, https://github.com/dyson-ai/bencher
6
6
  Project-URL: Home, https://github.com/dyson-ai/bencher
@@ -33,12 +33,16 @@ Requires-Dist: rerun-notebook; extra == 'rerun'
33
33
  Requires-Dist: rerun-sdk==0.21.0; extra == 'rerun'
34
34
  Provides-Extra: test
35
35
  Requires-Dist: coverage<=7.6.10,>=7.5.4; extra == 'test'
36
- Requires-Dist: hypothesis<=6.123.2,>=6.104.2; extra == 'test'
37
- Requires-Dist: pre-commit<=4.0.1; extra == 'test'
38
- Requires-Dist: pylint<=3.3.3,>=3.2.5; extra == 'test'
36
+ Requires-Dist: hypothesis<=6.124.9,>=6.104.2; extra == 'test'
37
+ Requires-Dist: ipykernel; extra == 'test'
38
+ Requires-Dist: jupyter-bokeh; extra == 'test'
39
+ Requires-Dist: nbformat; extra == 'test'
40
+ Requires-Dist: pip; extra == 'test'
41
+ Requires-Dist: pre-commit<=4.1.0; extra == 'test'
42
+ Requires-Dist: pylint<=3.3.4,>=3.2.5; extra == 'test'
39
43
  Requires-Dist: pytest-cov<=6.0.0,>=4.1; extra == 'test'
40
44
  Requires-Dist: pytest<=8.3.4,>=7.4; extra == 'test'
41
- Requires-Dist: ruff<=0.8.5,>=0.5.0; extra == 'test'
45
+ Requires-Dist: ruff<=0.9.4,>=0.5.0; extra == 'test'
42
46
  Description-Content-Type: text/markdown
43
47
 
44
48
  # Bencher
@@ -105,7 +109,7 @@ pixi run demo
105
109
 
106
110
  An example of the type of output bencher produces can be seen here:
107
111
 
108
- https://dyson-ai.github.io/bencher/
112
+ https://blooop.github.io/bencher/
109
113
 
110
114
 
111
115
  ## Examples
@@ -127,6 +131,7 @@ Start with example_simple_float.py and explore other examples based on your data
127
131
 
128
132
  ## Documentation
129
133
 
130
- API documentation can be found at https://bencher.readthedocs.io/en/latest/
134
+ - [Examples Documentation](https://bencher.readthedocs.io/reference/index.html)
135
+ - [API documentation](https://bencher.readthedocs.io/autoapi/bencher/index.html)
131
136
 
132
137
  More documentation is needed for the examples and general workflow.
@@ -2,12 +2,12 @@ bencher/__init__.py,sha256=hWfQxlvuHRsFK4ZPCpRXo3nDzQB52JOUoi67wcnhopE,1890
2
2
  bencher/bench_cfg.py,sha256=gEpF1J4RAxCQPSkI8npKfhw-o3-8cw80TjiWK7As5WE,18417
3
3
  bencher/bench_plot_server.py,sha256=nvGTr981XgWELqV7yID91j6V1UIPGtKilzxHcNWaZ6Q,4196
4
4
  bencher/bench_report.py,sha256=ikMSHceyc8cYFH-sIza167DH-H-_iiTYDm2TmusUHDc,7515
5
- bencher/bench_runner.py,sha256=xoeXt8gcEhx5nAFsKBs8RmdkEyXUOyFd8mrEXyIxj3U,6531
5
+ bencher/bench_runner.py,sha256=wShmZ504BOKgHj0sOrGZtduyPfJHFFBfHRsz5tYy5_Q,7000
6
6
  bencher/bencher.py,sha256=-vbZIzBr2IYYG7be5Hh8IZgIGUysTxoxQUV6xUToH14,35437
7
7
  bencher/caching.py,sha256=AusaNrzGGlj5m6zcwcqnTn55Mam2mQdF--oqelO806M,1627
8
8
  bencher/class_enum.py,sha256=kYHW9qKkKcNdwaXizZL-fTptS_DUEGv4c88yCehk3gc,1492
9
9
  bencher/flask_server.py,sha256=uMhMaySUki5StC-r_TXb4KTVqAiffyqfH7UzQidFqSw,831
10
- bencher/job.py,sha256=smSRLLZNxFSuAo7mA3m_lzHc2opjNf-DjzszsCn4ENU,6216
10
+ bencher/job.py,sha256=8tztOwSYZqULaqD1Xv-wAdA6Rhgsa2I19P-ZzvnWPPw,6218
11
11
  bencher/optuna_conversions.py,sha256=an-LfPsQXyyvhIZnG8Wl1RQVYMvJj7WOi3YNqoUnuxQ,5356
12
12
  bencher/utils.py,sha256=DP2GJP28nSEihvZwiV1Rl7YJ5NTrRt2zBLs46eQ37hQ,9887
13
13
  bencher/utils_rerun.py,sha256=E1itolYJMjmtBE5qcSotiS20I-dobVnjznsTRvZaV0s,1212
@@ -15,41 +15,41 @@ bencher/video_writer.py,sha256=z49tAG_ttXc8iWcTkWPJO1QaneaVdsmYL6Hpal-pd4Q,2176
15
15
  bencher/worker_job.py,sha256=FREi0yWQACFmH86R1j-LH72tALEFkKhLDmmoGQY9Jh4,1571
16
16
  bencher/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  bencher/example/benchmark_data.py,sha256=DL5Grj7UwnKZz2BHfGNKv35Ln0y2ntFwvZdkchOMHVU,6985
18
- bencher/example/example_all.py,sha256=iiKV2poYWu4SUIQkpoX4qT1zTm574QfuNHpYww3meFA,1952
19
- bencher/example/example_categorical.py,sha256=ydJa-76aZLxxiqzVFkCY3SZNon0yscYhgX41yonoCnU,3685
18
+ bencher/example/example_all.py,sha256=_jOiz07fsjghiIuLfMpZiRVEkPaH7dM8OftOGcdL6cU,1960
19
+ bencher/example/example_categorical.py,sha256=S6PP3LHZewHVymNZmEY-AEMRlJbv0CEgJ1NRWNDEnC8,3659
20
20
  bencher/example/example_composable_container.py,sha256=URN_2Wv98_JpjWJUhbvK2YejpqumUJMTbQ9ok07TNZw,3753
21
21
  bencher/example/example_composable_container2.py,sha256=tVcSggLAzuXsiHM00qSJk9fKOgqXbSzzyjs7IayLZCw,5667
22
22
  bencher/example/example_consts.py,sha256=upKkrMNYUCS38IA4duuyJHERwdZIMB4FA60Gytu_BzU,1475
23
- bencher/example/example_custom_sweep.py,sha256=Tl3SJXXlx2_Jko-q8nkeKLfVL21rITI3j4bTrPJVJiA,1917
23
+ bencher/example/example_custom_sweep.py,sha256=OvAMqirV9KzbuaQ6ELOAbrRrj5zYHjpEs3tG-rgmFJM,1891
24
24
  bencher/example/example_custom_sweep2.py,sha256=6RBiyVVaxAh5Aul85DfYA5P-lwhwW3Bb54o0CBgTB6Q,1225
25
25
  bencher/example/example_dataframe.py,sha256=aGSdMnsRvRC2dgkUVmzEJz5yo6k1lPjsUM6gFShNcRI,1792
26
- bencher/example/example_docs.py,sha256=aUi33O543JBPoOGlpHaY2eA74GR7cHH_6-hcC8xf3z0,1174
26
+ bencher/example/example_docs.py,sha256=j80DCZqfvfkzvy7kgasSvq4F011ZHuq8jjFsEWiFTMk,1200
27
27
  bencher/example/example_filepath.py,sha256=O3VO9rWAXB_1tagVSvxhiSMjcTkgZe2duw7W17ij7po,827
28
- bencher/example/example_float3D.py,sha256=Ya9zIfUZmbqV6GZrRjcV44uMnKeKgG6RrLBsky0P5LY,3066
29
- bencher/example/example_float_cat.py,sha256=nQDBWYRVZrJW5ABIizqcD6mXswHWSdEDzM-FeYFqYqY,3821
30
- bencher/example/example_floats.py,sha256=HcQgfwldTVeFBmBTMtZ0yRy17ZJ4cfJeI_t8TxY2iOI,4269
31
- bencher/example/example_floats2D.py,sha256=D0kljoUCinMKCEW-Zg-cQ8sYu_yPCZqzKJ9tRtt-Ono,3697
32
- bencher/example/example_holosweep.py,sha256=u3w2ixvpx96nNS49sE5j704ZSFwdJVS5HVRsz19kIXc,3021
33
- bencher/example/example_holosweep_objects.py,sha256=vHuAtkM1VrJelHOazn_SJfzxNywKyaMzN-DE8W7Ricc,3228
34
- bencher/example/example_holosweep_tap.py,sha256=NYXofWGV9GaBN72Q3kKPT5lKJ-slYZH5VzTAavUu23w,4527
35
- bencher/example/example_image.py,sha256=UiRzV1cKdtBLxlD16xswro61memxxcy25wteHyMjSkc,5548
28
+ bencher/example/example_float3D.py,sha256=QBPET3oxRJXM5ToXdOPtIsHd-9SBK8GD9y0gC9N4UC4,3034
29
+ bencher/example/example_float_cat.py,sha256=_jedRBPQmKwxo1Yvph8SnUGVoK5Mpj9aLZIYex31bzQ,3789
30
+ bencher/example/example_floats.py,sha256=x-3wx9-SHueuqjNHuKqEGeYWU7ZdZ1DR7X_1dktOKbg,4237
31
+ bencher/example/example_floats2D.py,sha256=1V5hCxr0Iz2KT2JyePn-XmugsMXlDzf0GazWWvq0kYo,3665
32
+ bencher/example/example_holosweep.py,sha256=emNUKCHPb-JrSWPjHajuAlQmUU9A9S7O-jdrvixg0Io,2989
33
+ bencher/example/example_holosweep_objects.py,sha256=eqOjuTYh4Pis5lGsSeN7BJZXKR2upOSjynEtR0HqyoY,3196
34
+ bencher/example/example_holosweep_tap.py,sha256=vKGyCdc1H8oECWRACW1kj5s1OJPAUETWHbP88R9hW_A,4475
35
+ bencher/example/example_image.py,sha256=9VG2XiQnhksYh6WuU18a4b36KIrF-yY7dhZKdL0oG1I,5490
36
36
  bencher/example/example_image1.py,sha256=GO-PuiEKcFBma5fVNDi-203ZhYJvP4hojjxsDa9B9HM,2678
37
- bencher/example/example_levels.py,sha256=gcNqjdsC0Bi0dX9oakssPEmuh_zFqpJhPYPPoDN3uw8,6890
37
+ bencher/example/example_levels.py,sha256=Gl3hIGYmzLufKWIG_YFTvW-TCfao6Ys6W0uc4dAcizw,6858
38
38
  bencher/example/example_levels2.py,sha256=tMhA6dYYQskzMeAZdaz6jRmQTe-c-jLXfkaUqWT30-I,1117
39
- bencher/example/example_pareto.py,sha256=sLh37iZSQitW7DE7ktbyaOgHr1ZWxG7pXxCMH00KKqQ,2688
39
+ bencher/example/example_pareto.py,sha256=tQxX9g8VfASv2vyRAm-Bv3qsYKjKnU-HyuLXtiZYEpw,2656
40
40
  bencher/example/example_publish.py,sha256=qIilHdsjqcUQ5u_IuGjjhJCLRkcQvhVuhI3efDrFTww,1005
41
41
  bencher/example/example_rerun.py,sha256=gruldZ6tmW56Mc6bPrNc7ChZEGHhYXPE4VVeG-L8w7M,981
42
42
  bencher/example/example_rerun2.py,sha256=TV8e2UMwLFowhiXb_sQG2IS-W5jXF67VCitVjD8u1o8,660
43
- bencher/example/example_sample_cache.py,sha256=sN5AcbX0Ycw1EFVRHWT0k6P3I1yKKDU-cPkZsqW2kGA,4188
43
+ bencher/example/example_sample_cache.py,sha256=VxL-lT3IuI57ToDdGZlBvzt_c_bl4AveyylQFMXg-vE,4162
44
44
  bencher/example/example_sample_cache_context.py,sha256=v_4hfmwZK38ZqV6QyEfs_I4W3BJX7RO_J-wDaS_DTT0,4062
45
45
  bencher/example/example_simple.py,sha256=E1-D10N-O50S33UQ9iLIlq09-x7BohbjYaR_lzLjQjc,11706
46
46
  bencher/example/example_simple_bool.py,sha256=GZ6pyj8FaQV9gNxaqAmX6c5XWtMvKosezAbSADEl0G0,1248
47
- bencher/example/example_simple_cat.py,sha256=XsV_75Jk3phVPI4om3q0vn1POfREb3CGRm9Kq1tL-OA,1760
48
- bencher/example/example_simple_float.py,sha256=5l3O6DzS1AV9LdpN_HfYxR-rvheXoRtWQWIER6-92aw,988
47
+ bencher/example/example_simple_cat.py,sha256=cPlt9JP1lgTqatZVAP1tk72lPSLkGkj4BjUl6fpRF_A,1728
48
+ bencher/example/example_simple_float.py,sha256=c3ZR0LXfgGcH63MnUpQovRVnzpx5lpDQs1T-Qzcm2U0,944
49
49
  bencher/example/example_simple_float2d.py,sha256=xsVOLO6AtMi9_fybpS_JZnhev5f11YuYWHrAOzJw2dI,1033
50
- bencher/example/example_strings.py,sha256=vStjrvfezNz7115iRtuwy0i7Gbu6w8mu-oHNfKNLNog,1570
51
- bencher/example/example_time_event.py,sha256=e6R-a6ZPe-ePiWoNvN3YuSQK-Y2HOGntsjCm_SPon28,2159
52
- bencher/example/example_video.py,sha256=QnEaMOt7taHVKD_t3EZ60aCTkVdt2hhJ2bDH2fNparg,3897
50
+ bencher/example/example_strings.py,sha256=NpOGwC1KRAyAAC2VQZCg09ArraESdU0lupFj4b0I-sQ,1538
51
+ bencher/example/example_time_event.py,sha256=l2dEut9oYnxxF7kRXnZx8Ohw1EdT5Iezo_b8CwCcCHA,2133
52
+ bencher/example/example_video.py,sha256=LUiFV841oQ7r-cP3vSHBT0-fIJ-AK51_HyL2gOLMv9k,3839
53
53
  bencher/example/example_workflow.py,sha256=00QnUuViMfX_PqzqkXmg1wPX6yAq7IS7mCL_RFKwrMM,6806
54
54
  bencher/example/experimental/example_bokeh_plotly.py,sha256=3jUKh8eKIAlpklKnp8UopIHhUDw1A0_5CwjeyTzbi7o,846
55
55
  bencher/example/experimental/example_hover_ex.py,sha256=qszw4FkIfqQkVviPSpmUoFOoi6PGotGbsc7Ojyx8EtU,1052
@@ -60,13 +60,20 @@ bencher/example/experimental/example_streams.py,sha256=rrTmcmxDlirGoyTbJ4LT4fBIA
60
60
  bencher/example/experimental/example_template.py,sha256=XdIVS9RtLdE5GNnerWiZMXvP7n17lzuc_YTLqJTwb6Q,1172
61
61
  bencher/example/experimental/example_updates.py,sha256=rF4UgWY-CW6ohNtOpQklTuwbwVRvEM5j6edZOiMkspQ,1835
62
62
  bencher/example/experimental/example_vector.py,sha256=3o_1dA4dc2HL6uIEvDAcvLPVJB8jgkq1QZ3BQIL-LEo,3118
63
- bencher/example/inputs_0D/example_0D.py,sha256=WgelKMVahagrLpCByosqh4bHC58BXJ4-AO7zqgjNjH8,1225
64
- bencher/example/inputs_1D/example_1D.py,sha256=aT_4mtYNSN49qMG51jgW9X3NSGGC_GrGpgUNG6i0NZ8,1315
65
- bencher/example/meta/example_meta.py,sha256=XBpfu47z86vz8QSZjLA1uWltoRZSej7W48nveFKqj5w,5564
66
- bencher/example/meta/example_meta_cat.py,sha256=FMBT0yMPJJo0pmUYVtlq64R6qn_EXEt74xYAsK6HQag,641
67
- bencher/example/meta/example_meta_float.py,sha256=D71oiFqGauLvqTxv2BC4CJOwHIdpvq8FdCBVejwZ4Do,624
68
- bencher/example/meta/example_meta_levels.py,sha256=MkVL8pAIogn8ObKdSn8BC_DKk6PSVvvPU7_KUCgP5vQ,1436
69
- bencher/example/optuna/example_optuna.py,sha256=-RIuDrdPjfXz1c1hOAmWeJNdmGICiWnyJfAavRsiMuk,2370
63
+ bencher/example/inputs_0D/example_0_in_1_out.py,sha256=Lm4lgNGy6oLAEuqDEWHqWGbU6-T2LUudNtP3NKrFDho,1706
64
+ bencher/example/inputs_0D/example_0_in_2_out.py,sha256=HFtuuuZspK0Hy_1hEbaQy8Ah3SFtSf04yHbaaB9YYec,1389
65
+ bencher/example/inputs_1D/example1d_common.py,sha256=QurBf3rYq4B3nG9J7Rra30XXtoE6EeDHjPH0CrQ-T9g,2069
66
+ bencher/example/inputs_1D/example_1_in_1_out.py,sha256=eqAztAufMNTSVE3xdA9Nyqc8UXUn7Y2cjsIP_T_ITUw,1774
67
+ bencher/example/inputs_1D/example_1_in_2_out.py,sha256=9qwDF5m25pzwRLeqQB_IO1I0ER07-izc9lFJBcapMdo,1908
68
+ bencher/example/inputs_1D/example_1_in_2_out_repeats.py,sha256=0xt1B9xkCdDhTa8zBVmV565z22SO0RCQcAkCRuF4c1k,1804
69
+ bencher/example/meta/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
+ bencher/example/meta/example_meta.py,sha256=ZXW8LZ1DGs05RiZRHLrOx-qt9x10qL6v2tt7Ulay-mM,5549
71
+ bencher/example/meta/example_meta_cat.py,sha256=j3OCi1Yra47wrXOVr8epMYPGIXjQwdQoCcCICPmE2lo,609
72
+ bencher/example/meta/example_meta_float.py,sha256=Y-zo7QAZkpt3mQEE4guiPmRHmKjn6-y8D_AjWeGCqEs,598
73
+ bencher/example/meta/example_meta_levels.py,sha256=ZZ14r99z6cs73ZwvBJvDKdEVIdTyHzrWsenxRgFXfXQ,1410
74
+ bencher/example/meta/generate_examples.py,sha256=Uicdr5PlamqiFGgEzEtdPzQPfVRE6UOa1CH-3UQ6T_I,1540
75
+ bencher/example/meta/generate_meta.py,sha256=1euRIVEAUlT3a_olmhZXbHMaG9OCSzsgKajXXwf1vOI,3874
76
+ bencher/example/optuna/example_optuna.py,sha256=0zA6IIDWe7FM0rnYJ-FHF9GZtrhYdKHQTosUD2Raw0M,2338
70
77
  bencher/example/shelved/example_float2D_scatter.py,sha256=z8ranMq8IcJ1yoVSFDncp3gw-yWG7X9lXLimXKpy5Ks,3372
71
78
  bencher/example/shelved/example_float3D_cone.py,sha256=T3dkiEhjm6z3-Vs2SjCNWPKeHk8Bp4FbANE6yXYc_YM,2970
72
79
  bencher/example/shelved/example_kwargs.py,sha256=ahWC3d1vQMS0bdYtZGEILyDGnT5ixR5nVHSnvqMgFL0,2462
@@ -75,10 +82,10 @@ bencher/plotting/plot_filter.py,sha256=hWRjZa9zTncVJiF6r_DI4Ce1xcU49PxJw4gXk7Azs
75
82
  bencher/plotting/plt_cnt_cfg.py,sha256=0P9KjVQSUfPY7Kh7UGAbTqihaTgnmLm3oZ5Nvf-pcjM,3193
76
83
  bencher/results/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
77
84
  bencher/results/bench_result.py,sha256=j-Al54h26Qypma0dYbx0hs8lBUUX46xXov7DQAZsG7A,3763
78
- bencher/results/bench_result_base.py,sha256=9woMlOI2elc14SA8XGWOiOEEg7C3hzACelp6NogLCGM,21897
85
+ bencher/results/bench_result_base.py,sha256=a_IHbliBtLgziqBjkz0MJiu7JkSkrmz1VzBnLenXF6E,22005
79
86
  bencher/results/dataset_result.py,sha256=qXmFMrVAo_1qM6hhV4XpQqmCz9RiVkQo6ICYmbT-Kvk,8680
80
87
  bencher/results/float_formatter.py,sha256=sX6HNCyaXdHDxC8ybVUHwCJ3qOKbPUkBOplVIHtKWjM,1746
81
- bencher/results/holoview_result.py,sha256=9tmVUrP7qJD_5lIURm0QJFRDvFfnZKr_0UGvktx5u5g,29112
88
+ bencher/results/holoview_result.py,sha256=r9G9p2i7r01O2ZnsPoyOJU39ImMQhW1QvGV0mNgolc4,29463
82
89
  bencher/results/hvplot_result.py,sha256=bYSewYhPLVzW6HF_WPjAhS1ZiRp9FJHs008UEBXgH4Y,1993
83
90
  bencher/results/optuna_result.py,sha256=QtZ4TGRun7gJoFVUjEyXKPF5yakwOSXrqEXQVJdJmm4,13587
84
91
  bencher/results/panel_result.py,sha256=lXOtfhWKSspf53Wgm94DTiVD3rliieHQW96sOdu5UYk,1336
@@ -91,13 +98,13 @@ bencher/results/composable_container/composable_container_dataframe.py,sha256=Zb
91
98
  bencher/results/composable_container/composable_container_panel.py,sha256=HrOoeGB0y0jGQcxcci_M82ftsvklLkJgo-4SjDBJCks,1232
92
99
  bencher/results/composable_container/composable_container_video.py,sha256=X6XxBNDglnNLjQ4QrhxJ8W3Re_aLeTZKKVsbjjJ3av8,7107
93
100
  bencher/variables/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
94
- bencher/variables/inputs.py,sha256=vxpVKhbM8inYiiHcatJLGl0zg9boMYKJRtLVc32YGpY,6730
101
+ bencher/variables/inputs.py,sha256=B4IycsuZQOx51OGO2e8zK5TjfRWvYXI7Ngle3KpVIdw,6694
95
102
  bencher/variables/parametrised_sweep.py,sha256=fxjKOQ2x5xuCyi0kO1_XS9bXiib1bjThhvpulZPeyv8,7802
96
103
  bencher/variables/results.py,sha256=Wq14e8rAj5mcK22325wcaeTMjgZ6JuduqceAHItHFY8,7750
97
104
  bencher/variables/sweep_base.py,sha256=gfEhKvsb16ZLbe38JewZqu0AMOHpsqwRbZbt-aCg9Bc,6258
98
105
  bencher/variables/time.py,sha256=zcRS5p4ZkFjMta9nZMEuWv86rLnPkUSqyO69QwI5q3E,3142
99
106
  resource/bencher,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
100
- holobench-1.36.2.dist-info/METADATA,sha256=LatneVFqrFrPAUgv83lZ-icNbRrYR_M-WjpaGGMj5rE,6600
101
- holobench-1.36.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
102
- holobench-1.36.2.dist-info/licenses/LICENSE,sha256=dSHXTdRY4Y7qGFMv63UksV700iff7iE-p7GGs6Sbnvo,1065
103
- holobench-1.36.2.dist-info/RECORD,,
107
+ holobench-1.39.0.dist-info/METADATA,sha256=Gg7yTS0RBzAm-0Z--FcKn2Wzvqseg_0fiEUuqXRGgtI,6848
108
+ holobench-1.39.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
109
+ holobench-1.39.0.dist-info/licenses/LICENSE,sha256=dSHXTdRY4Y7qGFMv63UksV700iff7iE-p7GGs6Sbnvo,1065
110
+ holobench-1.39.0.dist-info/RECORD,,