-
Notifications
You must be signed in to change notification settings - Fork 252
Beat the limitations of EE in terms of singular elements pushed into batch inputs #1504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 21 commits
61eaa05
0ffd261
ed2da81
d328c1f
b72719c
9e7765a
fb704d3
69ebbb1
55211a2
c6a7ab5
c4b59cb
ac237f2
4cf7bb1
546fad8
0b38378
714d88c
2eb0ba3
831583a
62460e9
37c120b
32dd916
86d8787
25646cc
852fe54
8355698
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -86,6 +86,35 @@ batch-oriented input, it will be treated as a SIMD step. | |||||
| Non-SIMD steps, by contrast, are expected to deliver a single result for the input data. In the case of non-SIMD | ||||||
| flow-control steps, they affect all downstream steps as a whole, rather than individually for each element in a batch. | ||||||
|
|
||||||
| Historically, Execution Engine could not handle well al scenarios when non-SIMD steps' outputs were fed into SIMD steps | ||||||
| inputs - causing compilation error due to lack of ability to automatically cast such outputs into batches when feeding | ||||||
| into SIMD seps. Starting with Execution Engine `v1.6.0`, the handling of SIMD and non-SIMD blocks has been improved | ||||||
| through the introduction of **Auto Batch Casting**: | ||||||
|
|
||||||
| * When a SIMD input is detected but receives scalar data, the Execution Engine automatically casts it into a batch. | ||||||
|
|
||||||
| * The dimensionality of the batch is determined at compile time, using *lineage* information from other | ||||||
| batch-oriented inputs when available. Missing dimensions are generated in a manner similar to `torch.unsqueeze(...)`. | ||||||
|
|
||||||
| * Outputs are evaluated against the casting context - leaving them as scalars when block keeps or decreases output | ||||||
| dimensionality or **creating new batches** when increase of dimensionality is expected. | ||||||
|
|
||||||
| !!! warning "We don't support multiple sources of batch-oriented data" | ||||||
|
|
||||||
| While Auto Batch Casting simplifies mixing SIMD and non-SIMD blocks, there is one major limitation to be aware of. | ||||||
|
|
||||||
| If multiple first-level batches are created from different origins (for instance inputs and steps taking scalars | ||||||
| and raising output dimensionality into batch at first level of depth), the Execution Engine cannot deterministically | ||||||
| construct the output. In previous versions, the assumption was that **outputs were lists directly tied to inputs | ||||||
| batch order**. With Auto Batch Casting, batches may also be generated dynamically, and no deterministic ordering | ||||||
| can be guaranteed (imagine scenario when you feed batch of 4 images, and there is a block generating dynamic batch | ||||||
| with 3 images - when results are to be returned, Execution Engine is unable to determine a single input batch which | ||||||
| would dictate output order alignment, which is a hard requirement caused by falty design choices). | ||||||
|
||||||
| would dictate output order alignment, which is a hard requirement caused by falty design choices). | |
| would dictate output order alignment, which is a hard requirement caused by previous design choices). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| __version__ = "0.52.1" | ||
| __version__ = "0.53.0" | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,12 +64,16 @@ def parse_block_manifest( | |
| inputs_accepting_batches_and_scalars = set( | ||
| manifest_type.get_parameters_accepting_batches_and_scalars() | ||
| ) | ||
| inputs_enforcing_auto_batch_casting = set( | ||
| manifest_type.get_parameters_enforcing_auto_batch_casting() | ||
| ) | ||
| return parse_block_manifest_schema( | ||
| schema=schema, | ||
| inputs_dimensionality_offsets=inputs_dimensionality_offsets, | ||
| dimensionality_reference_property=dimensionality_reference_property, | ||
| inputs_accepting_batches=inputs_accepting_batches, | ||
| inputs_accepting_batches_and_scalars=inputs_accepting_batches_and_scalars, | ||
| inputs_enforcing_auto_batch_casting=inputs_enforcing_auto_batch_casting, | ||
| ) | ||
|
|
||
|
|
||
|
|
@@ -79,6 +83,7 @@ def parse_block_manifest_schema( | |
| dimensionality_reference_property: Optional[str], | ||
| inputs_accepting_batches: Set[str], | ||
| inputs_accepting_batches_and_scalars: Set[str], | ||
| inputs_enforcing_auto_batch_casting: Set[str], | ||
| ) -> BlockManifestMetadata: | ||
| primitive_types = retrieve_primitives_from_schema( | ||
| schema=schema, | ||
|
|
@@ -89,6 +94,7 @@ def parse_block_manifest_schema( | |
| dimensionality_reference_property=dimensionality_reference_property, | ||
| inputs_accepting_batches=inputs_accepting_batches, | ||
| inputs_accepting_batches_and_scalars=inputs_accepting_batches_and_scalars, | ||
| inputs_enforcing_auto_batch_casting=inputs_enforcing_auto_batch_casting, | ||
| ) | ||
| return BlockManifestMetadata( | ||
| primitive_types=primitive_types, | ||
|
|
@@ -255,6 +261,7 @@ def retrieve_selectors_from_schema( | |
| dimensionality_reference_property: Optional[str], | ||
| inputs_accepting_batches: Set[str], | ||
| inputs_accepting_batches_and_scalars: Set[str], | ||
| inputs_enforcing_auto_batch_casting: Set[str], | ||
| ) -> Dict[str, SelectorDefinition]: | ||
| result = [] | ||
| for property_name, property_definition in schema[PROPERTIES_KEY].items(): | ||
|
|
@@ -277,6 +284,7 @@ def retrieve_selectors_from_schema( | |
| is_list_element=True, | ||
| inputs_accepting_batches=inputs_accepting_batches, | ||
| inputs_accepting_batches_and_scalars=inputs_accepting_batches_and_scalars, | ||
| inputs_enforcing_auto_batch_casting=inputs_enforcing_auto_batch_casting, | ||
| ) | ||
| elif property_definition.get(TYPE_KEY) == OBJECT_TYPE and isinstance( | ||
| property_definition.get(ADDITIONAL_PROPERTIES_KEY), dict | ||
|
|
@@ -290,6 +298,7 @@ def retrieve_selectors_from_schema( | |
| is_dict_element=True, | ||
| inputs_accepting_batches=inputs_accepting_batches, | ||
| inputs_accepting_batches_and_scalars=inputs_accepting_batches_and_scalars, | ||
| inputs_enforcing_auto_batch_casting=inputs_enforcing_auto_batch_casting, | ||
| ) | ||
| else: | ||
| selector = retrieve_selectors_from_simple_property( | ||
|
|
@@ -300,6 +309,7 @@ def retrieve_selectors_from_schema( | |
| is_dimensionality_reference_property=is_dimensionality_reference_property, | ||
| inputs_accepting_batches=inputs_accepting_batches, | ||
| inputs_accepting_batches_and_scalars=inputs_accepting_batches_and_scalars, | ||
| inputs_enforcing_auto_batch_casting=inputs_enforcing_auto_batch_casting, | ||
| ) | ||
| if selector is not None: | ||
| result.append(selector) | ||
|
|
@@ -314,6 +324,7 @@ def retrieve_selectors_from_simple_property( | |
| is_dimensionality_reference_property: bool, | ||
| inputs_accepting_batches: Set[str], | ||
| inputs_accepting_batches_and_scalars: Set[str], | ||
| inputs_enforcing_auto_batch_casting: Set[str], | ||
| is_list_element: bool = False, | ||
| is_dict_element: bool = False, | ||
| ) -> Optional[SelectorDefinition]: | ||
|
|
@@ -323,9 +334,15 @@ def retrieve_selectors_from_simple_property( | |
| ) | ||
| if declared_points_to_batch == "dynamic": | ||
| if property_name in inputs_accepting_batches_and_scalars: | ||
| points_to_batch = {True, False} | ||
| if property_name in inputs_enforcing_auto_batch_casting: | ||
| points_to_batch = {True} | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why only True here?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is for enforced auto-batch casting - which is turning all parameters into batches in case there is a mix (compound fields) or when we have this special case of non-batch oriented block downgrading the output dim (then we need to add this new class method to the manifest, otherwise the only way to judge which input params are to be wrapped [to make it possible to reduce across last dim] is to analyse the signature annotations, which we avoided to do as this is very flaky) |
||
| else: | ||
| points_to_batch = {True, False} | ||
| else: | ||
| points_to_batch = {property_name in inputs_accepting_batches} | ||
| points_to_batch = { | ||
| property_name in inputs_accepting_batches | ||
| or property_name in inputs_enforcing_auto_batch_casting | ||
| } | ||
| else: | ||
| points_to_batch = {declared_points_to_batch} | ||
| allowed_references = [ | ||
|
|
@@ -359,6 +376,7 @@ def retrieve_selectors_from_simple_property( | |
| is_dimensionality_reference_property=is_dimensionality_reference_property, | ||
| inputs_accepting_batches=inputs_accepting_batches, | ||
| inputs_accepting_batches_and_scalars=inputs_accepting_batches_and_scalars, | ||
| inputs_enforcing_auto_batch_casting=inputs_enforcing_auto_batch_casting, | ||
| is_list_element=True, | ||
| ) | ||
| if property_defines_union(property_definition=property_definition): | ||
|
|
@@ -372,6 +390,7 @@ def retrieve_selectors_from_simple_property( | |
| is_dimensionality_reference_property=is_dimensionality_reference_property, | ||
| inputs_accepting_batches=inputs_accepting_batches, | ||
| inputs_accepting_batches_and_scalars=inputs_accepting_batches_and_scalars, | ||
| inputs_enforcing_auto_batch_casting=inputs_enforcing_auto_batch_casting, | ||
| ) | ||
| return None | ||
|
|
||
|
|
@@ -394,6 +413,7 @@ def retrieve_selectors_from_union_definition( | |
| is_dimensionality_reference_property: bool, | ||
| inputs_accepting_batches: Set[str], | ||
| inputs_accepting_batches_and_scalars: Set[str], | ||
| inputs_enforcing_auto_batch_casting: Set[str], | ||
| ) -> Optional[SelectorDefinition]: | ||
| union_types = ( | ||
| union_definition.get(ANY_OF_KEY, []) | ||
|
|
@@ -410,6 +430,7 @@ def retrieve_selectors_from_union_definition( | |
| is_dimensionality_reference_property=is_dimensionality_reference_property, | ||
| inputs_accepting_batches=inputs_accepting_batches, | ||
| inputs_accepting_batches_and_scalars=inputs_accepting_batches_and_scalars, | ||
| inputs_enforcing_auto_batch_casting=inputs_enforcing_auto_batch_casting, | ||
| is_list_element=is_list_element, | ||
| ) | ||
| if result is None: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.