holobench 1.40.1__py3-none-any.whl → 1.41.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.
- CHANGELOG.md +10 -0
- bencher/bench_cfg.py +3 -7
- bencher/caching.py +1 -4
- bencher/example/example_composable_container_image.py +60 -0
- bencher/example/example_composable_container_video.py +49 -0
- bencher/example/example_image.py +17 -21
- bencher/example/example_image1.py +16 -20
- bencher/example/example_video.py +33 -17
- bencher/example/experimental/example_hvplot_explorer.py +2 -3
- bencher/example/inputs_1D/example_1_float_2_cat_repeats.py +12 -0
- bencher/example/meta/generate_examples.py +6 -0
- bencher/job.py +1 -3
- bencher/results/bench_result.py +2 -1
- bencher/results/bench_result_base.py +2 -2
- bencher/results/composable_container/composable_container_video.py +39 -12
- bencher/results/holoview_result.py +21 -12
- bencher/results/laxtex_result.py +42 -35
- bencher/utils.py +1 -4
- bencher/video_writer.py +37 -2
- bencher/worker_job.py +3 -4
- {holobench-1.40.1.dist-info → holobench-1.41.0.dist-info}/METADATA +9 -13
- {holobench-1.40.1.dist-info → holobench-1.41.0.dist-info}/RECORD +24 -21
- bencher/example/example_composable_container.py +0 -106
- {holobench-1.40.1.dist-info → holobench-1.41.0.dist-info}/WHEEL +0 -0
- {holobench-1.40.1.dist-info → holobench-1.41.0.dist-info}/licenses/LICENSE +0 -0
CHANGELOG.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [0.3.10]
|
9
|
+
|
10
|
+
Before changelogs
|
bencher/bench_cfg.py
CHANGED
@@ -6,7 +6,6 @@ import logging
|
|
6
6
|
from typing import List
|
7
7
|
|
8
8
|
import param
|
9
|
-
from str2bool import str2bool
|
10
9
|
import panel as pn
|
11
10
|
from datetime import datetime
|
12
11
|
|
@@ -197,11 +196,8 @@ class BenchRunCfg(BenchPlotSrvCfg):
|
|
197
196
|
|
198
197
|
parser.add_argument(
|
199
198
|
"--nightly",
|
200
|
-
|
201
|
-
|
202
|
-
const=False,
|
203
|
-
default=False,
|
204
|
-
help="turn on nightly benchmarking",
|
199
|
+
action="store_true",
|
200
|
+
help="Turn on nightly benchmarking",
|
205
201
|
)
|
206
202
|
|
207
203
|
parser.add_argument(
|
@@ -351,7 +347,7 @@ class BenchCfg(BenchRunCfg):
|
|
351
347
|
latex = self.to_latex()
|
352
348
|
desc = pn.pane.Markdown(self.describe_benchmark(), width=width)
|
353
349
|
if accordion:
|
354
|
-
desc = pn.Accordion(("Data Collection Parameters", desc))
|
350
|
+
desc = pn.Accordion(("Expand Full Data Collection Parameters", desc))
|
355
351
|
|
356
352
|
sentence = self.sweep_sentence()
|
357
353
|
if latex is not None:
|
bencher/caching.py
CHANGED
@@ -3,9 +3,6 @@ from diskcache import Cache
|
|
3
3
|
from bencher.variables.parametrised_sweep import ParametrizedSweep
|
4
4
|
from bencher.utils import hash_sha1
|
5
5
|
import logging
|
6
|
-
from sortedcontainers import SortedDict
|
7
|
-
|
8
|
-
# from job import job,JobCache,JobFunctionCache
|
9
6
|
|
10
7
|
|
11
8
|
class CachedParams(ParametrizedSweep):
|
@@ -20,7 +17,7 @@ class CachedParams(ParametrizedSweep):
|
|
20
17
|
self.cache.clear()
|
21
18
|
|
22
19
|
def kwargs_to_hash_key(self, **kwargs):
|
23
|
-
return tuple(
|
20
|
+
return tuple(sorted(kwargs.items(), key=lambda item: str(item[0])))
|
24
21
|
|
25
22
|
def in_cache(self, **kwargs):
|
26
23
|
self.update_params_from_kwargs(**kwargs)
|
@@ -0,0 +1,60 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
|
3
|
+
from bencher.example.example_image import BenchPolygons
|
4
|
+
|
5
|
+
|
6
|
+
class BenchComposableContainerImage(BenchPolygons):
|
7
|
+
compose_method = bch.EnumSweep(bch.ComposeType)
|
8
|
+
labels = bch.BoolSweep()
|
9
|
+
num_frames = bch.IntSweep(default=5, bounds=[1, 100])
|
10
|
+
|
11
|
+
polygon_vid = bch.ResultVideo()
|
12
|
+
|
13
|
+
def __call__(self, **kwargs):
|
14
|
+
self.update_params_from_kwargs(**kwargs)
|
15
|
+
var_name = None
|
16
|
+
var_value = None
|
17
|
+
|
18
|
+
if self.labels:
|
19
|
+
var_name = "sides"
|
20
|
+
var_value = self.sides
|
21
|
+
vr = bch.ComposableContainerVideo()
|
22
|
+
for i in range(self.num_frames):
|
23
|
+
res = super().__call__(start_angle=i)
|
24
|
+
print(res)
|
25
|
+
vr.append(res["polygon"])
|
26
|
+
self.polygon_vid = vr.to_video(
|
27
|
+
bch.RenderCfg(
|
28
|
+
compose_method=self.compose_method,
|
29
|
+
var_name=var_name,
|
30
|
+
var_value=var_value,
|
31
|
+
max_frame_duration=1.0 / 20.0,
|
32
|
+
)
|
33
|
+
)
|
34
|
+
return self.get_results_values_as_dict()
|
35
|
+
|
36
|
+
|
37
|
+
def example_composable_container_image(
|
38
|
+
run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
|
39
|
+
) -> bch.Bench:
|
40
|
+
bench = BenchComposableContainerImage().to_bench(run_cfg, report)
|
41
|
+
# bench.add_plot_callback(bch.BenchResult.to_panes)
|
42
|
+
# bench.add_plot_callback(bch.BenchResult.to_video_grid, result_types=(bch.ResultVideo))
|
43
|
+
# bench.add_plot_callback(bch.BenchResult.to_video_summary, result_types=(bch.ResultVideo))
|
44
|
+
# bench.plot_sweep(input_vars=["compose_method", "labels"])
|
45
|
+
|
46
|
+
bench.plot_sweep(input_vars=["compose_method"])
|
47
|
+
|
48
|
+
# bench.compose_
|
49
|
+
# bench.plot_sweep(
|
50
|
+
# input_vars=[bch.p("num_frames", [2, 8, 20])],
|
51
|
+
# const_vars=dict(compose_method=bch.ComposeType.sequence),
|
52
|
+
# )
|
53
|
+
|
54
|
+
return bench
|
55
|
+
|
56
|
+
|
57
|
+
if __name__ == "__main__":
|
58
|
+
ex_run_cfg = bch.BenchRunCfg()
|
59
|
+
ex_composable_image = example_composable_container_image(ex_run_cfg)
|
60
|
+
ex_composable_image.report.show()
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
from bencher.example.example_composable_container_image import BenchComposableContainerImage
|
3
|
+
|
4
|
+
|
5
|
+
class BenchComposableContainerVideo(bch.ParametrizedSweep):
|
6
|
+
unequal_length = bch.BoolSweep()
|
7
|
+
compose_method = bch.EnumSweep(bch.ComposeType)
|
8
|
+
labels = bch.BoolSweep()
|
9
|
+
polygon_vid = bch.ResultVideo()
|
10
|
+
|
11
|
+
def __call__(self, **kwargs):
|
12
|
+
self.update_params_from_kwargs(**kwargs)
|
13
|
+
vr = bch.ComposableContainerVideo()
|
14
|
+
for i in range(3, 5):
|
15
|
+
num_frames = i * 10 if self.unequal_length else 5
|
16
|
+
res = BenchComposableContainerImage().__call__(
|
17
|
+
compose_method=bch.ComposeType.sequence, sides=i, num_frames=num_frames
|
18
|
+
)
|
19
|
+
vr.append(res["polygon_vid"])
|
20
|
+
|
21
|
+
self.polygon_vid = vr.to_video(bch.RenderCfg(compose_method=kwargs.get("compose_method")))
|
22
|
+
return self.get_results_values_as_dict()
|
23
|
+
|
24
|
+
|
25
|
+
def example_composable_container_video(
|
26
|
+
run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
|
27
|
+
) -> bch.Bench:
|
28
|
+
bench = BenchComposableContainerVideo().to_bench(run_cfg, report)
|
29
|
+
|
30
|
+
bench.result_vars = ["polygon_vid"]
|
31
|
+
bench.add_plot_callback(bch.BenchResult.to_panes)
|
32
|
+
bench.add_plot_callback(bch.BenchResult.to_video_grid, result_types=(bch.ResultVideo))
|
33
|
+
bench.add_plot_callback(bch.BenchResult.to_video_summary, result_types=(bch.ResultVideo))
|
34
|
+
bench.plot_sweep(input_vars=["compose_method", "labels"], const_vars=dict(unequal_length=True))
|
35
|
+
|
36
|
+
res = bench.plot_sweep(
|
37
|
+
input_vars=[],
|
38
|
+
const_vars=dict(unequal_length=False, compose_method=bch.ComposeType.sequence),
|
39
|
+
plot_callbacks=False,
|
40
|
+
)
|
41
|
+
|
42
|
+
bench.report.append(res.to_video_grid())
|
43
|
+
|
44
|
+
return bench
|
45
|
+
|
46
|
+
|
47
|
+
if __name__ == "__main__":
|
48
|
+
ex_run_cfg = bch.BenchRunCfg()
|
49
|
+
example_composable_container_video(ex_run_cfg).report.show()
|
bencher/example/example_image.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import bencher as bch
|
2
2
|
import numpy as np
|
3
3
|
import math
|
4
|
-
import
|
4
|
+
from PIL import Image, ImageDraw
|
5
5
|
|
6
6
|
|
7
7
|
def polygon_points(radius: float, sides: int, start_angle: float):
|
@@ -16,7 +16,6 @@ class BenchPolygons(bch.ParametrizedSweep):
|
|
16
16
|
sides = bch.IntSweep(default=3, bounds=(3, 7))
|
17
17
|
radius = bch.FloatSweep(default=1, bounds=(0.2, 1))
|
18
18
|
linewidth = bch.FloatSweep(default=1, bounds=(1, 10))
|
19
|
-
linestyle = bch.StringSweep(["solid", "dashed", "dotted"])
|
20
19
|
color = bch.StringSweep(["red", "green", "blue"])
|
21
20
|
start_angle = bch.FloatSweep(default=0, bounds=[0, 360])
|
22
21
|
polygon = bch.ResultImage()
|
@@ -26,33 +25,30 @@ class BenchPolygons(bch.ParametrizedSweep):
|
|
26
25
|
def __call__(self, **kwargs):
|
27
26
|
self.update_params_from_kwargs(**kwargs)
|
28
27
|
points = polygon_points(self.radius, self.sides, self.start_angle)
|
29
|
-
|
30
|
-
self.polygon = self.points_to_polygon_png(points,
|
28
|
+
filepath = bch.gen_image_path("polygon")
|
29
|
+
self.polygon = self.points_to_polygon_png(points, filepath)
|
30
|
+
# Verify filepath is being returned
|
31
|
+
assert isinstance(self.polygon, str), f"Expected string filepath, got {type(self.polygon)}"
|
31
32
|
|
32
33
|
self.side_length = 2 * self.radius * math.sin(math.pi / self.sides)
|
33
34
|
self.area = (self.sides * self.side_length**2) / (4 * math.tan(math.pi / self.sides))
|
34
35
|
return super().__call__()
|
35
36
|
|
36
37
|
def points_to_polygon_png(self, points: list[float], filename: str):
|
37
|
-
"""Draw a closed polygon and save to png"""
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
linewidth=self.linewidth,
|
45
|
-
linestyle=self.linestyle,
|
46
|
-
color=self.color,
|
47
|
-
)
|
48
|
-
ax.set_xlim(-1, 1)
|
49
|
-
ax.set_ylim(-1, 1)
|
38
|
+
"""Draw a closed polygon and save to png using PIL"""
|
39
|
+
size = 300
|
40
|
+
img = Image.new("RGBA", (size, size), (0, 0, 0, 0))
|
41
|
+
draw = ImageDraw.Draw(img)
|
42
|
+
|
43
|
+
# Scale points to image size (from [-1,1] to [0,size])
|
44
|
+
scaled_points = [(((p[0] + 1) * size / 2), ((1 - p[1]) * size / 2)) for p in points]
|
50
45
|
|
51
|
-
|
52
|
-
|
53
|
-
fig.savefig(filename, dpi=30)
|
46
|
+
# Draw polygon outline
|
47
|
+
draw.line(scaled_points, fill=self.color, width=int(self.linewidth))
|
54
48
|
|
55
|
-
|
49
|
+
img.save(filename, "PNG")
|
50
|
+
# Explicitly return the filename string
|
51
|
+
return str(filename)
|
56
52
|
|
57
53
|
|
58
54
|
def example_image(run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None) -> bch.Bench:
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import bencher as bch
|
2
2
|
import numpy as np
|
3
3
|
import math
|
4
|
-
import
|
4
|
+
from PIL import Image, ImageDraw
|
5
5
|
|
6
6
|
|
7
7
|
def polygon_points(radius: float, sides: int, start_angle: float):
|
@@ -28,36 +28,32 @@ class BenchPolygons(bch.ParametrizedSweep):
|
|
28
28
|
def __call__(self, **kwargs):
|
29
29
|
self.update_params_from_kwargs(**kwargs)
|
30
30
|
points = polygon_points(self.radius, self.sides, self.start_angle)
|
31
|
-
|
32
|
-
self.polygon = self.points_to_polygon_png(points,
|
31
|
+
filepath = bch.gen_image_path("polygon")
|
32
|
+
self.polygon = self.points_to_polygon_png(points, filepath, dpi=30)
|
33
33
|
self.polygon_small = self.points_to_polygon_png(
|
34
34
|
points, bch.gen_image_path("polygon"), dpi=10
|
35
35
|
)
|
36
|
+
# Verify filepaths are being returned
|
37
|
+
assert isinstance(self.polygon, str), f"Expected string filepath, got {type(self.polygon)}"
|
38
|
+
assert isinstance(self.polygon_small, str), (
|
39
|
+
f"Expected string filepath, got {type(self.polygon_small)}"
|
40
|
+
)
|
36
41
|
|
37
42
|
self.side_length = 2 * self.radius * math.sin(math.pi / self.sides)
|
38
43
|
self.area = (self.sides * self.side_length**2) / (4 * math.tan(math.pi / self.sides))
|
39
44
|
return super().__call__()
|
40
45
|
|
41
46
|
def points_to_polygon_png(self, points: list[float], filename: str, dpi):
|
42
|
-
"""Draw a closed polygon and save to png"""
|
43
|
-
|
44
|
-
|
45
|
-
|
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)
|
47
|
+
"""Draw a closed polygon and save to png using PIL"""
|
48
|
+
size = int(100 * (dpi / 30))
|
49
|
+
img = Image.new("RGBA", (size, size), (0, 0, 0, 0))
|
50
|
+
draw = ImageDraw.Draw(img)
|
55
51
|
|
56
|
-
|
57
|
-
|
58
|
-
fig.savefig(filename, dpi=dpi)
|
52
|
+
scaled_points = [(((p[0] + 1) * size / 2), ((1 - p[1]) * size / 2)) for p in points]
|
53
|
+
draw.line(scaled_points, fill=self.color, width=int(self.linewidth))
|
59
54
|
|
60
|
-
|
55
|
+
img.save(filename, "PNG")
|
56
|
+
return str(filename)
|
61
57
|
|
62
58
|
|
63
59
|
def example_image_vid_sequential1(
|
bencher/example/example_video.py
CHANGED
@@ -1,9 +1,24 @@
|
|
1
1
|
import bencher as bch
|
2
2
|
import numpy as np
|
3
|
-
|
3
|
+
from PIL import Image
|
4
|
+
import colorcet as cc
|
5
|
+
import numpy.typing as npt
|
6
|
+
|
7
|
+
|
8
|
+
def apply_colormap(data: npt.NDArray) -> npt.NDArray:
|
9
|
+
"""Apply a perceptually uniform colormap to the data"""
|
10
|
+
# Normalize data to [0, 1]
|
11
|
+
normalized = (data - data.min()) / (data.max() - data.min())
|
12
|
+
# Convert hex colors to RGB values using numpy's frombuffer
|
13
|
+
colors = np.array(
|
14
|
+
[np.frombuffer(bytes.fromhex(c.lstrip("#")), dtype=np.uint8) for c in cc.rainbow]
|
15
|
+
)
|
16
|
+
# Map normalized values to colormap indices
|
17
|
+
indices = (normalized * (len(colors) - 1)).astype(int)
|
18
|
+
# Create RGB array from the colormap
|
19
|
+
return colors[indices]
|
4
20
|
|
5
21
|
|
6
|
-
# code from https://ipython-books.github.io/124-simulating-a-partial-differential-equation-reaction-diffusion-systems-and-turing-patterns/
|
7
22
|
class TuringPattern(bch.ParametrizedSweep):
|
8
23
|
alpha = bch.FloatSweep(default=2.8e-4, bounds=(2e-4, 5e-3))
|
9
24
|
beta = bch.FloatSweep(default=5e-3, bounds=(1e-3, 9e-3))
|
@@ -17,6 +32,7 @@ class TuringPattern(bch.ParametrizedSweep):
|
|
17
32
|
video = bch.ResultVideo()
|
18
33
|
score = bch.ResultVar()
|
19
34
|
img = bch.ResultImage()
|
35
|
+
img_extracted = bch.ResultImage()
|
20
36
|
|
21
37
|
def laplacian(self, Z, dx):
|
22
38
|
Ztop = Z[0:-2, 1:-1]
|
@@ -49,28 +65,28 @@ class TuringPattern(bch.ParametrizedSweep):
|
|
49
65
|
def __call__(self, **kwargs):
|
50
66
|
self.update_params_from_kwargs(**kwargs)
|
51
67
|
|
52
|
-
n = int(self.time / self.dt)
|
53
|
-
dx = 2.0 / self.size
|
68
|
+
n = int(self.time / self.dt)
|
69
|
+
dx = 2.0 / self.size
|
54
70
|
|
55
71
|
U = np.random.rand(self.size, self.size)
|
56
72
|
V = np.random.rand(self.size, self.size)
|
57
73
|
|
58
|
-
fig, ax = plt.subplots(frameon=False, figsize=(2, 2))
|
59
|
-
fig.set_tight_layout(True)
|
60
|
-
ax.set_axis_off()
|
61
74
|
vid_writer = bch.VideoWriter()
|
62
75
|
for i in range(n):
|
63
76
|
self.update(U, V, dx)
|
64
77
|
if i % 500 == 0:
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
78
|
+
# Apply colormap to create RGB image
|
79
|
+
rgb = apply_colormap(U)
|
80
|
+
# Create PIL image with alpha channel
|
81
|
+
img = Image.fromarray(rgb, "RGB").convert("RGBA")
|
82
|
+
img = img.resize((200, 200), Image.Resampling.LANCZOS)
|
83
|
+
rgb_alpha = np.array(img)
|
84
|
+
vid_writer.append(rgb_alpha)
|
85
|
+
|
86
|
+
self.img = bch.add_image(rgb_alpha)
|
72
87
|
self.video = vid_writer.write()
|
73
|
-
|
88
|
+
self.img_extracted = bch.video_writer.VideoWriter.extract_frame(self.video)
|
89
|
+
print("img path", self.img_extracted)
|
74
90
|
self.score = self.alpha + self.beta
|
75
91
|
return super().__call__()
|
76
92
|
|
@@ -109,8 +125,8 @@ def example_video_tap(
|
|
109
125
|
if __name__ == "__main__":
|
110
126
|
run_cfg_ex = bch.BenchRunCfg()
|
111
127
|
run_cfg_ex.level = 2
|
112
|
-
run_cfg_ex.cache_samples = True
|
113
|
-
run_cfg_ex.only_hash_tag = True
|
128
|
+
# run_cfg_ex.cache_samples = True
|
129
|
+
# run_cfg_ex.only_hash_tag = True
|
114
130
|
|
115
131
|
# example_video(run_cfg_ex).report.show()
|
116
132
|
example_video_tap(run_cfg_ex).report.show()
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# THIS IS NOT A WORKING EXAMPLE YET
|
2
2
|
# pylint: disable=duplicate-code
|
3
|
-
import hvplot
|
4
3
|
import bencher as bch
|
5
4
|
from bencher import ExampleBenchCfgIn, ExampleBenchCfgOut, bench_function
|
6
5
|
|
@@ -35,5 +34,5 @@ if __name__ == "__main__":
|
|
35
34
|
),
|
36
35
|
)
|
37
36
|
|
38
|
-
|
39
|
-
|
37
|
+
bench.report.append(bench_out.to_explorer())
|
38
|
+
bench.report.show()
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import bencher as bch
|
2
|
+
from bencher.example.meta.example_meta import BenchableObject
|
3
|
+
|
4
|
+
run_cfg = bch.BenchRunCfg()
|
5
|
+
run_cfg.repeats = 20
|
6
|
+
run_cfg.level = 4
|
7
|
+
bench = BenchableObject().to_bench(run_cfg)
|
8
|
+
res = bench.plot_sweep(
|
9
|
+
input_vars=["float1", "noisy", "noise_distribution"], result_vars=["distance", "sample_noise"]
|
10
|
+
)
|
11
|
+
|
12
|
+
bench.report.show()
|
@@ -48,3 +48,9 @@ if __name__ == "__main__":
|
|
48
48
|
convert_example_to_jupyter_notebook(
|
49
49
|
"/workspaces/bencher/bencher/example/inputs_1D/example_1_in_2_out_repeats.py", "1D"
|
50
50
|
)
|
51
|
+
|
52
|
+
# todo, enable
|
53
|
+
# convert_example_to_jupyter_notebook(
|
54
|
+
# "/workspaces/bencher/bencher/example/example_composable_container_video.py",
|
55
|
+
# "Media",
|
56
|
+
# )
|
bencher/job.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
from typing import Callable
|
3
|
-
from sortedcontainers import SortedDict
|
4
3
|
import logging
|
5
4
|
from diskcache import Cache
|
6
5
|
from concurrent.futures import Future, ProcessPoolExecutor
|
@@ -11,7 +10,6 @@ from enum import auto
|
|
11
10
|
try:
|
12
11
|
from scoop import futures as scoop_future_executor
|
13
12
|
except ImportError as e:
|
14
|
-
logging.warning(e.msg)
|
15
13
|
scoop_future_executor = None
|
16
14
|
|
17
15
|
|
@@ -23,7 +21,7 @@ class Job:
|
|
23
21
|
self.function = function
|
24
22
|
self.job_args = job_args
|
25
23
|
if job_key is None:
|
26
|
-
self.job_key = hash_sha1(tuple(
|
24
|
+
self.job_key = hash_sha1(tuple(sorted(self.job_args.items())))
|
27
25
|
else:
|
28
26
|
self.job_key = job_key
|
29
27
|
self.tag = tag
|
bencher/results/bench_result.py
CHANGED
@@ -53,6 +53,7 @@ class BenchResult(PlotlyResult, HoloviewResult, HvplotResult, VideoSummaryResult
|
|
53
53
|
self,
|
54
54
|
plot_list: List[callable] = None,
|
55
55
|
remove_plots: List[callable] = None,
|
56
|
+
default_container=pn.Column,
|
56
57
|
**kwargs,
|
57
58
|
) -> List[pn.panel]:
|
58
59
|
self.plt_cnt_cfg.print_debug = False
|
@@ -67,7 +68,7 @@ class BenchResult(PlotlyResult, HoloviewResult, HvplotResult, VideoSummaryResult
|
|
67
68
|
|
68
69
|
kwargs = self.set_plot_size(**kwargs)
|
69
70
|
|
70
|
-
row = EmptyContainer(
|
71
|
+
row = EmptyContainer(default_container())
|
71
72
|
for plot_callback in plot_list:
|
72
73
|
if self.plt_cnt_cfg.print_debug:
|
73
74
|
print(f"checking: {plot_callback.__name__}")
|
@@ -321,7 +321,7 @@ class BenchResultBase(OptunaResult):
|
|
321
321
|
**kwargs,
|
322
322
|
) -> Optional[pn.Row]:
|
323
323
|
if hv_dataset is None:
|
324
|
-
hv_dataset = self.to_hv_dataset()
|
324
|
+
hv_dataset = self.to_hv_dataset(reduce=reduce)
|
325
325
|
|
326
326
|
if pane_collection is None:
|
327
327
|
pane_collection = pn.Row()
|
@@ -333,7 +333,7 @@ class BenchResultBase(OptunaResult):
|
|
333
333
|
if result_types is None or isinstance(rv, result_types):
|
334
334
|
row.append(
|
335
335
|
self.to_panes_multi_panel(
|
336
|
-
|
336
|
+
hv_dataset,
|
337
337
|
rv,
|
338
338
|
plot_callback=partial(plot_callback, **kwargs),
|
339
339
|
target_dimension=target_dimension,
|
@@ -3,7 +3,7 @@ import numpy as np
|
|
3
3
|
from copy import deepcopy
|
4
4
|
from pathlib import Path
|
5
5
|
from dataclasses import dataclass
|
6
|
-
from moviepy
|
6
|
+
from moviepy import (
|
7
7
|
ImageClip,
|
8
8
|
CompositeVideoClip,
|
9
9
|
clips_array,
|
@@ -11,22 +11,43 @@ from moviepy.editor import (
|
|
11
11
|
VideoClip,
|
12
12
|
VideoFileClip,
|
13
13
|
)
|
14
|
-
from moviepy.video.fx.margin import margin
|
15
14
|
|
16
15
|
from bencher.results.composable_container.composable_container_base import (
|
17
16
|
ComposableContainerBase,
|
18
17
|
ComposeType,
|
19
18
|
)
|
20
19
|
from bencher.video_writer import VideoWriter
|
20
|
+
from moviepy import vfx
|
21
21
|
|
22
22
|
|
23
23
|
@dataclass()
|
24
24
|
class RenderCfg:
|
25
|
+
"""Configuration class for video rendering options.
|
26
|
+
|
27
|
+
This class controls how videos and images are composed and rendered together.
|
28
|
+
It provides options for timing, layout, appearance, and labeling of the output.
|
29
|
+
|
30
|
+
Attributes:
|
31
|
+
compose_method (ComposeType): Method to compose multiple clips (sequence, right, down, overlay).
|
32
|
+
Defaults to ComposeType.sequence.
|
33
|
+
var_name (str, optional): Variable name for labeling. Defaults to None.
|
34
|
+
var_value (str, optional): Variable value for labeling. Defaults to None.
|
35
|
+
background_col (tuple[int, int, int]): RGB color for background. Defaults to white (255, 255, 255).
|
36
|
+
duration (float): Target duration for the composed video in seconds. Defaults to 10.0.
|
37
|
+
default_duration (float): Fallback duration when duration is None. Defaults to 10.0.
|
38
|
+
duration_target (bool): If True, tries to match target duration while respecting frame
|
39
|
+
duration constraints. If False, uses exact duration. Defaults to True.
|
40
|
+
min_frame_duration (float): Minimum duration for each frame in seconds. Defaults to 1/30.
|
41
|
+
max_frame_duration (float): Maximum duration for each frame in seconds. Defaults to 2.0.
|
42
|
+
margin (int): Margin size in pixels to add around clips. Defaults to 0.
|
43
|
+
"""
|
44
|
+
|
25
45
|
compose_method: ComposeType = ComposeType.sequence
|
26
46
|
var_name: str = None
|
27
47
|
var_value: str = None
|
28
48
|
background_col: tuple[int, int, int] = (255, 255, 255)
|
29
49
|
duration: float = 10.0
|
50
|
+
default_duration: float = 10.0
|
30
51
|
duration_target: bool = True
|
31
52
|
min_frame_duration: float = 1.0 / 30
|
32
53
|
max_frame_duration: float = 2.0
|
@@ -69,7 +90,9 @@ class ComposableContainerVideo(ComposableContainerBase):
|
|
69
90
|
def calculate_duration(self, frames, render_cfg: RenderCfg):
|
70
91
|
if render_cfg.duration_target:
|
71
92
|
# calculate duration based on fps constraints
|
72
|
-
duration =
|
93
|
+
duration = (
|
94
|
+
render_cfg.default_duration if render_cfg.duration is None else render_cfg.duration
|
95
|
+
)
|
73
96
|
frame_duration = duration / frames
|
74
97
|
if render_cfg.min_frame_duration is not None:
|
75
98
|
frame_duration = max(frame_duration, render_cfg.min_frame_duration)
|
@@ -77,7 +100,10 @@ class ComposableContainerVideo(ComposableContainerBase):
|
|
77
100
|
frame_duration = min(frame_duration, render_cfg.max_frame_duration)
|
78
101
|
duration = frame_duration * frames
|
79
102
|
else:
|
80
|
-
|
103
|
+
if render_cfg.duration is None:
|
104
|
+
duration = render_cfg.default_duration
|
105
|
+
else:
|
106
|
+
duration = render_cfg.duration
|
81
107
|
frame_duration = duration / float(frames)
|
82
108
|
|
83
109
|
print("max_frame_duration", render_cfg.max_frame_duration)
|
@@ -111,8 +137,8 @@ class ComposableContainerVideo(ComposableContainerBase):
|
|
111
137
|
case ComposeType.right | ComposeType.down:
|
112
138
|
for i in range(len(self.container)):
|
113
139
|
self.container[i] = self.extend_clip(self.container[i], max_duration)
|
114
|
-
self.container[i] =
|
115
|
-
|
140
|
+
self.container[i] = self.container[i].with_effects(
|
141
|
+
[vfx.Margin(top=render_cfg.margin, color=render_cfg.background_col)]
|
116
142
|
)
|
117
143
|
|
118
144
|
if render_cfg.compose_method == ComposeType.right:
|
@@ -126,13 +152,14 @@ class ComposableContainerVideo(ComposableContainerBase):
|
|
126
152
|
out = concatenate_videoclips(
|
127
153
|
self.container, bg_color=render_cfg.background_col, method="compose"
|
128
154
|
)
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
# # out.duration = fps
|
155
|
+
case ComposeType.overlay:
|
156
|
+
for i in range(len(self.container)):
|
157
|
+
self.container[i] = self.container[i].with_opacity(1.0 / len(self.container))
|
158
|
+
out = CompositeVideoClip(self.container, bg_color=render_cfg.background_col)
|
134
159
|
case _:
|
135
|
-
raise RuntimeError(
|
160
|
+
raise RuntimeError(
|
161
|
+
f"This compose type is not supported: {render_cfg.compose_method}"
|
162
|
+
)
|
136
163
|
|
137
164
|
label = self.label_formatter(render_cfg.var_name, render_cfg.var_value)
|
138
165
|
if label is not None:
|
@@ -154,14 +154,14 @@ class HoloviewResult(PanelResult):
|
|
154
154
|
tap_var = [tap_var]
|
155
155
|
|
156
156
|
if len(tap_var) == 0 or self.plt_cnt_cfg.inputs_cnt > 1 or not use_tap:
|
157
|
-
|
157
|
+
line_cb = self.to_line_ds
|
158
158
|
else:
|
159
|
-
|
159
|
+
line_cb = partial(
|
160
160
|
self.to_line_tap_ds, result_var_plots=tap_var, container=tap_container
|
161
161
|
)
|
162
162
|
|
163
163
|
return self.filter(
|
164
|
-
|
164
|
+
line_cb,
|
165
165
|
float_range=VarRange(1, 1),
|
166
166
|
cat_range=VarRange(0, None),
|
167
167
|
repeats_range=VarRange(1, 1),
|
@@ -202,17 +202,26 @@ 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
|
-
|
206
|
-
# print(
|
205
|
+
# print(result_var.name)
|
206
|
+
# print( dataset)
|
207
207
|
pt = hv.Overlay()
|
208
208
|
# find pairs of {var_name} {var_name}_std to plot the line and their spreads.
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
209
|
+
var = result_var.name
|
210
|
+
std_var = f"{var}_std"
|
211
|
+
|
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
|
+
|
217
|
+
# for var in dataset.data_vars:
|
218
|
+
# print(var)
|
219
|
+
# if not var.endswith("_std"):
|
220
|
+
# std_var = f"{var}_std"
|
221
|
+
# pt *= hvds.to(hv.Curve, vdims=var, label=var).opts(title=title, **kwargs)
|
222
|
+
# #Only create a Spread if the matching _std variable exists
|
223
|
+
# if std_var in dataset.data_vars:
|
224
|
+
# pt *= hvds.to(hv.Spread, vdims=[var, std_var])
|
216
225
|
|
217
226
|
return pt.opts(legend_position="right")
|
218
227
|
|
bencher/results/laxtex_result.py
CHANGED
@@ -1,60 +1,67 @@
|
|
1
|
-
from __future__ import annotations
|
2
1
|
import panel as pn
|
3
2
|
from panel.pane import LaTeX
|
4
|
-
from typing import Optional
|
3
|
+
from typing import Optional, List, Any
|
5
4
|
|
6
5
|
pn.extension("mathjax")
|
7
6
|
|
8
7
|
|
9
|
-
def latex_text(
|
10
|
-
|
11
|
-
return r"\text{" +
|
8
|
+
def latex_text(text: str) -> str:
|
9
|
+
"""Convert text to LaTeX text format, replacing underscores with spaces."""
|
10
|
+
return r"\text{" + text.replace("_", " ") + r"} \\"
|
12
11
|
|
13
12
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
def format_values_list(values: List[Any], max_display: int = 5) -> List[Any]:
|
14
|
+
"""Format a list of values, showing ellipsis if too long."""
|
15
|
+
if len(values) <= max_display:
|
16
|
+
return values
|
17
|
+
return [values[i] for i in [0, 1, 0, -2, -1]]
|
18
|
+
|
19
|
+
|
20
|
+
def create_matrix_array(values: List[Any]) -> str:
|
21
|
+
"""Create a LaTeX matrix array from values."""
|
22
|
+
displayed_vals = format_values_list(values)
|
23
|
+
if len(values) > 5:
|
19
24
|
displayed_vals[2] = "⋮"
|
20
|
-
|
25
|
+
return r"\\ ".join([str(val) for val in displayed_vals])
|
26
|
+
|
21
27
|
|
22
|
-
|
28
|
+
def input_var_to_latex(input_var) -> str:
|
29
|
+
"""Convert input variable to LaTeX format."""
|
30
|
+
vals = input_var.values()
|
31
|
+
latex_str = r"\begin{array}{c}"
|
23
32
|
latex_str += latex_text(input_var.name)
|
24
33
|
latex_str += f"{len(vals)}" + r"\times1 \\"
|
25
34
|
latex_str += r"\left[ \begin{array}{c}"
|
26
|
-
latex_str +=
|
35
|
+
latex_str += create_matrix_array(vals)
|
27
36
|
latex_str += r"\end{array} \right] \end{array}"
|
28
37
|
return latex_str
|
29
38
|
|
30
39
|
|
31
|
-
def result_var_to_latex(bench_cfg):
|
32
|
-
|
40
|
+
def result_var_to_latex(bench_cfg) -> str:
|
41
|
+
"""Convert result variables to LaTeX format."""
|
33
42
|
sizes = [str(len(i.values())) for i in bench_cfg.all_vars]
|
34
43
|
if len(sizes) == 1:
|
35
44
|
sizes.insert(0, "1")
|
36
|
-
sizes_str = r"\times".join(reversed(sizes))
|
37
|
-
latex_str += sizes_str + r"\\ of \\"
|
38
|
-
latex_str += r" \left[\begin{array}{cc}"
|
39
45
|
|
40
|
-
|
41
|
-
|
42
|
-
latex_str += r"\
|
43
|
-
latex_str +=
|
46
|
+
latex_str = r"\begin{array}{c}"
|
47
|
+
latex_str += r"\times".join(reversed(sizes)) + r"\\ of \\"
|
48
|
+
latex_str += r" \left[\begin{array}{cc}"
|
49
|
+
latex_str += "".join(latex_text(rv.name) for rv in bench_cfg.result_vars)
|
50
|
+
latex_str += r"\end{array} \right]\end{array}"
|
44
51
|
return latex_str
|
45
52
|
|
46
53
|
|
47
54
|
def to_latex(bench_cfg) -> Optional[pn.pane.LaTeX]:
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
return
|
55
|
+
"""Convert benchmark configuration to LaTeX visualization.
|
56
|
+
|
57
|
+
Returns None if there are no variables to display.
|
58
|
+
"""
|
59
|
+
if not bench_cfg.all_vars:
|
60
|
+
return None
|
61
|
+
|
62
|
+
latex_str = r"\[" + r"\bigtimes".join(input_var_to_latex(iv) for iv in bench_cfg.all_vars)
|
63
|
+
latex_str += r"\rightarrow\quad"
|
64
|
+
latex_str += result_var_to_latex(bench_cfg)
|
65
|
+
latex_str += r"\]"
|
66
|
+
|
67
|
+
return LaTeX(latex_str.replace("_", r"\;"))
|
bencher/utils.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
from collections import namedtuple
|
2
2
|
import xarray as xr
|
3
|
-
from sortedcontainers import SortedDict
|
4
3
|
import hashlib
|
5
4
|
import re
|
6
5
|
import math
|
@@ -27,9 +26,7 @@ def hmap_canonical_input(dic: dict) -> tuple:
|
|
27
26
|
Returns:
|
28
27
|
tuple: values of the dictionary always in the same order and hashable
|
29
28
|
"""
|
30
|
-
|
31
|
-
function_input = SortedDict(dic)
|
32
|
-
return tuple(function_input.values())
|
29
|
+
return tuple(value for _, value in sorted(dic.items()))
|
33
30
|
|
34
31
|
|
35
32
|
def make_namedtuple(class_name: str, **fields) -> namedtuple:
|
bencher/video_writer.py
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
import numpy as np
|
2
2
|
import moviepy.video.io.ImageSequenceClip
|
3
|
+
import moviepy.video.io.VideoFileClip
|
3
4
|
from pathlib import Path
|
4
5
|
from .utils import gen_video_path, gen_image_path
|
5
|
-
|
6
|
-
import moviepy
|
7
6
|
from PIL import Image, ImageDraw
|
8
7
|
|
9
8
|
|
@@ -46,6 +45,16 @@ class VideoWriter:
|
|
46
45
|
new_img.paste(image, (0, padding))
|
47
46
|
return new_img
|
48
47
|
|
48
|
+
@staticmethod
|
49
|
+
def convert_to_compatible_format(video_path: str) -> str:
|
50
|
+
new_path = Path(video_path)
|
51
|
+
new_path = new_path.with_name(f"{new_path.stem}_fixed{new_path.suffix}").as_posix()
|
52
|
+
vw = VideoWriter()
|
53
|
+
vw.filename = new_path
|
54
|
+
with moviepy.video.io.VideoFileClip.VideoFileClip(video_path) as vid:
|
55
|
+
vw.write_video_raw(vid)
|
56
|
+
return new_path
|
57
|
+
|
49
58
|
def write_video_raw(self, video_clip: moviepy.video.VideoClip, fps: int = 30) -> str:
|
50
59
|
video_clip.write_videofile(
|
51
60
|
self.filename,
|
@@ -59,6 +68,32 @@ class VideoWriter:
|
|
59
68
|
video_clip.close()
|
60
69
|
return self.filename
|
61
70
|
|
71
|
+
@staticmethod
|
72
|
+
def extract_frame(video_path: str, time: float = None, output_path: str = None) -> str:
|
73
|
+
"""Extract a frame from a video at a specific time.
|
74
|
+
|
75
|
+
Args:
|
76
|
+
video_path: Path to the video file
|
77
|
+
time: Time in seconds to extract frame. If None, uses last frame
|
78
|
+
output_path: Optional path where to save the image. If None, uses video name with _frame.png
|
79
|
+
|
80
|
+
Returns:
|
81
|
+
str: Path to the saved PNG image
|
82
|
+
"""
|
83
|
+
if output_path is None:
|
84
|
+
output_path = (
|
85
|
+
Path(video_path).with_stem(f"{Path(video_path).stem}_frame").with_suffix(".png")
|
86
|
+
)
|
87
|
+
else:
|
88
|
+
output_path = Path(output_path)
|
89
|
+
|
90
|
+
with moviepy.video.io.VideoFileClip.VideoFileClip(video_path) as video:
|
91
|
+
frame_time = time if time is not None else video.duration
|
92
|
+
frame = video.get_frame(frame_time)
|
93
|
+
Image.fromarray(frame).save(output_path)
|
94
|
+
|
95
|
+
return output_path.as_posix()
|
96
|
+
|
62
97
|
|
63
98
|
def add_image(np_array: np.ndarray, name: str = "img") -> str:
|
64
99
|
"""Creates a file on disk from a numpy array and returns the created image path"""
|
bencher/worker_job.py
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
from typing import List, Tuple, Any
|
2
2
|
from dataclasses import dataclass, field
|
3
|
-
from sortedcontainers import SortedDict
|
4
3
|
from .utils import hash_sha1
|
5
4
|
from bencher.utils import hmap_canonical_input
|
6
5
|
|
@@ -14,7 +13,7 @@ class WorkerJob:
|
|
14
13
|
bench_cfg_sample_hash: str
|
15
14
|
tag: str
|
16
15
|
|
17
|
-
function_input:
|
16
|
+
function_input: dict = None
|
18
17
|
canonical_input: Tuple[Any] = None
|
19
18
|
fn_inputs_sorted: List[str] = None
|
20
19
|
function_input_signature_pure: str = None
|
@@ -23,7 +22,7 @@ class WorkerJob:
|
|
23
22
|
msgs: List[str] = field(default_factory=list)
|
24
23
|
|
25
24
|
def setup_hashes(self) -> None:
|
26
|
-
self.function_input =
|
25
|
+
self.function_input = dict(zip(self.dims_name, self.function_input_vars))
|
27
26
|
|
28
27
|
self.canonical_input = hmap_canonical_input(self.function_input)
|
29
28
|
|
@@ -32,7 +31,7 @@ class WorkerJob:
|
|
32
31
|
|
33
32
|
# store a tuple of the inputs as keys for a holomap
|
34
33
|
# the signature is the hash of the inputs to to the function + meta variables such as repeat and time + the hash of the benchmark sweep as a whole (without the repeats hash)
|
35
|
-
self.fn_inputs_sorted =
|
34
|
+
self.fn_inputs_sorted = sorted(self.function_input.items())
|
36
35
|
self.function_input_signature_pure = hash_sha1((self.fn_inputs_sorted, self.tag))
|
37
36
|
|
38
37
|
self.function_input_signature_benchmark_context = hash_sha1(
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: holobench
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.41.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
|
@@ -12,28 +12,24 @@ Requires-Python: <3.13,>=3.10
|
|
12
12
|
Requires-Dist: diskcache<=5.6.3,>=5.6
|
13
13
|
Requires-Dist: holoviews<=1.20.0,>=1.15
|
14
14
|
Requires-Dist: hvplot<=0.10.0,>=0.8
|
15
|
-
Requires-Dist:
|
16
|
-
Requires-Dist:
|
17
|
-
Requires-Dist:
|
18
|
-
Requires-Dist: optuna<=4.2.0,>=3.2
|
15
|
+
Requires-Dist: moviepy<=2.1.2,>=2.1.2
|
16
|
+
Requires-Dist: numpy<=2.2.3,>=1.0
|
17
|
+
Requires-Dist: optuna<=4.2.1,>=3.2
|
19
18
|
Requires-Dist: pandas<=2.2.3,>=2.0
|
20
|
-
Requires-Dist: panel<=1.6.
|
19
|
+
Requires-Dist: panel<=1.6.1,>=1.3.6
|
21
20
|
Requires-Dist: param<=2.2.0,>=1.13.0
|
22
21
|
Requires-Dist: plotly<=6.0.0,>=5.15
|
23
22
|
Requires-Dist: scikit-learn<=1.6.1,>=1.2
|
24
|
-
Requires-Dist: scoop<=0.7.2.0,>=0.7.0
|
25
|
-
Requires-Dist: sortedcontainers<=2.4,>=2.4
|
26
|
-
Requires-Dist: str2bool<=1.1,>=1.1
|
27
23
|
Requires-Dist: strenum<=0.4.15,>=0.4.0
|
28
24
|
Requires-Dist: xarray<=2025.1.2,>=2023.7
|
29
25
|
Provides-Extra: rerun
|
30
26
|
Requires-Dist: flask; extra == 'rerun'
|
31
27
|
Requires-Dist: flask-cors; extra == 'rerun'
|
32
28
|
Requires-Dist: rerun-notebook; extra == 'rerun'
|
33
|
-
Requires-Dist: rerun-sdk==0.
|
29
|
+
Requires-Dist: rerun-sdk==0.22.0; extra == 'rerun'
|
34
30
|
Provides-Extra: test
|
35
|
-
Requires-Dist: coverage<=7.6.
|
36
|
-
Requires-Dist: hypothesis<=6.
|
31
|
+
Requires-Dist: coverage<=7.6.12,>=7.5.4; extra == 'test'
|
32
|
+
Requires-Dist: hypothesis<=6.125.3,>=6.104.2; extra == 'test'
|
37
33
|
Requires-Dist: ipykernel; extra == 'test'
|
38
34
|
Requires-Dist: jupyter-bokeh; extra == 'test'
|
39
35
|
Requires-Dist: nbformat; extra == 'test'
|
@@ -42,7 +38,7 @@ Requires-Dist: pre-commit<=4.1.0; extra == 'test'
|
|
42
38
|
Requires-Dist: pylint<=3.3.4,>=3.2.5; extra == 'test'
|
43
39
|
Requires-Dist: pytest-cov<=6.0.0,>=4.1; extra == 'test'
|
44
40
|
Requires-Dist: pytest<=8.3.4,>=7.4; extra == 'test'
|
45
|
-
Requires-Dist: ruff<=0.9.
|
41
|
+
Requires-Dist: ruff<=0.9.6,>=0.5.0; extra == 'test'
|
46
42
|
Description-Content-Type: text/markdown
|
47
43
|
|
48
44
|
# Bencher
|
@@ -1,24 +1,26 @@
|
|
1
|
+
CHANGELOG.md,sha256=alEi3CoMNOpKigEqP1uvdpuZMkpHJFCfO-tx8a_utss,284
|
1
2
|
bencher/__init__.py,sha256=hWfQxlvuHRsFK4ZPCpRXo3nDzQB52JOUoi67wcnhopE,1890
|
2
|
-
bencher/bench_cfg.py,sha256=
|
3
|
+
bencher/bench_cfg.py,sha256=FbjRAjbxKyHnb-3gPBLdE4GM_vgJeq7ciySH853j3gI,19040
|
3
4
|
bencher/bench_plot_server.py,sha256=nvGTr981XgWELqV7yID91j6V1UIPGtKilzxHcNWaZ6Q,4196
|
4
5
|
bencher/bench_report.py,sha256=ikMSHceyc8cYFH-sIza167DH-H-_iiTYDm2TmusUHDc,7515
|
5
6
|
bencher/bench_runner.py,sha256=wShmZ504BOKgHj0sOrGZtduyPfJHFFBfHRsz5tYy5_Q,7000
|
6
7
|
bencher/bencher.py,sha256=-vbZIzBr2IYYG7be5Hh8IZgIGUysTxoxQUV6xUToH14,35437
|
7
|
-
bencher/caching.py,sha256=
|
8
|
+
bencher/caching.py,sha256=RYvh6FLcYlMrfYcbkK5k8ZnT4lP2g5klUgo1oPfXhxg,1565
|
8
9
|
bencher/class_enum.py,sha256=kYHW9qKkKcNdwaXizZL-fTptS_DUEGv4c88yCehk3gc,1492
|
9
10
|
bencher/flask_server.py,sha256=uMhMaySUki5StC-r_TXb4KTVqAiffyqfH7UzQidFqSw,831
|
10
|
-
bencher/job.py,sha256=
|
11
|
+
bencher/job.py,sha256=cBsyw249iigZi1OhzW_ImU3AZMgCJPgvIDierI9xYNg,6147
|
11
12
|
bencher/optuna_conversions.py,sha256=an-LfPsQXyyvhIZnG8Wl1RQVYMvJj7WOi3YNqoUnuxQ,5356
|
12
|
-
bencher/utils.py,sha256=
|
13
|
+
bencher/utils.py,sha256=HpNI-CsEFqOgAOO_pYdwqNQzkc6DU1cQeA7x7hTIIvk,9827
|
13
14
|
bencher/utils_rerun.py,sha256=E1itolYJMjmtBE5qcSotiS20I-dobVnjznsTRvZaV0s,1212
|
14
|
-
bencher/video_writer.py,sha256=
|
15
|
-
bencher/worker_job.py,sha256=
|
15
|
+
bencher/video_writer.py,sha256=7oj_P6n9kWZ9geITSL1atBEdWk-GByRH--wxQJbTgHQ,3613
|
16
|
+
bencher/worker_job.py,sha256=F8Zh1yWLaSKtDhkZL0hBZ-I3nc_ifaCOkwWAju3nq4I,1509
|
16
17
|
bencher/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
18
|
bencher/example/benchmark_data.py,sha256=DL5Grj7UwnKZz2BHfGNKv35Ln0y2ntFwvZdkchOMHVU,6985
|
18
19
|
bencher/example/example_all.py,sha256=_jOiz07fsjghiIuLfMpZiRVEkPaH7dM8OftOGcdL6cU,1960
|
19
20
|
bencher/example/example_categorical.py,sha256=S6PP3LHZewHVymNZmEY-AEMRlJbv0CEgJ1NRWNDEnC8,3659
|
20
|
-
bencher/example/example_composable_container.py,sha256=URN_2Wv98_JpjWJUhbvK2YejpqumUJMTbQ9ok07TNZw,3753
|
21
21
|
bencher/example/example_composable_container2.py,sha256=tVcSggLAzuXsiHM00qSJk9fKOgqXbSzzyjs7IayLZCw,5667
|
22
|
+
bencher/example/example_composable_container_image.py,sha256=FPk0JUWr8aKRMk5x7CfR2z97a6QNt2BEA_BFgsjwav4,1961
|
23
|
+
bencher/example/example_composable_container_video.py,sha256=1kClqIP5ueOBEGSo1NJybmydCYfeyU3GmaqLwvGgfyQ,1849
|
22
24
|
bencher/example/example_consts.py,sha256=upKkrMNYUCS38IA4duuyJHERwdZIMB4FA60Gytu_BzU,1475
|
23
25
|
bencher/example/example_custom_sweep.py,sha256=OvAMqirV9KzbuaQ6ELOAbrRrj5zYHjpEs3tG-rgmFJM,1891
|
24
26
|
bencher/example/example_custom_sweep2.py,sha256=6RBiyVVaxAh5Aul85DfYA5P-lwhwW3Bb54o0CBgTB6Q,1225
|
@@ -32,8 +34,8 @@ bencher/example/example_floats2D.py,sha256=1V5hCxr0Iz2KT2JyePn-XmugsMXlDzf0GazWW
|
|
32
34
|
bencher/example/example_holosweep.py,sha256=emNUKCHPb-JrSWPjHajuAlQmUU9A9S7O-jdrvixg0Io,2989
|
33
35
|
bencher/example/example_holosweep_objects.py,sha256=eqOjuTYh4Pis5lGsSeN7BJZXKR2upOSjynEtR0HqyoY,3196
|
34
36
|
bencher/example/example_holosweep_tap.py,sha256=vKGyCdc1H8oECWRACW1kj5s1OJPAUETWHbP88R9hW_A,4475
|
35
|
-
bencher/example/example_image.py,sha256=
|
36
|
-
bencher/example/example_image1.py,sha256=
|
37
|
+
bencher/example/example_image.py,sha256=QovSZtxepBwNSYDjouTCrhtP3NXJUXYoqRT2sFavsio,5554
|
38
|
+
bencher/example/example_image1.py,sha256=XAR99ko6f4KZ6pHKoAebF2agTZRm8Hm5DZ1_lHdO2gI,2817
|
37
39
|
bencher/example/example_levels.py,sha256=Gl3hIGYmzLufKWIG_YFTvW-TCfao6Ys6W0uc4dAcizw,6858
|
38
40
|
bencher/example/example_levels2.py,sha256=tMhA6dYYQskzMeAZdaz6jRmQTe-c-jLXfkaUqWT30-I,1117
|
39
41
|
bencher/example/example_pareto.py,sha256=tQxX9g8VfASv2vyRAm-Bv3qsYKjKnU-HyuLXtiZYEpw,2656
|
@@ -49,11 +51,11 @@ bencher/example/example_simple_float.py,sha256=c3ZR0LXfgGcH63MnUpQovRVnzpx5lpDQs
|
|
49
51
|
bencher/example/example_simple_float2d.py,sha256=xsVOLO6AtMi9_fybpS_JZnhev5f11YuYWHrAOzJw2dI,1033
|
50
52
|
bencher/example/example_strings.py,sha256=NpOGwC1KRAyAAC2VQZCg09ArraESdU0lupFj4b0I-sQ,1538
|
51
53
|
bencher/example/example_time_event.py,sha256=l2dEut9oYnxxF7kRXnZx8Ohw1EdT5Iezo_b8CwCcCHA,2133
|
52
|
-
bencher/example/example_video.py,sha256=
|
54
|
+
bencher/example/example_video.py,sha256=UGcAoY-DvYRuGQB0UgtVebCFtW2ru0s8MfZbhm3efUk,4527
|
53
55
|
bencher/example/example_workflow.py,sha256=00QnUuViMfX_PqzqkXmg1wPX6yAq7IS7mCL_RFKwrMM,6806
|
54
56
|
bencher/example/experimental/example_bokeh_plotly.py,sha256=3jUKh8eKIAlpklKnp8UopIHhUDw1A0_5CwjeyTzbi7o,846
|
55
57
|
bencher/example/experimental/example_hover_ex.py,sha256=qszw4FkIfqQkVviPSpmUoFOoi6PGotGbsc7Ojyx8EtU,1052
|
56
|
-
bencher/example/experimental/example_hvplot_explorer.py,sha256=
|
58
|
+
bencher/example/experimental/example_hvplot_explorer.py,sha256=k3NXqLLDOf_uFi09S0RAkArasTZULMb3upwzqi09hMA,1796
|
57
59
|
bencher/example/experimental/example_interactive.py,sha256=MM1A2EVsKTy95RERTNnld0tUmZmCy8N41_jGm2wlG7U,2619
|
58
60
|
bencher/example/experimental/example_streamnd.py,sha256=LqkTtdY4NhnP5dEB1Ifv7RQ5Vq4dLkp5E3aWnWuzniA,1414
|
59
61
|
bencher/example/experimental/example_streams.py,sha256=rrTmcmxDlirGoyTbJ4LT4fBIAc1k28qjnjy5JxGKyhg,1030
|
@@ -63,6 +65,7 @@ bencher/example/experimental/example_vector.py,sha256=3o_1dA4dc2HL6uIEvDAcvLPVJB
|
|
63
65
|
bencher/example/inputs_0D/example_0_in_1_out.py,sha256=Lm4lgNGy6oLAEuqDEWHqWGbU6-T2LUudNtP3NKrFDho,1706
|
64
66
|
bencher/example/inputs_0D/example_0_in_2_out.py,sha256=HFtuuuZspK0Hy_1hEbaQy8Ah3SFtSf04yHbaaB9YYec,1389
|
65
67
|
bencher/example/inputs_1D/example1d_common.py,sha256=QurBf3rYq4B3nG9J7Rra30XXtoE6EeDHjPH0CrQ-T9g,2069
|
68
|
+
bencher/example/inputs_1D/example_1_float_2_cat_repeats.py,sha256=E8IfubrWgZLX8yrZ-QdWVmEdzx2x8cjSIQUfcwJRUyk,342
|
66
69
|
bencher/example/inputs_1D/example_1_in_1_out.py,sha256=eqAztAufMNTSVE3xdA9Nyqc8UXUn7Y2cjsIP_T_ITUw,1774
|
67
70
|
bencher/example/inputs_1D/example_1_in_2_out.py,sha256=9qwDF5m25pzwRLeqQB_IO1I0ER07-izc9lFJBcapMdo,1908
|
68
71
|
bencher/example/inputs_1D/example_1_in_2_out_repeats.py,sha256=0xt1B9xkCdDhTa8zBVmV565z22SO0RCQcAkCRuF4c1k,1804
|
@@ -71,7 +74,7 @@ bencher/example/meta/example_meta.py,sha256=ZXW8LZ1DGs05RiZRHLrOx-qt9x10qL6v2tt7
|
|
71
74
|
bencher/example/meta/example_meta_cat.py,sha256=j3OCi1Yra47wrXOVr8epMYPGIXjQwdQoCcCICPmE2lo,609
|
72
75
|
bencher/example/meta/example_meta_float.py,sha256=Y-zo7QAZkpt3mQEE4guiPmRHmKjn6-y8D_AjWeGCqEs,598
|
73
76
|
bencher/example/meta/example_meta_levels.py,sha256=ZZ14r99z6cs73ZwvBJvDKdEVIdTyHzrWsenxRgFXfXQ,1410
|
74
|
-
bencher/example/meta/generate_examples.py,sha256=
|
77
|
+
bencher/example/meta/generate_examples.py,sha256=z_EoIRT_g15XftQ3_rHXpt_oAJEy0DBPGh2Vpt-ZVfE,1593
|
75
78
|
bencher/example/meta/generate_meta.py,sha256=Pu7bvu5tNKsPuEPFU90g4z1d-ZPEitqhr4rPQe_X_I8,4861
|
76
79
|
bencher/example/optuna/example_optuna.py,sha256=0zA6IIDWe7FM0rnYJ-FHF9GZtrhYdKHQTosUD2Raw0M,2338
|
77
80
|
bencher/example/shelved/example_float2D_scatter.py,sha256=z8ranMq8IcJ1yoVSFDncp3gw-yWG7X9lXLimXKpy5Ks,3372
|
@@ -81,13 +84,13 @@ bencher/plotting/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
|
|
81
84
|
bencher/plotting/plot_filter.py,sha256=hWRjZa9zTncVJiF6r_DI4Ce1xcU49PxJw4gXk7AzsnA,4931
|
82
85
|
bencher/plotting/plt_cnt_cfg.py,sha256=0P9KjVQSUfPY7Kh7UGAbTqihaTgnmLm3oZ5Nvf-pcjM,3193
|
83
86
|
bencher/results/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
84
|
-
bencher/results/bench_result.py,sha256=
|
85
|
-
bencher/results/bench_result_base.py,sha256=
|
87
|
+
bencher/results/bench_result.py,sha256=JVVhFVMc4P9FqL6zBKsSK3npOkyn1IEKvNOOkvBciew,3811
|
88
|
+
bencher/results/bench_result_base.py,sha256=OgSu--RcpEElJum0y7XIEKyGznSaJvrxxx3ZbhhvIl8,21980
|
86
89
|
bencher/results/dataset_result.py,sha256=qXmFMrVAo_1qM6hhV4XpQqmCz9RiVkQo6ICYmbT-Kvk,8680
|
87
90
|
bencher/results/float_formatter.py,sha256=sX6HNCyaXdHDxC8ybVUHwCJ3qOKbPUkBOplVIHtKWjM,1746
|
88
|
-
bencher/results/holoview_result.py,sha256=
|
91
|
+
bencher/results/holoview_result.py,sha256=Nc8m-kdQBylTy0JGB_mES3oaisNzHm8sRjT1mMtWWPo,29821
|
89
92
|
bencher/results/hvplot_result.py,sha256=bYSewYhPLVzW6HF_WPjAhS1ZiRp9FJHs008UEBXgH4Y,1993
|
90
|
-
bencher/results/laxtex_result.py,sha256=
|
93
|
+
bencher/results/laxtex_result.py,sha256=BL9iNgSoNpE8WTwW_OjVbYdYgRdlP27zv_nQ9PpwLds,2212
|
91
94
|
bencher/results/optuna_result.py,sha256=QtZ4TGRun7gJoFVUjEyXKPF5yakwOSXrqEXQVJdJmm4,13587
|
92
95
|
bencher/results/panel_result.py,sha256=lXOtfhWKSspf53Wgm94DTiVD3rliieHQW96sOdu5UYk,1336
|
93
96
|
bencher/results/plotly_result.py,sha256=wkgfL38qJp6RviekXBYpNPeU4HCf0nbtKDAhu5QZhUg,2132
|
@@ -97,7 +100,7 @@ bencher/results/composable_container/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeu
|
|
97
100
|
bencher/results/composable_container/composable_container_base.py,sha256=gmlQl3NQ3LWIfH15neLoZMNos6hbu3SklslfcFDAacA,2778
|
98
101
|
bencher/results/composable_container/composable_container_dataframe.py,sha256=ZbFaQSo4UsRxY8NUdJPjNFW3_kzlm8jtWuoLf8y_t8U,1789
|
99
102
|
bencher/results/composable_container/composable_container_panel.py,sha256=HrOoeGB0y0jGQcxcci_M82ftsvklLkJgo-4SjDBJCks,1232
|
100
|
-
bencher/results/composable_container/composable_container_video.py,sha256=
|
103
|
+
bencher/results/composable_container/composable_container_video.py,sha256=yLfGRIswSHHWfFwVFBVz31wzKB9x-3bTfMtr-BqIyzk,8672
|
101
104
|
bencher/variables/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
102
105
|
bencher/variables/inputs.py,sha256=B4IycsuZQOx51OGO2e8zK5TjfRWvYXI7Ngle3KpVIdw,6694
|
103
106
|
bencher/variables/parametrised_sweep.py,sha256=fxjKOQ2x5xuCyi0kO1_XS9bXiib1bjThhvpulZPeyv8,7802
|
@@ -105,7 +108,7 @@ bencher/variables/results.py,sha256=Wq14e8rAj5mcK22325wcaeTMjgZ6JuduqceAHItHFY8,
|
|
105
108
|
bencher/variables/sweep_base.py,sha256=gfEhKvsb16ZLbe38JewZqu0AMOHpsqwRbZbt-aCg9Bc,6258
|
106
109
|
bencher/variables/time.py,sha256=zcRS5p4ZkFjMta9nZMEuWv86rLnPkUSqyO69QwI5q3E,3142
|
107
110
|
resource/bencher,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
108
|
-
holobench-1.
|
109
|
-
holobench-1.
|
110
|
-
holobench-1.
|
111
|
-
holobench-1.
|
111
|
+
holobench-1.41.0.dist-info/METADATA,sha256=M6tXWaG8Ft_a17Dm8sgcIDuMWEELgI-qmYjcpl5v4FE,6693
|
112
|
+
holobench-1.41.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
113
|
+
holobench-1.41.0.dist-info/licenses/LICENSE,sha256=dSHXTdRY4Y7qGFMv63UksV700iff7iE-p7GGs6Sbnvo,1065
|
114
|
+
holobench-1.41.0.dist-info/RECORD,,
|
@@ -1,106 +0,0 @@
|
|
1
|
-
import bencher as bch
|
2
|
-
|
3
|
-
from bencher.example.example_image import BenchPolygons
|
4
|
-
|
5
|
-
|
6
|
-
class BenchComposableContainerImage(BenchPolygons):
|
7
|
-
compose_method = bch.EnumSweep(bch.ComposeType)
|
8
|
-
labels = bch.BoolSweep()
|
9
|
-
num_frames = bch.IntSweep(default=5, bounds=[1, 100])
|
10
|
-
polygon_vid = bch.ResultVideo()
|
11
|
-
|
12
|
-
def __call__(self, **kwargs):
|
13
|
-
self.update_params_from_kwargs(**kwargs)
|
14
|
-
var_name = None
|
15
|
-
var_value = None
|
16
|
-
|
17
|
-
if self.labels:
|
18
|
-
var_name = "sides"
|
19
|
-
var_value = self.sides
|
20
|
-
vr = bch.ComposableContainerVideo()
|
21
|
-
for i in range(self.num_frames):
|
22
|
-
res = super().__call__(start_angle=i)
|
23
|
-
print(res)
|
24
|
-
vr.append(res["polygon"])
|
25
|
-
self.polygon_vid = vr.to_video(
|
26
|
-
bch.RenderCfg(
|
27
|
-
compose_method=self.compose_method,
|
28
|
-
var_name=var_name,
|
29
|
-
var_value=var_value,
|
30
|
-
max_frame_duration=1.0 / 20.0,
|
31
|
-
)
|
32
|
-
)
|
33
|
-
return self.get_results_values_as_dict()
|
34
|
-
|
35
|
-
|
36
|
-
class BenchComposableContainerVideo(bch.ParametrizedSweep):
|
37
|
-
unequal_length = bch.BoolSweep()
|
38
|
-
compose_method = bch.EnumSweep(bch.ComposeType)
|
39
|
-
labels = bch.BoolSweep()
|
40
|
-
polygon_vid = bch.ResultVideo()
|
41
|
-
|
42
|
-
def __call__(self, **kwargs):
|
43
|
-
self.update_params_from_kwargs(**kwargs)
|
44
|
-
vr = bch.ComposableContainerVideo()
|
45
|
-
for i in range(3, 5):
|
46
|
-
num_frames = i * 10 if self.unequal_length else 5
|
47
|
-
res = BenchComposableContainerImage().__call__(
|
48
|
-
compose_method=bch.ComposeType.sequence, sides=i, num_frames=num_frames
|
49
|
-
)
|
50
|
-
vr.append(res["polygon_vid"])
|
51
|
-
|
52
|
-
self.polygon_vid = vr.to_video(bch.RenderCfg(compose_method=kwargs.get("compose_method")))
|
53
|
-
return self.get_results_values_as_dict()
|
54
|
-
|
55
|
-
|
56
|
-
def example_composable_container_image(
|
57
|
-
run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
|
58
|
-
) -> bch.Bench:
|
59
|
-
bench = BenchComposableContainerImage().to_bench(run_cfg, report)
|
60
|
-
bench.result_vars = ["polygon_vid"]
|
61
|
-
# bench.add_plot_callback(bch.BenchResult.to_panes)
|
62
|
-
# bench.add_plot_callback(bch.BenchResult.to_video_grid, result_types=(bch.ResultVideo))
|
63
|
-
# bench.add_plot_callback(bch.BenchResult.to_video_summary, result_types=(bch.ResultVideo))
|
64
|
-
# bench.plot_sweep(input_vars=["compose_method", "labels"])
|
65
|
-
|
66
|
-
bench.plot_sweep(input_vars=["compose_method"])
|
67
|
-
|
68
|
-
# bench.compose_
|
69
|
-
# bench.plot_sweep(
|
70
|
-
# input_vars=[bch.p("num_frames", [2, 8, 20])],
|
71
|
-
# const_vars=dict(compose_method=bch.ComposeType.sequence),
|
72
|
-
# )
|
73
|
-
|
74
|
-
return bench
|
75
|
-
|
76
|
-
|
77
|
-
def example_composable_container_video(
|
78
|
-
run_cfg: bch.BenchRunCfg = None, report: bch.BenchReport = None
|
79
|
-
) -> bch.Bench:
|
80
|
-
bench = BenchComposableContainerVideo().to_bench(run_cfg, report)
|
81
|
-
|
82
|
-
bench.result_vars = ["polygon_vid"]
|
83
|
-
bench.add_plot_callback(bch.BenchResult.to_panes)
|
84
|
-
bench.add_plot_callback(bch.BenchResult.to_video_grid, result_types=(bch.ResultVideo))
|
85
|
-
bench.add_plot_callback(bch.BenchResult.to_video_summary, result_types=(bch.ResultVideo))
|
86
|
-
bench.plot_sweep(input_vars=["compose_method", "labels"], const_vars=dict(unequal_length=True))
|
87
|
-
|
88
|
-
res = bench.plot_sweep(
|
89
|
-
input_vars=[],
|
90
|
-
const_vars=dict(unequal_length=False, compose_method=bch.ComposeType.sequence),
|
91
|
-
plot_callbacks=False,
|
92
|
-
)
|
93
|
-
|
94
|
-
bench.report.append(res.to_video_grid())
|
95
|
-
|
96
|
-
return bench
|
97
|
-
|
98
|
-
|
99
|
-
if __name__ == "__main__":
|
100
|
-
ex_run_cfg = bch.BenchRunCfg()
|
101
|
-
ex_run_cfg.cache_samples = False
|
102
|
-
# ex_run_cfg.level = 2
|
103
|
-
ex_report = bch.BenchReport()
|
104
|
-
example_composable_container_image(ex_run_cfg, report=ex_report)
|
105
|
-
# example_composable_container_video(ex_run_cfg, report=ex_report)
|
106
|
-
ex_report.show()
|
File without changes
|
File without changes
|