holobench 1.28.1__py3-none-any.whl → 1.30.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 +1 -0
- bencher/bench_cfg.py +9 -9
- bencher/bench_plot_server.py +1 -1
- bencher/bench_runner.py +1 -1
- bencher/bencher.py +23 -11
- bencher/example/benchmark_data.py +1 -1
- bencher/example/example_categorical.py +1 -1
- bencher/example/example_custom_sweep.py +1 -1
- bencher/example/example_custom_sweep2.py +1 -1
- bencher/example/example_dataframe.py +47 -0
- bencher/example/example_image.py +5 -7
- bencher/example/example_image1.py +80 -0
- bencher/example/example_levels.py +1 -1
- bencher/example/example_levels2.py +1 -1
- bencher/example/example_pareto.py +1 -1
- bencher/example/example_sample_cache_context.py +2 -2
- bencher/example/example_simple.py +5 -5
- bencher/example/meta/example_meta.py +1 -1
- bencher/example/shelved/example_kwargs.py +1 -1
- bencher/plotting/plot_filter.py +2 -2
- bencher/plotting/plt_cnt_cfg.py +10 -3
- bencher/results/bench_result.py +3 -1
- bencher/results/bench_result_base.py +58 -9
- bencher/results/composable_container/composable_container_base.py +2 -2
- bencher/results/composable_container/composable_container_dataframe.py +52 -0
- bencher/results/dataset_result.py +227 -0
- bencher/results/optuna_result.py +7 -6
- bencher/variables/inputs.py +5 -5
- bencher/variables/parametrised_sweep.py +2 -2
- bencher/variables/results.py +29 -1
- bencher/variables/sweep_base.py +1 -1
- bencher/variables/time.py +3 -3
- bencher/video_writer.py +1 -1
- {holobench-1.28.1.dist-info → holobench-1.30.2.dist-info}/METADATA +72 -39
- {holobench-1.28.1.dist-info → holobench-1.30.2.dist-info}/RECORD +38 -36
- {holobench-1.28.1.dist-info → holobench-1.30.2.dist-info}/WHEEL +1 -2
- holobench-1.28.1.data/data/share/bencher/package.xml +0 -33
- holobench-1.28.1.dist-info/top_level.txt +0 -1
- {holobench-1.28.1.dist-info → holobench-1.30.2.dist-info/licenses}/LICENSE +0 -0
- {holobench-1.28.1.data/data/share/ament_index/resource_index/packages → resource}/bencher +0 -0
@@ -19,9 +19,7 @@ from bencher.variables.results import ResultVar
|
|
19
19
|
from bencher.plotting.plot_filter import VarRange, PlotFilter
|
20
20
|
from bencher.utils import listify
|
21
21
|
|
22
|
-
from bencher.variables.results import
|
23
|
-
ResultReference,
|
24
|
-
)
|
22
|
+
from bencher.variables.results import ResultReference, ResultDataSet
|
25
23
|
|
26
24
|
from bencher.results.composable_container.composable_container_panel import ComposableContainerPanel
|
27
25
|
|
@@ -62,7 +60,7 @@ class BenchResultBase(OptunaResult):
|
|
62
60
|
"""Generate a holoviews dataset from the xarray dataset.
|
63
61
|
|
64
62
|
Args:
|
65
|
-
reduce (ReduceType, optional): Optionally perform reduce options on the dataset. By default the returned dataset will calculate the mean and standard
|
63
|
+
reduce (ReduceType, optional): Optionally perform reduce options on the dataset. By default the returned dataset will calculate the mean and standard deviation over the "repeat" dimension so that the dataset plays nicely with most of the holoviews plot types. Reduce.Sqeeze is used if there is only 1 repeat and you want the "reduce" variable removed from the dataset. ReduceType.None returns an unaltered dataset. Defaults to ReduceType.AUTO.
|
66
64
|
|
67
65
|
Returns:
|
68
66
|
hv.Dataset: results in the form of a holoviews dataset
|
@@ -79,7 +77,7 @@ class BenchResultBase(OptunaResult):
|
|
79
77
|
"""Generate a summarised xarray dataset.
|
80
78
|
|
81
79
|
Args:
|
82
|
-
reduce (ReduceType, optional): Optionally perform reduce options on the dataset. By default the returned dataset will calculate the mean and standard
|
80
|
+
reduce (ReduceType, optional): Optionally perform reduce options on the dataset. By default the returned dataset will calculate the mean and standard deviation over the "repeat" dimension so that the dataset plays nicely with most of the holoviews plot types. Reduce.Sqeeze is used if there is only 1 repeat and you want the "reduce" variable removed from the dataset. ReduceType.None returns an unaltered dataset. Defaults to ReduceType.AUTO.
|
83
81
|
|
84
82
|
Returns:
|
85
83
|
xr.Dataset: results in the form of an xarray dataset
|
@@ -89,7 +87,7 @@ class BenchResultBase(OptunaResult):
|
|
89
87
|
|
90
88
|
ds_out = self.ds if result_var is None else self.ds[result_var.name]
|
91
89
|
|
92
|
-
match
|
90
|
+
match reduce:
|
93
91
|
case ReduceType.REDUCE:
|
94
92
|
ds_reduce_mean = ds_out.mean(dim="repeat", keep_attrs=True)
|
95
93
|
ds_reduce_std = ds_out.std(dim="repeat", keep_attrs=True)
|
@@ -149,9 +147,9 @@ class BenchResultBase(OptunaResult):
|
|
149
147
|
opt_val = result_da.max()
|
150
148
|
else:
|
151
149
|
opt_val = result_da.min()
|
152
|
-
|
150
|
+
indices = result_da.where(result_da == opt_val, drop=True).squeeze()
|
153
151
|
logging.info(f"optimal value of {result_var.name}: {opt_val.values}")
|
154
|
-
return
|
152
|
+
return indices
|
155
153
|
|
156
154
|
def get_optimal_inputs(
|
157
155
|
self,
|
@@ -242,6 +240,46 @@ class BenchResultBase(OptunaResult):
|
|
242
240
|
row.append(plot_callback(rv))
|
243
241
|
return row.get()
|
244
242
|
|
243
|
+
@staticmethod
|
244
|
+
def zip_results1D(args): # pragma: no cover
|
245
|
+
first_el = [a[0] for a in args]
|
246
|
+
out = pn.Column()
|
247
|
+
for a in zip(*first_el):
|
248
|
+
row = pn.Row()
|
249
|
+
row.append(a[0])
|
250
|
+
for a1 in range(1, len(a[1])):
|
251
|
+
row.append(a[a1][1])
|
252
|
+
out.append(row)
|
253
|
+
return out
|
254
|
+
|
255
|
+
@staticmethod
|
256
|
+
def zip_results1D1(panel_list): # pragma: no cover
|
257
|
+
container_args = {"styles": {}}
|
258
|
+
container_args["styles"]["border-bottom"] = f"{2}px solid grey"
|
259
|
+
print(panel_list)
|
260
|
+
out = pn.Column()
|
261
|
+
for a in zip(*panel_list):
|
262
|
+
row = pn.Row(**container_args)
|
263
|
+
row.append(a[0][0])
|
264
|
+
for a1 in range(0, len(a)):
|
265
|
+
row.append(a[a1][1])
|
266
|
+
out.append(row)
|
267
|
+
return out
|
268
|
+
|
269
|
+
@staticmethod
|
270
|
+
def zip_results1D2(panel_list): # pragma: no cover
|
271
|
+
if panel_list is not None:
|
272
|
+
print(panel_list)
|
273
|
+
primary = panel_list[0]
|
274
|
+
secondary = panel_list[1:]
|
275
|
+
for i in range(len(primary)):
|
276
|
+
print(type(primary[i]))
|
277
|
+
if isinstance(primary[i], (pn.Column, pn.Row)):
|
278
|
+
for j in range(len(secondary)):
|
279
|
+
primary[i].append(secondary[j][i][1])
|
280
|
+
return primary
|
281
|
+
return panel_list
|
282
|
+
|
245
283
|
def map_plot_panes(
|
246
284
|
self,
|
247
285
|
plot_callback: callable,
|
@@ -250,6 +288,7 @@ class BenchResultBase(OptunaResult):
|
|
250
288
|
result_var: ResultVar = None,
|
251
289
|
result_types=None,
|
252
290
|
pane_collection: pn.pane = None,
|
291
|
+
zip_results=False,
|
253
292
|
**kwargs,
|
254
293
|
) -> Optional[pn.Row]:
|
255
294
|
if hv_dataset is None:
|
@@ -271,6 +310,9 @@ class BenchResultBase(OptunaResult):
|
|
271
310
|
target_dimension=target_dimension,
|
272
311
|
)
|
273
312
|
)
|
313
|
+
|
314
|
+
if zip_results:
|
315
|
+
return self.zip_results1D2(row.get())
|
274
316
|
return row.get()
|
275
317
|
|
276
318
|
def filter(
|
@@ -405,10 +447,17 @@ class BenchResultBase(OptunaResult):
|
|
405
447
|
return da_ds.values.squeeze().item()
|
406
448
|
return da.expand_dims(dim).values[0]
|
407
449
|
|
408
|
-
def ds_to_container(
|
450
|
+
def ds_to_container( # pylint: disable=too-many-return-statements
|
409
451
|
self, dataset: xr.Dataset, result_var: Parameter, container, **kwargs
|
410
452
|
) -> Any:
|
411
453
|
val = self.zero_dim_da_to_val(dataset[result_var.name])
|
454
|
+
if isinstance(result_var, ResultDataSet):
|
455
|
+
ref = self.dataset_list[val]
|
456
|
+
if ref is not None:
|
457
|
+
if container is not None:
|
458
|
+
return container(ref.obj)
|
459
|
+
return ref.obj
|
460
|
+
return None
|
412
461
|
if isinstance(result_var, ResultReference):
|
413
462
|
ref = self.object_index[val]
|
414
463
|
if ref is not None:
|
@@ -10,7 +10,7 @@ class ComposeType(StrEnum):
|
|
10
10
|
right = auto() # append the container to the right (creates a row)
|
11
11
|
down = auto() # append the container below (creates a column)
|
12
12
|
sequence = auto() # display the container after (in time)
|
13
|
-
|
13
|
+
overlay = auto() # overlay on top of the current container (alpha blending)
|
14
14
|
|
15
15
|
def flip(self):
|
16
16
|
match self:
|
@@ -65,7 +65,7 @@ class ComposableContainerBase:
|
|
65
65
|
self.container.append(obj)
|
66
66
|
|
67
67
|
def render(self):
|
68
|
-
"""Return a representation of the container that can be composed with other render() results. This function can also be used to defer layout and rending options until all the information about the container content is known. You may need to
|
68
|
+
"""Return a representation of the container that can be composed with other render() results. This function can also be used to defer layout and rending options until all the information about the container content is known. You may need to override this method depending on the container. See composable_container_video as an example.
|
69
69
|
|
70
70
|
Returns:
|
71
71
|
Any: Visual representation of the container that can be combined with other containers
|
@@ -0,0 +1,52 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
import panel as pn
|
3
|
+
import xarray as xr
|
4
|
+
from bencher.results.composable_container.composable_container_base import ComposableContainerBase
|
5
|
+
from bencher.results.composable_container.composable_container_base import ComposeType
|
6
|
+
|
7
|
+
|
8
|
+
@dataclass(kw_only=True)
|
9
|
+
class ComposableContainerDataset(ComposableContainerBase):
|
10
|
+
name: str = None
|
11
|
+
var_name: str = None
|
12
|
+
var_value: str = None
|
13
|
+
width: int = None
|
14
|
+
background_col: str = None
|
15
|
+
horizontal: bool = True
|
16
|
+
|
17
|
+
def __post_init__(
|
18
|
+
self,
|
19
|
+
) -> None:
|
20
|
+
container_args = {
|
21
|
+
"name": self.name,
|
22
|
+
"styles": {},
|
23
|
+
}
|
24
|
+
|
25
|
+
if self.width is not None:
|
26
|
+
container_args["styles"]["border-bottom"] = f"{self.width}px solid grey"
|
27
|
+
if self.background_col is not None:
|
28
|
+
container_args["styles"]["background"] = self.background_col
|
29
|
+
|
30
|
+
if self.horizontal:
|
31
|
+
self.container = pn.Column(**container_args)
|
32
|
+
align = ("center", "center")
|
33
|
+
else:
|
34
|
+
self.container = pn.Row(**container_args)
|
35
|
+
align = ("end", "center")
|
36
|
+
|
37
|
+
label = self.label_formatter(self.var_name, self.var_value)
|
38
|
+
if label is not None:
|
39
|
+
self.label_len = len(label)
|
40
|
+
side = pn.pane.Markdown(label, align=align)
|
41
|
+
self.append(side)
|
42
|
+
|
43
|
+
def render(self, **kwargs): # pylint: disable=unused-argument
|
44
|
+
match self.compose_method:
|
45
|
+
case ComposeType.right:
|
46
|
+
return xr.concat(self.container, 0)
|
47
|
+
case ComposeType.down:
|
48
|
+
return xr.concat(self.container, 1)
|
49
|
+
case ComposeType.sequence:
|
50
|
+
return xr.concat(self.container, 2)
|
51
|
+
# case ComposeType.overlay:
|
52
|
+
# return xr.Dataset.mean()
|
@@ -0,0 +1,227 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
import panel as pn
|
3
|
+
from param import Parameter
|
4
|
+
from bencher.results.bench_result_base import BenchResultBase, ReduceType
|
5
|
+
|
6
|
+
|
7
|
+
from functools import partial
|
8
|
+
import holoviews as hv
|
9
|
+
from bencher.variables.results import (
|
10
|
+
PANEL_TYPES,
|
11
|
+
)
|
12
|
+
|
13
|
+
|
14
|
+
class DataSetResult(BenchResultBase):
|
15
|
+
def to_dataset1(
|
16
|
+
self,
|
17
|
+
result_var: Parameter = None,
|
18
|
+
hv_dataset=None,
|
19
|
+
target_dimension: int = 0,
|
20
|
+
container=None,
|
21
|
+
level: int = None,
|
22
|
+
**kwargs,
|
23
|
+
) -> Optional[pn.pane.panel]:
|
24
|
+
if hv_dataset is None:
|
25
|
+
hv_dataset = self.to_hv_dataset(ReduceType.SQUEEZE, level=level)
|
26
|
+
elif not isinstance(hv_dataset, hv.Dataset):
|
27
|
+
hv_dataset = hv.Dataset(hv_dataset)
|
28
|
+
return self.map_plot_panes(
|
29
|
+
partial(self.ds_to_container, container=container),
|
30
|
+
hv_dataset=hv_dataset,
|
31
|
+
target_dimension=target_dimension,
|
32
|
+
result_var=result_var,
|
33
|
+
result_types=PANEL_TYPES,
|
34
|
+
**kwargs,
|
35
|
+
)
|
36
|
+
|
37
|
+
|
38
|
+
# class DataSetResult(BenchResultBase):
|
39
|
+
|
40
|
+
# def to_datatset(
|
41
|
+
# self,
|
42
|
+
# result_var: Parameter = None,
|
43
|
+
# result_types=(ResultDataSet,),
|
44
|
+
# pane_collection: pn.pane = None,
|
45
|
+
# time_sequence_dimension=0,
|
46
|
+
# target_duration: float = None,
|
47
|
+
# **kwargs,
|
48
|
+
# ) -> Optional[pn.panel]:
|
49
|
+
# """Returns the results compiled into a video
|
50
|
+
|
51
|
+
# Args:
|
52
|
+
# result_var (Parameter, optional): The result var to plot. Defaults to None.
|
53
|
+
# result_types (tuple, optional): The types of result var to convert to video. Defaults to (ResultDataSet,).
|
54
|
+
# collection (pn.pane, optional): If there are multiple results, use this collection to stack them. Defaults to pn.Row().
|
55
|
+
|
56
|
+
# Returns:
|
57
|
+
# Optional[pn.panel]: a panel pane with a video of all results concatenated together
|
58
|
+
# """
|
59
|
+
# plot_filter = PlotFilter(
|
60
|
+
# float_range=VarRange(0, None),
|
61
|
+
# cat_range=VarRange(0, None),
|
62
|
+
# panel_range=VarRange(1, None),
|
63
|
+
# input_range=VarRange(0, None),
|
64
|
+
# )
|
65
|
+
# matches_res = plot_filter.matches_result(
|
66
|
+
# self.plt_cnt_cfg, callable_name(self.to_video_grid_ds)
|
67
|
+
# )
|
68
|
+
|
69
|
+
# if pane_collection is None:
|
70
|
+
# pane_collection = pn.Row()
|
71
|
+
|
72
|
+
# if matches_res.overall:
|
73
|
+
# ds = self.to_dataset(ReduceType.SQUEEZE)
|
74
|
+
# for rv in self.get_results_var_list(result_var):
|
75
|
+
# if isinstance(rv, result_types):
|
76
|
+
# pane_collection.append(
|
77
|
+
# self.to_video_grid_ds(
|
78
|
+
# ds,
|
79
|
+
# rv,
|
80
|
+
# time_sequence_dimension=time_sequence_dimension,
|
81
|
+
# target_duration=target_duration,
|
82
|
+
# **kwargs,
|
83
|
+
# )
|
84
|
+
# )
|
85
|
+
# return pane_collection
|
86
|
+
# return matches_res.to_panel()
|
87
|
+
|
88
|
+
# def to_video_grid_ds(
|
89
|
+
# self,
|
90
|
+
# dataset: xr.Dataset,
|
91
|
+
# result_var: Parameter,
|
92
|
+
# reverse=True,
|
93
|
+
# time_sequence_dimension=0,
|
94
|
+
# video_controls: VideoControls = None,
|
95
|
+
# target_duration: float = None,
|
96
|
+
# **kwargs,
|
97
|
+
# ):
|
98
|
+
# cvc = self._to_video_panes_ds(
|
99
|
+
# dataset,
|
100
|
+
# self.plot_cb,
|
101
|
+
# target_dimension=0,
|
102
|
+
# horizontal=True,
|
103
|
+
# compose_method=ComposeType.right,
|
104
|
+
# time_sequence_dimension=time_sequence_dimension,
|
105
|
+
# result_var=result_var,
|
106
|
+
# final=True,
|
107
|
+
# reverse=reverse,
|
108
|
+
# target_duration=target_duration,
|
109
|
+
# **kwargs,
|
110
|
+
# )
|
111
|
+
|
112
|
+
# filename = VideoWriter().write_video_raw(cvc)
|
113
|
+
|
114
|
+
# if filename is not None:
|
115
|
+
# if video_controls is None:
|
116
|
+
# video_controls = VideoControls()
|
117
|
+
# return video_controls.video_container(
|
118
|
+
# filename, width=kwargs.get("width", None), height=kwargs.get("height", None)
|
119
|
+
# )
|
120
|
+
# return None
|
121
|
+
|
122
|
+
# def plot_cb(self, dataset, result_var, **kwargs):
|
123
|
+
# val = self.ds_to_container(dataset, result_var, container=None, **kwargs)
|
124
|
+
# return val
|
125
|
+
|
126
|
+
# def dataset_to_compose_list(
|
127
|
+
# self,
|
128
|
+
# dataset: xr.Dataset,
|
129
|
+
# first_compose_method: ComposeType = ComposeType.down,
|
130
|
+
# time_sequence_dimension: int = 0,
|
131
|
+
# ) -> List[ComposeType]:
|
132
|
+
# """ "Given a dataset, chose an order for composing the results. By default will flip between right and down and the last dimension will be a time sequence.
|
133
|
+
|
134
|
+
# Args:
|
135
|
+
# dataset (xr.Dataset): the dataset to render
|
136
|
+
# first_compose_method (ComposeType, optional): the direction of the first composition method. Defaults to ComposeType.right.
|
137
|
+
# time_sequence_dimension (int, optional): The dimension to start time sequencing instead of composing in space. Defaults to 0.
|
138
|
+
|
139
|
+
# Returns:
|
140
|
+
# List[ComposeType]: A list of composition methods for composing the dataset result
|
141
|
+
# """
|
142
|
+
|
143
|
+
# num_dims = len(dataset.sizes)
|
144
|
+
# if time_sequence_dimension == -1: # use time sequence for everything
|
145
|
+
# compose_method_list = [ComposeType.sequence] * (num_dims + 1)
|
146
|
+
# else:
|
147
|
+
# compose_method_list = [first_compose_method]
|
148
|
+
# compose_method_list.extend(
|
149
|
+
# ComposeType.flip(compose_method_list[-1]) for _ in range(num_dims - 1)
|
150
|
+
# )
|
151
|
+
# compose_method_list.append(ComposeType.sequence)
|
152
|
+
|
153
|
+
# for i in range(min(len(compose_method_list), time_sequence_dimension + 1)):
|
154
|
+
# compose_method_list[i] = ComposeType.sequence
|
155
|
+
|
156
|
+
# return compose_method_list
|
157
|
+
|
158
|
+
# def _to_video_panes_ds(
|
159
|
+
# self,
|
160
|
+
# dataset: xr.Dataset,
|
161
|
+
# plot_callback: callable = None,
|
162
|
+
# target_dimension=0,
|
163
|
+
# compose_method=ComposeType.right,
|
164
|
+
# compose_method_list=None,
|
165
|
+
# result_var=None,
|
166
|
+
# time_sequence_dimension=0,
|
167
|
+
# root_dimensions=None,
|
168
|
+
# reverse=False,
|
169
|
+
# target_duration: float = None,
|
170
|
+
# **kwargs,
|
171
|
+
# ) -> pn.panel:
|
172
|
+
# num_dims = len(dataset.sizes)
|
173
|
+
# dims = list(d for d in dataset.sizes)
|
174
|
+
# if reverse:
|
175
|
+
# dims = list(reversed(dims))
|
176
|
+
|
177
|
+
# if root_dimensions is None:
|
178
|
+
# root_dimensions = num_dims
|
179
|
+
|
180
|
+
# if compose_method_list is None:
|
181
|
+
# compose_method_list = self.dataset_to_compose_list(
|
182
|
+
# dataset, compose_method, time_sequence_dimension=time_sequence_dimension
|
183
|
+
# )
|
184
|
+
|
185
|
+
# # print(compose_method_list)
|
186
|
+
|
187
|
+
# compose_method_list_pop = deepcopy(compose_method_list)
|
188
|
+
# if len(compose_method_list_pop) > 1:
|
189
|
+
# compose_method = compose_method_list_pop.pop()
|
190
|
+
|
191
|
+
# if num_dims > (target_dimension) and num_dims != 0:
|
192
|
+
# selected_dim = dims[-1]
|
193
|
+
# outer_container = ComposableContainerVideo()
|
194
|
+
# for i in range(dataset.sizes[selected_dim]):
|
195
|
+
# sliced = dataset.isel({selected_dim: i})
|
196
|
+
# label_val = sliced.coords[selected_dim].values.item()
|
197
|
+
# inner_container = ComposableContainerVideo()
|
198
|
+
|
199
|
+
# panes = self._to_video_panes_ds(
|
200
|
+
# sliced,
|
201
|
+
# plot_callback=plot_callback,
|
202
|
+
# target_dimension=target_dimension,
|
203
|
+
# compose_method_list=compose_method_list_pop,
|
204
|
+
# result_var=result_var,
|
205
|
+
# root_dimensions=root_dimensions,
|
206
|
+
# time_sequence_dimension=time_sequence_dimension,
|
207
|
+
# )
|
208
|
+
# inner_container.append(panes)
|
209
|
+
|
210
|
+
# rendered = inner_container.render(
|
211
|
+
# RenderCfg(
|
212
|
+
# var_name=selected_dim,
|
213
|
+
# var_value=label_val,
|
214
|
+
# compose_method=compose_method,
|
215
|
+
# duration=target_duration,
|
216
|
+
# )
|
217
|
+
# )
|
218
|
+
# outer_container.append(rendered)
|
219
|
+
# return outer_container.render(
|
220
|
+
# RenderCfg(
|
221
|
+
# compose_method=compose_method,
|
222
|
+
# duration=target_duration,
|
223
|
+
# background_col=color_tuple_to_255(int_to_col(num_dims - 2, 0.05, 1.0)),
|
224
|
+
# # background_col= (255,0,0),
|
225
|
+
# )
|
226
|
+
# )
|
227
|
+
# return plot_callback(dataset=dataset, result_var=result_var, **kwargs)
|
bencher/results/optuna_result.py
CHANGED
@@ -34,7 +34,7 @@ from bencher.optuna_conversions import (
|
|
34
34
|
|
35
35
|
|
36
36
|
def convert_dataset_bool_dims_to_str(dataset: xr.Dataset) -> xr.Dataset:
|
37
|
-
"""Given a dataarray that contains boolean coordinates,
|
37
|
+
"""Given a dataarray that contains boolean coordinates, convert them to strings so that holoviews loads the data properly
|
38
38
|
|
39
39
|
Args:
|
40
40
|
dataarray (xr.DataArray): dataarray with boolean coordinates
|
@@ -63,6 +63,7 @@ class OptunaResult:
|
|
63
63
|
self.studies = []
|
64
64
|
self.plt_cnt_cfg = PltCntCfg()
|
65
65
|
self.plot_inputs = []
|
66
|
+
self.dataset_list = []
|
66
67
|
|
67
68
|
# self.width=600/
|
68
69
|
# self.height=600
|
@@ -177,7 +178,7 @@ class OptunaResult:
|
|
177
178
|
df = self.to_pandas()
|
178
179
|
all_vars = []
|
179
180
|
for v in self.bench_cfg.all_vars:
|
180
|
-
if type(v)
|
181
|
+
if type(v) is not TimeEvent:
|
181
182
|
all_vars.append(v)
|
182
183
|
|
183
184
|
print("All vars", all_vars)
|
@@ -202,8 +203,8 @@ class OptunaResult:
|
|
202
203
|
params = {}
|
203
204
|
values = []
|
204
205
|
for i in all_vars:
|
205
|
-
if type(i)
|
206
|
-
if type(row[1][i.name])
|
206
|
+
if type(i) is TimeSnapshot:
|
207
|
+
if type(row[1][i.name]) is np.datetime64:
|
207
208
|
params[i.name] = row[1][i.name].timestamp()
|
208
209
|
else:
|
209
210
|
params[i.name] = row[1][i.name]
|
@@ -341,14 +342,14 @@ class OptunaResult:
|
|
341
342
|
if "width" not in kwargs:
|
342
343
|
if self.bench_cfg.plot_size is not None:
|
343
344
|
kwargs["width"] = self.bench_cfg.plot_size
|
344
|
-
# specific width
|
345
|
+
# specific width overrides general size
|
345
346
|
if self.bench_cfg.plot_width is not None:
|
346
347
|
kwargs["width"] = self.bench_cfg.plot_width
|
347
348
|
|
348
349
|
if "height" not in kwargs:
|
349
350
|
if self.bench_cfg.plot_size is not None:
|
350
351
|
kwargs["height"] = self.bench_cfg.plot_size
|
351
|
-
# specific height
|
352
|
+
# specific height overrides general size
|
352
353
|
if self.bench_cfg.plot_height is not None:
|
353
354
|
kwargs["height"] = self.bench_cfg.plot_height
|
354
355
|
return kwargs
|
bencher/variables/inputs.py
CHANGED
@@ -7,7 +7,7 @@ from bencher.variables.sweep_base import SweepBase, shared_slots
|
|
7
7
|
|
8
8
|
|
9
9
|
class SweepSelector(Selector, SweepBase):
|
10
|
-
"""A class to
|
10
|
+
"""A class to represent a parameter sweep of bools"""
|
11
11
|
|
12
12
|
__slots__ = shared_slots
|
13
13
|
|
@@ -27,7 +27,7 @@ class SweepSelector(Selector, SweepBase):
|
|
27
27
|
|
28
28
|
|
29
29
|
class BoolSweep(SweepSelector):
|
30
|
-
"""A class to
|
30
|
+
"""A class to represent a parameter sweep of bools"""
|
31
31
|
|
32
32
|
def __init__(self, units: str = "ul", samples: int = None, default=True, **params):
|
33
33
|
SweepSelector.__init__(
|
@@ -41,7 +41,7 @@ class BoolSweep(SweepSelector):
|
|
41
41
|
|
42
42
|
|
43
43
|
class StringSweep(SweepSelector):
|
44
|
-
"""A class to
|
44
|
+
"""A class to represent a parameter sweep of strings"""
|
45
45
|
|
46
46
|
def __init__(
|
47
47
|
self,
|
@@ -61,7 +61,7 @@ class StringSweep(SweepSelector):
|
|
61
61
|
|
62
62
|
|
63
63
|
class EnumSweep(SweepSelector):
|
64
|
-
"""A class to
|
64
|
+
"""A class to represent a parameter sweep of enums"""
|
65
65
|
|
66
66
|
__slots__ = shared_slots
|
67
67
|
|
@@ -82,7 +82,7 @@ class EnumSweep(SweepSelector):
|
|
82
82
|
|
83
83
|
|
84
84
|
class IntSweep(Integer, SweepBase):
|
85
|
-
"""A class to
|
85
|
+
"""A class to represent a parameter sweep of ints"""
|
86
86
|
|
87
87
|
__slots__ = shared_slots + ["sample_values"]
|
88
88
|
|
@@ -3,7 +3,7 @@ from typing import List, Tuple, Any
|
|
3
3
|
from param import Parameter, Parameterized
|
4
4
|
import holoviews as hv
|
5
5
|
import panel as pn
|
6
|
-
|
6
|
+
from copy import deepcopy
|
7
7
|
|
8
8
|
from bencher.utils import make_namedtuple, hash_sha1
|
9
9
|
from bencher.variables.results import ALL_RESULT_TYPES, ResultHmap
|
@@ -127,7 +127,7 @@ class ParametrizedSweep(Parameterized):
|
|
127
127
|
inp = cls.get_inputs_only()
|
128
128
|
defaults = {}
|
129
129
|
for i in inp:
|
130
|
-
defaults[i.name] = i.default
|
130
|
+
defaults[i.name] = deepcopy(i.default)
|
131
131
|
|
132
132
|
for k, v in kwargs.items():
|
133
133
|
defaults[k] = v
|
bencher/variables/results.py
CHANGED
@@ -186,6 +186,25 @@ class ResultReference(param.Parameter):
|
|
186
186
|
return hash_sha1(self)
|
187
187
|
|
188
188
|
|
189
|
+
class ResultDataSet(param.Parameter):
|
190
|
+
__slots__ = ["units", "obj"]
|
191
|
+
|
192
|
+
def __init__(
|
193
|
+
self,
|
194
|
+
obj: Any = None,
|
195
|
+
default: Any = None,
|
196
|
+
units: str = "dataset",
|
197
|
+
**params,
|
198
|
+
):
|
199
|
+
super().__init__(default=default, **params)
|
200
|
+
self.units = units
|
201
|
+
self.obj = obj
|
202
|
+
|
203
|
+
def hash_persistent(self) -> str:
|
204
|
+
"""A hash function that avoids the PYTHONHASHSEED 'feature' which returns a different hash value each time the program is run"""
|
205
|
+
return hash_sha1(self)
|
206
|
+
|
207
|
+
|
189
208
|
class ResultVolume(param.Parameter):
|
190
209
|
__slots__ = ["units", "obj"]
|
191
210
|
|
@@ -199,7 +218,15 @@ class ResultVolume(param.Parameter):
|
|
199
218
|
return hash_sha1(self)
|
200
219
|
|
201
220
|
|
202
|
-
PANEL_TYPES = (
|
221
|
+
PANEL_TYPES = (
|
222
|
+
ResultPath,
|
223
|
+
ResultImage,
|
224
|
+
ResultVideo,
|
225
|
+
ResultContainer,
|
226
|
+
ResultString,
|
227
|
+
ResultReference,
|
228
|
+
ResultDataSet,
|
229
|
+
)
|
203
230
|
|
204
231
|
ALL_RESULT_TYPES = (
|
205
232
|
ResultVar,
|
@@ -210,5 +237,6 @@ ALL_RESULT_TYPES = (
|
|
210
237
|
ResultImage,
|
211
238
|
ResultString,
|
212
239
|
ResultContainer,
|
240
|
+
ResultDataSet,
|
213
241
|
ResultReference,
|
214
242
|
)
|
bencher/variables/sweep_base.py
CHANGED
@@ -77,7 +77,7 @@ class SweepBase(param.Parameter):
|
|
77
77
|
"""given a sweep variable (self), return the range of values as a panel slider
|
78
78
|
|
79
79
|
Args:
|
80
|
-
debug (bool, optional): pass to the sweepvar to produce a full set of
|
80
|
+
debug (bool, optional): pass to the sweepvar to produce a full set of variables, or when debug=True, a reduces number of sweep vars. Defaults to False.
|
81
81
|
|
82
82
|
Returns:
|
83
83
|
pn.widgets.slider.DiscreteSlider: A panel slider with the values() of the sweep variable
|
bencher/variables/time.py
CHANGED
@@ -7,7 +7,7 @@ from bencher.variables.sweep_base import SweepBase, shared_slots
|
|
7
7
|
|
8
8
|
|
9
9
|
class TimeBase(SweepBase, Selector):
|
10
|
-
"""A class to capture a time snapshot of benchmark values. Time is
|
10
|
+
"""A class to capture a time snapshot of benchmark values. Time is represent as a continuous value i.e a datetime which is converted into a np.datetime64. To represent time as a discrete value use the TimeEvent class. The distinction is because holoview and plotly code makes different assumptions about discrete vs continuous variables"""
|
11
11
|
|
12
12
|
def __init__(
|
13
13
|
self,
|
@@ -40,7 +40,7 @@ class TimeBase(SweepBase, Selector):
|
|
40
40
|
|
41
41
|
|
42
42
|
class TimeSnapshot(TimeBase):
|
43
|
-
"""A class to capture a time snapshot of benchmark values. Time is
|
43
|
+
"""A class to capture a time snapshot of benchmark values. Time is represent as a continuous value i.e a datetime which is converted into a np.datetime64. To represent time as a discrete value use the TimeEvent class. The distinction is because holoview and plotly code makes different assumptions about discrete vs continuous variables"""
|
44
44
|
|
45
45
|
__slots__ = shared_slots
|
46
46
|
|
@@ -68,7 +68,7 @@ class TimeSnapshot(TimeBase):
|
|
68
68
|
|
69
69
|
|
70
70
|
class TimeEvent(TimeBase):
|
71
|
-
"""A class to represent a discrete event in time where the data was captured i.e a series of pull requests. Here time is discrete and can't be interpolated, to represent time as a
|
71
|
+
"""A class to represent a discrete event in time where the data was captured i.e a series of pull requests. Here time is discrete and can't be interpolated, to represent time as a continuous value use the TimeSnapshot class. The distinction is because holoview and plotly code makes different assumptions about discrete vs continuous variables"""
|
72
72
|
|
73
73
|
__slots__ = shared_slots
|
74
74
|
|
bencher/video_writer.py
CHANGED
@@ -30,7 +30,7 @@ class VideoWriter:
|
|
30
30
|
if width is None:
|
31
31
|
width = len(label) * 10
|
32
32
|
new_img = Image.new("RGB", (width, height), color=color)
|
33
|
-
# ImageDraw.Draw(new_img).text((width/2, 0), label, (0, 0, 0),align="center",
|
33
|
+
# ImageDraw.Draw(new_img).text((width/2, 0), label, (0, 0, 0),align="center",anchor="ms")
|
34
34
|
ImageDraw.Draw(new_img).text(
|
35
35
|
(width / 2.0, 0), label, (0, 0, 0), anchor="mt", font_size=height
|
36
36
|
)
|