# While Loops and Variable Vertical Offsets in GTC
###### tags: `cycle 3`
shaped by: EddieD
## Problem
The Lagrangian to Eulerian vertical remapping motif in the FV3 dynamical core has been implemented using a single `gt4py` stencil in `fv3core` using a `while` loop frontend feature. This has already been implemented in the legacy toolchain using variable vertical offsets. These are offsets in the *k*-direction that can be integer scalars or fields rather than only integer literals. In this case, the value of the varaible offset is added to the current *k*-level. These features need to be implemented in the GTC toolchain as well.
The typical use case in a stencil is like the following,
```python=
def while_loop_stencil(
pe1: FloatField,
pe2: FloatField,
lev: IntFieldIJ,
qout: FloatField,
):
with computation(FORWARD), interval(...):
while pe1[0, 0, lev + 1] < pe2[0, 0, lev + 1]:
qout += pe1[0, 0, lev] * pe2[0, 0, lev]
lev += 1
```
In this example, the fields `pe1` and `pe2` correspond to two pressure varaibles that are being compared, `lev` is a 2D integer field for keeping track of the current `k`-level, and `qout` is an output field containing the summation.
## Appetite
* Probably half-cycle, as the work is in already in progress.
## Solution
The implementation is separated into two parts:
1. The variable vertical offsets
2. The `while` loop construct
The legacy toolchain versions of each feature are implemented in `gt4py` pull requests [396](https://github.com/GridTools/gt4py/pull/396) and [410](https://github.com/GridTools/gt4py/pull/410), respectively.
### 1. Variable Vertical Offsets in GTC
The proposed solution is to add a new node type called `VariableOffset` that extends the existing `CartesianOffset` type by allowing the `k` offset to be any expression. A validator verifies that the expression has an integer data type. For the purposes of extent analysis, the `VariableOffset` returns an arbitrary large integer value for `k`. The generic `VaraibleOffset` in `common` is mirrored in the `GTIR`, `OIR`, `GTCpp`, and `CUIR` intermediate representations. Code generation is not modified since the `CartesianOffset` templates can be reused for `VariableOffset` nodes.
### 2. While Loops in GTC
The `while` statement in GTC is implemented similarly to an `if` statement with a conditional expression and a body of statements. The `While` node in the `GTIR` is lowered to a `MaskStmt` in OIR much like the `ScalarIfStmt`. An `is_loop` attribute is added to the `MaskStmt` to indicate whether it should be used to generate an `if` statement or a `while`, but this implementation is certainly open to discussion. In the `GtCpp` backend, the `MaskStmt` with loop is lowered back to a `While` statement, much like the `IfStmt`, but remains a `MaskStmt` in CUIR. The code generation macros are updated accordingly.
## Potential Rabbit Holes
1. There has been some active discussion about whether such a feature belongs as part of a DSL as it tends toward a general purpose language. Another issue is the difficulty of applying optimizations to such a generic feature. The proposed `while` and `for` loop abstractions could potentially be lifted to a more general conditional concept in the OIR.
2. Keeping track of the current `k`-level requires passing an IJ integer field into the stencil to be used as a counter. A full 3D field would not work so a temporary cannot be used. Either typed temporaries, e.g., `tmp: Field[IJK, int] = 0` would be required to replace this, or a compiler pass that can infer that the field used in the variable vertical offset should be 2D.
3. As in a general purpose language, there are currently no safety checks on the `while` loop conditions meaning that infinite loops are possible. The backend could instead generate code that guarantees the variable offset when added to the current *k*-level does not exceed the domain size in the *k*-direction.
## No Gos
The aforementioned discussion about whether such general purpose loop constructs belong in a DSL for weather and climate applications results in the conclusion, that no, indeed they do not.