holobench 1.3.0__py3-none-any.whl → 1.3.2__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.
bencher/__init__.py CHANGED
@@ -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
bencher/bencher.py CHANGED
@@ -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
 
bencher/utils.py CHANGED
@@ -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
  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"
@@ -1,13 +1,14 @@
1
- bencher/__init__.py,sha256=wfTebGwGL5ImpwkFife9xuUxhH4vSHRewyUzXVEu8g4,1052
1
+ bencher/__init__.py,sha256=l3s3a3hf7E6RciydXdHNuzzXPUUrqCs-imMnBrWqerU,1161
2
2
  bencher/bench_cfg.py,sha256=EMoANsz0bj4lioOCO_hlJNHH9-ciK042YAXvj2pk_dE,18244
3
3
  bencher/bench_plot_server.py,sha256=HnW6XpmARweMCd-koqzu1lxuj0gA4_fP-72D3Yfy-0M,4087
4
4
  bencher/bench_report.py,sha256=b9jLksrXzBhSmvI7KetO1i0hsHknE7qk4b4k0MGGtNw,10484
5
5
  bencher/bench_runner.py,sha256=TLJGn-NO4BBBZMG8W5E6u7IPyij67Yk3S4B29ONClnk,6049
6
- bencher/bencher.py,sha256=kxPo4NYn7OzUgM4PzBm6CVcCIjLr2Iidh_n200n5z_g,28593
6
+ bencher/bencher.py,sha256=ACP0OjkYi4vGO3lfBTzV5RAMqci_-ErNuEyIlnO_48o,28609
7
7
  bencher/caching.py,sha256=AusaNrzGGlj5m6zcwcqnTn55Mam2mQdF--oqelO806M,1627
8
8
  bencher/job.py,sha256=Q2zpia95Ibukk8EeFq5IBbpo2PMRe7o5keelJCJlGnI,5927
9
9
  bencher/optuna_conversions.py,sha256=XwRUQjFZs_zCZo0iT4cudstorSSXThLKOv4o75IxBrw,5427
10
- bencher/utils.py,sha256=vbk90hujMm11YwObreWthLqdFzydRP94ijoeT4ASAMw,3801
10
+ bencher/utils.py,sha256=ddhTAXp9ciBhZBK5gLAJgpE6rUrMpnt4g7Wug1sSc_Q,4291
11
+ bencher/video_writer.py,sha256=PlYLm6IBYG5MrK1J6U0ti2rvBzeMW2iXE4Pge7RsVII,523
11
12
  bencher/worker_job.py,sha256=FREi0yWQACFmH86R1j-LH72tALEFkKhLDmmoGQY9Jh4,1571
12
13
  bencher/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
14
  bencher/example/benchmark_data.py,sha256=D9yUg_KKtqqEkAiLceodDwsv6sh7xEFWZNp6P6Y3pj4,6989
@@ -22,7 +23,7 @@ bencher/example/example_floats2D.py,sha256=D0kljoUCinMKCEW-Zg-cQ8sYu_yPCZqzKJ9tR
22
23
  bencher/example/example_holosweep.py,sha256=d9g5aWCAUb7FMZahb4t3xNs344EshPhA-8-K6K1SBXg,3180
23
24
  bencher/example/example_holosweep_objects.py,sha256=vHuAtkM1VrJelHOazn_SJfzxNywKyaMzN-DE8W7Ricc,3228
24
25
  bencher/example/example_holosweep_tap.py,sha256=3ayQ0bTj_XWP_92ifQJAhe1whwPAj_xWHPkzC7fvqAY,4540
25
- bencher/example/example_image.py,sha256=d9ldZDxbOXkkZGppbG9orn8sSTNzNQoKrfj_5F5TMAg,2714
26
+ bencher/example/example_image.py,sha256=DBB7oe-67XoxPBPhUJNSr45U8t8xJvi9KiC3ptZkAHE,2713
26
27
  bencher/example/example_levels.py,sha256=rpSNB571yfMnT7iO66Ds-DPGHWzOTM9FLMNfSetJdHY,6896
27
28
  bencher/example/example_pareto.py,sha256=yyAg8Vb-5sgsS6LkYKT7T5Evcfg69FlCqCakUippSmU,2687
28
29
  bencher/example/example_sample_cache.py,sha256=7gf1BJ63VAgdqNuNXkbL9-jeTeC3kXA_PY9yG3ulTz0,4200
@@ -33,7 +34,7 @@ bencher/example/example_simple_cat.py,sha256=YFccE84g37U2M3ByWYIcGNLXWdW_ktJbbZv
33
34
  bencher/example/example_simple_float.py,sha256=X4vsH0F4fZAoO0EKB1xIzFMY0f0Wyk8LV2plPlSEsbI,1323
34
35
  bencher/example/example_strings.py,sha256=BdsEZgLT9mOxLkBKNHz2XpPwwe4SzNTdjnY1WVlOmNM,1570
