holobench 1.30.3__py3-none-any.whl → 1.31.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.
bencher/__init__.py CHANGED
@@ -1,9 +1,20 @@
1
1
  from .bencher import Bench, BenchCfg, BenchRunCfg
2
2
  from .bench_runner import BenchRunner
3
- from .example.benchmark_data import ExampleBenchCfgIn, ExampleBenchCfgOut, bench_function
3
+ from .example.benchmark_data import (
4
+ ExampleBenchCfgIn,
5
+ ExampleBenchCfgOut,
6
+ bench_function,
7
+ )
4
8
  from .bench_plot_server import BenchPlotServer
5
9
  from .variables.sweep_base import hash_sha1
6
- from .variables.inputs import IntSweep, FloatSweep, StringSweep, EnumSweep, BoolSweep, SweepBase
10
+ from .variables.inputs import (
11
+ IntSweep,
12
+ FloatSweep,
13
+ StringSweep,
14
+ EnumSweep,
15
+ BoolSweep,
16
+ SweepBase,
17
+ )
7
18
  from .variables.time import TimeSnapshot
8
19
 
9
20
  from .variables.inputs import box, p
@@ -32,7 +43,6 @@ from .results.composable_container.composable_container_video import (
32
43
  RenderCfg,
33
44
  )
34
45
 
