# [GT4Py] NamedTuple-like Field Collections (AKA pytrees) - Shaped by: - Appetite (FTEs, weeks): - Developers: <!-- Filled in at the betting table unless someone is specifically required here --> This task was originally shaped for [cycle 20](https://hackmd.io/4KDbjmE7SO6L_OjtLx2z0Q#). This project is stripped-down but with more details. ## Problem GT4Py has basic support for collections via tuples. We identified several features that would profit from a general mechanism for collections. See [cycle 20](https://hackmd.io/4KDbjmE7SO6L_OjtLx2z0Q#) for an overview. In this project we aim to support ### NamedTuple-like collections This is syntax sugar for long argument lists and allows to group related fields Example: extraction ```python! class Velocities: u: Field[DomT, DT] v: Field[DomT, DT] def foo(velocity: Velocities) -> Field[[Dim], Dtype]: return sqrt(velocity.u**2 + velocity.v**2) ``` Example: creation ```python def foo( u: Field[[Dim], Dtype], v: Field[[Dim], Dtype] ) -> Velocities: return Velocities(u, v) ``` ## Solution With *pytree*s, JAX offers an extensible mechanism that provides this functionality. We would like to implement a similar mechanism for GT4Py. A prototype is implemented in https://github.com/GridTools/gt4py/pull/2211 that sketches the ingredients of this project. Concrete decisions on how to expose registration and how to implement `flatten` (see later) are not yet taken. ### Access mechanisms In this project we want to focus on attribute access for NamedTuple-like containers. #### Expose type information at compile-time (parsing) and run-time To support any user-defined container and not only a specific subset (e.g. NamedTuples, Dataclasses and Attr classes), the user needs to provide the following information: - the GT4Py type of the collection: e.g. `NamedTupleType` that contains the `keys` (attributes) of the tuple elements on top of the plain tuple types. - the GT4Py FunctionType for the constructor to be able to validate args/kwargs when constructing the object in the DSL. - a flatten mechanism that converts the custom collection elements to a plain tuple which will be passed to the backend (this function is performance aka Python-overhead relevant), see [pytree protocol](https://jax.readthedocs.io/en/latest/pytrees.html) used by JAX or the the tree registering mechanism used in [autoray](https://github.com/jcmgray/autoray/blob/a0be3702f37bc64507ae501dd22717d224383ad2/autoray/autoray.py#L504). ### Lowering We can resolve attribute access by `tuple_get` by mapping the attribute-name to the index as layed out in a `NamedTupleType`. ### Creation within the DSL (parsing) The Custom container type need to be accessible including in type-checking. Utilities are already in place to get this information from ClosureVars. ## Rabbit holes <!-- Details about the solution worth calling out to avoid problems --> ## No-gos In this project we aim at basic support for NamedTuple-like attribute access. Implicit unrolling (expandable parameter style) and optimizations are not part of the project. ## 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. --> - [x] Task 1 ([PR#xxxx](https://github.com/GridTools/gt4py/pulls)) - [x] Subtask A - [x] Subtask X - [ ] Task 2 - [x] Subtask H - [ ] Subtask J - [ ] Discovered Task 3 - [ ] Subtask L - [ ] Subtask S - [ ] Task 4