holobench 1.3.0__tar.gz → 1.3.2__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 (74) hide show
  1. {holobench-1.3.0 → holobench-1.3.2}/PKG-INFO +3 -2
  2. {holobench-1.3.0 → holobench-1.3.2}/bencher/__init__.py +9 -1
  3. {holobench-1.3.0 → holobench-1.3.2}/bencher/bencher.py +1 -1
  4. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_image.py +1 -1
  5. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_video.py +1 -1
  6. {holobench-1.3.0 → holobench-1.3.2}/bencher/results/bench_result_base.py +16 -3
  7. holobench-1.3.2/bencher/results/float_formatter.py +44 -0
  8. {holobench-1.3.0 → holobench-1.3.2}/bencher/results/holoview_result.py +0 -1
  9. {holobench-1.3.0 → holobench-1.3.2}/bencher/results/panel_result.py +7 -4
  10. {holobench-1.3.0 → holobench-1.3.2}/bencher/utils.py +16 -0
  11. {holobench-1.3.0 → holobench-1.3.2}/bencher/variables/inputs.py +6 -0
  12. {holobench-1.3.0 → holobench-1.3.2}/bencher/variables/parametrised_sweep.py +2 -15
  13. holobench-1.3.2/bencher/video_writer.py +17 -0
  14. {holobench-1.3.0 → holobench-1.3.2}/pyproject.toml +3 -2
  15. {holobench-1.3.0 → holobench-1.3.2}/README.md +0 -0
  16. {holobench-1.3.0 → holobench-1.3.2}/bencher/bench_cfg.py +0 -0
  17. {holobench-1.3.0 → holobench-1.3.2}/bencher/bench_plot_server.py +0 -0
  18. {holobench-1.3.0 → holobench-1.3.2}/bencher/bench_report.py +0 -0
  19. {holobench-1.3.0 → holobench-1.3.2}/bencher/bench_runner.py +0 -0
  20. {holobench-1.3.0 → holobench-1.3.2}/bencher/caching.py +0 -0
  21. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/__init__.py +0 -0
  22. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/benchmark_data.py +0 -0
  23. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_all.py +0 -0
  24. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_categorical.py +0 -0
  25. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_custom_sweep.py +0 -0
  26. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_docs.py +0 -0
  27. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_float3D.py +0 -0
  28. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_float_cat.py +0 -0
  29. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_floats.py +0 -0
  30. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_floats2D.py +0 -0
  31. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_holosweep.py +0 -0
  32. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_holosweep_objects.py +0 -0
  33. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_holosweep_tap.py +0 -0
  34. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_levels.py +0 -0
  35. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_pareto.py +0 -0
  36. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_sample_cache.py +0 -0
  37. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_sample_cache_context.py +0 -0
  38. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_simple.py +0 -0
  39. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_simple_bool.py +0 -0
  40. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_simple_cat.py +0 -0
  41. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_simple_float.py +0 -0
  42. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_strings.py +0 -0
  43. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_time_event.py +0 -0
  44. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/example_workflow.py +0 -0
  45. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/experimental/example_bokeh_plotly.py +0 -0
  46. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/experimental/example_hover_ex.py +0 -0
  47. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/experimental/example_hvplot_explorer.py +0 -0
  48. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/experimental/example_interactive.py +0 -0
  49. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/experimental/example_streamnd.py +0 -0
  50. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/experimental/example_streams.py +0 -0
  51. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/experimental/example_template.py +0 -0
  52. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/experimental/example_updates.py +0 -0
  53. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/experimental/example_vector.py +0 -0
  54. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/meta/example_meta.py +0 -0
  55. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/meta/example_meta_cat.py +0 -0
  56. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/meta/example_meta_float.py +0 -0
  57. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/meta/example_meta_levels.py +0 -0
  58. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/optuna/example_optuna.py +0 -0
  59. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/shelved/example_float2D_scatter.py +0 -0
  60. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/shelved/example_float3D_cone.py +0 -0
  61. {holobench-1.3.0 → holobench-1.3.2}/bencher/example/shelved/example_kwargs.py +0 -0
  62. {holobench-1.3.0 → holobench-1.3.2}/bencher/job.py +0 -0
  63. {holobench-1.3.0 → holobench-1.3.2}/bencher/optuna_conversions.py +0 -0
  64. {holobench-1.3.0 → holobench-1.3.2}/bencher/plotting/__init__.py +0 -0
  65. {holobench-1.3.0 → holobench-1.3.2}/bencher/plotting/plot_filter.py +0 -0
  66. {holobench-1.3.0 → holobench-1.3.2}/bencher/plotting/plt_cnt_cfg.py +0 -0
  67. {holobench-1.3.0 → holobench-1.3.2}/bencher/results/__init__.py +0 -0
  68. {holobench-1.3.0 → holobench-1.3.2}/bencher/results/bench_result.py +0 -0
  69. {holobench-1.3.0 → holobench-1.3.2}/bencher/results/optuna_result.py +0 -0
  70. {holobench-1.3.0 → holobench-1.3.2}/bencher/results/plotly_result.py +0 -0
  71. {holobench-1.3.0 → holobench-1.3.2}/bencher/variables/results.py +0 -0
  72. {holobench-1.3.0 → holobench-1.3.2}/bencher/variables/sweep_base.py +0 -0
  73. {holobench-1.3.0 → holobench-1.3.2}/bencher/variables/time.py +0 -0
  74. {holobench-1.3.0 → holobench-1.3.2}/bencher/worker_job.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: holobench
