Skip to content
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

feat[next]: Inline dynamic shifts #1738

Open
wants to merge 153 commits into
base: main
Choose a base branch
from

Conversation

tehrengruber
Copy link
Contributor

@tehrengruber tehrengruber commented Nov 14, 2024

Dynamic shifts are not supported in the domain inference. In order to make them work nonetheless this PR aggressively inlines all arguments to as_fieldop until they contain only references to itir.Program params. Additionally the domain inference is extended to tolerate such as_fieldop by introducing a special domain marker that signifies a domain is unknown.

@edopao
Copy link
Contributor

edopao commented Nov 15, 2024

I run icon4py stencils and I found that one small change is needed in dace backend. It makes sense to include it in this PR:

--- a/src/gt4py/next/program_processors/runners/dace_fieldview/gtir_dataflow.py
+++ b/src/gt4py/next/program_processors/runners/dace_fieldview/gtir_dataflow.py
@@ -1057,7 +1057,6 @@ class LambdaToDataflow(eve.NodeVisitor):
         """Implements shift in unstructured domain by means of a neighbor table."""
         assert connectivity.neighbor_axis in it.dimensions
         neighbor_dim = connectivity.neighbor_axis
-        assert neighbor_dim not in it.indices
 
         origin_dim = connectivity.origin_axis
         assert origin_dim in it.indices

@tehrengruber
Copy link
Contributor Author

Feel free to push your Dace changes (as long as they are isolated to dace parts otherwise it'll be to confusing).

@@ -67,6 +67,107 @@ def _is_tuple_expr_of_literals(expr: itir.Expr):
return isinstance(expr, itir.Literal)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All changes in this file are merely a small refactoring that extracts the field operator fusion for a single as_fieldop from the FuseAsFieldOp pass into a dedicated function fuse_as_fieldop used by the InlineDynamicShifts pass.

@@ -10,7 +10,7 @@

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SF-N could you review the changes in this file?

Copy link
Contributor

@SF-N SF-N left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the changes make sense to me. The only thing one could reconsider is the name allowed_unknown_domains as it somehow implies to be a collection of domains rather than references.

src/gt4py/next/iterator/transforms/infer_domain.py Outdated Show resolved Hide resolved
src/gt4py/next/iterator/transforms/infer_domain.py Outdated Show resolved Hide resolved
src/gt4py/next/iterator/transforms/infer_domain.py Outdated Show resolved Hide resolved
return expr, accessed_domains


def _infer_stmt(
stmt: itir.Stmt,
offset_provider: common.OffsetProvider,
symbolic_domain_sizes: Optional[dict[str, str]],
allowed_unknown_domains: list[str],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, I am confused why this is introduced...
Are all program parameters allowed to be unknown, but the rest isn't?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand the logic, then I would remove it from here and rather write a separate path for checking this and avoid uglifying the this interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I minimized cluttering the interface by introducing a typed dict InferenceOptions that handles forwarding of the arguments. I tried a separate path for checking, but this felt more error prone and ugly (let's discuss if you want more details why). The typed dict feels like a good compromise to me (also allows setting a breakpoint at the place where the error occurs), but I don't insist on it :-P.

@@ -157,5 +161,8 @@ def apply_fieldview_transforms(
ir = inline_fundefs.prune_unreferenced_fundefs(ir)
ir = InlineLambdas.apply(ir, opcount_preserving=True, force_inline_lambda_args=True)
ir = CollapseTuple.apply(ir, offset_provider=offset_provider) # type: ignore[assignment] # type is still `itir.Program`
ir = inline_dynamic_shifts.InlineDynamicShifts.apply(
ir
) # domain inference does not support dynamic offsets yet
ir = infer_domain.infer_program(ir, offset_provider=offset_provider)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to support unknown domain in the type inference for as_offset?

Copy link
Contributor Author

@tehrengruber tehrengruber Nov 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss quickly, I'm not sure I understand the question in its entirety.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants