# Utilities

Important

Loki is still under active development and has not yet seen a stable release. Interfaces can change at any time, objects may be renamed, or concepts may be re-thought. Make sure to sync your work to the current release frequently by rebasing feature branches and upstreaming more general applicable work in the form of pull requests.

To assist the development of custom transformations, a number of useful tools for recurring tasks or house keeping are included with Loki.

## Pragma utilities

An easy way of injecting information at specific locations in source files is to insert pragmas. This allows to annotate declarations or loops, mark source code regions or specify locations. Pragmas are represented by a unique node type `Pragma` and thus can be picked out easily during a transformation.

A number of utility routines and context manager are available that allow for easy parsing of pragmas, can attach pragmas to other nodes (such as `Loop`), or extract pragma regions and wrap them in a dedicated internal node type `PragmaRegion`:

`loki.pragma_utils.is_loki_pragma`(pragma[, ...]) | Checks for a pragma annotation and, if it exists, for the `loki` keyword.
`loki.pragma_utils.get_pragma_parameters`(pragma) | Parse the pragma content for parameters in the form `<command>[(<arg>)]` and return them as a map `{<command>: <arg> or None}`.
`loki.pragma_utils.pragmas_attached`(...[, ...]) | Create a context in which pragmas preceding nodes of given type(s) inside the module's or routine's IR are attached to these nodes.
`loki.pragma_utils.pragma_regions_attached`(...) | Create a context in which `PragmaRegion` node objects are inserted into the IR to define code regions marked by matching pairs of pragmas.

## Dataflow analysis

Rudimentary dataflow analysis utilities are included with Loki that determine for each IR node what symbols it defines (i.e., assigns a value), reads (i.e., uses before defining it), and which symbols are live (i.e., have been defined before) entering the IR node in the control flow.

`loki.analyse.analyse_dataflow.dataflow_analysis_attached`(...) | Create a context in which information about defined, live and used symbols is attached to each IR node

## Dimensions

With the modification of data layouts and iteration spaces as one of the core tasks in many transformation pipelines in mind, Loki has a `Dimension` class to define such a one-dimensional space.

`loki.dimension.Dimension`([name, index, ...]) | Dimension object that defines a one-dimensional data and iteration space.

## Python utilities

Some convenience utility routines, e.g., to simplify working with strings or files are included in `loki.tools`:

`loki.tools.files` |
`loki.tools.strings` |
`loki.tools.util` |

A notable example is `CaseInsensitiveDict`, a dict with strings as keys for which the case is ignored. It is repeatedly used in other Loki data structures when mapping symbol names that stem from Fortran source code. Since Fortran is not case-sensitive, these names can potentially appear with mixed case yet all refer to the same symbol and `CaseInsensitiveDict` makes sure no problems arise due to that.

Other frequently used utilities for working with lists and tuples are `as_tuple`, `is_iterable` and `flatten`.

## Loki house keeping

For internal purposes exist a global configuration `loki.config.Configuration` and logging functionality.

`loki.config` | Dictionary class that holds global configuration parameters.
`loki.logging` | Loki's logger classes and logging utilities.

## Build subpackage

As part of Loki’s test suite but also useful as a standalone package are the build utilities `loki.build`:

## Linting functionality

The source analysis capabilities of Loki can be used to build a static source code analysis tool for Fortran. This is being developed as a standalone script loki-lint and includes a few data structures for the linter mechanics in `loki.lint`:

`loki.lint.linter.Linter`(reporter, rules[, ...]) | The operator class for Loki's linter functionality
`loki.lint.reporter` |
`loki.lint.rules.GenericRule`() | Generic interface for linter rules providing default values and the general `check()` routine that calls the specific entry points to rules (subroutines, modules, and the source file).
`loki.lint.utils.Fixer`() | Operater class to fix problems reported by fixable rules.