---
# System prepended metadata

title: '[GT4Py] Cartesian offset syntax'
tags: [cycle20]

---

# [GT4Py] Cartesian offset syntax

<!-- Add the tag for the current cycle number in the top bar -->

- Shaped by:
- Appetite (FTEs, weeks):
- Developers: <!-- Filled in at the betting table unless someone is specifically required here -->

## Problem

Currently we only support the following syntax for Cartesian offsets `field(Ioff[1])(Joff[-1])`. For convenience we want to support the syntax `field(I+1,J-1)`.

This is a introductory task in to GT4Py. It covers the following levels of the GT4Py toolchain: embedded execution, parsing (func_to_foast) and (possibly) lowering.

## Appetite
<!-- Explain how much time we want to spend and how that constrains the solution -->

## Solution

The project has 2 parts: (1) adding the +/- syntax, (2) allowing multiple offsets in a single *remap* call.

### Embedded execution

1. Add `__add__` and `__sub__` functions to [`Dimension`](https://github.com/GridTools/gt4py/blob/main/src/gt4py/next/common.py)~~`FieldOffset`~~ and implement analogous to `__getitem__` (Edit @tehrengruber: we will change `Dimension` not `FieldOffset`).
2. Add variadic form to `__call__` of `common.Field` and their implementation ([ndarray_field.NdArrayField]([src/gt4py/next/embedded/nd_array_field.py](https://github.com/GridTools/gt4py/blob/main/src/gt4py/next/embedded/nd_array_field.py))), the implementation could be just multiple calls to `remap` (which should probably keep the single parameter form).

### Parsing and lowering

Both tasks could be resolved in lowering from Python AST to field operator ast (func_to_foast), by constructing the currently supported syntax. This could make sense as a first step to see quick results and play with the transformations.

In a next step, the transformation should be moved to foast_to_itir.


## Rabbit holes
<!-- Details about the solution worth calling out to avoid problems -->

## No-gos
<!-- Anything specifically excluded from the concept: functionality or use cases we intentionally aren’t covering to fit the ## appetite or make the problem tractable -->

## Progress
<!-- Don't fill during shaping. This area is for collecting TODOs during building. As first task during building add a preliminary list of coarse-grained tasks for the project and refine them with finer-grained items when it makes sense as you work on them. -->

Steps:
- [x] Add support for `I+1`. Conceptually Dimension + Int -> Offset (use just random name for offset in beginning)
- [x] Change Laplacian test to use new syntax
- [x] Add support for `field(I+1, J+1)` using a new test case.

Example:
Laplacian: sum all Xs. 
```
0 X 0
X X X
0 X 0
```

New Test: sum all Xs. 
```
X 0 X
0 X 0
X 0 X
```


## Results/Overview
####  Previous syntax:
`field(Ioff[1])(Joff[-1])`

#### Newly supported syntax:
`field(IDim+1,JDim-1)` or `field(IDim+1)(JDim-1)`

In case the order matters like for `field(E2V[0])(C2E[0])` only `field(E2V[0])(C2E[0])` is supported to avoid confusion.

### Code changes:
#### Embedded execution:
-  Introduced `__add__` and `__sub__` functions to [`Dimension`](https://github.com/GridTools/gt4py/blob/main/src/gt4py/next/common.py#L80)
-  Added variadic form to `__call__` to [`Field`](https://github.com/GridTools/gt4py/blob/main/src/gt4py/next/common.py#L613) and call `remap` recursively.

#### Parsing and lowering:
-  Extended [type_deduction](https://github.com/GridTools/gt4py/blob/main/src/gt4py/next/ffront/foast_passes/type_deduction.py), [type-info](https://github.com/GridTools/gt4py/blob/main/src/gt4py/next/type_system/type_info.py), and [foast_to_itir](https://github.com/GridTools/gt4py/blob/main/src/gt4py/next/ffront/foast_to_itir.py)