3
- Version: 1.3.0
3
+ Version: 1.3.2
4
4
  Summary: A package for benchmarking the performance of arbitrary functions
5
5
  Author-email: Austin Gregg-Smith <blooop@gmail.com>
6
6
  Requires-Python: >=3.10
@@ -10,7 +10,7 @@ Requires-Dist: numpy>=1.0,<=1.26.2
10
10
  Requires-Dist: param>=1.13.0,<=2.0.1
11
11
  Requires-Dist: hvplot>=0.8,<=0.9.1
12
12
  Requires-Dist: matplotlib>=3.6.3,<=3.8.2
13
- Requires-Dist: panel>=1.2.3,<1.4
13
+ Requires-Dist: panel>=1.3.6,<=1.3.6
14
14
  Requires-Dist: diskcache>=5.6,<=5.6.3
15
15
  Requires-Dist: optuna>=3.2,<=3.5.0
16
16
  Requires-Dist: xarray>=2023.7,<=2023.12.0
@@ -22,6 +22,7 @@ Requires-Dist: scikit-learn>=1.2,<=1.3.2
22
22
  Requires-Dist: str2bool>=1.1,<=1.1
23
23
  Requires-Dist: scoop>=0.7.0,<=0.7.2.0
24
24
  Requires-Dist: ffmpeg-downloader>=0.3.0,<=0.3.0
25
+ Requires-Dist: moviepy>=1.0.3,<=1.0.3
25
26
  Requires-Dist: black>=23,<=23.12.1 ; extra == "test"
26
27
  Requires-Dist: pylint>=2.16,<=3.0.3 ; extra == "test"
27
28
  Requires-Dist: pytest-cov>=4.1,<=4.1 ; extra == "test"
@@ -18,7 +18,14 @@ from .variables.results import (
18
18
  curve,
19
19
  )
20
20
  from .plotting.plot_filter import VarRange, PlotFilter
21
- from .utils import hmap_canonical_input, get_nearest_coords, make_namedtuple
21
+ from .utils import (
22
+ hmap_canonical_input,
23
+ get_nearest_coords,
24
+ make_namedtuple,
25
+ gen_path,
26
+ gen_image_path,
27
+ gen_video_path,
28
+ )
22
29
  from .variables.parametrised_sweep import ParametrizedSweep
23
30
  from .caching import CachedParams
24
31
  from .results.bench_result import BenchResult
@@ -26,3 +33,4 @@ from .results.panel_result import PanelResult
26
33
  from .results.holoview_result import ReduceType, HoloviewResult
27
34
  from .bench_report import BenchReport
28
35
  from .job import Executors
