holobench 1.28.1__tar.gz → 1.29.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. {holobench-1.28.1/holobench.egg-info → holobench-1.29.0}/PKG-INFO +1 -1
  2. {holobench-1.28.1 → holobench-1.29.0}/bencher/__init__.py +1 -0
  3. {holobench-1.28.1 → holobench-1.29.0}/bencher/bencher.py +13 -1
  4. holobench-1.29.0/bencher/example/example_dataframe.py +48 -0
  5. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_image.py +5 -7
  6. holobench-1.29.0/bencher/example/example_image1.py +81 -0
  7. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/bench_result.py +3 -1
  8. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/bench_result_base.py +53 -4
  9. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/composable_container/composable_container_base.py +1 -1
  10. holobench-1.29.0/bencher/results/composable_container/composable_container_dataframe.py +52 -0
  11. holobench-1.29.0/bencher/results/dataset_result.py +227 -0
  12. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/optuna_result.py +1 -0
  13. {holobench-1.28.1 → holobench-1.29.0}/bencher/variables/parametrised_sweep.py +2 -2
  14. {holobench-1.28.1 → holobench-1.29.0}/bencher/variables/results.py +29 -1
  15. {holobench-1.28.1 → holobench-1.29.0/holobench.egg-info}/PKG-INFO +1 -1
  16. {holobench-1.28.1 → holobench-1.29.0}/holobench.egg-info/SOURCES.txt +4 -0
  17. {holobench-1.28.1 → holobench-1.29.0}/pyproject.toml +2 -1
  18. {holobench-1.28.1 → holobench-1.29.0}/test/test_bench_examples.py +4 -0
  19. {holobench-1.28.1 → holobench-1.29.0}/LICENSE +0 -0
  20. {holobench-1.28.1 → holobench-1.29.0}/MANIFEST.in +0 -0
  21. {holobench-1.28.1 → holobench-1.29.0}/README.md +0 -0
  22. {holobench-1.28.1 → holobench-1.29.0}/bencher/bench_cfg.py +0 -0
  23. {holobench-1.28.1 → holobench-1.29.0}/bencher/bench_plot_server.py +0 -0
  24. {holobench-1.28.1 → holobench-1.29.0}/bencher/bench_report.py +0 -0
  25. {holobench-1.28.1 → holobench-1.29.0}/bencher/bench_runner.py +0 -0
  26. {holobench-1.28.1 → holobench-1.29.0}/bencher/caching.py +0 -0
  27. {holobench-1.28.1 → holobench-1.29.0}/bencher/class_enum.py +0 -0
  28. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/__init__.py +0 -0
  29. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/benchmark_data.py +0 -0
  30. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_all.py +0 -0
  31. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_categorical.py +0 -0
  32. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_composable_container.py +0 -0
  33. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_composable_container2.py +0 -0
  34. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_consts.py +0 -0
  35. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_custom_sweep.py +0 -0
  36. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_custom_sweep2.py +0 -0
  37. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_docs.py +0 -0
  38. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_filepath.py +0 -0
  39. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_float3D.py +0 -0
  40. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_float_cat.py +0 -0
  41. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_floats.py +0 -0
  42. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_floats2D.py +0 -0
  43. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_holosweep.py +0 -0
  44. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_holosweep_objects.py +0 -0
  45. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_holosweep_tap.py +0 -0
  46. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_levels.py +0 -0
  47. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_levels2.py +0 -0
  48. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_pareto.py +0 -0
  49. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_sample_cache.py +0 -0
  50. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_sample_cache_context.py +0 -0
  51. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_simple.py +0 -0
  52. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_simple_bool.py +0 -0
  53. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_simple_cat.py +0 -0
  54. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_simple_float.py +0 -0
  55. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_simple_float2d.py +0 -0
  56. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_strings.py +0 -0
  57. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_time_event.py +0 -0
  58. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_video.py +0 -0
  59. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/example_workflow.py +0 -0
  60. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/experimental/example_bokeh_plotly.py +0 -0
  61. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/experimental/example_hover_ex.py +0 -0
  62. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/experimental/example_hvplot_explorer.py +0 -0
  63. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/experimental/example_interactive.py +0 -0
  64. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/experimental/example_streamnd.py +0 -0
  65. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/experimental/example_streams.py +0 -0
  66. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/experimental/example_template.py +0 -0
  67. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/experimental/example_updates.py +0 -0
  68. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/experimental/example_vector.py +0 -0
  69. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/meta/example_meta.py +0 -0
  70. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/meta/example_meta_cat.py +0 -0
  71. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/meta/example_meta_float.py +0 -0
  72. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/meta/example_meta_levels.py +0 -0
  73. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/optuna/example_optuna.py +0 -0
  74. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/shelved/example_float2D_scatter.py +0 -0
  75. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/shelved/example_float3D_cone.py +0 -0
  76. {holobench-1.28.1 → holobench-1.29.0}/bencher/example/shelved/example_kwargs.py +0 -0
  77. {holobench-1.28.1 → holobench-1.29.0}/bencher/job.py +0 -0
  78. {holobench-1.28.1 → holobench-1.29.0}/bencher/optuna_conversions.py +0 -0
  79. {holobench-1.28.1 → holobench-1.29.0}/bencher/plotting/__init__.py +0 -0
  80. {holobench-1.28.1 → holobench-1.29.0}/bencher/plotting/plot_filter.py +0 -0
  81. {holobench-1.28.1 → holobench-1.29.0}/bencher/plotting/plt_cnt_cfg.py +0 -0
  82. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/__init__.py +0 -0
  83. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/composable_container/__init__.py +0 -0
  84. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/composable_container/composable_container_panel.py +0 -0
  85. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/composable_container/composable_container_video.py +0 -0
  86. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/float_formatter.py +0 -0
  87. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/holoview_result.py +0 -0
  88. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/panel_result.py +0 -0
  89. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/plotly_result.py +0 -0
  90. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/video_result.py +0 -0
  91. {holobench-1.28.1 → holobench-1.29.0}/bencher/results/video_summary.py +0 -0
  92. {holobench-1.28.1 → holobench-1.29.0}/bencher/utils.py +0 -0
  93. {holobench-1.28.1 → holobench-1.29.0}/bencher/variables/__init__.py +0 -0
  94. {holobench-1.28.1 → holobench-1.29.0}/bencher/variables/inputs.py +0 -0
  95. {holobench-1.28.1 → holobench-1.29.0}/bencher/variables/sweep_base.py +0 -0
  96. {holobench-1.28.1 → holobench-1.29.0}/bencher/variables/time.py +0 -0
  97. {holobench-1.28.1 → holobench-1.29.0}/bencher/video_writer.py +0 -0
  98. {holobench-1.28.1 → holobench-1.29.0}/bencher/worker_job.py +0 -0
  99. {holobench-1.28.1 → holobench-1.29.0}/holobench.egg-info/dependency_links.txt +0 -0
  100. {holobench-1.28.1 → holobench-1.29.0}/holobench.egg-info/not-zip-safe +0 -0
  101. {holobench-1.28.1 → holobench-1.29.0}/holobench.egg-info/requires.txt +0 -0
  102. {holobench-1.28.1 → holobench-1.29.0}/holobench.egg-info/top_level.txt +0 -0
  103. {holobench-1.28.1 → holobench-1.29.0}/package.xml +0 -0
  104. {holobench-1.28.1 → holobench-1.29.0}/resource/bencher +0 -0
  105. {holobench-1.28.1 → holobench-1.29.0}/setup.cfg +0 -0
  106. {holobench-1.28.1 → holobench-1.29.0}/setup.py +0 -0
  107. {holobench-1.28.1 → holobench-1.29.0}/test/test_bch_p.py +0 -0
  108. {holobench-1.28.1 → holobench-1.29.0}/test/test_bench_report.py +0 -0
  109. {holobench-1.28.1 → holobench-1.29.0}/test/test_bench_result_base.py +0 -0
  110. {holobench-1.28.1 → holobench-1.29.0}/test/test_bench_runner.py +0 -0
  111. {holobench-1.28.1 → holobench-1.29.0}/test/test_bencher.py +0 -0
  112. {holobench-1.28.1 → holobench-1.29.0}/test/test_cache.py +0 -0
  113. {holobench-1.28.1 → holobench-1.29.0}/test/test_class_enum.py +0 -0
  114. {holobench-1.28.1 → holobench-1.29.0}/test/test_combinations.py +0 -0
  115. {holobench-1.28.1 → holobench-1.29.0}/test/test_composable_container_base.py +0 -0
  116. {holobench-1.28.1 → holobench-1.29.0}/test/test_composable_container_video.py +0 -0
  117. {holobench-1.28.1 → holobench-1.29.0}/test/test_float_formatter.py +0 -0
  118. {holobench-1.28.1 → holobench-1.29.0}/test/test_job.py +0 -0
  119. {holobench-1.28.1 → holobench-1.29.0}/test/test_meta_tests.py +0 -0
  120. {holobench-1.28.1 → holobench-1.29.0}/test/test_parametrized_sweep.py +0 -0
  121. {holobench-1.28.1 → holobench-1.29.0}/test/test_plot_filter.py +0 -0
  122. {holobench-1.28.1 → holobench-1.29.0}/test/test_plot_server.py +0 -0
  123. {holobench-1.28.1 → holobench-1.29.0}/test/test_sample_cache.py +0 -0
  124. {holobench-1.28.1 → holobench-1.29.0}/test/test_sweep_base.py +0 -0
  125. {holobench-1.28.1 → holobench-1.29.0}/test/test_sweep_vars.py +0 -0
  126. {holobench-1.28.1 → holobench-1.29.0}/test/test_utils.py +0 -0
  127. {holobench-1.28.1 → holobench-1.29.0}/test/test_vars.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: holobench
