# [GT4Py] GTIR Domain inference
- Shaped by:
- Appetite (FTEs, weeks):
- Developers: Sara
## Problem
<!-- The raw idea, a use case, or something we’ve seen that motivates us to work on this -->
## Appetite
<!-- Explain how much time we want to spend and how that constrains the solution -->
## Solution
- Write test cases in ITIR for a meaningful set of stencils
```python
# no-composition
expr = as_fieldop(stencil)(inp_field, ...)
# with composition (required for dace backend)
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)
```
```python
# 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)
```
- Write a pass that using `TraceShift`s infers the minimal domain of `as_fieldop` and `SetAt` on temporaries such that after the pass all `as_fieldop` should have their domain arg inferred, e.g. `as_fieldop(stencil)(inp_field, ...)` is transformed into `as_fieldop(stencil, cartesian_domain(...))(inp_field, ...)`. Focus on Cartesian first. The minimal domain is always inferred in a backwards fashion starting from the last `SetAt`, outer `as_fieldop` to inner most `as_fieldop`.
### Scratchpad
```
# helper function in IR makers
cartesian_domain({"I": (1, "some_var"), "J": (1, 20)})
```
<!-- The core elements we came up with, presented in a form that’s easy for people to immediately understand -->
## Rabbit holes
<!-- Details about the solution worth calling out to avoid problems -->
## No-gos
<!-- Anything specifically excluded from the concept: functionality or use cases we intentionally aren’t covering to fit the ## appetite or make the problem tractable -->