36
+ from .video_writer import VideoWriter
@@ -228,7 +228,7 @@ class Bench(BenchPlotServer):
228
228
  )
229
229
  input_vars = self.worker_class_instance.get_inputs_only()
230
230
  for i in input_vars:
231
- logging.info(i.name)
231
+ logging.info(f"input var: {i.name}")
232
232
  if result_vars is None:
233
233
  logging.info(
234
234
  "No results variables passed, using all result variables in bench class:"
@@ -25,7 +25,7 @@ class BenchPolygons(bch.ParametrizedSweep):
25
25
  self.update_params_from_kwargs(**kwargs)
26
26
  points = polygon_points(self.radius, self.sides)
27
27
  self.hmap = hv.Curve(points)
28
- self.polygon = self.points_to_polygon_png(points, self.gen_image_path("polygon"))
28
+ self.polygon = self.points_to_polygon_png(points, bch.gen_image_path("polygon"))
29
29
  return super().__call__()
30
30
 
31
31
  def points_to_polygon_png(self, points: list[float], filename: str):
@@ -66,7 +66,7 @@ class TuringPattern(bch.ParametrizedSweep):
66
66
  artists.append([ax.imshow(U)])
67
67
 
68
68
  ani = ArtistAnimation(fig=fig, artists=artists, interval=60, blit=True)
69
- path = self.gen_path("turing", "vid", ".mp4")
69
+ path = bch.gen_video_path("turing", ".mp4")
70
70
  # path = self.gen_path("turing", "vid", ".gif")
71
71
  print(f"saving {len(artists)} frames")
72
72
  ani.save(path)
@@ -12,6 +12,7 @@ from bencher.variables.results import OptDir
12
12
  from copy import deepcopy
13
13
  from bencher.results.optuna_result import OptunaResult
14
14
  from bencher.variables.results import ResultVar
15
+ from bencher.results.float_formatter import FormatFloat
15
16
  import panel as pn
16
17
 
17
18
 
@@ -293,12 +294,19 @@ class BenchResultBase(OptunaResult):
293
294
 
294
295
  container_args = {"name": name, "styles": {"background": background_col}}
295
296
  outer_container = (
296
- pn.Row(**container_args) if horizontal else pn.Column(**container_args, align="end")
297
+ pn.Row(**container_args) if horizontal else pn.Column(**container_args)
297
298
  )
298
299
 
300
+ max_len = 0
301
+
299
302
  for i in range(dataset.sizes[dim_sel]):
300
303
  sliced = dataset.isel({dim_sel: i})
301
- label = f"{dim_sel}={sliced.coords[dim_sel].values}"
304
+
305
+ lable_val = sliced.coords[dim_sel].values.item()
306
+ if isinstance(lable_val, (int, float)):
307
+ lable_val = FormatFloat()(lable_val)
308
+
309
+ label = f"{dim_sel}={lable_val}"
302
310
 
303
311
  panes = self._to_panes_da(
304
312
  sliced,
@@ -321,12 +329,17 @@ class BenchResultBase(OptunaResult):
321
329
  inner_container = pn.Row(**container_args)
322
330
  align = ("end", "center")
323
331
 
324
- side = pn.pane.Markdown(f"{label}", align=align)
332
+ label_len = len(label)
333
+ if label_len > max_len:
334
+ max_len = label_len
335
+ side = pn.pane.Markdown(label, align=align)
325
336
 
326
337
  inner_container.append(side)
327
338
  inner_container.append(panes)
328
339
  outer_container.append(inner_container)
329
340
  # outer_container.append(pn.Row(inner_container, align="center"))
341
+ for c in outer_container:
342
+ c[0].width = max_len * 7
330
343
  else:
331
344
  return plot_callback(dataset=dataset, result_var=result_var, **kwargs)
332
345
 
@@ -0,0 +1,44 @@
1
+ # from https://stackoverflow.com/questions/22989372/how-to-format-a-floating-number-to-maximum-fixed-width-in-python
2
+
3
+
4
+ class FormatFloat:
5
+ def __init__(self, width=8):
6
+ self.width = width
7
+ self.maxnum = int("9" * (width - 1)) # 9999999
8
+ self.minnum = -int("9" * (width - 2)) # -999999
9
+
10
+ def __call__(self, x):
11
+ # for small numbers
12
+ # if -999,999 < given < 9,999,999:
13
+ if self.minnum < x < self.maxnum:
14
+ # o = f'{x:7}'
15
+ o = f"{x:{self.width - 1}}"
16
+
17
+ # converting int to float without adding zero
18
+ if "." not in o:
19
+ o += "."
20
+
21
+ # float longer than 8 will need rounding to fit width
22
+ elif len(o) > self.width:
23
+ # output = str(round(x, 7 - str(x).index(".")))
24
+ o = str(round(x, self.width - 1 - str(x).index(".")))
25
+ if len(o) < self.width:
26
+ o += (self.width - len(o)) * "0"
27
+
28
+ else:
29
+ # for exponents
30
+ # added a loop for super large numbers or negative as "-" is another char
31
+ # Added max(max_char, 5) to account for max length of less
32
+ # than 5, was having too much fun
33
+ # TODO can i come up with a threshold value for these up front,
34
+ # so that i dont have to do this calc for every value??
35
+ for n in range(max(self.width, 5) - 5, 0, -1):
36
+ fill = f".{n}e"
37
+ o = f"{x:{fill}}".replace("+0", "+")
38
+
39
+ # if all good stop looping
40
+ if len(o) == self.width:
41
+ break
42
+ else:
43
+ raise ValueError(f"Number is too large to fit in {self.width} characters", x)
44
+ return o
@@ -388,7 +388,6 @@ class HoloviewResult(PanelResult):
388
388
  return htmap + tap_htmap
389
389
 
390
390
  def to_nd_layout(self, hmap_name: str) -> hv.NdLayout:
391
- print(self.bench_cfg.hmap_kdims)
392
391
  return hv.NdLayout(self.get_hmap(hmap_name), kdims=self.bench_cfg.hmap_kdims).opts(
393
392
  shared_axes=False, shared_datasource=False
394
393
  )
@@ -1,4 +1,5 @@
1
1
  from typing import Optional, Any
2
+ from pathlib import Path
2
3
  from functools import partial
3
4
  import panel as pn
4
5
  import xarray as xr
@@ -23,10 +24,12 @@ class PanelResult(BenchResultBase):
23
24
  xr_dataset = self.to_hv_dataset(ReduceType.SQUEEZE)
24
25
 
25
26
  def to_video_da(da, **kwargs):
26
- vid = pn.pane.Video(da, autoplay=True, **kwargs)
27
- vid.loop = True
28
- vid_p.append(vid)
29
- return vid
27
+ if da is not None and Path(da).exists():
28
+ vid = pn.pane.Video(da, autoplay=True, **kwargs)
29
+ vid.loop = True
30
+ vid_p.append(vid)
31
+ return vid
32
+ return pn.pane.Markdown(f"video does not exist {da}")
30
33
 
31
34
  plot_callback = partial(self.ds_to_container, container=partial(to_video_da, **kwargs))
32
35
 
@@ -5,6 +5,8 @@ import hashlib
5
5
  import re
6
6
  import math
7
7
  from colorsys import hsv_to_rgb
8
+ from pathlib import Path
9
+ from uuid import uuid4
8
10
 
9
11
 
10
12
  def hmap_canonical_input(dic: dict) -> tuple:
@@ -106,3 +108,17 @@ def int_to_col(int_val, sat=0.5, val=0.95, alpha=-1) -> tuple[float, float, floa
106
108
 
107
109
  def color_tuple_to_css(color: tuple[float, float, float]) -> str:
108
110
  return f"rgb{(color[0] * 255, color[1] * 255, color[2] * 255)}"
111
+
112
+
113
+ def gen_path(filename, folder, suffix):
114
+ path = Path(f"cachedir/{folder}/{filename}/")
115
+ path.mkdir(parents=True, exist_ok=True)
116
+ return f"{path.absolute().as_posix()}/{filename}_{uuid4()}{suffix}"
117
+
118
+
119
+ def gen_video_path(video_name: str, extension: str = ".webm") -> str:
120
+ return gen_path(video_name, "vid", extension)
121
+
122
+
123
+ def gen_image_path(image_name: str, filetype=".png") -> str:
124
+ return gen_path(image_name, "img", filetype)
@@ -185,3 +185,9 @@ class FloatSweep(Number, SweepBase):
185
185
  ]
186
186
  return [self.sample_values[i] for i in indices]
187
187
  return self.sample_values
188
+
189
+
190
+ def box(name, center, width):
191
+ var = FloatSweep(default=center, bounds=(center - width, center + width))
192
+ var.name = name
193
+ return var
@@ -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
- from pathlib import Path
6
+
7
7
 
8
8
  from bencher.utils import make_namedtuple, hash_sha1
9
9
  from bencher.variables.results import (
@@ -17,8 +17,6 @@ from bencher.variables.results import (
17
17
  ResultReference,
18
18
  )
19
19
 
20
- from uuid import uuid4
21
-
22
20
 
23
21
  class ParametrizedSweep(Parameterized):
24
22
  """Parent class for all Sweep types that need a custom hash"""
@@ -197,23 +195,12 @@ class ParametrizedSweep(Parameterized):
197
195
  def plot_hmap(self, **kwargs):
198
196
  return self.__call__(**kwargs)["hmap"]
199
197
 
200
- def gen_path(self, filename, folder, suffix):
201
- path = Path(f"cachedir/{folder}") / Path(filename)
202
- path.mkdir(parents=True, exist_ok=True)
203
- return f"{path.absolute().as_posix()}_{uuid4()}{suffix}"
204
-
205
- def gen_video_path(self, video_name: str) -> str:
206
- return self.gen_path(video_name, "vid", ".webm")
207
-
208
- def gen_image_path(self, image_name: str, filetype=".png") -> str:
209
- return self.gen_path(image_name, "img", filetype)
210
-
211
198
  def to_bench(self, run_cfg=None, report=None, name: str = None):
212
199
  from bencher import Bench
213
200
 
214
201
  assert isinstance(self, ParametrizedSweep)
215
202
 
216
203
  if name is None:
217
- name = self.name
204
+ name = self.name[:-5] # param adds 5 digit number to the end, so remove it
218
205
 
219
206
  return Bench(name, self, run_cfg=run_cfg, report=report)
@@ -0,0 +1,17 @@
1
+ from bencher import gen_video_path
2
+
3
+
4
+ class VideoWriter:
5
+ def __init__(self, filename: str) -> None:
6
+ self.images = []
7
+ self.filename = gen_video_path(filename)
8
+
9
+ def append(self, img):
10
+ self.images.append(img)
11
+
12
+ def write(self, bitrate: int = 1500) -> str:
13
+ import moviepy.video.io.ImageSequenceClip
14
+
15
+ clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(self.images, fps=30)
16
+ clip.write_videofile(self.filename, bitrate=f"{bitrate}k")
17
+ return self.filename
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "holobench"
3
- version = "1.3.0"
3
+ version = "1.3.2"
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"
@@ -15,7 +15,7 @@ dependencies = [
15
15
  "param>=1.13.0,<=2.0.1",
16
16
  "hvplot>=0.8,<=0.9.1",
17
17
  "matplotlib>=3.6.3,<=3.8.2",
18
- "panel>=1.2.3,<1.4",
18
+ "panel>=1.3.6,<=1.3.6",
19
19
  "diskcache>=5.6,<=5.6.3",
20
20
  "optuna>=3.2,<=3.5.0",
21
21
  "xarray>=2023.7,<=2023.12.0",
@@ -27,6 +27,7 @@ dependencies = [
27
27
  "str2bool>=1.1,<=1.1",
28
28
  "scoop>=0.7.0,<=0.7.2.0",
29
29
  "ffmpeg-downloader>=0.3.0,<=0.3.0",
30
+ "moviepy>=1.0.3,<=1.0.3",
30
31
  ]
31
32
 
32
33
  [project.optional-dependencies]
File without changes
File without changes
File without changes