35
36
  bencher/example/example_time_event.py,sha256=y1vpK7UDrObEu0Z1x3e4OQzvGCQ7pF5GZvpKLegMbYk,2158
36
- bencher/example/example_video.py,sha256=ZvmaJUnIw-0v8nInbUrpv6qtp1HXEGLHrGiffPwzGWU,3389
37
+ bencher/example/example_video.py,sha256=uI8tjF8BTTD9NsrBhK5rluBujLAaOaRAB5uXAvM1fZU,3387
37
38
  bencher/example/example_workflow.py,sha256=00QnUuViMfX_PqzqkXmg1wPX6yAq7IS7mCL_RFKwrMM,6806
38
39
  bencher/example/experimental/example_bokeh_plotly.py,sha256=3jUKh8eKIAlpklKnp8UopIHhUDw1A0_5CwjeyTzbi7o,846
39
40
  bencher/example/experimental/example_hover_ex.py,sha256=qszw4FkIfqQkVviPSpmUoFOoi6PGotGbsc7Ojyx8EtU,1052
@@ -57,16 +58,17 @@ bencher/plotting/plot_filter.py,sha256=Zff02hEcRffiqDEoXUHVZQJK5kW4HbMxe2GYCrxI8
57
58
  bencher/plotting/plt_cnt_cfg.py,sha256=BkiAsgHm35Mqb5OsjULGVK0Q6pGZ0WSsJxxwSOrbaQs,3124
58
59
  bencher/results/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
60
  bencher/results/bench_result.py,sha256=O0RxxUoudT43zukIKEmwaj8Q156UrEfwyj8NGFFwI0c,2797
60
- bencher/results/bench_result_base.py,sha256=SGln2bdnUUCrW3e4mdUHLyqejaako-A48Yfc1s0S1BA,13539
61
- bencher/results/holoview_result.py,sha256=h-Q48m2dkHLPmvHnxmREpzt7MzQ-6iYLWrURDdLPjOw,21310
61
+ bencher/results/bench_result_base.py,sha256=_TQk3WRORY6obm57ZhsDwk6Gbq-d8u_q69OgGKtS2sU,13960
62
+ bencher/results/float_formatter.py,sha256=sX6HNCyaXdHDxC8ybVUHwCJ3qOKbPUkBOplVIHtKWjM,1746
63
+ bencher/results/holoview_result.py,sha256=kcqetUFlz5HdBvV3ZjG6F-QCZabpFSNupAGYPkIZKuA,21269
62
64
  bencher/results/optuna_result.py,sha256=704l1eFJUQGTmnTaj2pIJ9ocRehLgu4PwMYmJU2rY9w,12399
63
- bencher/results/panel_result.py,sha256=Fkp7eWt7lzmnM5R6MdEsBeyGg7CEJmlSEHWzNujcIUc,3479
65
+ bencher/results/panel_result.py,sha256=5oMY0KDRoGK_3LoUJB-pRy9b0QMowVvu7hR6f2-0P8c,3647
64
66
  bencher/results/plotly_result.py,sha256=vny-HPyWIWzsLWQaOvMswtgVDub9bgQzqcartlFCqjI,2368
65
- bencher/variables/inputs.py,sha256=5yN45tet1cPyok6R_XD8xn1FZB5OUUp_TWWF2wIVVdg,6247
66
- bencher/variables/parametrised_sweep.py,sha256=q633o5zFY7P0ZeHX4G3AW3jYBfwoqLZZoUeibcln1u0,7483
67
+ bencher/variables/inputs.py,sha256=HYWEK75qfzk86dWvZbb6TeZr6yEvXgXILdddAqGuvEs,6392
68
+ bencher/variables/parametrised_sweep.py,sha256=96fLNjq1x7tGSwGCVshR3_LK9PRHhLipj8pbJ5umbnA,7029
67
69
  bencher/variables/results.py,sha256=yXdLjfGPSerWhipw_GDZJpBB8KQgCqcdreb8WjIeah8,5119
68
70
  bencher/variables/sweep_base.py,sha256=I1LEeG1y5Jsw0a-Ik03t0tSzcfENht2GmBECJ3KNs28,6559
69
71
  bencher/variables/time.py,sha256=Le7s8_oUYJD4wCqwQw-a_FRDpYQOi8CqMbGYsBF07jg,2860
70
- holobench-1.3.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
71
- holobench-1.3.0.dist-info/METADATA,sha256=Rp3JUzAKRIZXYW2YT1X_kEnO1ZH2fbs6ln0dx4Sux1w,4953
72
- holobench-1.3.0.dist-info/RECORD,,
72
+ holobench-1.3.2.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
73
+ holobench-1.3.2.dist-info/METADATA,sha256=rDXDdz5mTtMkOgBnmiVjJfU_JPIgZxDu1VnGlh_KTQw,4994
74
+ holobench-1.3.2.dist-info/RECORD,,