---
# System prepended metadata

title: Compiled Backend Temporaries
tags: [functional cycle 13]

---

# Compiled Backend Temporaries

###### tags: `functional cycle 13`

- Developers: Till
- Appetite: Full cycle

## Problem

On Iterator level composition of stencils is realized using the `lift` builtin. The resulting iterator of an applied `lift` can be used to evaluate a stencil on neighboring locations (i.e. grid points). Without memorization those stencils are regularly evaluated many times on the same location. As a result the runtime $t$ of a stencil closure grows exponentially in composition depth $d$, i.e. $t(n, d) \in \mathcal{O}(n^d)$, where $c$ is the maximum number of neighboring locations on any nesting level. This is particularly devestating in terms of runtime for nested reductions. Even a simple second order advection scheme can easily require reevaluation of a hundred or more stencils. Without memorization fusing of stencils in Icon4Py and a clean / scalable implemention of the FVM dycore is impractical.

## Solution

An efficient way of memorization is the creation of temporaries containing the values of `lift`ed stencils, evaluated at all locations they accessed on.

## Goals

The goal of this project is support temporaries in the embedded and gtfn backend for all frontend and iterator tests (unless otherwise disabled).

## Non-goals


## Current state

ITIR has already been extended by two nodes (`Temporary`, `FencilWithTemporaries`) required to represent temporaries and fencils with temporaries. A pass transforming a regular `Fencil` into
a `FencilWithTemporaries` has been implemented in `split_closures` (this can be triggered by using `LiftMode.ForceTemporaries`). This pass is currently limited in that it can only handle some structures of ITIR, but notably fails for patterns encountered in ITIR generated by the frontend.

_Example stencil not supported by `split_closures` pass_
```python=
@fundef
def stencil(closure_arg_it):
    scalar = 1+1
    lifted_it = lift(lambda it: deref(it)+scalar)(closure_arg_it)
    return deref(lifted_it)
```

Code reference: https://github.com/GridTools/gt4py/blob/functional/src/functional/iterator/transforms/global_tmps.py

## Known steps

- Extend the `split_closures` pass to support ITIR as generated by the frontend
- Optional, but desired: Implement a heuristic with reasonable performance (inbetween `LiftMode.ForceTemporaries` and `LiftMode.ForceInline`)

## Possible rabbit holes