35
- from .plotting.plot_filter import VarRange, PlotFilter
36
46
  from .utils import (
37
47
  hmap_canonical_input,
38
48
  get_nearest_coords,
@@ -40,9 +50,15 @@ from .utils import (
40
50
  gen_path,
41
51
  gen_image_path,
42
52
  gen_video_path,
53
+ gen_rerun_data_path,
43
54
  lerp,
44
55
  tabs_in_markdown,
56
+ publish_file,
57
+ github_content,
45
58
  )
59
+ from .utils_rerun import publish_and_view_rrd, rrd_to_pane, record_rerun_session
60
+
61
+ from .plotting.plot_filter import VarRange, PlotFilter
46
62
  from .variables.parametrised_sweep import ParametrizedSweep
47
63
  from .caching import CachedParams
48
64
  from .results.bench_result import BenchResult
@@ -52,3 +68,5 @@ from .bench_report import BenchReport
52
68
  from .job import Executors
53
69
  from .video_writer import VideoWriter, add_image
54
70
  from .class_enum import ClassEnum, ExampleEnum
71
+
72
+ from .flask_server import run_flask_in_thread
bencher/bench_report.py CHANGED
@@ -1,12 +1,11 @@
1
1
  import logging
2
2
  from typing import Callable
3
3
  import os
4
- import panel as pn
5
4
  from pathlib import Path
6
5
  import tempfile
7
-
8
6
  from threading import Thread
9
7
 
8
+ import panel as pn
10
9
  from bencher.results.bench_result import BenchResult
11
10
  from bencher.bench_plot_server import BenchPlotServer
12
11
  from bencher.bench_cfg import BenchRunCfg
@@ -0,0 +1,30 @@
1
+ import rerun as rr
2
+ import bencher as bch
3
+
4
+ rr.init("rerun_example_my_blueprint")
5
+
6
+
7
+ class SweepRerun(bch.ParametrizedSweep):
8
+ theta = bch.FloatSweep(default=1, bounds=[1, 4], doc="Input angle", units="rad", samples=30)
9
+
10
+ out_pane = bch.ResultContainer()
11
+
12
+ def __call__(self, **kwargs):
13
+ self.update_params_from_kwargs(**kwargs)
14
+ self.out_pane = bch.record_rerun_session()
15
+ rr.log("s1", rr.Boxes2D(half_sizes=[self.theta, 1]))
16
+
17
+ return super().__call__(**kwargs)
18
+
19
+
20
+ def example_rerun(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
21
+ """This example shows how to sample a 1 dimensional float variable and plot the result of passing that parameter sweep to the benchmarking function"""
22
+
23
+ bench = SweepRerun().to_bench(run_cfg, report)
24
+ bench.plot_sweep()
25
+ return bench
26
+
27
+
28
+ if __name__ == "__main__":
29
+ bch.run_flask_in_thread()
30
+ example_rerun(bch.BenchRunCfg(level=3)).report.show()
@@ -0,0 +1,29 @@
1
+ import rerun as rr
2
+ import bencher as bch
3
+ import panel as pn
4
+
5
+
6
+ rr.init("rerun_example_local", spawn=True)
7
+ file_path = "dat1.rrd"
8
+ rr.save(file_path)
9
+
10
+ rr.log("s1", rr.Scalar(1))
11
+ rr.log("s1", rr.Scalar(4))
12
+ rr.log("s1", rr.Scalar(2))
13
+
14
+ local = True
15
+
16
+ if local:
17
+ row = pn.Row()
18
+ # row.append(rrd_to_pane("http://localhost:8001/dat2.rrd"))
19
+
20
+ row.append(bch.rrd_to_pane("http://127.0.0.1:8001/dat2.rrd"))
21
+ row.show()
22
+ else:
23
+ # publish data to a github branch
24
+ bch.publish_and_view_rrd(
25
+ file_path,
26
+ remote="https://github.com/dyson-ai/bencher.git",
27
+ branch_name="test_rrd",
28
+ content_callback=bch.github_content,
29
+ ).show()
@@ -0,0 +1,25 @@
1
+ from flask import Flask, send_from_directory
2
+ from flask_cors import CORS
3
+ import threading
4
+ from pathlib import Path
5
+
6
+
7
+ def create_server(directory):
8
+ """Create a Flask app configured to serve files from the specified directory."""
9
+ app = Flask(__name__)
10
+ CORS(app)
11
+
12
+ @app.route("/<path:path>", methods=["GET"])
13
+ def serve_file(path):
14
+ return send_from_directory(directory, path)
15
+
16
+ return app
17
+
18
+
19
+ def run_flask_in_thread(directory=None, port=8001):
20
+ """Run the Flask server to serve files from the specified directory."""
21
+ if directory is None:
22
+ directory = Path("cachedir/").absolute().as_posix()
23
+ app = create_server(directory)
24
+ threading.Thread(target=app.run, kwargs={"port": port}, daemon=True).start()
25
+ print(f"Flask server is running on port {port} serving files from {directory}")
bencher/utils.py CHANGED
@@ -9,6 +9,11 @@ from pathlib import Path
9
9
  from uuid import uuid4
10
10
  from functools import partial
11
11
  from typing import Callable, Any, List, Tuple
12
+ import logging
13
+ import os
14
+ import tempfile
15
+ import shutil
16
+
12
17
  import param
13
18
  import numpy as np
14
19
 
@@ -169,6 +174,10 @@ def gen_image_path(image_name: str = "img", filetype=".png") -> str:
169
174
  return gen_path(image_name, "img", filetype)
170
175
 
171
176
 
177
+ def gen_rerun_data_path(rrd_name: str = "rrd", filetype=".rrd") -> str:
178
+ return gen_path(rrd_name, "rrd", filetype)
179
+
180
+
172
181
  def callable_name(any_callable: Callable[..., Any]) -> str:
173
182
  if isinstance(any_callable, partial):
174
183
  return any_callable.func.__name__
@@ -197,3 +206,90 @@ def get_name(var):
197
206
 
198
207
  def params_to_str(param_list: List[param.Parameter]):
199
208
  return [get_name(i) for i in param_list]
209
+
210
+
211
+ def publish_file(filepath: str, remote: str, branch_name: str) -> str: # pragma: no cover
212
+ """Publish a file to an orphan git branch:
213
+
214
+ .. code-block:: python
215
+
216
+ def publish_args(branch_name) -> Tuple[str, str]:
217
+ return (
218
+ "https://github.com/dyson-ai/bencher.git",
219
+ f"https://github.com/dyson-ai/bencher/blob/{branch_name}")
220
+
221
+
222
+ Args:
223
+ remote (Callable): A function the returns a tuple of the publishing urls. It must follow the signature def publish_args(branch_name) -> Tuple[str, str]. The first url is the git repo name, the second url needs to match the format for viewable html pages on your git provider. The second url can use the argument branch_name to point to the file on a specified branch.
224
+
225
+ Returns:
226
+ str: the url of the published file
227
+ """
228
+
229
+ with tempfile.TemporaryDirectory() as temp_dir:
230
+ shutil.copy(filepath, temp_dir)
231
+ filename = Path(filepath).name
232
+ filepath_tmp = Path(temp_dir) / filename
233
+
234
+ logging.info(f"created report at: {filepath_tmp.absolute()}")
235
+ cd_dir = f"cd {temp_dir} &&"
236
+
237
+ # create a new git repo and add files to that. Push the file to another arbitrary repo. The aim of doing it this way is that no data needs to be downloaded.
238
+
239
+ # os.system(f"{cd_dir} git config init.defaultBranch {branch_name}")
240
+ os.system(f"{cd_dir} git init")
241
+ os.system(f"{cd_dir} git branch -m {branch_name}")
242
+ os.system(f"{cd_dir} git add {filename}")
243
+ os.system(f'{cd_dir} git commit -m "publish {branch_name}"')
244
+ os.system(f"{cd_dir} git remote add origin {remote}")
245
+ os.system(f"{cd_dir} git push --set-upstream origin {branch_name} -f")
246
+
247
+
248
+ def github_content(remote: str, branch_name: str, filename: str): # pragma: no cover
249
+ raw = remote.replace(".git", "").replace(
250
+ "https://github.com/", "https://raw.githubusercontent.com/"
251
+ )
252
+ return f"{raw}/{branch_name}/{filename}?token=$(date +%s)"
253
+
254
+
255
+ # import logging
256
+ # # from rerun.legacy_notebook import as_html
257
+ # import rerun as rr
258
+ # import panel as pn
259
+ # # from .utils import publish_file, gen_rerun_data_path
260
+
261
+
262
+ # def rrd_to_pane(
263
+ # url: str, width: int = 499, height: int = 600, version: str = None
264
+ # ): # pragma: no cover
265
+ # if version is None:
266
+ # version = "-1.20.1" # TODO find a better way of doing this
267
+ # return pn.pane.HTML(
268
+ # f'<iframe src="https://app.rerun.io/version/{version}/?url={url}" width={width} height={height}></iframe>'
269
+ # )
270
+
271
+
272
+ # # def to_pane(path: str):
273
+ # # as_html()
274
+ # # return rrd_to_pane(path)
275
+
276
+
277
+ # def publish_and_view_rrd(
278
+ # file_path: str,
279
+ # remote: str,
280
+ # branch_name,
281
+ # content_callback: callable,
282
+ # version: str = None,
283
+ # ): # pragma: no cover
284
+ # as_html()
285
+ # publish_file(file_path, remote=remote, branch_name="test_rrd")
286
+ # publish_path = content_callback(remote, branch_name, file_path)
287
+ # logging.info(publish_path)
288
+ # return rrd_to_pane(publish_path, version=version)
289
+
290
+
291
+ # def record_rerun_session():
292
+ # rrd_path = gen_rerun_data_path()
293
+ # rr.save(rrd_path)
294
+ # path = rrd_path.split("cachedir")[0]
295
+ # return rrd_to_pane(f"http://126.0.0.1:8001/{path}")
bencher/utils_rerun.py ADDED
@@ -0,0 +1,41 @@
1
+ import logging
2
+ from rerun.legacy_notebook import as_html
3
+ import rerun as rr
4
+ import panel as pn
5
+ from .utils import publish_file, gen_rerun_data_path
6
+
7
+
8
+ def rrd_to_pane(
9
+ url: str, width: int = 500, height: int = 600, version: str = None
10
+ ): # pragma: no cover
11
+ if version is None:
12
+ version = "0.20.1" # TODO find a better way of doing this
13
+ return pn.pane.HTML(
14
+ f'<iframe src="https://app.rerun.io/version/{version}/?url={url}" width={width} height={height}></iframe>'
15
+ )
16
+
17
+
18
+ def to_pane(path: str):
19
+ as_html()
20
+ return rrd_to_pane(path)
21
+
22
+
23
+ def publish_and_view_rrd(
24
+ file_path: str,
25
+ remote: str,
26
+ branch_name,
27
+ content_callback: callable,
28
+ version: str = None,
29
+ ): # pragma: no cover
30
+ as_html()
31
+ publish_file(file_path, remote=remote, branch_name="test_rrd")
32
+ publish_path = content_callback(remote, branch_name, file_path)
33
+ logging.info(publish_path)
34
+ return rrd_to_pane(publish_path, version=version)
35
+
36
+
37
+ def record_rerun_session():
38
+ rrd_path = gen_rerun_data_path()
39
+ rr.save(rrd_path)
40
+ path = rrd_path.split("cachedir")[1]
41
+ return rrd_to_pane(f"http://127.0.0.1:8001/{path}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: holobench
3
- Version: 1.30.3
3
+ Version: 1.31.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
@@ -9,6 +9,8 @@ Author-email: Austin Gregg-Smith <blooop@gmail.com>
9
9
  License: MIT
10
10
  Requires-Python: <3.13,>=3.10
11
11
  Requires-Dist: diskcache<=5.6.3,>=5.6
12
+ Requires-Dist: flask
13
+ Requires-Dist: flask-cors
12
14
  Requires-Dist: holoviews<=1.19.1,>=1.15
13
15
  Requires-Dist: hvplot<=0.10.0,>=0.8
14
16
  Requires-Dist: matplotlib<=3.9.2,>=3.6.3
@@ -19,6 +21,8 @@ Requires-Dist: pandas<=2.2.2,>=2.0
19
21
  Requires-Dist: panel<=1.4.5,>=1.3.6
20
22
  Requires-Dist: param<=2.1.1,>=1.13.0
21
23
  Requires-Dist: plotly<=5.24.1,>=5.15
24
+ Requires-Dist: rerun-notebook
25
+ Requires-Dist: rerun-sdk==0.20.1
22
26
  Requires-Dist: scikit-learn<=1.5.1,>=1.2
23
27
  Requires-Dist: scoop<=0.7.2.0,>=0.7.0
24
28
  Requires-Dist: sortedcontainers<=2.4,>=2.4
@@ -1,14 +1,16 @@
1
- bencher/__init__.py,sha256=VtSU6Dq3XdjphKQJ9s3yZlA3el5B9kNGqsJMM-vyYx0,1580
1
+ bencher/__init__.py,sha256=kJtu0hg6Bf6CgBMahI8vqi3NqgywqE_YCv7NRpbE4BY,1818
2
2
  bencher/bench_cfg.py,sha256=mcsF5VU7Z-BLKE0bh9te73cEVNzr9pCnbsdIOPCJPy4,18414
3
3
  bencher/bench_plot_server.py,sha256=nvGTr981XgWELqV7yID91j6V1UIPGtKilzxHcNWaZ6Q,4196
4
- bencher/bench_report.py,sha256=95K4ubVGXyyGO40fsdFysgPmxrI6JbXpQKdMiahm7KI,6365
4
+ bencher/bench_report.py,sha256=FVMPZutQKTxq5Um46xLeJahntmuP76n7PaYhVGi4bB8,6364
5
5
  bencher/bench_runner.py,sha256=5h_g-WCxocUEIDix-D81zOz0YdN-3kC7tneN9yKEE0s,6201
6
6
  bencher/bencher.py,sha256=C71paITRtrESt_O2RNFdJ17Hg2zB6FSX4RINRsJq59c,35328
7
7
  bencher/caching.py,sha256=AusaNrzGGlj5m6zcwcqnTn55Mam2mQdF--oqelO806M,1627
8
8
  bencher/class_enum.py,sha256=kYHW9qKkKcNdwaXizZL-fTptS_DUEGv4c88yCehk3gc,1492
9
+ bencher/flask_server.py,sha256=uMhMaySUki5StC-r_TXb4KTVqAiffyqfH7UzQidFqSw,831
9
10
  bencher/job.py,sha256=swa0VwrZf41v7qNjreVDIYUU6r_dfuLipPZbg_w5x7c,6089
10
11
  bencher/optuna_conversions.py,sha256=an-LfPsQXyyvhIZnG8Wl1RQVYMvJj7WOi3YNqoUnuxQ,5356
11
- bencher/utils.py,sha256=9KAThtIG8jNd0nd4Wft8miNM_yHWmZUkIBfJh19pzgI,6480
12
+ bencher/utils.py,sha256=DP2GJP28nSEihvZwiV1Rl7YJ5NTrRt2zBLs46eQ37hQ,9887
13
+ bencher/utils_rerun.py,sha256=jkKe6ZetWrFjiATxl0-YmUrfR6zzEtzawgeULwxAZQY,1149
12
14
  bencher/video_writer.py,sha256=z49tAG_ttXc8iWcTkWPJO1QaneaVdsmYL6Hpal-pd4Q,2176
13
15
  bencher/worker_job.py,sha256=FREi0yWQACFmH86R1j-LH72tALEFkKhLDmmoGQY9Jh4,1571
14
16
  bencher/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -35,6 +37,8 @@ bencher/example/example_image1.py,sha256=3T6rgmCL7mCra2F6us-Fy0_jwhh7OvStmSieQui
35
37
  bencher/example/example_levels.py,sha256=gcNqjdsC0Bi0dX9oakssPEmuh_zFqpJhPYPPoDN3uw8,6890
36
38
  bencher/example/example_levels2.py,sha256=tMhA6dYYQskzMeAZdaz6jRmQTe-c-jLXfkaUqWT30-I,1117
37
39
  bencher/example/example_pareto.py,sha256=sLh37iZSQitW7DE7ktbyaOgHr1ZWxG7pXxCMH00KKqQ,2688
40
+ bencher/example/example_rerun.py,sha256=QNN2yRLrDM6Ph1iEk9m-81mMxmS5dRNuEA0R70gz4gA,960
41
+ bencher/example/example_rerun2.py,sha256=TV8e2UMwLFowhiXb_sQG2IS-W5jXF67VCitVjD8u1o8,660
38
42
  bencher/example/example_sample_cache.py,sha256=7gf1BJ63VAgdqNuNXkbL9-jeTeC3kXA_PY9yG3ulTz0,4200
39
43
  bencher/example/example_sample_cache_context.py,sha256=QmNM5Y8bCWEvbE7-6uRJVZhLaIEriL4lpMIV5-yTUg8,4065
40
44
  bencher/example/example_simple.py,sha256=E1-D10N-O50S33UQ9iLIlq09-x7BohbjYaR_lzLjQjc,11706
@@ -89,7 +93,7 @@ bencher/variables/results.py,sha256=Wq14e8rAj5mcK22325wcaeTMjgZ6JuduqceAHItHFY8,
89
93
  bencher/variables/sweep_base.py,sha256=gfEhKvsb16ZLbe38JewZqu0AMOHpsqwRbZbt-aCg9Bc,6258
90
94
  bencher/variables/time.py,sha256=zcRS5p4ZkFjMta9nZMEuWv86rLnPkUSqyO69QwI5q3E,3142
91
95
  resource/bencher,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
- holobench-1.30.3.dist-info/METADATA,sha256=Hcm68cVxVMskIezkmj2E74MsOo37QZYg-OB9V5kX3so,6360
93
- holobench-1.30.3.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
94
- holobench-1.30.3.dist-info/licenses/LICENSE,sha256=dSHXTdRY4Y7qGFMv63UksV700iff7iE-p7GGs6Sbnvo,1065
95
- holobench-1.30.3.dist-info/RECORD,,
96
+ holobench-1.31.0.dist-info/METADATA,sha256=iB9DhPLAcCVVu88N_X2A0n-tNkOKammffgHXDbg33Io,6470
97
+ holobench-1.31.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
98
+ holobench-1.31.0.dist-info/licenses/LICENSE,sha256=dSHXTdRY4Y7qGFMv63UksV700iff7iE-p7GGs6Sbnvo,1065
99
+ holobench-1.31.0.dist-info/RECORD,,