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

GTIR domain inference #1568

Merged
merged 41 commits into from
Aug 21, 2024
Merged

GTIR domain inference #1568

merged 41 commits into from
Aug 21, 2024

Conversation

SF-N
Copy link
Contributor

@SF-N SF-N commented Jul 3, 2024

Uses TraceShifts to infer the minimal domain of (nested) as_fieldops and SetAt:

Domain inference of let-statements is not implemented yet and will be done in PR #1591

expr = as_fieldop(stencil)(as_fieldop(stencil)(inp_field))

domain = cartesian_domain(...)

# new_expr has transformed all as_fieldop(stencil) into as_fieldop(stencil, domain)
infer_as_fieldop(expr, domain) -> new_expr, dict(referenced_field => accessed domain)
# with new_expr = as_fieldop(stencil, cartesian_domain(...))(inp_field, ...)

# multiple SetAt (no composition)
tmp <- as_fieldop(stencil)(inp_field, ...) @ auto_domain()
out <- as_fieldop(stencil)(tmp, ...) @ ...

# domain is inferred bottom up from last SetAt, only domains of SetAt on temporaries are changed
infer_program(program_expr)

PR Description

  • New file gt4py.next.iterator.transforms.infer_domain with function infer_as_fieldop and infer_program
  • Several new tests in test_infer_domain.py to test functionality
  • New function SymbolicDomain.translate
  • New helper-function domain and as_fieldop in ir.makers
  • Uses constant folding of itir.Literals to simplify resulting domains

Todos

  • Domain inference for nested as_fieldops (cartesian_domain)
  • Domain inference for SetAt
  • Extend to unstructured grids

Note

I agree that my contribution in this PR is additionally licensed under the BSD-3-Clause license (SPDX short identifier).

@SF-N SF-N requested a review from tehrengruber July 3, 2024 09:38
Copy link
Contributor

@tehrengruber tehrengruber left a comment

Choose a reason for hiding this comment

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

First course round.

src/gt4py/next/iterator/ir_utils/ir_makers.py Outdated Show resolved Hide resolved
src/gt4py/next/iterator/ir_utils/ir_makers.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
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
@SF-N SF-N requested a review from tehrengruber July 4, 2024 14:38
src/gt4py/next/iterator/ir_utils/ir_makers.py Outdated Show resolved Hide resolved
src/gt4py/next/iterator/ir_utils/ir_makers.py Outdated Show resolved Hide resolved
src/gt4py/next/iterator/ir_utils/ir_makers.py Outdated Show resolved Hide resolved
@SF-N SF-N requested a review from tehrengruber July 8, 2024 14:47
@tehrengruber
Copy link
Contributor

Note to myself: One function for itir.Program with temporaries, one without (only the simple for loop). When writing temporary pass introduce ProgramWithUnresolvedTemporaries that allows _gtmp_auto_domain and potentially move the inference (continuing to build upon the primitive function operaton on as_fieldop here) there.

SF-N added 2 commits July 10, 2024 00:05
…add functionality to infer domain of a program with several SetAt
src/gt4py/next/iterator/ir_utils/ir_makers.py Outdated Show resolved Hide resolved
src/gt4py/next/iterator/transforms/global_tmps.py Outdated Show resolved Hide resolved
src/gt4py/next/iterator/transforms/global_tmps.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
src/gt4py/next/iterator/transforms/infer_domain.py Outdated Show resolved Hide resolved
@SF-N SF-N requested a review from tehrengruber July 22, 2024 14:00
tehrengruber added a commit that referenced this pull request Jul 23, 2024
This PR fixes a bug where the size of unstructured temporary fields was
wrong in certain cases. This bug surfaced while working on #1568. It
took me a while to figure out why this never surfaced in validation
tests anywhere:
Right now we compute temporaries for unstructured everywhere, e.g. on
all vertices, etc.. What _everywhere_ means is derived from the offset
provider in `_max_domain_sizes_by_location_type`. The information is
contained either
- explicitly if we have a connectivity with origin axis being the axis
whose size we want to know. E.g. if we have a V2E connectivity then we
have `table.shape[0]` many vertices.
- or implicitly if we have a connectivity with the neighbor axis whose
size we want to know. E.g. if we have a V2E connectivity then we have at
least `table.max()+1` many edges. This computation was wrong.

So as long as we have also the E2V connectivity for the examples above,
the implicit information is not needed / used and everything works fine.
For all our test cases this is indeed the case and since computing
temporaries everywhere is only a temporary solution anyway I am fine
with just fixing this without increasing test coverage.

---------

Co-authored-by: edopao <edoardo.paone@cscs.ch>
src/gt4py/next/iterator/transforms/infer_domain.py Outdated Show resolved Hide resolved
Comment on lines +191 to +198
transformed_set_ats.insert(
0,
itir.SetAt(
expr=transformed_as_fieldop,
domain=SymbolicDomain.as_expr(accessed_domains[set_at.target.id]),
target=set_at.target,
),
)
Copy link
Contributor

Choose a reason for hiding this comment

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

updating the domain should only be done if the original domain is AUTO_DOMAIN, correct? I am wondering if we should split this pass in 2. One that propagates domains between set_at (i.e. resolves AUTO_DOMAIN) and one that just annotates as_fieldops. I find it confusing that we do both in the same pass, but not sure if I am missing something.

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 am also not sure if I am missing something, but I think this is only possible with some code duplication.
One option could be to add a pass that infers the domains of all as_fieldops which is then only called by DaCe.
Let's discuss this next time we talk.

Copy link
Contributor

Choose a reason for hiding this comment

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

As discussed: We discovered that running the domain propagation prior to temporary extraction should make all temporary related code in the propagation unnecessary and can hence be removed. We've placed a todo (in the let branch) and kept it in here for now so that we can move on.

@tehrengruber tehrengruber merged commit 196cc5f into GridTools:main Aug 21, 2024
31 checks passed
tehrengruber added a commit that referenced this pull request Sep 20, 2024
)

Infers the minimal domain of (nested) `let`, `make_tuple`, `tuple_get`,
`cond` and other builtins as an extension to PR #1568

- New functions `infer_let`, `infer_make_tuple`, `infer_tuple_get`,
`infer_cond` in `gt4py.next.iterator.transforms.infer_domain`
- New function `infer_expr` in
gt4py.next.iterator.transforms.infer_domain which calls the appropriate
of the above (or `infer_as_fieldop` and `infer_program`)
- Several new tests in test_infer_domain.py to test functionality

Note:
Temporary handling was only present until commit fc4846f and has been
removed in commit e8e679d to reduce unneeded complexity. This pass will
be executed before temporary extraction, hence there exist valid
`domain`s in all program calls, i.e. all `SetAt` do have a domain (not
`AUTO_DOMAIN`) that doesn't need to be inferred.

---------

Co-authored-by: Till Ehrengruber <till.ehrengruber@cscs.ch>
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.

3 participants