-
Notifications
You must be signed in to change notification settings - Fork 297
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
[Bug] Set bindings for ArrayNode #2742
Conversation
Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>
Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>
Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>
…ayNode Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>
flytekit/core/array_node.py
Outdated
if ctx.compilation_state is not None: | ||
# interface mismatch between the target and the actual inputs since we don't create a new entity with a | ||
# transformed to list interface | ||
transformed_kwargs = { |
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.
this is fairly hacky. Would love if there's a better way to do this.
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.
I think this is fine... but can you pull this out into a separate function and add some comments and that also makes it easier to write a unit test for this.
I assume this is why the bindings in the subnode in the test seem to be binding to the first item. Could you add a comment somewhere explaining why?
Also does this feature work in local execution? If so, could you add some more units that just exercise local execution?
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.
@wild-endeavor cleaned this up a lot by passing in an "overriden_interface" that is the subnode's interface transformed to a list interface like we do in array node map tasks. By passing in a fake, transformed-to-list interface we can bind all the correct/original inputs for the subnode
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.
Yup, this works for local execution (updated to still create and not link the node from local execute). There are a couple unit tests to test local execute:
def test_local_exec_lp_min_successes(min_successes, min_success_ratio, should_raise_error): |
def test_map_task_wrapper(): |
flytekit/core/array_node.py
Outdated
@@ -49,6 +50,7 @@ def __init__( | |||
self._concurrency = concurrency | |||
self._execution_mode = execution_mode | |||
self.id = target.name | |||
self._bindings: List[_literal_models.Binding] = [] |
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.
Make this optional? and set default to 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.
@wild-endeavor would it make sense to keep this as is since this isn't a passed in value and to have:
@property
def bindings(self) -> List[_literal_models.Binding]:
# Required in get_serializable_node
return self._bindings
return an empty list if the bindings aren't set
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.
see slack
flytekit/core/array_node.py
Outdated
if ctx.compilation_state is not None: | ||
# interface mismatch between the target and the actual inputs since we don't create a new entity with a | ||
# transformed to list interface | ||
transformed_kwargs = { |
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.
I think this is fine... but can you pull this out into a separate function and add some comments and that also makes it easier to write a unit test for this.
I assume this is why the bindings in the subnode in the test seem to be binding to the first item. Could you add a comment somewhere explaining why?
Also does this feature work in local execution? If so, could you add some more units that just exercise local execution?
also, one more question, so the unit test with all the asserts... that's how propeller expects the node to be? It's supposed to bound to the first element of the list? Can we write an example with unions also? What if we're mapping over a union, and different elements are of different types of the union, does that matter? |
ArrayNode SubNodeSpec input bindings aren't utilized in propeller. This input binding would just be used to set a parameter name to get set for a workflow node's input. We don't update the interface of the underlying subnode, launch plan in this case, to a list of a type so we bypass this mismatch during compilation. Update: I went back and cleaned things up so the correct/original types are set for the input bindings. I also updated unit testing to include a param with a union or different types. |
Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>
Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>
Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>
Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>
Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>
Signed-off-by: Paul Dittamo <pvdittamo@gmail.com>
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #2742 +/- ##
===========================================
- Coverage 90.87% 40.62% -50.25%
===========================================
Files 74 194 +120
Lines 3331 19774 +16443
Branches 0 3899 +3899
===========================================
+ Hits 3027 8033 +5006
- Misses 304 11626 +11322
- Partials 0 115 +115 ☔ View full report in Codecov by Sentry. |
@@ -137,7 +139,8 @@ def local_execute(self, ctx: FlyteContext, **kwargs) -> Union[Tuple[Promise], Pr | |||
literals = [] | |||
for i in range(mapped_entity_count): | |||
single_instance_inputs = {} | |||
for k in self.python_interface.inputs.keys(): | |||
for binding in self.bindings: | |||
k = binding.var | |||
if k not in self._bound_inputs: | |||
single_instance_inputs[k] = kwargs[k][i] |
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.
could probably iterate through the bindings here instead, but this feels cleaner for now...
flytekit/core/array_node.py
Outdated
@@ -49,6 +50,7 @@ def __init__( | |||
self._concurrency = concurrency | |||
self._execution_mode = execution_mode | |||
self.id = target.name | |||
self._bindings: List[_literal_models.Binding] = [] |
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.
see slack
flytekit/core/promise.py
Outdated
node_id = ( | ||
f"{ctx.compilation_state.prefix}n{len(ctx.compilation_state.nodes)}" | ||
if add_node_to_compilation_state and ctx.compilation_state | ||
else "" |
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.
can we add an additional optional argument to this function for node_id? and then let's pass in a constant "ARRAY_NODE_SUB"
or some other constant string? at least that way it'll be obvious.
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.
sounds good. Updated
Tracking issue
fixes: https://linear.app/unionai/issue/COR-1822/mapping-over-launch-plans-w-default-inputs-doesnt-compile
Why are the changes needed?
Compiling a workflow fails when evaluating an ArrayNode that maps over a LaunchPlan contains a default input. This occurs since we don't set the input bindings for the node.
https://github.com/unionai/flyte/blob/926cadac9a8cf406b85c8e7443668a13a3f60dfe/flytepropeller/pkg/compiler/validators/interface.go#L76-L86
Get errors such as:
What changes were proposed in this pull request?
Update create_and_link_node and create_and_link_node_remote functions to create a node and optionally link it to the workflow context
clean up some of the setting of bound_inputs for array node since that isn't supported atm
How was this patch tested?
Setup process
Screenshots
Check all the applicable boxes
Related PRs
Docs link