code-loader 1.0.179.dev1__tar.gz → 1.0.180__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/PKG-INFO +1 -1
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/contract/datasetclasses.py +20 -8
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/contract/responsedataclasses.py +7 -0
- code_loader-1.0.180/code_loader/contract/sim_config.py +92 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/inner_leap_binder/leapbinder.py +14 -1
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/inner_leap_binder/leapbinder_decorators.py +143 -16
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/leaploader.py +22 -2
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/mixpanel_tracker.py +1 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/pyproject.toml +1 -1
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/LICENSE +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/README.md +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/__init__.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/contract/__init__.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/contract/enums.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/contract/exceptions.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/contract/mapping.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/contract/visualizer_classes.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/default_losses.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/default_metrics.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/experiment_api/__init__.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/experiment_api/api.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/experiment_api/cli_config_utils.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/experiment_api/client.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/experiment_api/epoch.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/experiment_api/experiment.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/experiment_api/experiment_context.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/experiment_api/types.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/experiment_api/utils.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/experiment_api/workingspace_config_utils.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/inner_leap_binder/__init__.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/leaploaderbase.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/plot_functions/__init__.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/plot_functions/plot_functions.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/plot_functions/visualize.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/utils.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/visualizers/__init__.py +0 -0
- {code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/visualizers/default_visualizers.py +0 -0
|
@@ -9,9 +9,12 @@ from code_loader.contract.enums import DataStateType, DataStateEnum, LeapDataTyp
|
|
|
9
9
|
MetricDirection, DatasetMetadataType
|
|
10
10
|
from code_loader.contract.visualizer_classes import LeapImage, LeapText, LeapGraph, LeapHorizontalBar, \
|
|
11
11
|
LeapTextMask, LeapImageMask, LeapImageWithBBox, LeapImageWithHeatmap, LeapVideo
|
|
12
|
+
from code_loader.contract.sim_config import SimConfig
|
|
12
13
|
|
|
13
14
|
custom_latent_space_attribute = "custom_latent_space"
|
|
14
15
|
|
|
16
|
+
_simulation_context: dict = {"active": False}
|
|
17
|
+
|
|
15
18
|
|
|
16
19
|
@dataclass
|
|
17
20
|
class PreprocessResponse:
|
|
@@ -41,6 +44,7 @@ class PreprocessResponse:
|
|
|
41
44
|
sample_id_type: Optional[Union[Type[str], Type[int]]] = None
|
|
42
45
|
sample_ids_to_instance_mappings: Optional[Dict[str, List[str]]] = None # in use only for element instance
|
|
43
46
|
instance_to_sample_ids_mappings: Optional[Dict[str, str]] = None # in use only for element instance
|
|
47
|
+
tl_generated: bool = False
|
|
44
48
|
|
|
45
49
|
def __post_init__(self) -> None:
|
|
46
50
|
assert self.sample_ids_to_instance_mappings is None, f"Keep sample_ids_to_instance_mappings None when initializing PreprocessResponse"
|
|
@@ -60,14 +64,14 @@ class PreprocessResponse:
|
|
|
60
64
|
raise Exception("length is deprecated, please use sample_ids instead.")
|
|
61
65
|
|
|
62
66
|
if self.state is None:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
if not _simulation_context["active"]:
|
|
68
|
+
from code_loader.inner_leap_binder.leapbinder_decorators import store_warning_by_param
|
|
69
|
+
store_warning_by_param(
|
|
70
|
+
param_name="PreprocessResponse.state",
|
|
71
|
+
user_func_name="tensorleap_preprocess",
|
|
72
|
+
default_value=str("specific order"),
|
|
73
|
+
link_to_docs="https://docs.tensorleap.ai/tensorleap-integration/writing-integration-code/preprocess-function",
|
|
74
|
+
)
|
|
71
75
|
else:
|
|
72
76
|
assert isinstance(self.state, DataStateType), f"PreprocessResponse.state must be of type {DataStateType.__name__} but got {type(self.state)}"
|
|
73
77
|
|
|
@@ -252,6 +256,13 @@ class CustomLayerHandler:
|
|
|
252
256
|
use_custom_latent_space: bool = False
|
|
253
257
|
|
|
254
258
|
|
|
259
|
+
@dataclass
|
|
260
|
+
class SimulationHandler:
|
|
261
|
+
name: str
|
|
262
|
+
function: Callable[..., PreprocessResponse]
|
|
263
|
+
sim_config: SimConfig
|
|
264
|
+
|
|
265
|
+
|
|
255
266
|
@dataclass
|
|
256
267
|
class DatasetIntegrationSetup:
|
|
257
268
|
preprocess: Optional[PreprocessHandler] = None
|
|
@@ -267,6 +278,7 @@ class DatasetIntegrationSetup:
|
|
|
267
278
|
instance_metrics: List[InstanceMetricHandler] = field(default_factory=list)
|
|
268
279
|
custom_layers: Dict[str, CustomLayerHandler] = field(default_factory=dict)
|
|
269
280
|
custom_latent_space: Optional[CustomLatentSpaceHandler] = None
|
|
281
|
+
simulations: List[SimulationHandler] = field(default_factory=list)
|
|
270
282
|
|
|
271
283
|
|
|
272
284
|
@dataclass
|
{code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/contract/responsedataclasses.py
RENAMED
|
@@ -69,6 +69,12 @@ class PredictionTypeInstance:
|
|
|
69
69
|
channel_dim: int
|
|
70
70
|
|
|
71
71
|
|
|
72
|
+
@dataclass
|
|
73
|
+
class SimulationInstance:
|
|
74
|
+
name: str
|
|
75
|
+
sim_config: Dict[str, Any]
|
|
76
|
+
|
|
77
|
+
|
|
72
78
|
@dataclass
|
|
73
79
|
class DatasetSetup:
|
|
74
80
|
preprocess: DatasetPreprocess
|
|
@@ -79,6 +85,7 @@ class DatasetSetup:
|
|
|
79
85
|
prediction_types: List[PredictionTypeInstance]
|
|
80
86
|
custom_losses: List[CustomLossInstance]
|
|
81
87
|
metrics: List[MetricInstance] = field(default_factory=list)
|
|
88
|
+
simulations: List[SimulationInstance] = field(default_factory=list)
|
|
82
89
|
|
|
83
90
|
|
|
84
91
|
@dataclass
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Any, Dict, List, Union
|
|
3
|
+
|
|
4
|
+
from code_loader.contract.enums import DatasetMetadataType
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class FloatBounds:
|
|
9
|
+
min: float
|
|
10
|
+
max: float
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class IntBounds:
|
|
15
|
+
min: int
|
|
16
|
+
max: int
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class CategoricalBounds:
|
|
21
|
+
values: List[str]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class SimParamConfig:
|
|
26
|
+
type: DatasetMetadataType
|
|
27
|
+
bounds: Union[FloatBounds, IntBounds, CategoricalBounds]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
SimConfig = Dict[str, SimParamConfig]
|
|
31
|
+
|
|
32
|
+
PARAM_TYPE_MAP = {
|
|
33
|
+
float: DatasetMetadataType.float,
|
|
34
|
+
int: DatasetMetadataType.int,
|
|
35
|
+
str: DatasetMetadataType.string,
|
|
36
|
+
"float": DatasetMetadataType.float,
|
|
37
|
+
"int": DatasetMetadataType.int,
|
|
38
|
+
"str": DatasetMetadataType.string,
|
|
39
|
+
"string": DatasetMetadataType.string,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _parse_bounds(name: str, metadata_type: DatasetMetadataType, bounds_raw: Dict[str, Any]) -> Union[FloatBounds, IntBounds, CategoricalBounds]:
|
|
44
|
+
if metadata_type in (DatasetMetadataType.float, DatasetMetadataType.int):
|
|
45
|
+
if "min" not in bounds_raw or "max" not in bounds_raw:
|
|
46
|
+
raise ValueError(
|
|
47
|
+
f"Parameter '{name}' bounds must have 'min' and 'max' for numeric type."
|
|
48
|
+
)
|
|
49
|
+
if bounds_raw["min"] >= bounds_raw["max"]:
|
|
50
|
+
raise ValueError(
|
|
51
|
+
f"Parameter '{name}': min ({bounds_raw['min']}) must be < max ({bounds_raw['max']})."
|
|
52
|
+
)
|
|
53
|
+
if metadata_type == DatasetMetadataType.float:
|
|
54
|
+
return FloatBounds(min=float(bounds_raw["min"]), max=float(bounds_raw["max"]))
|
|
55
|
+
return IntBounds(min=int(bounds_raw["min"]), max=int(bounds_raw["max"]))
|
|
56
|
+
|
|
57
|
+
if metadata_type == DatasetMetadataType.string:
|
|
58
|
+
if "values" not in bounds_raw:
|
|
59
|
+
raise ValueError(
|
|
60
|
+
f"Parameter '{name}' bounds must have 'values' for string type."
|
|
61
|
+
)
|
|
62
|
+
if not bounds_raw["values"]:
|
|
63
|
+
raise ValueError(f"Parameter '{name}' 'values' must not be empty.")
|
|
64
|
+
return CategoricalBounds(values=list(bounds_raw["values"]))
|
|
65
|
+
|
|
66
|
+
raise ValueError(f"Parameter '{name}' has unsupported metadata type: {metadata_type}.")
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def parse_sim_config(raw: Dict[str, Any]) -> SimConfig:
|
|
70
|
+
if not raw:
|
|
71
|
+
raise ValueError("sim_config must have at least one parameter.")
|
|
72
|
+
|
|
73
|
+
result: SimConfig = {}
|
|
74
|
+
for name, param in raw.items():
|
|
75
|
+
if "type" not in param:
|
|
76
|
+
raise ValueError(f"Parameter '{name}' missing 'type'.")
|
|
77
|
+
if param["type"] not in PARAM_TYPE_MAP:
|
|
78
|
+
raise ValueError(
|
|
79
|
+
f"Parameter '{name}' has unsupported type '{param['type']}'. "
|
|
80
|
+
f"Supported: float, int, str (or string)."
|
|
81
|
+
)
|
|
82
|
+
metadata_type = PARAM_TYPE_MAP[param["type"]]
|
|
83
|
+
|
|
84
|
+
if "bounds" not in param:
|
|
85
|
+
raise ValueError(f"Parameter '{name}' missing 'bounds'.")
|
|
86
|
+
|
|
87
|
+
result[name] = SimParamConfig(
|
|
88
|
+
type=metadata_type,
|
|
89
|
+
bounds=_parse_bounds(name, metadata_type, param["bounds"]),
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
return result
|
{code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/inner_leap_binder/leapbinder.py
RENAMED
|
@@ -12,7 +12,8 @@ from code_loader.contract.datasetclasses import SectionCallableInterface, InputH
|
|
|
12
12
|
CustomCallableInterfaceMultiArgs, ConfusionMatrixCallableInterfaceMultiArgs, LeapData, \
|
|
13
13
|
CustomMultipleReturnCallableInterfaceMultiArgs, DatasetBaseHandler, custom_latent_space_attribute, \
|
|
14
14
|
RawInputsForHeatmap, VisualizerHandlerData, MetricHandlerData, CustomLossHandlerData, SamplePreprocessResponse, \
|
|
15
|
-
ElementInstanceMasksHandler, InstanceCallableInterface, CustomLatentSpaceHandler, InstanceMetricHandler
|
|
15
|
+
ElementInstanceMasksHandler, InstanceCallableInterface, CustomLatentSpaceHandler, InstanceMetricHandler, \
|
|
16
|
+
SimulationHandler
|
|
16
17
|
from code_loader.contract.enums import LeapDataType, DataStateEnum, DataStateType, MetricDirection, DatasetMetadataType
|
|
17
18
|
from code_loader.contract.mapping import NodeConnection, NodeMapping, NodeMappingType
|
|
18
19
|
from code_loader.contract.responsedataclasses import DatasetTestResultPayload, LeapAnalysisConfiguration
|
|
@@ -20,6 +21,7 @@ from code_loader.contract.visualizer_classes import map_leap_data_type_to_visual
|
|
|
20
21
|
from code_loader.default_losses import loss_name_to_function
|
|
21
22
|
from code_loader.default_metrics import metrics_names_to_functions_and_direction
|
|
22
23
|
from code_loader.utils import to_numpy_return_wrapper, get_shape, to_numpy_return_masks_wrapper
|
|
24
|
+
from code_loader.contract.sim_config import parse_sim_config
|
|
23
25
|
from code_loader.visualizers.default_visualizers import DefaultVisualizer, \
|
|
24
26
|
default_graph_visualizer, \
|
|
25
27
|
default_image_visualizer, default_horizontal_bar_visualizer, default_word_visualizer, \
|
|
@@ -219,6 +221,17 @@ class LeapBinder:
|
|
|
219
221
|
"""
|
|
220
222
|
self.setup_container.unlabeled_data_preprocess = UnlabeledDataPreprocessHandler(function)
|
|
221
223
|
|
|
224
|
+
def set_simulation(self, function: Callable[..., PreprocessResponse], name: str, sim_config_raw: Dict[str, Any]) -> None:
|
|
225
|
+
for sim in self.setup_container.simulations:
|
|
226
|
+
if sim.name == name:
|
|
227
|
+
raise Exception(
|
|
228
|
+
f"Simulation with name '{name}' already exists. Please choose another."
|
|
229
|
+
)
|
|
230
|
+
sim_config = parse_sim_config(sim_config_raw)
|
|
231
|
+
self.setup_container.simulations.append(
|
|
232
|
+
SimulationHandler(name=name, function=function, sim_config=sim_config)
|
|
233
|
+
)
|
|
234
|
+
|
|
222
235
|
def set_input(self, function: SectionCallableInterface, name: str, channel_dim: int = -1) -> None:
|
|
223
236
|
"""
|
|
224
237
|
Set the input handler function.
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# mypy: ignore-errors
|
|
2
|
+
import inspect
|
|
2
3
|
import os
|
|
3
4
|
import warnings
|
|
4
5
|
import logging
|
|
5
6
|
from collections import defaultdict
|
|
7
|
+
import functools
|
|
6
8
|
from functools import lru_cache
|
|
7
9
|
from pathlib import Path
|
|
8
10
|
from typing import Optional, Union, Callable, List, Dict, Set, Any
|
|
@@ -28,10 +30,6 @@ from code_loader.contract.visualizer_classes import LeapImage, LeapImageMask, Le
|
|
|
28
30
|
from code_loader.inner_leap_binder.leapbinder import mapping_runtime_mode_env_var_mame
|
|
29
31
|
from code_loader.mixpanel_tracker import clear_integration_events, AnalyticsEvent, emit_integration_event_once
|
|
30
32
|
|
|
31
|
-
import inspect
|
|
32
|
-
import functools
|
|
33
|
-
from pathlib import Path
|
|
34
|
-
|
|
35
33
|
_called_from_inside_tl_decorator = 0
|
|
36
34
|
_called_from_inside_tl_integration_test_decorator = False
|
|
37
35
|
_call_from_tl_platform = os.environ.get('IS_TENSORLEAP_PLATFORM') == 'true'
|
|
@@ -77,6 +75,13 @@ def store_warning_by_param(
|
|
|
77
75
|
_PARAM_DEFAULT_DOCS[param_name] = link_to_docs
|
|
78
76
|
|
|
79
77
|
|
|
78
|
+
def store_general_warning(*, key: tuple, message: str, link_to_docs: Optional[str] = None) -> None:
|
|
79
|
+
if key in _STORED_WARNING_KEYS:
|
|
80
|
+
return
|
|
81
|
+
_STORED_WARNING_KEYS.add(key)
|
|
82
|
+
_STORED_WARNINGS.append({"message": message, "link_to_docs": link_to_docs})
|
|
83
|
+
|
|
84
|
+
|
|
80
85
|
def _get_param_default_warnings() -> Dict[str, Dict[str, Any]]:
|
|
81
86
|
out: Dict[str, Dict[str, Any]] = {}
|
|
82
87
|
for p, funcs in _PARAM_DEFAULT_FUNCS.items():
|
|
@@ -1226,8 +1231,9 @@ def tensorleap_metadata(
|
|
|
1226
1231
|
def _validate_result(result):
|
|
1227
1232
|
supported_result_types = (type(None), int, str, bool, float, dict, np.floating,
|
|
1228
1233
|
np.bool_, np.unsignedinteger, np.signedinteger, np.integer)
|
|
1229
|
-
|
|
1230
|
-
|
|
1234
|
+
if isinstance(result, tuple):
|
|
1235
|
+
validate_output_structure(result, func_name=user_function.__name__,
|
|
1236
|
+
expected_type_name=supported_result_types)
|
|
1231
1237
|
assert isinstance(result, supported_result_types), \
|
|
1232
1238
|
(f'{user_function.__name__}() validation failed: '
|
|
1233
1239
|
f'Unsupported return type. Got {type(result)}. should be any of {str(supported_result_types)}')
|
|
@@ -1295,17 +1301,17 @@ def tensorleap_custom_latent_space():
|
|
|
1295
1301
|
(f'tensorleap_custom_latent_space validation failed: '
|
|
1296
1302
|
f'The return type should be a numpy array. Got {type(result)}.')
|
|
1297
1303
|
if result.ndim > 1:
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
warnings.warn(
|
|
1304
|
+
flat_dim = int(np.prod(result.shape))
|
|
1305
|
+
store_general_warning(
|
|
1306
|
+
key=("tensorleap_custom_latent_space_flatten", tuple(result.shape)),
|
|
1307
|
+
message=(
|
|
1303
1308
|
f"tensorleap_custom_latent_space returned per-sample shape {tuple(result.shape)} "
|
|
1304
1309
|
f"(ndim={result.ndim}). Tensorleap assumes per-sample shape (d, ...) and will "
|
|
1305
1310
|
f"flatten to ({flat_dim},) before downstream visualization and clustering. "
|
|
1306
1311
|
f"If you want a different aggregation (e.g. global average pooling), do it "
|
|
1307
1312
|
f"inside your function."
|
|
1308
|
-
)
|
|
1313
|
+
),
|
|
1314
|
+
)
|
|
1309
1315
|
|
|
1310
1316
|
def inner_without_validate(sample_id, preprocess_response):
|
|
1311
1317
|
global _called_from_inside_tl_decorator
|
|
@@ -1393,6 +1399,89 @@ def tensorleap_preprocess():
|
|
|
1393
1399
|
return decorating_function
|
|
1394
1400
|
|
|
1395
1401
|
|
|
1402
|
+
def tensorleap_simulation(name: str, sim_params: dict):
|
|
1403
|
+
def decorating_function(user_function: Callable[..., PreprocessResponse]):
|
|
1404
|
+
sig = inspect.signature(user_function)
|
|
1405
|
+
func_params = set(sig.parameters.keys())
|
|
1406
|
+
expected_params = set(sim_params.keys()) | {"N"}
|
|
1407
|
+
|
|
1408
|
+
missing = expected_params - func_params
|
|
1409
|
+
if missing:
|
|
1410
|
+
raise Exception(
|
|
1411
|
+
f"{user_function.__name__}() registration failed: "
|
|
1412
|
+
f"Missing required parameters: {missing}. "
|
|
1413
|
+
f"Function must accept all sim_params params plus 'N'."
|
|
1414
|
+
)
|
|
1415
|
+
|
|
1416
|
+
extra = func_params - expected_params - {"seed"}
|
|
1417
|
+
if extra:
|
|
1418
|
+
raise Exception(
|
|
1419
|
+
f"{user_function.__name__}() registration failed: "
|
|
1420
|
+
f"Unexpected parameters: {extra}. "
|
|
1421
|
+
f"Function must only accept sim_params params plus 'N' and optionally 'seed'."
|
|
1422
|
+
)
|
|
1423
|
+
|
|
1424
|
+
leap_binder.set_simulation(user_function, name, sim_params)
|
|
1425
|
+
|
|
1426
|
+
if not _call_from_tl_platform:
|
|
1427
|
+
register_sim(name)
|
|
1428
|
+
|
|
1429
|
+
def _validate_input_args(*args, **kwargs):
|
|
1430
|
+
assert len(args) == 0, (
|
|
1431
|
+
f"{user_function.__name__}() validation failed: "
|
|
1432
|
+
f"Simulation functions must be called with keyword arguments only. Got positional args: {args}."
|
|
1433
|
+
)
|
|
1434
|
+
missing = expected_params - set(kwargs.keys())
|
|
1435
|
+
assert not missing, (
|
|
1436
|
+
f"{user_function.__name__}() validation failed: "
|
|
1437
|
+
f"Missing required keyword arguments: {missing}."
|
|
1438
|
+
)
|
|
1439
|
+
|
|
1440
|
+
def _validate_result(result):
|
|
1441
|
+
assert isinstance(result, PreprocessResponse), (
|
|
1442
|
+
f"{user_function.__name__}() validation failed: "
|
|
1443
|
+
f"Expected return type PreprocessResponse. Got {type(result).__name__}."
|
|
1444
|
+
)
|
|
1445
|
+
|
|
1446
|
+
def inner(*args, **kwargs):
|
|
1447
|
+
if not _call_from_tl_platform:
|
|
1448
|
+
set_current('tensorleap simulation')
|
|
1449
|
+
try:
|
|
1450
|
+
from code_loader.contract.datasetclasses import _simulation_context
|
|
1451
|
+
_validate_input_args(*args, **kwargs)
|
|
1452
|
+
_simulation_context["active"] = True
|
|
1453
|
+
try:
|
|
1454
|
+
result = user_function(*args, **kwargs)
|
|
1455
|
+
finally:
|
|
1456
|
+
_simulation_context["active"] = False
|
|
1457
|
+
_validate_result(result)
|
|
1458
|
+
if result.state is not None and result.state != DataStateType.additional:
|
|
1459
|
+
logger.warning(
|
|
1460
|
+
f"{user_function.__name__}() returned state={result.state!r}; "
|
|
1461
|
+
f"overriding to DataStateType.additional."
|
|
1462
|
+
)
|
|
1463
|
+
result.state = DataStateType.additional
|
|
1464
|
+
result.tl_generated = True
|
|
1465
|
+
try:
|
|
1466
|
+
emit_integration_event_once(AnalyticsEvent.SIMULATION_INTEGRATION_TEST, {
|
|
1467
|
+
'simulation_name': name,
|
|
1468
|
+
'sim_params_count': len(sim_params)
|
|
1469
|
+
})
|
|
1470
|
+
except Exception as e:
|
|
1471
|
+
logger.debug(f"Failed to emit simulation integration test event: {e}")
|
|
1472
|
+
if not _call_from_tl_platform:
|
|
1473
|
+
mark_sim_result(name, True)
|
|
1474
|
+
return result
|
|
1475
|
+
except Exception:
|
|
1476
|
+
if not _call_from_tl_platform:
|
|
1477
|
+
mark_sim_result(name, False)
|
|
1478
|
+
raise
|
|
1479
|
+
|
|
1480
|
+
return inner
|
|
1481
|
+
|
|
1482
|
+
return decorating_function
|
|
1483
|
+
|
|
1484
|
+
|
|
1396
1485
|
def tensorleap_element_instance_preprocess(
|
|
1397
1486
|
instance_length_encoder: InstanceLengthCallableInterface, instance_mask_encoder: InstanceCallableInterface):
|
|
1398
1487
|
def decorating_function(user_function: Callable[[], List[PreprocessResponse]]):
|
|
@@ -1989,7 +2078,8 @@ def tensorleap_status_table():
|
|
|
1989
2078
|
|
|
1990
2079
|
def _print_param_default_warnings():
|
|
1991
2080
|
data = _get_param_default_warnings()
|
|
1992
|
-
|
|
2081
|
+
stored = _get_stored_warnings()
|
|
2082
|
+
if not data and not stored:
|
|
1993
2083
|
return
|
|
1994
2084
|
|
|
1995
2085
|
print("\nWarnings (Default use. It is recommended to set values explicitly):")
|
|
@@ -2003,11 +2093,19 @@ def tensorleap_status_table():
|
|
|
2003
2093
|
print(
|
|
2004
2094
|
f" ⚠️ Parameter '{param_name}' defaults to {dv} in the following functions: [{funcs}]. "
|
|
2005
2095
|
f"For more information, check {docs_part}")
|
|
2006
|
-
|
|
2096
|
+
for w in stored:
|
|
2097
|
+
docs_link = w.get("link_to_docs")
|
|
2098
|
+
docs_part = f" {_link(docs_link)}" if docs_link else ""
|
|
2099
|
+
print(f" ⚠️ {w['message']}{docs_part}")
|
|
2100
|
+
if data:
|
|
2101
|
+
print("\nIf this isn’t the intended behaviour, set them explicitly.")
|
|
2007
2102
|
|
|
2008
2103
|
def _print_table():
|
|
2009
2104
|
_print_param_default_warnings()
|
|
2010
2105
|
|
|
2106
|
+
for msg in _sim_messages:
|
|
2107
|
+
print(f"\n⚠️ {msg}")
|
|
2108
|
+
|
|
2011
2109
|
if not started_from("leap_integration.py"):
|
|
2012
2110
|
return
|
|
2013
2111
|
|
|
@@ -2060,12 +2158,41 @@ def tensorleap_status_table():
|
|
|
2060
2158
|
else:
|
|
2061
2159
|
_set_status(name, CROSS)
|
|
2062
2160
|
|
|
2161
|
+
_sim_tracking: dict = {}
|
|
2162
|
+
_sim_messages: list = []
|
|
2163
|
+
|
|
2164
|
+
def register_sim(sim_name: str):
|
|
2165
|
+
if not _sim_tracking:
|
|
2166
|
+
table.append({"name": "tensorleap simulation (optional)", "Added to integration": UNKNOWN})
|
|
2167
|
+
_sim_tracking[sim_name] = "registered"
|
|
2168
|
+
|
|
2169
|
+
def mark_sim_result(sim_name: str, passed: bool):
|
|
2170
|
+
_sim_tracking[sim_name] = "passed" if passed else "failed"
|
|
2171
|
+
|
|
2172
|
+
def _resolve_sim_row():
|
|
2173
|
+
if not _sim_tracking:
|
|
2174
|
+
return
|
|
2175
|
+
row = _find_row("tensorleap simulation")
|
|
2176
|
+
if not row:
|
|
2177
|
+
return
|
|
2178
|
+
failed = [n for n, s in _sim_tracking.items() if s == "failed"]
|
|
2179
|
+
not_called = [n for n, s in _sim_tracking.items() if s == "registered"]
|
|
2180
|
+
if failed:
|
|
2181
|
+
row["Added to integration"] = CROSS
|
|
2182
|
+
_sim_messages.append(f"Simulation(s) failed validation: {', '.join(sorted(failed))}")
|
|
2183
|
+
elif not_called:
|
|
2184
|
+
row["Added to integration"] = UNKNOWN
|
|
2185
|
+
_sim_messages.append(f"Simulation(s) not called in integration test: {', '.join(sorted(not_called))}")
|
|
2186
|
+
else:
|
|
2187
|
+
row["Added to integration"] = CHECK
|
|
2188
|
+
|
|
2063
2189
|
def run_on_exit():
|
|
2064
2190
|
if _finalizer_called["done"]:
|
|
2065
2191
|
return
|
|
2066
2192
|
_finalizer_called["done"] = True
|
|
2067
2193
|
if not _crashed["value"]:
|
|
2068
2194
|
_mark_unknowns_as_cross()
|
|
2195
|
+
_resolve_sim_row()
|
|
2069
2196
|
|
|
2070
2197
|
_print_table()
|
|
2071
2198
|
|
|
@@ -2083,11 +2210,11 @@ def tensorleap_status_table():
|
|
|
2083
2210
|
atexit.register(run_on_exit)
|
|
2084
2211
|
sys.excepthook = handle_exception
|
|
2085
2212
|
|
|
2086
|
-
return set_current, update_env_params
|
|
2213
|
+
return set_current, update_env_params, register_sim, mark_sim_result
|
|
2087
2214
|
|
|
2088
2215
|
|
|
2089
2216
|
if not _call_from_tl_platform:
|
|
2090
|
-
set_current, update_env_params_func = tensorleap_status_table()
|
|
2217
|
+
set_current, update_env_params_func, register_sim, mark_sim_result = tensorleap_status_table()
|
|
2091
2218
|
|
|
2092
2219
|
|
|
2093
2220
|
|
|
@@ -22,13 +22,22 @@ from code_loader.contract.exceptions import DatasetScriptException
|
|
|
22
22
|
from code_loader.contract.responsedataclasses import DatasetIntegParseResult, DatasetTestResultPayload, \
|
|
23
23
|
DatasetPreprocess, DatasetSetup, DatasetInputInstance, DatasetOutputInstance, DatasetMetadataInstance, \
|
|
24
24
|
VisualizerInstance, PredictionTypeInstance, ModelSetup, CustomLayerInstance, MetricInstance, CustomLossInstance, \
|
|
25
|
-
EngineFileContract
|
|
25
|
+
EngineFileContract, SimulationInstance
|
|
26
|
+
from code_loader.contract.sim_config import FloatBounds, IntBounds, CategoricalBounds
|
|
26
27
|
from code_loader.inner_leap_binder import global_leap_binder
|
|
27
28
|
from code_loader.inner_leap_binder.leapbinder import mapping_runtime_mode_env_var_mame
|
|
28
29
|
from code_loader.leaploaderbase import LeapLoaderBase
|
|
29
30
|
from code_loader.utils import get_root_exception_file_and_line_number, get_metadata_type_from_variable
|
|
30
31
|
|
|
31
32
|
|
|
33
|
+
def _serialize_sim_bounds(bounds) -> dict:
|
|
34
|
+
if isinstance(bounds, (FloatBounds, IntBounds)):
|
|
35
|
+
return {"min": bounds.min, "max": bounds.max}
|
|
36
|
+
if isinstance(bounds, CategoricalBounds):
|
|
37
|
+
return {"values": bounds.values}
|
|
38
|
+
raise ValueError(f"Unknown bounds type: {type(bounds)}")
|
|
39
|
+
|
|
40
|
+
|
|
32
41
|
class LeapLoader(LeapLoaderBase):
|
|
33
42
|
def __init__(self, code_path: str, code_entry_name: str):
|
|
34
43
|
super().__init__(code_path, code_entry_name)
|
|
@@ -454,9 +463,20 @@ class LeapLoader(LeapLoaderBase):
|
|
|
454
463
|
metric_inst = MetricInstance(metric.metric_handler_data.name, metric.metric_handler_data.arg_names)
|
|
455
464
|
metrics.append(metric_inst)
|
|
456
465
|
|
|
466
|
+
simulations = []
|
|
467
|
+
for sim in setup.simulations:
|
|
468
|
+
sim_config_serialized = {
|
|
469
|
+
name: {
|
|
470
|
+
"type": param.type.value,
|
|
471
|
+
"bounds": _serialize_sim_bounds(param.bounds),
|
|
472
|
+
}
|
|
473
|
+
for name, param in sim.sim_config.items()
|
|
474
|
+
}
|
|
475
|
+
simulations.append(SimulationInstance(name=sim.name, sim_config=sim_config_serialized))
|
|
476
|
+
|
|
457
477
|
return DatasetSetup(preprocess=dataset_preprocess, inputs=inputs, outputs=ground_truths,
|
|
458
478
|
metadata=metadata_instances, visualizers=visualizers, prediction_types=prediction_types,
|
|
459
|
-
custom_losses=custom_losses, metrics=metrics)
|
|
479
|
+
custom_losses=custom_losses, metrics=metrics, simulations=simulations)
|
|
460
480
|
|
|
461
481
|
def get_model_setup_response(self) -> ModelSetup:
|
|
462
482
|
setup = global_leap_binder.setup_container
|
|
@@ -23,6 +23,7 @@ class AnalyticsEvent(str, Enum):
|
|
|
23
23
|
PREPROCESS_INTEGRATION_TEST = "preprocess_integration_test"
|
|
24
24
|
INPUT_ENCODER_INTEGRATION_TEST = "input_encoder_integration_test"
|
|
25
25
|
GT_ENCODER_INTEGRATION_TEST = "gt_encoder_integration_test"
|
|
26
|
+
SIMULATION_INTEGRATION_TEST = "simulation_integration_test"
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
class CodeLoaderLoadedProps(TypedDict, total=False):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/experiment_api/cli_config_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/experiment_api/experiment_context.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/plot_functions/plot_functions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{code_loader-1.0.179.dev1 → code_loader-1.0.180}/code_loader/visualizers/default_visualizers.py
RENAMED
|
File without changes
|