code-loader 1.0.206.dev1__py3-none-any.whl → 1.0.206.dev3__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.
@@ -143,6 +143,10 @@ class ElementInstance:
143
143
  name: str
144
144
  mask: npt.NDArray[np.float32]
145
145
  instance_metadata: Optional[Dict[str, Union[Optional[str], int, bool, Optional[float]]]] = None
146
+ # Per-key "this value is absent", the same pair shape DatasetSample carries. Populated at the
147
+ # masks funnel (utils.to_numpy_return_masks_wrapper) so the engine copies flags rather than
148
+ # deriving them, exactly as it does for sample-level metadata.
149
+ instance_metadata_is_none: Optional[Dict[str, bool]] = None
146
150
 
147
151
  SectionCallableInterface = Callable[[Union[int, str], PreprocessResponse], npt.NDArray[np.float32]]
148
152
  InstanceCallableInterface = Callable[[Union[int, str], PreprocessResponse, int], Optional[ElementInstance]]
@@ -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, map_dict_to_metadata_types, \
18
+ from code_loader.utils import get_metadata_type_from_variable, 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
@@ -27,7 +27,8 @@ from code_loader.contract.datasetclasses import CustomCallableInterfaceMultiArgs
27
27
  VisualizerCallableInterface, MetadataSectionCallableInterface, PreprocessResponse, SectionCallableInterface, \
28
28
  ConfusionMatrixElement, SamplePreprocessResponse, PredictionTypeHandler, InstanceCallableInterface, ElementInstance, \
29
29
  InstanceLengthCallableInterface, InstanceSectionCallableInterface, AutoregressiveStepCallableInterface
30
- from code_loader.contract.enums import MetricDirection, LeapDataType, DatasetMetadataType, DataStateType
30
+ from code_loader.contract.enums import MetricDirection, LeapDataType, DatasetMetadataType, DataStateType, \
31
+ DataStateEnum
31
32
  from code_loader import leap_binder, LeapLoader
32
33
  from code_loader.contract.mapping import NodeMapping, NodeMappingType, NodeConnection
33
34
  from code_loader.contract.visualizer_classes import LeapImage, LeapImageMask, LeapTextMask, LeapText, LeapGraph, \