3
- Version: 1.28.1
3
+ Version: 1.29.0
4
4
  Summary: A package for benchmarking the performance of arbitrary functions
5
5
  Author-email: Austin Gregg-Smith <blooop@gmail.com>
6
6
  Project-URL: Repository, https://github.com/dyson-ai/bencher
@@ -19,6 +19,7 @@ from .variables.results import (
19
19
  ResultReference,
20
20
  ResultVolume,
21
21
  OptDir,
22
+ ResultDataSet,
22
23
  curve,
23
24
  )
24
25
 
@@ -30,6 +30,7 @@ from bencher.variables.results import (
30
30
  ResultString,
31
31
  ResultContainer,
32
32
  ResultReference,
33
+ ResultDataSet,
33
34
  )
34
35
  from bencher.results.bench_result import BenchResult
35
36
  from bencher.variables.parametrised_sweep import ParametrizedSweep
@@ -612,12 +613,13 @@ class Bench(BenchPlotServer):
612
613
  )
613
614
  # xarray stores K N-dimensional arrays of data. Each array is named and in this case we have a nd array for each result variable
614
615
  data_vars = {}
616
+ dataset_list = []
615
617
 
616
618
  for rv in bench_cfg.result_vars:
617
619
  if isinstance(rv, ResultVar):
