code-loader 1.0.206.dev2__tar.gz → 1.0.207.dev0__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.
Files changed (37) hide show
  1. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/PKG-INFO +1 -1
  2. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/contract/responsedataclasses.py +2 -0
  3. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/inner_leap_binder/leapbinder_decorators.py +35 -27
  4. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/leaploader.py +23 -1
  5. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/pyproject.toml +1 -1
  6. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/LICENSE +0 -0
  7. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/README.md +0 -0
  8. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/__init__.py +0 -0
  9. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/contract/__init__.py +0 -0
  10. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/contract/datasetclasses.py +0 -0
  11. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/contract/enums.py +0 -0
  12. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/contract/exceptions.py +0 -0
  13. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/contract/mapping.py +0 -0
  14. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/contract/sim_config.py +0 -0
  15. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/contract/visualizer_classes.py +0 -0
  16. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/default_losses.py +0 -0
  17. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/default_metrics.py +0 -0
  18. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/experiment_api/__init__.py +0 -0
  19. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/experiment_api/api.py +0 -0
  20. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/experiment_api/cli_config_utils.py +0 -0
  21. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/experiment_api/client.py +0 -0
  22. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/experiment_api/epoch.py +0 -0
  23. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/experiment_api/experiment.py +0 -0
  24. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/experiment_api/experiment_context.py +0 -0
  25. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/experiment_api/types.py +0 -0
  26. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/experiment_api/utils.py +0 -0
  27. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/experiment_api/workingspace_config_utils.py +0 -0
  28. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/inner_leap_binder/__init__.py +0 -0
  29. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/inner_leap_binder/leapbinder.py +0 -0
  30. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/leaploaderbase.py +0 -0
  31. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/mixpanel_tracker.py +0 -0
  32. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/plot_functions/__init__.py +0 -0
  33. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/plot_functions/plot_functions.py +0 -0
  34. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/plot_functions/visualize.py +0 -0
  35. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/utils.py +0 -0
  36. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/visualizers/__init__.py +0 -0
  37. {code_loader-1.0.206.dev2 → code_loader-1.0.207.dev0}/code_loader/visualizers/default_visualizers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: code-loader
3
- Version: 1.0.206.dev2
3
+ Version: 1.0.207.dev0
4
4
  Summary:
5
5
  Home-page: https://github.com/tensorleap/code-loader
6
6
  License: MIT
@@ -86,6 +86,8 @@ class DatasetSetup:
86
86
  custom_losses: List[CustomLossInstance]
87
87
  metrics: List[MetricInstance] = field(default_factory=list)
88
88
  simulations: List[SimulationInstance] = field(default_factory=list)
89
+ # Structural: the integration registered an element-instance mask encoder.
90
+ has_element_instances: bool = False
89
91
 
90
92
 
91
93
  @dataclass
@@ -15,7 +15,7 @@ from typing import Optional, Union, Callable, List, Dict, get_args, get_origin,
15
15
  import numpy as np
16
16
  import numpy.typing as npt
17
17
 
18
- from code_loader.utils import get_metadata_type_from_variable, is_absent_metadata_value, \
18
+ from code_loader.utils import map_dict_to_metadata_types, is_absent_metadata_value, \
19
19
  validate_autoregressive_state_types, autoregressive_nests_equal, \
20
20
  simulate_engine_float16_downcast_on_call_args, ENGINE_STORAGE_DTYPE, \
21
21
  TL_DISABLE_ENGINE_FLOAT16_SIMULATION_ENV_VAR
@@ -3006,39 +3006,47 @@ def tensorleap_element_instance_preprocess(
3006
3006
 
3007
3007
  def resolve_instance_metadata_types(sample_id: Union[int, str], preprocess_response: PreprocessResponse,
3008
3008
  idx: int) -> Optional[Dict[str, DatasetMetadataType]]:
3009
- # The probe enumerates the KEYS; the declaration, where given, supplies the TYPE. A key
3010
- # that is absent on the probed instance and undeclared has no type available from either
3011
- # side -- fail with mechanism (a)'s own message so both paths read the same.
3009
+ # The probe enumerates the KEYS; the declaration, where given, supplies the TYPE.
3012
3010
  element_instance = instance_mask_encoder(sample_id, preprocess_response, idx)
3013
- element_instance_metadata = getattr(element_instance, 'instance_metadata', None)
3014
- if element_instance_metadata is None:
3011
+ if element_instance is None or element_instance.instance_metadata is None:
3015
3012
  return dict(instance_metadata_types) if instance_metadata_types else None
3013
+ metadata = element_instance.instance_metadata
3016
3014
  declared = instance_metadata_types or {}
3017
- resolved = {}
3018
- for name, value in element_instance_metadata.items():
3019
- if name in declared:
3020
- continue
3021
- if is_absent_metadata_value(value):
3022
- raise Exception(
3023
- f"Metadata {name} is None and no metadata type is provided. It is absent on "
3024
- f"instance {idx} of sample {sample_id!r}, so the type cannot come from the "
3025
- f"value -- declare it: tensorleap_element_instance_preprocess(..., "
3026
- f"instance_metadata_types={{'{name}': DatasetMetadataType.float}}).")
3027
- resolved[name] = get_metadata_type_from_variable(value)
3028
- # Declared wins, and a declared key gets a column even when the probed instance lacks it.
3029
- resolved.update(declared)
3030
- return resolved
3015
+ # A key absent here and undeclared has no type from either side. Mechanism (a)'s own
3016
+ # message, so both paths read the same, plus where to declare it.
3017
+ absent = [name for name, value in metadata.items()
3018
+ if name not in declared and is_absent_metadata_value(value)]
3019
+ if absent:
3020
+ raise Exception(
3021
+ f"Metadata {absent[0]} is None and no metadata type is provided. It is absent "
3022
+ f"on instance {idx} of sample {sample_id!r}, so the type cannot come from the "
3023
+ f"value -- declare it: tensorleap_element_instance_preprocess(..., "
3024
+ f"instance_metadata_types={{'{absent[0]}': DatasetMetadataType.float}}).")
3025
+ # Every present value goes through the same helper the sample path uses, which is also
3026
+ # what rejects an unsupported type -- so declaring a key cannot smuggle a list past
3027
+ # validation. The declaration then wins on type, and a declared key gets a column even
3028
+ # when the probed instance lacks it.
3029
+ inferred = map_dict_to_metadata_types(
3030
+ {name: value for name, value in metadata.items()
3031
+ if not is_absent_metadata_value(value)})
3032
+ return {**(inferred or {}), **declared}
3031
3033
 
3032
3034
  def user_function_instance() -> List[PreprocessResponse]:
3033
3035
  result = user_function()
3034
3036
  found_instance_metadata = False
3035
- # Resolve types on training, like mechanism (a) does (leapbinder.get_preprocess_result):
3036
- # only training is allowed to fail on an unresolvable absence. `state` is still None here
3037
- # whenever the integration did not set it, so fall back to list position -- which is what
3038
- # get_preprocess_result would assign, and position 0 is training.
3039
- probe_order = sorted(
3040
- range(len(result)),
3041
- key=lambda i: DataStateEnum[result[i].state.name] if result[i].state is not None else i)
3037
+ # Resolve types on training, as mechanism (a) does: only training is allowed to fail
3038
+ # on an unresolvable absence (leapbinder.check_handler). `state` is still None here when
3039
+ # the integration left it to position, which is how get_preprocess_result assigns it,
3040
+ # and position 0 is training. Rank training against the rest rather than sorting on the
3041
+ # state value: mixing enum values with positions in one key lets validation tie with
3042
+ # position 1 and stay ahead of training.
3043
+ def _is_training(i: int) -> bool:
3044
+ response = result[i]
3045
+ if response.state is not None:
3046
+ return response.state == DataStateType.training
3047
+ return i == 0
3048
+
3049
+ probe_order = sorted(range(len(result)), key=lambda i: (0 if _is_training(i) else 1, i))
3042
3050
  for preprocess_response in (result[i] for i in probe_order):
3043
3051
  if preprocess_response.is_grouped:
3044
3052
  raise Exception(
@@ -935,7 +935,29 @@ class LeapLoader(LeapLoaderBase):
935
935
 
936
936
  return DatasetSetup(preprocess=dataset_preprocess, inputs=inputs, outputs=ground_truths,
937
937
  metadata=metadata_instances, visualizers=visualizers, prediction_types=prediction_types,
938
- custom_losses=custom_losses, metrics=metrics, simulations=simulations)
938
+ custom_losses=custom_losses, metrics=metrics, simulations=simulations,
939
+ has_element_instances=self._has_element_instances())
940
+
941
+ def _has_element_instances(self) -> bool:
942
+ """Does this dataset have element instances? Both halves, because either alone lies.
943
+
944
+ A registered mask encoder without instance mappings is an integration that declares
945
+ instances and produces none: the engine would take the pooling path with nothing to pool,
946
+ and ask the UI to visualize an instance population that does not exist. Mappings without an
947
+ encoder cannot be masked. Preprocessing has already run by the time this is called (the
948
+ lengths above come from it), so reading the mappings costs nothing extra.
949
+ """
950
+ setup = global_leap_binder.setup_container
951
+ if not setup.instance_masks:
952
+ return False
953
+ try:
954
+ return any(response.instance_to_sample_ids_mappings
955
+ for response in self._preprocess_result().values())
956
+ except Exception:
957
+ # Preprocessing is broken, so this push is already failing. Re-raising here would replace
958
+ # the specific preprocess error in the exit table with a generic one from check_dataset's
959
+ # outer handler. False is the safe answer and the real error survives.
960
+ return False
939
961
 
940
962
  def get_model_setup_response(self) -> ModelSetup:
941
963
  setup = global_leap_binder.setup_container
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "code-loader"
3
- version = "1.0.206.dev2"
3
+ version = "1.0.207.dev0"
4
4
  description = ""
5
5
  authors = ["dorhar <doron.harnoy@tensorleap.ai>"]
6
6
  license = "MIT"