# Tutorial This tutorial goes through a simple example generating a C file from an input block specification. For this example the running sources are found in the `tests/inputs` folder of the ZOTI-Gen project root. The target file which we are trying to obtain in this tutorial is a C file representing the sequential implementation of a moving-average algorithm applied on a sequence of numbers. It consists in a composite pattern described functionally as ```{math} mav_1 (x) = \mathtt{ShiftMap}(\mathtt{MapReduce}(\mathtt{mulacc}))(x) ``` ## Specification Files We define the code blocks structure for the implemented system in the files `main.yaml` representing module `main` and `genspec_leafs.yaml` representing module `genspec_leafs`. ```{literalinclude} ../../tests/inputs/genspec_main.yaml --- language: yaml linenos: true caption: main.yaml --- ``` Notice the definition of `mav_1` which is an implementation of component `Skeleton.Compute.ShiftFarm` (i.e., the shift-map pattern) and instantiates block `fred_1` which is an implementation of `Skeleton.Compute.FarmRed_Acc` (i.e., the map-reduce pattern with an accumulator). The latter instantiates `mulacc` defined below as a regular block, containing the "native" kernel code in its `code` entry. Also note that the top block `main` implements a `Generic.Infinite` template (i.e., an infinite loop) scheduling three placeholders as of its `param/schedule`: `readio` (for reading a stream of input numbers), `exec` (expanding the `mav_1` block) and `writeio` (for printing the results to the terminal). ```{literalinclude} ../../tests/inputs/genspec_leafs.yaml --- language: yaml linenos: true caption: genspec_leafs.yaml --- ``` Notice that the input specification is as verbose as it needs to be to facilitate the parsing of data. This is because these files are not meant to be written by humans, much rather generated by upstream tools[^1]. Also, the convenient information in the `usage` and `prototype` entries is also meant to be provided by an upstream pre-processor with the help of a type system, but this is outside the scope of ZOTI-Gen. [^1]: For specifying the same input in a less verbose and slightly more feature-rich syntax, one could consider a more human-readable frontend, such as ZOTI-YAML. ## Bindings and Names After resolving the structure here is how the block components look like. Pay attention to the label bindings, as well as their resolved names, as compared to their initial description. ```{graphviz} assets/main.genspec.dot ``` ## Library Components The library components are grouped into two modules (or packages): `Generic` for harboring generic templates, and `Skeleton` for defining templates for specialized collective operations, all targeting a sequential C implementation. ### Generic The generic components are spread throughout several files showcasing some of the template design tips described in [](template-libs). ```{literalinclude} ../../tests/inputs/Generic/__init__.py --- language: python linenos: true caption: Generic/\_\_init\_\_.py --- ``` ```{literalinclude} ../../tests/inputs/Generic/IO.py --- language: python linenos: true caption: Generic/IO.py --- ``` ```{literalinclude} ../../tests/inputs/Generic/templates.c --- language: c linenos: true caption: Generic/templates.c --- ``` ### Specialized Collective Operations The `Skeleton` module showcases more advanced template design using the ZOTI-Gen Jinja extensions. ```{literalinclude} ../../tests/inputs/Skeleton/Compute.py --- language: python linenos: true caption: Skeleton/Compute.py --- ``` Notice that both `ShiftFarm` and `FarmRed_Acc` specify a requirement upon a certain target library header `cutils.h`. This is where functions used in their template such as `min` are supposed to be defined. ```{literalinclude} ../../tests/inputs/Skeleton/templates.c --- language: jinja linenos: true caption: Skeleton/templates.c --- ``` The template definition shows an example of using local Jinja [macro](https://jinja.palletsprojects.com/en/3.1.x/templates/#macros), as well as the in-house {meth}`zoti_gen.render.JinjaExtensions.setdefaults` filter. ## Output Artifacts Finally, the generated artifacts can be seen in this section. In this case the artifacts are presented as two separate files: * a JSON file representing the include dependencies, useful for a post-processor, e.g. to generate the preamble of the .c file. * a .c file containing the bulk of the code (without the preamble). ```{literalinclude} assets/deps.json --- language: json linenos: true caption: Dependencies --- ``` Notice that the generated code reflects the directive flags passed during block instantiation: all blocks are expanded as inline text except `mulacc` which is not using the `"expand"` directive. This is because it contains plain non-template native code which needs to be isolated as a separate function. ```{literalinclude} assets/out.c --- language: c linenos: true caption: Output C code --- ``` To obtain these files we ran the ZOTI-Gen CLI tool using the following configuration, assuming that all source files, libraries as well as the CLI tool are accessible from the current folder. ```{literalinclude} assets/zoticonf.toml --- language: toml caption: zoticonf.json --- ```