---
# System prepended metadata

title: Field view additions
tags: [functional cycle 9]

---

# Field view additions

###### tags: `functional cycle 9`

Developer: Till, Ben (1/2 cycle)

## Scan

__Appetite__: 1-2 weeks 1 FTE

__Gloal__: Implement the `scan_operator` decorator to support vertical solvers.

### Syntax & Semantics
<!--In cycle 9 we plan to add `scan` to the field view.

Shape this project for the next cycle:
- Syntax proposals
- Lowering and semantics
- Experiments

A scan pass is a function that takes a set of one or more scalar-like arguments, i.e. scalar or tuple of scalars and returns a scalar-like argument. By means of the `scan_operator` decorator a scan-pass is lifted to a field operator, attributing meaning to its arguments: The first argument contains the initial value on the first vertical level and the previous return value on consecutive calls. Additional arguments ...-->

```python
scan_operator(f, init, axis=Dimension("K"), reverse=False)
```

__Parameters__:
- `f` (`Callable[[Carry, X...], Y]`): A function to be scanned. Takes the carried value, i.e. the value returned in the last iteration or `init`, as first argument. Remaining arguments are the values of the fields in the current level.
- `init` (`Carry`): Initial value.
- `reverse` (`bool`): The direction/order in which `f` is applied.

__Returns__: A field operator mapping a set of fields to a field defined on the union of its input field domains.

### Example

```python=
@scan_operator(init=0.0)
def tridiag_forward(
    state: Tuple[float, float],
    a: float,
    b: float,
    c: float,
    d: float
):
    return (
        c / (b - a - state[0]),
        (d - a * state[1]) / (b - a * state[0])
    )


@scan_operator(init=0.0, reverse=True)
def tridiag_backward(
    x_kp1: float,
    cp: float,
    dp: float,
) -> float:
    return dp - cp * x_kp1


@field_operator
def solve_tridiag(
    a: Field[[I, J, K], dtype],
    b: Field[[I, J, K], dtype],
    c: Field[[I, J, K], dtype],
    d: Field[[I, J, K], dtype]
) -> Field[[I, J, K], dtype]:
    cp, dp = tridiag_forward(a, b, c, d)
    return tridiag_backward(cp, dp)
```

### Tasks

- Implement subscript operator on tuples in frontend.
- Implement lowering from Python to FOAST. This will require some small changes to FOAST (either introduction of a new ScanOperator node or generalization of the FieldOperator node). Only a subset of syntax is allowed inside the scan pass. With the current functionality of FOAST this is automatically ensured when restricting the arguments to scalars.
- Implement lowering from FOAST to ITIR.
- Port all existing iterator tests to the new syntax.

## Conditionals / where (good beginners task)

__Appetite__: <1 week

...

## Additional built-ins: `sin, cos, min, max, ...` (good beginners task)

__Appetite__: 1 day

...

## Multiple output fields

Both for calling in field operator and program context.

## Weights

See https://hackmd.io/3Hetx4FGRBifZMKxsW0Dvg#Inline-construction-of-fields

Low priority.