---
# System prepended metadata

title: GT4Py/Green use of symbols from modules in GT4Py programs
tags: [cycle 24 - 08/24, gt4py]

---

# GT4Py/Green use of symbols from modules in GT4Py programs
<!-- Add the tag for the current cycle number on top -->

- Shaped by: Nikki, Hannes
- Appetite (FTEs, weeks): 1/2 cycle for step 1
- Developers: Nikki, Hannes <!-- Filled in at the betting table unless someone is specifically required here -->

gt4py calls from modules are currently possible only in type hints. 

gt4py decorators do not allow for parameters to be imported with modules reference, e.g.:

```python=
 @gtx.program
    def prog(
        f: gtx.Field[Dims[dims.IDim], float], 
        out: gtx.Field[Dims[dims.IDim], float]):
        
        field_op(f, out=out, domain={dims.IDim: (0, 8)})
```

In this case `IDim` is called from the `dims` module directly in the domain

### Step 1: programs

The first step is to allow module for Dimensions in domain arguments. This means creating `Attribute` class and visits in past steps (`func_to_past`, `program_ast`, and `type_deduction`) and adapt code where Attributes are now allowed. 

A difficulty of this task is to make the code dynamic such that an indefinite number of module calls can be made: 

```python
field_op(f, out=out, domain={a.b.c.dims.IDim: (0, 8)})
```

Hannes' solution is the introduction of this class in type_translation for recursive search:

```python
@dataclasses.dataclass(frozen=True)
class UnknownPythonObject(ts.TypeSpec):
    _object: Any

    def __getattr__(self, key: str) -> ts.TypeSpec:
        value = getattr(self._object, key)
        return from_value(value)

    def __deepcopy__(self, _: dict[int, Any]) -> UnknownPythonObject:
        return UnknownPythonObject(self._object)
```

### Step 2: field_operator

Next step is to introduce such logic in the field_operators as well, e.g.

```python
@gtx.field_operator
    def mod_op(f: cases.IKField) -> cases.IKField:
        return f(cases.Ioff[1])
```

This feature might require edits in the lowering (`foast_to_itir`) and will involve: types, builtins, field_operators, constants, Dimensions, ...

A question is whether it is better to make edits in the lowering whenever needed or somehow change the Attribute to a Name earlier and leave the lowering as is.  

It is important that if two parameters have the same node.id in the Name (e.g. a.field and b.field), they are distinguished until needed.

### Step 3: scan_operator

Next cycle maybe 