618
620
  result_data = np.full(dims_cfg.dims_size, np.nan, dtype=float)
619
621
  data_vars[rv.name] = (dims_cfg.dims_name, result_data)
620
- if isinstance(rv, ResultReference):
622
+ if isinstance(rv, (ResultReference, ResultDataSet)):
621
623
  result_data = np.full(dims_cfg.dims_size, -1, dtype=int)
622
624
  data_vars[rv.name] = (dims_cfg.dims_name, result_data)
623
625
  if isinstance(
@@ -625,6 +627,7 @@ class Bench(BenchPlotServer):
625
627
  ):
626
628
  result_data = np.full(dims_cfg.dims_size, "NAN", dtype=object)
627
629
  data_vars[rv.name] = (dims_cfg.dims_name, result_data)
630
+
628
631
  elif type(rv) == ResultVec:
629
632
  for i in range(rv.size):
630
633
  result_data = np.full(dims_cfg.dims_size, np.nan)
@@ -633,6 +636,7 @@ class Bench(BenchPlotServer):
633
636
  bench_res = BenchResult(bench_cfg)
634
637
  bench_res.ds = xr.Dataset(data_vars=data_vars, coords=dims_cfg.coords)
635
638
  bench_res.ds_dynamic = self.ds_dynamic
639
+ bench_res.dataset_list = dataset_list
636
640
  bench_res.setup_object_index()
637
641
 
638
642
  return bench_res, function_inputs, dims_cfg.dims_name
@@ -770,6 +774,13 @@ class Bench(BenchPlotServer):
770
774
  ),
771
775
  ):
772
776
  set_xarray_multidim(bench_res.ds[rv.name], worker_job.index_tuple, result_value)
777
+ elif isinstance(rv, ResultDataSet):
778
+ bench_res.dataset_list.append(result_value)
779
+ set_xarray_multidim(
780
+ bench_res.ds[rv.name],
781
+ worker_job.index_tuple,
782
+ len(bench_res.dataset_list) - 1,
783
+ )
773
784
  elif isinstance(rv, ResultReference):
774
785
  bench_res.object_index.append(result_value)
775
786
  set_xarray_multidim(
@@ -777,6 +788,7 @@ class Bench(BenchPlotServer):
777
788
  worker_job.index_tuple,
778
789
  len(bench_res.object_index) - 1,
779
790
  )
791
+
780
792
  elif isinstance(rv, ResultVec):
781
793
  if isinstance(result_value, (list, np.ndarray)):
782
794
  if len(result_value) == rv.size:
@@ -0,0 +1,48 @@
1
+ import bencher as bch
2
+
3
+ import xarray as xr
4
+ import numpy as np
5
+ import holoviews as hv
6
+
7
+
8
+ class ExampleMergeDataset(bch.ParametrizedSweep):
9
+
10
+ value = bch.FloatSweep(default=0, bounds=[0, 10])
11
+ repeats_x = bch.IntSweep(default=2, bounds=[2, 4])
12
+ # repeats_y = bch.IntSweep(default=2, bounds=[2, 4])
13
+
14
+ result_df = bch.ResultDataSet()
15
+
16
+ def __call__(self, **kwargs):
17
+ self.update_params_from_kwargs(**kwargs)
18
+ # First, create a DataArray from the vector
19
+ vector = [v + self.value for v in range(1, self.repeats_x)]
20
+ data_array = xr.DataArray(vector, dims=["index"], coords={"index": np.arange(len(vector))})
21
+ # Convert the DataArray to a Dataset
22
+ result_df = xr.Dataset({"result_df": data_array})
23
+ self.result_df = bch.ResultDataSet(result_df.to_pandas())
24
+ return super().__call__(**kwargs)
25
+
26
+
27
+ def example_dataset(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None):
28
+ bench = ExampleMergeDataset().to_bench(run_cfg, report)
29
+ res = bench.plot_sweep(input_vars=["value"], const_vars=dict(repeats_x=4))
30
+ # bench.report.append(res.to_panes(target_dimension=1))
31
+ # bench.report.append(res.to_panes(target_dimension=2))
32
+ # bench.reprt.append(res.to_video_grid
33
+ # # bch.BenchResult.to_video_grid,
34
+ # target_duration=0.06,
35
+ # compose_method_list=[
36
+ # bch.ComposeType.right,
37
+ # bch.ComposeType.right,
38
+ # bch.ComposeType.sequence,
39
+ # ],
40
+ # )
41
+ # bench.report.append(res.to_panes(container=hv.Bars,target_dimension=1))
42
+ # bench.report.append(res.to_panes(container=hv.Curve))
43
+ bench.report.append(res.to_dataset1(container=hv.Curve))
44
+ return bench
45
+
46
+
47
+ if __name__ == "__main__":
48
+ example_dataset().report.show()
@@ -121,14 +121,12 @@ if __name__ == "__main__":
121
121
 
122
122
  # res = bench.sweep(input_vars=["sides", "radius"])
123
123
 
124
- # bench.report.append(res.to_heatmap(target_dimension=3))
125
-
126
124
  bench.plot_sweep(input_vars=["sides"])
127
125
  bench.plot_sweep(input_vars=["sides", "color"])
128
126
 
129
- bench.plot_sweep(input_vars=["sides", "radius"])
130
-
131
- # bench.report.append(res.to_line(target_dimension=1))
127
+ res = bench.plot_sweep(input_vars=["sides", "radius"])
128
+ bench.report.append(res.to_heatmap(target_dimension=3))
129
+ bench.report.append(res.to_line(target_dimension=1))
132
130
 
