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:

loki.build.binary.Binary(name[, objs, libs])

A binary build target to generate executables.

loki.build.header.Header(*args[, name])

loki.build.lib.Lib(name[, shared, objs, ...])

A library object linked from multiple compiled objects (Obj).

loki.build.obj.Obj(*args[, name])

A single source object representing a single C or Fortran source file.

loki.build.builder.Builder([source_dirs, ...])

A Builder that compiles binaries or libraries, while performing automated dependency discovery from one or more source paths.

loki.build.compiler

loki.build.max_compiler

loki.build.workqueue([workers, logger, manager])

Parallel work queue manager that creates a worker pool and exposes the q.execute(cmd) utility to invoke shell commands in parallel.

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.