# Enable pre-compilation aka Frozen Stencil
<!-- 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
Refactor the workflow into AOT compilable structure.
(moved from cycle 22)
## Appetite
<!-- Explain how much time we want to spend and how that constrains the solution -->
## Solution
<!-- The core elements we came up with, presented in a form that’s easy for people to immediately understand -->
```mermaid
graph TB
%% fdef(FieldOperatorDefinition) -->|func_to_foast| foast(FoastOperatorDefinition)
%% foast -->|foast_to_itir| itir_expr(itir.Expr)
%% foasta -->|foast_to_foast_closure| fclos(FoastClosure)
%% fclos -->|foast_to_past_closure| pclos(PastClosure)
pdefa(InputWithArgs) --> puwr{{"split compile info from args/kwargs"}} --> pdef
ahead_entry(AOT Entrypoint) --> pspec_args
ahead_entry --> pdef
pclos -->|past_process_args| pclos
pclos -->|past_to_itir| pcompile(CompilableProgram)
pdef(ProgramDefinition) -->|func_to_past| past(PastProgramDefinition)
past -->|past_lint| past
pasta -->|past_to_past_closure| pclos(ProgramClosure)
%% fdefa(InputWithArgs) --> fuwr{{"internal unwrapping"}} --> fdef
%% fuwr --> fargs(args, kwargs)
%% foast --> fiwr{{"internal wrapping"}} --> foasta(InputWithArgs)
%% fargs --> foasta
puwr --> pargs(args, kwargs)
puwr --> pspec_args(Signature of args/kwargs)
pspec_args --> piwr
past --> piwr{{"internal wrapping"}} --> pasta(AOTProgramDefinition)
pargs --> exec_call
pcompile -->|compile| pexec(Executable)
pexec --> exec_call{{"call Executable"}} --> result
```
- Use a few tests first before updating the test infrastructure: use the test_arg_call_interface (or whatever)
- Update to the new workflow as described above
- Update the test infrastructure
## 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. -->
- [ ] atomically update each step starting from the compilation and working going towards the transforms to be ahead-of-time capable. To achieve atomicity, always keep the ahead-of-time capable part of the toolchain wrapped in the "split compile info from args --> toolchain --> reinsert args" pattern. A prototype for that could be the `foast_to_past_closure` step. In the process, keep updating stage types etc (most likely there will be some duplication in stage types to keep the current toolchains testable).
- [ ] `program_processors.codegens.gtfn.gtfn_module.GTFNTranslationStep`
- [ ] (optional) `program_procesors.runners.dace_iterator.workflow.DaceTranslator`
If we choose not to do this one, we need to decide whether we want to build a the above toolchain for GTFN in parallel or drop tests for `dace_iterator`, once GTFN is fully AOT-capable.
- [ ] `past_to_itir` (trivial)
- [ ] `past_process_args` Probably the most work, requires moving the "size args" generation into the "decorate" step of the compilation.
- [ ] (optional) Check if possible to get rid of the "size args" already at this point.
- [ ] build a parallel fully AOT GTFN toolchain and test it
- [ ] If feasible, support it in the Backend class and testing utils (depends on test utils and state of `dace_iterator` at that point)
- [ ] Adapt decorators, wrapper classes etc.
- [ ] Cleanup
- [ ] check if some utilities have become obsolete
- [ ] check if program processors still have a reason to exist
- [ ] possibly rename otf to jit