133
131
  return bench
134
132
 
@@ -148,8 +146,8 @@ if __name__ == "__main__":
148
146
  # ex_run_cfg.debug = True
149
147
  # ex_run_cfg.repeats = 2
150
148
  ex_run_cfg.level = 4
151
- example_image_vid(ex_run_cfg).report.show()
152
- # simple().report.show()
149
+ # example_image_vid(ex_run_cfg).report.show()
150
+ simple().report.show()
153
151
 
154
152
  # example_image_vid_sequential(ex_run_cfg).report.show()
155
153
  # example_image(ex_run_cfg).report.show()
@@ -0,0 +1,81 @@
1
+ import bencher as bch
2
+ import numpy as np
3
+ import math
4
+ import matplotlib.pyplot as plt
5
+
6
+
7
+ def polygon_points(radius: float, sides: int, start_angle: float):
8
+ points = []
9
+ for ang in np.linspace(0, 360, sides + 1):
10
+ angle = math.radians(start_angle + ang)
11
+ points.append(([math.sin(angle) * radius, math.cos(angle) * radius]))
12
+ return points
13
+
14
+
15
+ class BenchPolygons(bch.ParametrizedSweep):
16
+ sides = bch.IntSweep(default=3, bounds=(3, 7))
17
+ radius = bch.FloatSweep(default=1, bounds=(0.2, 1))
18
+ linewidth = bch.FloatSweep(default=1, bounds=(1, 10))
19
+ linestyle = bch.StringSweep(["solid", "dashed", "dotted"])
20
+ color = bch.StringSweep(["red", "green", "blue"])
21
+ start_angle = bch.FloatSweep(default=0, bounds=[0, 360])
22
+ polygon = bch.ResultImage()
23
+ polygon_small = bch.ResultImage()
24
+
25
+ area = bch.ResultVar()
26
+ side_length = bch.ResultVar()
27
+
28
+ def __call__(self, **kwargs):
29
+ self.update_params_from_kwargs(**kwargs)
30
+ points = polygon_points(self.radius, self.sides, self.start_angle)
31
+ # self.hmap = hv.Curve(points)
32
+ self.polygon = self.points_to_polygon_png(points, bch.gen_image_path("polygon"), dpi=30)
33
+ self.polygon_small = self.points_to_polygon_png(
34
+ points, bch.gen_image_path("polygon"), dpi=10
35
+ )
36
+
37
+ self.side_length = 2 * self.radius * math.sin(math.pi / self.sides)
38
+ self.area = (self.sides * self.side_length**2) / (4 * math.tan(math.pi / self.sides))
39
+ return super().__call__()
40
+
41
+ def points_to_polygon_png(self, points: list[float], filename: str, dpi):
42
+ """Draw a closed polygon and save to png"""
43
+ fig = plt.figure(frameon=False)
44
+ ax = plt.Axes(fig, [0.0, 0.0, 1.0, 1.0], frameon=False)
45
+ ax.set_axis_off()
46
+ ax.plot(
47
+ [p[0] for p in points],
48
+ [p[1] for p in points],
49
+ linewidth=self.linewidth,
50
+ linestyle=self.linestyle,
51
+ color=self.color,
52
+ )
53
+ ax.set_xlim(-1, 1)
54
+ ax.set_ylim(-1, 1)
55
+
56
+ ax.set_aspect("equal")
57
+ fig.add_axes(ax)
58
+ fig.savefig(filename, dpi=dpi)
59
+
60
+ return filename
61
+
62
+
63
+ def example_image_vid_sequential1(
64
+ run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
65
+ ) -> bch.Bench:
66
+ bench = BenchPolygons().to_bench(run_cfg, report)
67
+ res = bench.plot_sweep(input_vars=["sides"])
68
+
69
+ bench.report.append(res.to_panes(zip_results=True))
70
+
71
+ return bench
72
+
73
+
74
+ if __name__ == "__main__":
75
+
76
+ ex_run_cfg = bch.BenchRunCfg()
77
+ ex_run_cfg.use_sample_cache = True
78
+ ex_run_cfg.overwrite_sample_cache = True
79
+ ex_run_cfg.level = 3
80
+
81
+ example_image_vid_sequential1(ex_run_cfg).report.show()
@@ -7,15 +7,17 @@ from bencher.results.video_summary import VideoSummaryResult
7
7
  from bencher.results.panel_result import PanelResult
8
8
  from bencher.results.plotly_result import PlotlyResult
9
9
  from bencher.results.holoview_result import HoloviewResult
10
+ from bencher.results.dataset_result import DataSetResult
10
11
  from bencher.utils import listify
11
12
 
12
13
 
13
- class BenchResult(PlotlyResult, HoloviewResult, VideoSummaryResult):
14
+ class BenchResult(PlotlyResult, HoloviewResult, VideoSummaryResult, DataSetResult):
14
15
  """Contains the results of the benchmark and has methods to cast the results to various datatypes and graphical representations"""
15
16
 
16
17
  def __init__(self, bench_cfg) -> None:
17
18
  PlotlyResult.__init__(self, bench_cfg)
18
19
  HoloviewResult.__init__(self, bench_cfg)
20
+ # DataSetResult.__init__(self.bench_cfg)
19
21
 
20
22
  @staticmethod
21
23
  def default_plot_callbacks():
