-
Notifications
You must be signed in to change notification settings - Fork 2
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
Alternative interfaces for macro definition #85
Comments
So there's a number of things going on here. For me the first and most important is that when you have a macro where two (or more) children are receiving the same input, there is no convenient way to synchronize these; as shown in your top example, a How do we implement such a thing? Under the hood, there is actually some formalism for how all this is happening. In this case, the relevant parts are that "connections" are only formed between input and output channel pairs, IO or OI, never II or OO. In addition to this, two channels of the same category (II or OO) can be "linked" so that value updates to one are automatically sent to the other. Currently, channels can have an arbitrary number of connections but send their value updates to at most one other channel. These features allow us to "pull" on a node and automatically construct its upstream dependencies and give us the freedom to choose whether that pulling stays inside the scope of a given macro, or punches through macro walls to get the entire dependency stack. I'm not claiming it's the only set of properties/implementation that can give us these features, just that whatever choices we make need to continue to support that functionality. So one choice would be to soften the linking restriction so a channel can synchronize its
Another choice would be to interpret the macro creating function in two passes: first, scrape off all args/kwargs beyond the first one and use them to create
So I think this can be done and I like it as a short-hand so that users don't need to define their own Then the second thing is restricting macro output with the return value, i.e.
With that said, while I am happy with the existence of Original wish@macro_node(output_labels="fit_dict")
def internal_macro(wf: Macro, instance, calculator) -> None:
wf.generate_structures = generate_structures(instance=instance)
wf.calc_with_calculator = calc_with_calculator(calculator=calculator, task_dict=wf.generate_structures)
wf.fit = analyse_structures(
instance=instance, output_dict=wf.calc_with_calculator
)
return wf.fit.fit_dict Pros:
Cons:
Proposed alternative@macro_node()
def internal_macro(wf: Macro, instance) -> None:
wf.generate_structures = generate_structures(instance=instance)
wf.calc_with_calculator = calc_with_calculator(task_dict=wf.generate_structures)
wf.fit = analyse_structures(
instance=instance,
output_dict=wf.calc_with_calculator
)
# And supposing there was some other output we wanted to explicitly silence
wf.outputs_map = {"generate_structures__imagined": None}
# Or even cooler, but is a separate issue:
# wf.outputs_map = {wf.generate_structures.outputs.imagined: None} Pros:
Cons:
|
@jan-janssen wrote
The text was updated successfully, but these errors were encountered: