# 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.