@@ -19,9 +19,7 @@ from bencher.variables.results import ResultVar
19
19
  from bencher.plotting.plot_filter import VarRange, PlotFilter
20
20
  from bencher.utils import listify
21
21
 
22
- from bencher.variables.results import (
23
- ResultReference,
24
- )
22
+ from bencher.variables.results import ResultReference, ResultDataSet
25
23
 
26
24
  from bencher.results.composable_container.composable_container_panel import ComposableContainerPanel
27
25
 
@@ -242,6 +240,46 @@ class BenchResultBase(OptunaResult):
242
240
  row.append(plot_callback(rv))
243
241
  return row.get()
244
242
 
243
+ @staticmethod
244
+ def zip_results1D(args): # pragma: no cover
245
+ first_el = [a[0] for a in args]
246
+ out = pn.Column()
247
+ for a in zip(*first_el):
248
+ row = pn.Row()
249
+ row.append(a[0])
250
+ for a1 in range(1, len(a[1])):
251
+ row.append(a[a1][1])
252
+ out.append(row)
253
+ return out
254
+
255
+ @staticmethod
256
+ def zip_results1D1(panel_list): # pragma: no cover
257
+ container_args = {"styles": {}}
258
+ container_args["styles"]["border-bottom"] = f"{2}px solid grey"
259
+ print(panel_list)
260
+ out = pn.Column()
261
+ for a in zip(*panel_list):
262
+ row = pn.Row(**container_args)
263
+ row.append(a[0][0])
264
+ for a1 in range(0, len(a)):
265
+ row.append(a[a1][1])
266
+ out.append(row)
267
+ return out
268
+
269
+ @staticmethod
270
+ def zip_results1D2(panel_list): # pragma: no cover
271
+ if panel_list is not None:
272
+ print(panel_list)
273
+ primary = panel_list[0]
274
+ secondary = panel_list[1:]
275
+ for i in range(len(primary)):
276
+ print(type(primary[i]))
277
+ if isinstance(primary[i], (pn.Column, pn.Row)):
278
+ for j in range(len(secondary)):
279
+ primary[i].append(secondary[j][i][1])
280
+ return primary
281
+ return panel_list
282
+
245
283
  def map_plot_panes(
246
284
  self,
247
285
  plot_callback: callable,
@@ -250,6 +288,7 @@ class BenchResultBase(OptunaResult):
250
288
  result_var: ResultVar = None,
251
289
  result_types=None,
252
290
  pane_collection: pn.pane = None,
291
+ zip_results=False,
253
292
  **kwargs,
254
293
  ) -> Optional[pn.Row]:
255
294
  if hv_dataset is None:
@@ -271,6 +310,9 @@ class BenchResultBase(OptunaResult):
271
310
  target_dimension=target_dimension,
272
311
  )
273
312
  )
313
+
314
+ if zip_results:
315
+ return self.zip_results1D2(row.get())
274
316
  return row.get()
275
317
 
