---
# System prepended metadata

title: 'Shape Up: Control flow'
tags: [archive]

---

# Shape Up: Control flow

###### tags: `archive`

The main idea of this project is to enable expressions outside of the `with computation` regions. While the constructs allowed are constrained by the usual restrictions valid inside the stencil computations, these expressions nevertheless will allow control flow and additional patterns to be implemented in the framework. The main constructs are:
- `while` loops
- `for` loops
- conditionals

Once the control flow is enabled, it would be fairly simple to introduce reductions, for instance.

### Note
Calling stencils from stencils can be seen as an instance of control flow, since it entails having expressions outside the `with computation` regions.

## Conditionals

```python
BACKEND = "gtcuda"
dtype = np.float_

@gtscript.function
def lapf(phi, alpha):
    return -alpha * phi[0, 0, 0] + 
          phi[-1, 0, 0] + phi[1, 0, 0] + phi[0, -1, 0] + phi[0, 1, 0]


@gtscript.stencil(backend=BACKEND, externals={"LIM": 0.01}, domain=[...])
def diffusion_defs(in_phi: Field[dtype], bi_lap: Field[dtype],
                   *, alpha: float, double_lap: bool):

    if (double_lap):
        with computation(PARALLEL), interval(...):
            bilap = lapf(in_phi, alpha)
    else:
        with computation(PARALLEL), interval(...):
            lap = lapf(in_phi, alpha)        
            bilap = lapf(lap, alpha)
```

## While loops


```python
BACKEND = "gtcuda"
dtype = np.float_

@gtscript.function
def lapf(phi, alpha):
    return -alpha * phi[0, 0, 0] + 
          phi[-1, 0, 0] + phi[1, 0, 0] + phi[0, -1, 0] + phi[0, 1, 0]


@gtscript.stencil(backend=BACKEND, externals={"LIM": 0.01}, domain=[...])
def diffusion_defs(in_phi: Field[dtype], bi_lap: Field[dtype],
                   *, alpha: float, iterations: int):

    while (iterations > 0)
        with computation(PARALLEL), interval(...):
            bilap = lapf(in_phi, alpha)
            in_phi = bilap
        iterations = iterations - 1;
```

Interesting consequences of these features are with respect to extent analysis.

In conditionals both branches need to be acocunted for, while for while-loops, if the expressions have non-zero extents in the horizontals, the problem may be ill-posed. Surely halo-updates can be placed in an "unrolled" version of the loop, but the global boundaries will have issues. On the other had, I feel in many cases we may be fine. What about the code example above here?