@@ -3003,28 +3004,54 @@ def tensorleap_element_instance_preprocess(
3003
3004
  leap_binder.set_metadata(builtin_instance_extra_metadata,
3004
3005
  "builtin_instance_extra_metadata", metadata_types)
3005
3006
 
3006
- def probe_instance_metadata_types(sample_id: Union[int, str], preprocess_response: PreprocessResponse,
3007
- idx: int) -> Optional[Dict[str, DatasetMetadataType]]:
3008
- # Fallback when the types are not declared: infer them from one probed instance. A
3009
- # None there carries no type, so name the fields and point at the declaration.
3007
+ def resolve_instance_metadata_types(sample_id: Union[int, str], preprocess_response: PreprocessResponse,
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.
3010
3012
  element_instance = instance_mask_encoder(sample_id, preprocess_response, idx)
3011
3013
  element_instance_metadata = getattr(element_instance, 'instance_metadata', None)
3012
3014
  if element_instance_metadata is None:
3013
- return None
3014
- not_inferable = [name for name, value in element_instance_metadata.items() if value is None]
3015
- if not_inferable:
3016
- raise Exception(
3017
- f"tensorleap_element_instance_preprocess validation failed: cannot infer the "
3018
- f"type of instance metadata {not_inferable} from instance {idx} of sample "
3019
- f"{sample_id!r}, because it is None on that instance. The type cannot come from "
3020
- f"the value, so declare it: tensorleap_element_instance_preprocess(..., "
3021
- f"instance_metadata_types={{'{not_inferable[0]}': DatasetMetadataType.float}}).")
3022
- return map_dict_to_metadata_types(element_instance_metadata)
3015
+ return dict(instance_metadata_types) if instance_metadata_types else None
3016
+ declared = instance_metadata_types or {}
3017
+ resolved = {}
3018
+ for name, value in element_instance_metadata.items():
3019
+ if name in declared:
3020
+ # Still type-check the VALUE. Master ran every key through
3021
+ # map_dict_to_metadata_types, so declaring a key must not become a way to
3022
+ # smuggle a list or an ndarray past validation and have it fail at eval time.
3023
+ if not is_absent_metadata_value(value):
3024
+ get_metadata_type_from_variable(value)
3025
+ continue
3026
+ if is_absent_metadata_value(value):
3027
+ raise Exception(
3028
+ f"Metadata {name} is None and no metadata type is provided. It is absent on "
3029
+ f"instance {idx} of sample {sample_id!r}, so the type cannot come from the "
3030
+ f"value -- declare it: tensorleap_element_instance_preprocess(..., "
3031
+ f"instance_metadata_types={{'{name}': DatasetMetadataType.float}}).")
3032
+ resolved[name] = get_metadata_type_from_variable(value)
3033
+ # Declared wins, and a declared key gets a column even when the probed instance lacks it.
3034
+ resolved.update(declared)
3035
+ return resolved
3023
3036
 
3024
3037
  def user_function_instance() -> List[PreprocessResponse]:
3025
3038
  result = user_function()
3026
- found_instance_metadata = instance_metadata_types is not None
3027
- for preprocess_response in result:
3039
+ found_instance_metadata = False
3040
+ # Resolve types on training, like mechanism (a) does (leapbinder.get_preprocess_result):
3041
+ # only training is allowed to fail on an unresolvable absence. `state` is still None here
3042
+ # whenever the integration did not set it, so fall back to list position -- which is the
3043
+ # state get_preprocess_result would assign, and position 0 is training. Rank training
3044
+ # against everything else rather than sorting on the state value itself: mixing enum
3045
+ # values with list positions in one key lets a validation response tie with position 1
3046
+ # and keep its place ahead of training.
3047
+ def _is_training(i: int) -> bool:
3048
+ response = result[i]
3049
+ if response.state is not None:
3050
+ return response.state == DataStateType.training
3051
+ return i == 0
3052
+
3053
+ probe_order = sorted(range(len(result)), key=lambda i: (0 if _is_training(i) else 1, i))
3054
+ for preprocess_response in (result[i] for i in probe_order):
3028
3055
  if preprocess_response.is_grouped:
3029
3056
  raise Exception(
3030
3057
  "tensorleap_element_instance_preprocess validation failed: a grouped "
@@ -3047,10 +3074,10 @@ def tensorleap_element_instance_preprocess(
3047
3074
  # "Index <id> with sample_id: <id> cannot be found!".
3048
3075
  for idx, instance_id in enumerate(instances_ids):
3049
3076
  if not found_instance_metadata:
3050
- probed_types = probe_instance_metadata_types(
3077
+ resolved_types = resolve_instance_metadata_types(
3051
3078
  sample_id, preprocess_response, idx)
3052
- if probed_types is not None:
3053
- register_instance_extra_metadata(probed_types)
3079
+ if resolved_types:
3080
+ register_instance_extra_metadata(resolved_types)
3054
3081
  found_instance_metadata = True
3055
3082
 
3056
3083
  instance_to_sample_ids_mappings[instance_id] = sample_id
@@ -3066,8 +3093,6 @@ def tensorleap_element_instance_preprocess(
3066
3093
 
3067
3094
  leap_binder.set_preprocess(user_function_instance)
3068
3095
  leap_binder.set_metadata(builtin_instance_metadata, "builtin_instance_metadata")
3069
- if instance_metadata_types is not None:
3070
- register_instance_extra_metadata(instance_metadata_types)
3071
3096
 
3072
3097
  def _validate_input_args(*args, **kwargs):
3073
3098
  assert len(args) == 0 and len(kwargs) == 0, \
code_loader/leaploader.py CHANGED
@@ -28,7 +28,7 @@ from code_loader.inner_leap_binder import global_leap_binder
28
28
  from code_loader.inner_leap_binder.leapbinder import mapping_runtime_mode_env_var_mame
29
29
  from code_loader.leaploaderbase import LeapLoaderBase
30
30
  from code_loader.utils import get_root_exception_file_and_line_number, get_metadata_type_from_variable, \
31
- validate_autoregressive_state_types, autoregressive_nests_equal
31
+ validate_autoregressive_state_types, autoregressive_nests_equal, is_absent_metadata_value
32
32
 
33
33
 
34
34
  def _serialize_sim_bounds(bounds) -> dict:
@@ -1228,7 +1228,7 @@ class LeapLoader(LeapLoaderBase):
1228
1228
 
1229
1229
  try:
1230
1230
  is_none = False
1231
- if value is None or (isinstance(value, (int, float, np.integer, np.floating)) and not np.isfinite(value)):
1231
+ if is_absent_metadata_value(value):
1232
1232
  raise ValueError()
1233
1233
  converted_value = metadata_type_to_python_type[metadata_name_to_type[metadata_name]](value)
1234
1234
  except ValueError:
code_loader/utils.py CHANGED
@@ -15,6 +15,12 @@ from code_loader.contract.datasetclasses import SectionCallableInterface, Prepro
15
15
  from code_loader.contract.enums import DatasetMetadataType
16
16
 
17
17
 
18
+ def is_absent_metadata_value(value: Any) -> bool:
19
+ """The one definition of an absent metadata value, shared by every mechanism."""
20
+ return value is None or (isinstance(value, (int, float, np.integer, np.floating))
21
+ and not np.isfinite(value))
22
+
23
+
18
24
  def to_numpy_return_wrapper(encoder_function: SectionCallableInterface) -> SectionCallableInterface:
19
25
  def numpy_encoder_function(idx: Union[int, str], samples: PreprocessResponse) -> npt.NDArray[np.float32]:
20
26
  result = encoder_function(idx, samples)
@@ -39,6 +45,9 @@ def to_numpy_return_masks_wrapper(encoder_function: InstanceCallableInterface) -
39
45
  if result is None:
40
46
  return None
41
47
  result.mask = np.array(result.mask)
48
+ if result.instance_metadata is not None and result.instance_metadata_is_none is None:
49
+ result.instance_metadata_is_none = {
50
+ k: is_absent_metadata_value(v) for k, v in result.instance_metadata.items()}
42
51
  return result
43
52
  return numpy_encoder_function
44
53
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: code-loader
3
- Version: 1.0.206.dev1
3
+ Version: 1.0.206.dev3
4
4
  Summary:
5
5
  Home-page: https://github.com/tensorleap/code-loader
6
6
  License: MIT
@@ -1,7 +1,7 @@
1
1
  LICENSE,sha256=qIwWjdspQeSMTtnFZBC8MuT-95L02FPvzRUdWFxrwJY,1067
2
2
  code_loader/__init__.py,sha256=outxRQ0M-zMfV0QGVJmAed5qWfRmyD0TV6-goEGAzBw,406
3
3
  code_loader/contract/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- code_loader/contract/datasetclasses.py,sha256=ySmO5Ld4fyfUWOJxUdnH2qCMota4dtwtgMHJS7Y8IvA,17070
4
+ code_loader/contract/datasetclasses.py,sha256=6Ozy9_C7HCP6YHqM27teBLe503MRvn7jg7h8uXHPuUY,17395
5
5
  code_loader/contract/enums.py,sha256=__GkPkwAXi2agmDGtEQgbMucPm4-n80maG6n_MmObPA,1691
6
6
  code_loader/contract/exceptions.py,sha256=jWqu5i7t-0IG0jGRsKF4DjJdrsdpJjIYpUkN1F4RiyQ,51
7
7
  code_loader/contract/mapping.py,sha256=sWJhpng-IkOzQnWQdMT5w2ZZ3X1Z_OOzSwCLXIS7oxE,1446
@@ -22,17 +22,17 @@ code_loader/experiment_api/utils.py,sha256=XZHtxge12TS4H4-8PjV3sKuhp8Ud6ojAiIzTZ
22
22
  code_loader/experiment_api/workingspace_config_utils.py,sha256=DLzXQCg4dgTV_YgaSbeTVzq-2ja_SQw4zi7LXwKL9cY,990
23
23
  code_loader/inner_leap_binder/__init__.py,sha256=koOlJyMNYzGbEsoIbXathSmQ-L38N_pEXH_HvL7beXU,99
24
24
  code_loader/inner_leap_binder/leapbinder.py,sha256=mWcjx31fnrtRfV5agveW79lcMGJhwhDfLz7brpexBv0,60408
25
- code_loader/inner_leap_binder/leapbinder_decorators.py,sha256=lM2wFqzxdTVoe9lwC5YFdgnY8UwvY5r9foDnKJpQ7Mc,195252
26
- code_loader/leaploader.py,sha256=JjC5ljuofrtUP4qMh2KzRQLrIWvSTpR8ep6om92c3qc,91308
25
+ code_loader/inner_leap_binder/leapbinder_decorators.py,sha256=GQu5bGZ7dlZbDNy9LcNkw82CMBqEdNogHtO1D1x84dc,196885
26
+ code_loader/leaploader.py,sha256=CA2Ctpw9EN_x-wM6SmAWrBv4pijpA74ckJcqAtLJtv8,91263
27
27
  code_loader/leaploaderbase.py,sha256=Aa8wCcxojf8EBn_14W5I1gKI4OMBdpdEcNAZ_6E2eV4,10940
28
28
  code_loader/mixpanel_tracker.py,sha256=rNwRmFifNbdUoqLQvvhhgpKczWpWiEmd8MfyJe27sxw,9131
29
29
  code_loader/plot_functions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
30
  code_loader/plot_functions/plot_functions.py,sha256=2DC-zlVaN13P4VNx5d8csgs80C6SisaeP1-Kq2LW7iM,16075
31
31
  code_loader/plot_functions/visualize.py,sha256=gsBAYYkwMh7jIpJeDMPS8G4CW-pxwx6LznoQIvi4vpo,657
32
- code_loader/utils.py,sha256=mlwr-4ZeeEMMIRdMAL7JF0b-5ko7QSRhbKZ64DqKbTY,11452
32
+ code_loader/utils.py,sha256=Auw39lKpEQ7Ld2q1nj6S18GIDKWcjCxU0TDrur2UEko,11968
33
33
  code_loader/visualizers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  code_loader/visualizers/default_visualizers.py,sha256=grTPin_lCE9aci8i8CqA7DqQwAyXRB7_EamA3na_pls,5438
35
- code_loader-1.0.206.dev1.dist-info/LICENSE,sha256=qIwWjdspQeSMTtnFZBC8MuT-95L02FPvzRUdWFxrwJY,1067
36
- code_loader-1.0.206.dev1.dist-info/METADATA,sha256=v7DbX7F0l3-_L0R5gieoiNSAff1YAA9dqnJ9ncCD2yE,1095
37
- code_loader-1.0.206.dev1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
38
- code_loader-1.0.206.dev1.dist-info/RECORD,,
35
+ code_loader-1.0.206.dev3.dist-info/LICENSE,sha256=qIwWjdspQeSMTtnFZBC8MuT-95L02FPvzRUdWFxrwJY,1067
36
+ code_loader-1.0.206.dev3.dist-info/METADATA,sha256=_kkkAHCgoFUWxh8XzxcoE-pM8oDFSB3Pf32_Aqmq-Qw,1095
37
+ code_loader-1.0.206.dev3.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
38
+ code_loader-1.0.206.dev3.dist-info/RECORD,,