276
318
  def filter(
@@ -405,10 +447,17 @@ class BenchResultBase(OptunaResult):
405
447
  return da_ds.values.squeeze().item()
406
448
  return da.expand_dims(dim).values[0]
407
449
 
408
- def ds_to_container(
450
+ def ds_to_container( # pylint: disable=too-many-return-statements
409
451
  self, dataset: xr.Dataset, result_var: Parameter, container, **kwargs
410
452
  ) -> Any:
411
453
  val = self.zero_dim_da_to_val(dataset[result_var.name])
454
+ if isinstance(result_var, ResultDataSet):
455
+ ref = self.dataset_list[val]
456
+ if ref is not None:
457
+ if container is not None:
458
+ return container(ref.obj)
459
+ return ref.obj
460
+ return None
412
461
  if isinstance(result_var, ResultReference):
413
462
  ref = self.object_index[val]
414
463
  if ref is not None:
@@ -10,7 +10,7 @@ class ComposeType(StrEnum):
10
10
  right = auto() # append the container to the right (creates a row)
11
11
  down = auto() # append the container below (creates a column)
12
12
  sequence = auto() # display the container after (in time)
13
- # overlay = auto() # overlay on top of the current container (alpha blending)
13
+ overlay = auto() # overlay on top of the current container (alpha blending)
14
14
 
15
15
  def flip(self):
16
16
  match self:
@@ -0,0 +1,52 @@
1
+ from dataclasses import dataclass
2
+ import panel as pn
3
+ import xarray as xr
4
+ from bencher.results.composable_container.composable_container_base import ComposableContainerBase
5
+ from bencher.results.composable_container.composable_container_base import ComposeType
6
+
7
+
8
+ @dataclass(kw_only=True)
9
+ class ComposableContainerDataset(ComposableContainerBase):
10
+ name: str = None
11
+ var_name: str = None
12
+ var_value: str = None
13
+ width: int = None
14
+ background_col: str = None
15
+ horizontal: bool = True
16
+
17
+ def __post_init__(
18
+ self,
19
+ ) -> None:
20
+ container_args = {
21
+ "name": self.name,
22
+ "styles": {},
23
+ }
24
+
25
+ if self.width is not None:
26
+ container_args["styles"]["border-bottom"] = f"{self.width}px solid grey"
27
+ if self.background_col is not None:
28
+ container_args["styles"]["background"] = self.background_col
29
+
30
+ if self.horizontal:
31
+ self.container = pn.Column(**container_args)
32
+ align = ("center", "center")
33
+ else:
34
+ self.container = pn.Row(**container_args)
35
+ align = ("end", "center")
36
+
37
+ label = self.label_formatter(self.var_name, self.var_value)
38
+ if label is not None:
39
+ self.label_len = len(label)
40
+ side = pn.pane.Markdown(label, align=align)
41
+ self.append(side)
42
+
43
+ def render(self, **kwargs): # pylint: disable=unused-argument
44
+ match self.compose_method:
45
+ case ComposeType.right:
46
+ return xr.concat(self.container, 0)
47
+ case ComposeType.down:
48
+ return xr.concat(self.container, 1)
49
+ case ComposeType.sequence:
50
+ return xr.concat(self.container, 2)
51
+ # case ComposeType.overlay:
52
+ # return xr.Dataset.mean()
@@ -0,0 +1,227 @@
1
+ from typing import Optional
2
+ import panel as pn
3
+ from param import Parameter
4
+ from bencher.results.bench_result_base import BenchResultBase, ReduceType
5
+
6
+
7
+ from functools import partial
8
+ import holoviews as hv
9
+ from bencher.variables.results import (
10
+ PANEL_TYPES,
11
+ )
12
+
13
+
14
+ class DataSetResult(BenchResultBase):
15
+ def to_dataset1(
16
+ self,
17
+ result_var: Parameter = None,
18
+ hv_dataset=None,
19
+ target_dimension: int = 0,
20
+ container=None,
21
+ level: int = None,
22
+ **kwargs,
23
+ ) -> Optional[pn.pane.panel]:
24
+ if hv_dataset is None:
25
+ hv_dataset = self.to_hv_dataset(ReduceType.SQUEEZE, level=level)
26
+ elif not isinstance(hv_dataset, hv.Dataset):
27
+ hv_dataset = hv.Dataset(hv_dataset)
28
+ return self.map_plot_panes(
29
+ partial(self.ds_to_container, container=container),
30
+ hv_dataset=hv_dataset,
31
+ target_dimension=target_dimension,
32
+ result_var=result_var,
33
+ result_types=PANEL_TYPES,
34
+ **kwargs,
35
+ )
36
+
37
+
38
+ # class DataSetResult(BenchResultBase):
39
+
40
+ # def to_datatset(
41
+ # self,
42
+ # result_var: Parameter = None,
43
+ # result_types=(ResultDataSet,),
44
+ # pane_collection: pn.pane = None,
45
+ # time_sequence_dimension=0,
46
+ # target_duration: float = None,
47
+ # **kwargs,
48
+ # ) -> Optional[pn.panel]:
49
+ # """Returns the results compiled into a video
50
+
51
+ # Args:
52
+ # result_var (Parameter, optional): The result var to plot. Defaults to None.
53
+ # result_types (tuple, optional): The types of result var to convert to video. Defaults to (ResultDataSet,).
54
+ # collection (pn.pane, optional): If there are multiple results, use this collection to stack them. Defaults to pn.Row().
55
+
56
+ # Returns:
57
+ # Optional[pn.panel]: a panel pane with a video of all results concatenated together
58
+ # """
59
+ # plot_filter = PlotFilter(
60
+ # float_range=VarRange(0, None),
61
+ # cat_range=VarRange(0, None),
62
+ # panel_range=VarRange(1, None),
63
+ # input_range=VarRange(0, None),
64
+ # )
65
+ # matches_res = plot_filter.matches_result(
66
+ # self.plt_cnt_cfg, callable_name(self.to_video_grid_ds)
67
+ # )
68
+
69
+ # if pane_collection is None:
70
+ # pane_collection = pn.Row()
71
+
72
+ # if matches_res.overall:
73
+ # ds = self.to_dataset(ReduceType.SQUEEZE)
74
+ # for rv in self.get_results_var_list(result_var):
75
+ # if isinstance(rv, result_types):
76
+ # pane_collection.append(
77
+ # self.to_video_grid_ds(
78
+ # ds,
79
+ # rv,
80
+ # time_sequence_dimension=time_sequence_dimension,
81
+ # target_duration=target_duration,
82
+ # **kwargs,
83
+ # )
84
+ # )
85
+ # return pane_collection
86
+ # return matches_res.to_panel()
87
+
88
+ # def to_video_grid_ds(
89
+ # self,
90
+ # dataset: xr.Dataset,
91
+ # result_var: Parameter,
92
+ # reverse=True,
93
+ # time_sequence_dimension=0,
94
+ # video_controls: VideoControls = None,
95
+ # target_duration: float = None,
96
+ # **kwargs,
97
+ # ):
98
+ # cvc = self._to_video_panes_ds(
99
+ # dataset,
100
+ # self.plot_cb,
101
+ # target_dimension=0,
102
+ # horizontal=True,
103
+ # compose_method=ComposeType.right,
104
+ # time_sequence_dimension=time_sequence_dimension,
105
+ # result_var=result_var,
106
+ # final=True,
107
+ # reverse=reverse,
108
+ # target_duration=target_duration,
109
+ # **kwargs,
110
+ # )
111
+
112
+ # filename = VideoWriter().write_video_raw(cvc)
113
+
114
+ # if filename is not None:
115
+ # if video_controls is None:
116
+ # video_controls = VideoControls()
117
+ # return video_controls.video_container(
118
+ # filename, width=kwargs.get("width", None), height=kwargs.get("height", None)
119
+ # )
120
+ # return None
121
+
122
+ # def plot_cb(self, dataset, result_var, **kwargs):
123
+ # val = self.ds_to_container(dataset, result_var, container=None, **kwargs)
124
+ # return val
125
+
126
+ # def dataset_to_compose_list(
127
+ # self,
128
+ # dataset: xr.Dataset,
129
+ # first_compose_method: ComposeType = ComposeType.down,
130
+ # time_sequence_dimension: int = 0,
131
+ # ) -> List[ComposeType]:
132
+ # """ "Given a dataset, chose an order for composing the results. By default will flip between right and down and the last dimension will be a time sequence.
133
+
134
+ # Args:
135
+ # dataset (xr.Dataset): the dataset to render
136
+ # first_compose_method (ComposeType, optional): the direction of the first composition method. Defaults to ComposeType.right.
137
+ # time_sequence_dimension (int, optional): The dimension to start time sequencing instead of composing in space. Defaults to 0.
138
+
139
+ # Returns:
140
+ # List[ComposeType]: A list of composition methods for composing the dataset result
141
+ # """
142
+
143
+ # num_dims = len(dataset.sizes)
144
+ # if time_sequence_dimension == -1: # use time sequence for everything
145
+ # compose_method_list = [ComposeType.sequence] * (num_dims + 1)
146
+ # else:
147
+ # compose_method_list = [first_compose_method]
148
+ # compose_method_list.extend(
149
+ # ComposeType.flip(compose_method_list[-1]) for _ in range(num_dims - 1)
150
+ # )
151
+ # compose_method_list.append(ComposeType.sequence)
152
+
153
+ # for i in range(min(len(compose_method_list), time_sequence_dimension + 1)):
154
+ # compose_method_list[i] = ComposeType.sequence
155
+
156
+ # return compose_method_list
157
+
158
+ # def _to_video_panes_ds(
159
+ # self,
160
+ # dataset: xr.Dataset,
161
+ # plot_callback: callable = None,
162
+ # target_dimension=0,
163
+ # compose_method=ComposeType.right,
164
+ # compose_method_list=None,
165
+ # result_var=None,
166
+ # time_sequence_dimension=0,
167
+ # root_dimensions=None,
168
+ # reverse=False,
169
+ # target_duration: float = None,
170
+ # **kwargs,
171
+ # ) -> pn.panel:
172
+ # num_dims = len(dataset.sizes)
173
+ # dims = list(d for d in dataset.sizes)
174
+ # if reverse:
175
+ # dims = list(reversed(dims))
176
+
177
+ # if root_dimensions is None:
178
+ # root_dimensions = num_dims
179
+
180
+ # if compose_method_list is None:
181
+ # compose_method_list = self.dataset_to_compose_list(
182
+ # dataset, compose_method, time_sequence_dimension=time_sequence_dimension
183
+ # )
184
+
185
+ # # print(compose_method_list)
186
+
187
+ # compose_method_list_pop = deepcopy(compose_method_list)
188
+ # if len(compose_method_list_pop) > 1:
189
+ # compose_method = compose_method_list_pop.pop()
190
+
191
+ # if num_dims > (target_dimension) and num_dims != 0:
192
+ # selected_dim = dims[-1]
193
+ # outer_container = ComposableContainerVideo()
194
+ # for i in range(dataset.sizes[selected_dim]):
195
+ # sliced = dataset.isel({selected_dim: i})
196
+ # label_val = sliced.coords[selected_dim].values.item()
197
+ # inner_container = ComposableContainerVideo()
198
+
199
+ # panes = self._to_video_panes_ds(
200
+ # sliced,
201
+ # plot_callback=plot_callback,
202
+ # target_dimension=target_dimension,
203
+ # compose_method_list=compose_method_list_pop,
204
+ # result_var=result_var,
205
+ # root_dimensions=root_dimensions,
206
+ # time_sequence_dimension=time_sequence_dimension,
207
+ # )
208
+ # inner_container.append(panes)
209
+
210
+ # rendered = inner_container.render(
211
+ # RenderCfg(
212
+ # var_name=selected_dim,
213
+ # var_value=label_val,
214
+ # compose_method=compose_method,
215
+ # duration=target_duration,
216
+ # )
217
+ # )
218
+ # outer_container.append(rendered)
219
+ # return outer_container.render(
220
+ # RenderCfg(
221
+ # compose_method=compose_method,
222
+ # duration=target_duration,
223
+ # background_col=color_tuple_to_255(int_to_col(num_dims - 2, 0.05, 1.0)),
224
+ # # background_col= (255,0,0),
225
+ # )
226
+ # )
227
+ # return plot_callback(dataset=dataset, result_var=result_var, **kwargs)
@@ -63,6 +63,7 @@ class OptunaResult:
63
63
  self.studies = []
64
64
  self.plt_cnt_cfg = PltCntCfg()
65
65
  self.plot_inputs = []
66
+ self.dataset_list = []
66
67
 
67
68
  # self.width=600/
68
69
  # self.height=600
@@ -3,7 +3,7 @@ from typing import List, Tuple, Any
3
3
  from param import Parameter, Parameterized
4
4
  import holoviews as hv
5
5
  import panel as pn
6
-
6
+ from copy import deepcopy
7
7
 
8
8
  from bencher.utils import make_namedtuple, hash_sha1
9
9
  from bencher.variables.results import ALL_RESULT_TYPES, ResultHmap
@@ -127,7 +127,7 @@ class ParametrizedSweep(Parameterized):
127
127
  inp = cls.get_inputs_only()
128
128
  defaults = {}
129
129
  for i in inp:
130
- defaults[i.name] = i.default
130
+ defaults[i.name] = deepcopy(i.default)
131
131
 
132
132
  for k, v in kwargs.items():
133
133
  defaults[k] = v
@@ -186,6 +186,25 @@ class ResultReference(param.Parameter):
186
186
  return hash_sha1(self)
187
187
 
188
188
 
189
+ class ResultDataSet(param.Parameter):
190
+ __slots__ = ["units", "obj"]
191
+
192
+ def __init__(
193
+ self,
194
+ obj: Any = None,
195
+ default: Any = None,
196
+ units: str = "dataset",
197
+ **params,
198
+ ):
199
+ super().__init__(default=default, **params)
200
+ self.units = units
201
+ self.obj = obj
202
+
203
+ def hash_persistent(self) -> str:
204
+ """A hash function that avoids the PYTHONHASHSEED 'feature' which returns a different hash value each time the program is run"""
205
+ return hash_sha1(self)
206
+
207
+
189
208
  class ResultVolume(param.Parameter):
190
209
  __slots__ = ["units", "obj"]
191
210
 
@@ -199,7 +218,15 @@ class ResultVolume(param.Parameter):
199
218
  return hash_sha1(self)
200
219
 
201
220
 
202
- PANEL_TYPES = (ResultPath, ResultImage, ResultVideo, ResultContainer, ResultString, ResultReference)
221
+ PANEL_TYPES = (
222
+ ResultPath,
223
+ ResultImage,
224
+ ResultVideo,
225
+ ResultContainer,
226
+ ResultString,
227
+ ResultReference,
228
+ ResultDataSet,
229
+ )
203
230
 
204
231
  ALL_RESULT_TYPES = (
205
232
  ResultVar,
@@ -210,5 +237,6 @@ ALL_RESULT_TYPES = (
210
237
  ResultImage,
211
238
  ResultString,
212
239
  ResultContainer,
240
+ ResultDataSet,
213
241
  ResultReference,
214
242
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: holobench
3
- Version: 1.28.1
3
+ Version: 1.29.0
4
4
  Summary: A package for benchmarking the performance of arbitrary functions
5
5
  Author-email: Austin Gregg-Smith <blooop@gmail.com>
6
6
  Project-URL: Repository, https://github.com/dyson-ai/bencher
@@ -27,6 +27,7 @@ bencher/example/example_composable_container2.py
27
27
  bencher/example/example_consts.py
28
28
  bencher/example/example_custom_sweep.py
29
29
  bencher/example/example_custom_sweep2.py
30
+ bencher/example/example_dataframe.py
30
31
  bencher/example/example_docs.py
31
32
  bencher/example/example_filepath.py
32
33
  bencher/example/example_float3D.py
@@ -37,6 +38,7 @@ bencher/example/example_holosweep.py
37
38
  bencher/example/example_holosweep_objects.py
38
39
  bencher/example/example_holosweep_tap.py
39
40
  bencher/example/example_image.py
41
+ bencher/example/example_image1.py
40
42
  bencher/example/example_levels.py
41
43
  bencher/example/example_levels2.py
42
44
  bencher/example/example_pareto.py
@@ -74,6 +76,7 @@ bencher/plotting/plt_cnt_cfg.py
74
76
  bencher/results/__init__.py
75
77
  bencher/results/bench_result.py
76
78
  bencher/results/bench_result_base.py
79
+ bencher/results/dataset_result.py
77
80
  bencher/results/float_formatter.py
78
81
  bencher/results/holoview_result.py
79
82
  bencher/results/optuna_result.py
@@ -83,6 +86,7 @@ bencher/results/video_result.py
83
86
  bencher/results/video_summary.py
84
87
  bencher/results/composable_container/__init__.py
85
88
  bencher/results/composable_container/composable_container_base.py
89
+ bencher/results/composable_container/composable_container_dataframe.py
86
90
  bencher/results/composable_container/composable_container_panel.py
87
91
  bencher/results/composable_container/composable_container_video.py
88
92
  bencher/variables/__init__.py
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "holobench"
3
- version = "1.28.1"
3
+ version = "1.29.0"
4
4
 
5
5
  authors = [{ name = "Austin Gregg-Smith", email = "blooop@gmail.com" }]
6
6
  description = "A package for benchmarking the performance of arbitrary functions"
@@ -72,6 +72,7 @@ py310 = ["py310", "test"]
72
72
  py311 = ["py311", "test"]
73
73
 
74
74
  [tool.pixi.tasks]
75
+ success = "echo Success"
75
76
  format = "black ."
76
77
  check-clean-workspace = "git diff --exit-code"
77
78
  ruff-lint = "ruff check . --fix"
@@ -17,6 +17,7 @@ from bencher.example.example_workflow import example_floats2D_workflow, example_
17
17
  from bencher.example.example_holosweep import example_holosweep
18
18
  from bencher.example.example_holosweep_tap import example_holosweep_tap
19
19
 
20
+ from bencher.example.example_dataframe import example_dataset
20
21
  from bencher.example.optuna.example_optuna import optuna_rastrigin
21
22
  from bencher.example.example_sample_cache import example_sample_cache
22
23
  from bencher.example.example_strings import example_strings
@@ -95,6 +96,9 @@ class TestBenchExamples(unittest.TestCase):
95
96
  def test_example_float3D(self) -> None:
96
97
  self.examples_asserts(example_floats3D(self.create_run_cfg()))
97
98
 
99
+ def test_example_dataset(self) -> None:
100
+ self.examples_asserts(example_dataset(self.create_run_cfg()))
101
+
98
102
  def test_example_custom_sweep(self) -> None:
99
103
  self.examples_asserts(example_custom_sweep(self.create_run_cfg()))
100
104
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes