loki.expression.symbols

Expression tree node classes for Expression tree.

Functions

loki_make_stringifier(self[, ...])

Return a LokiStringifyMapper instance that can be used to generate a human-readable representation of self.

Classes

Array(name[, scope, type, dimensions])

Expression node for array variables.

ArraySubscript(aggregate, index)

Internal representation of an array subscript.

Cast(name, expression[, kind])

Internal representation of a data type cast.

Comparison(left, operator, right)

Representation of a comparison operation.

DeferredTypeSymbol(name[, scope])

Internal representation of symbols with deferred type

Dereference(expression)

Internal representation of a Dereference.

FloatLiteral(value, **kwargs)

A floating point constant in an expression.

InlineCall(function[, parameters, kw_parameters])

Internal representation of an in-line function call.

InlineDo(values, variable, bounds, **kwargs)

An inlined do, e.g., implied-do as used in array constructors

IntLiteral(value, **kwargs)

An integer constant in an expression.

IntrinsicLiteral(value, **kwargs)

Any literal not represented by a dedicated class.

Literal(value, **kwargs)

Factory class to instantiate the best-matching literal node.

LiteralList(values[, dtype])

A list of constant literals, e.g., as used in Array Initialization Lists.

LogicLiteral(value, **kwargs)

A boolean constant in an expression.

LogicalAnd(children)

Representation of an 'and' in a logical expression.

LogicalNot(child)

Representation of a negation in a logical expression.

LogicalOr(children)

Representation of an 'or' in a logical expression.

LoopRange(children, **kwargs)

Internal representation of a loop range.

MetaSymbol(symbol, *args, **kwargs)

Base class for meta symbols to encapsulate a symbol node with optional enclosing operations in a unifying interface

Power(base, exponent)

Representation of a power.

ProcedureSymbol(name[, scope, type])

Internal representation of a symbol that represents a callable subroutine or function

Product(children)

Representation of a product.

Quotient(numerator[, denominator])

Representation of a quotient.

Range(children, **kwargs)

Internal representation of a loop or index range.

RangeIndex(children, **kwargs)

Internal representation of a subscript range.

Reference(expression)

Internal representation of a Reference.

Scalar(name[, scope, type])

Expression node for scalar variables.

StrCompareMixin()

Mixin to enable comparing expressions to strings.

StringLiteral(value, **kwargs)

A string constant in an expression.

StringSubscript(aggregate, index)

Internal representation of a substring subscript operator.

Sum(children)

Representation of a sum.

TypedSymbol(*args, **kwargs)

Base class for symbols that carry type information.

Variable(**kwargs)

Factory class for TypedSymbol or MetaSymbol classes

VariableSymbol(*args, **kwargs)

Expression node to represent a variable symbol

loki_make_stringifier(self, originating_stringifier=None)

Return a LokiStringifyMapper instance that can be used to generate a human-readable representation of self.

This is used as common abstraction for the make_stringifier() method in Pymbolic expression nodes.

class StrCompareMixin

Bases: object

Mixin to enable comparing expressions to strings.

The purpose of the string comparison override is to reliably and flexibly identify expression symbols from equivalent strings.

make_stringifier(originating_stringifier=None)

Return a LokiStringifyMapper instance that can be used to generate a human-readable representation of self.

This is used as common abstraction for the make_stringifier() method in Pymbolic expression nodes.

class TypedSymbol(*args, **kwargs)

Bases: object

Base class for symbols that carry type information.

TypedSymbol can be associated with a specific Scope in which it is declared. In that case, all type information is cached in that scope’s SymbolTable. Creating TypedSymbol without attaching it to a scope stores the type information locally.

Note

Providing scope and type overwrites the corresponding entry in the scope’s symbol table. To not modify the type information omit type or use type=None.

Objects should always be created via the factory class Variable.

Parameters:
  • name (str) – The identifier of that symbol (e.g., variable name).

  • scope (Scope) – The scope in which that symbol is declared.

  • type (optional) – The type of that symbol. Defaults to BasicType.DEFERRED.

  • parent (Scalar or Array, optional) – The derived type variable this variable belongs to.

  • case_sensitive (bool, optional) – Mark the name of this symbol as case-sensitive (default: False)

  • *args (optional) – Any other positional arguments for other parent classes

  • **kwargs (optional) – Any other keyword arguments for other parent classes

init_arg_names = ('name', 'scope', 'parent', 'type', 'case_sensitive')
property name
property scope

The object corresponding to the symbol’s scope.

property type

Internal representation of the declared data type.

property parent

Parent variable for derived type members

Returns:

The parent variable or None

Return type:

TypedSymbol or MetaSymbol or NoneType

property parents

Variables nodes for all parents

Returns:

The list of parent variables, e.g., for a variable a%b%c%d this yields the nodes corresponding to (a, a%b, a%b%c)

Return type:

tuple

property variables

List of member variables in a derived type

Returns:

List of member variables in a derived type

Return type:

tuple of TypedSymbol or MetaSymbol if derived type variable, else None

property variable_map

Member variables in a derived type variable as a map

Returns:

Map of member variable basenames to variable objects

Return type:

dict of (str, TypedSymbol or MetaSymbol)

property basename

The symbol name without the qualifier from the parent.

property name_parts

All name parts with parent qualifiers separated

clone(**kwargs)

Replicate the object with the provided overrides.

rescope(scope)

Replicate the object with a new scope

This is a bespoke variant of clone() for rescoping symbols. The difference lies in the handling of the type information, making sure not to overwrite any existing symbol table entry in the provided scope.

get_derived_type_member(name_str)

Resolve type-bound variables of arbitrary nested depth.

class DeferredTypeSymbol(name, scope=None, **kwargs)

Bases: StrCompareMixin, TypedSymbol, Variable

Internal representation of symbols with deferred type

This is used, for example, in the symbol list of Import if a symbol’s definition is not available.

Note that symbols with deferred type are assumed to be variables, which implies they are included in the result from visitors such as FindVariables.

Parameters:
  • name (str) – The name of the symbol

  • scope (Scope) – The scope in which the symbol is declared

mapper_method = 'map_deferred_type_symbol'
class VariableSymbol(*args, **kwargs)

Bases: StrCompareMixin, TypedSymbol, Variable

Expression node to represent a variable symbol

Note that this node should not be used directly to represent variables but instead meta nodes Scalar or Array (via their factory Variable) should be used.

The purpose of this is to align Loki’s “convenience layer” for expressions with Pymbolic’s expression tree structure. Loki makes variable use (especially for arrays) with or without properties (such as subscript dimensions) directly accessible from a single object, whereas Pymbolic represents array subscripts as an operation applied to a variable.

Furthermore, it adds type information via TypedSymbol.

Parameters:
property initial

Initial value of the variable in declaration.

mapper_method = 'map_variable_symbol'
class ProcedureSymbol(name, scope=None, type=None, **kwargs)

Bases: StrCompareMixin, TypedSymbol, _FunctionSymbol

Internal representation of a symbol that represents a callable subroutine or function

Parameters:
  • name (str) – The name of the symbol.

  • scope (Scope) – The scope in which the symbol is declared.

  • type (optional) – The type of that symbol. Defaults to BasicType.DEFERRED.

mapper_method = 'map_procedure_symbol'
class MetaSymbol(symbol, *args, **kwargs)

Bases: StrCompareMixin, AlgebraicLeaf

Base class for meta symbols to encapsulate a symbol node with optional enclosing operations in a unifying interface

The motivation for this class is that Loki strives to make variables and their use accessible via uniform interfaces Scalar or Array. Pymbolic’s representation of array subscripts or access to members of a derived type are represented as operations on a symbol, thus resulting in a inside-out view that has the symbol innermost.

To make it more convenient to find symbols and apply transformations on them, Loki wraps these compositions of expression tree nodes into meta nodes that store these compositions and provide direct access to properties of the contained nodes from a single object.

In the simplest case, an instance of a TypedSymbol subclass is stored as symbol and accessible via this property. Typical properties of this symbol (such as name, type, etc.) are directly accessible as properties that are redirected to the actual symbol.

For arrays, not just the TypedSymbol subclass but also an enclosing ArraySubscript may be stored inside the meta symbol, providing additionally access to the subscript dimensions. The properties are then dynamically redirected to the relevant expression tree node.

property symbol

The underlying TypedSymbol node encapsulated by this meta node

property name

The fully qualifying symbol name

For derived type members this yields parent and basename

property basename

For derived type members this yields the declared member name without the parent’s name

property name_parts
property parent

For derived type members this yields the declared parent symbol to which it belongs

property parents

Yield all parent symbols for derived type members

property scope

The scope in which the symbol was declared

Note: for imported symbols this refers to the scope into which it is imported, _not_ where it was declared.

property type

The SymbolAttributes declared for this symbol

This includes data type as well as additional properties, such as INTENT, KIND etc.

property variables

List of member variables in a derived type

Returns:

List of member variables in a derived type

Return type:

tuple of TypedSymbol or MetaSymbol if derived type variable, else None

property variable_map

Member variables in a derived type variable as a map

Returns:

Map of member variable basenames to variable objects

Return type:

dict of (str, TypedSymbol or MetaSymbol)

property initial

Initial value of the variable in a declaration, if given

mapper_method = 'map_meta_symbol'
make_stringifier(originating_stringifier=None)

Return a LokiStringifyMapper instance that can be used to generate a human-readable representation of self.

This is used as common abstraction for the make_stringifier() method in Pymbolic expression nodes.

property init_arg_names
clone(**kwargs)

Replicate the object with the provided overrides.

rescope(scope)

Replicate the object with a new scope

This is a bespoke variant of clone() for rescoping symbols. The difference lies in the handling of the type information, making sure not to overwrite any existing symbol table entry in the provided scope.

property case_sensitive

Property to indicate that the name of this symbol is case-sensitive.

get_derived_type_member(name_str)

Resolve type-bound variables of arbitrary nested depth.

class Scalar(name, scope=None, type=None, **kwargs)

Bases: MetaSymbol

Expression node for scalar variables.

See MetaSymbol for a description of meta symbols.

Parameters:
  • name (str) – The name of the variable.

  • scope (Scope) – The scope in which the variable is declared.

  • type (optional) – The type of that symbol. Defaults to BasicType.DEFERRED.

mapper_method = 'map_scalar'
class Array(name, scope=None, type=None, dimensions=None, **kwargs)

Bases: MetaSymbol

Expression node for array variables.

Similar to Scalar with the notable difference that it has a shape (stored in type) and can have associated dimensions (i.e., the array subscript for indexing/slicing when accessing entries).

See MetaSymbol for a description of meta symbols.

Parameters:
  • name (str) – The name of the variable.

  • scope (Scope) – The scope in which the variable is declared.

  • type (optional) – The type of that symbol. Defaults to BasicType.DEFERRED.

  • dimensions (ArraySubscript, optional) – The array subscript expression.

property name_parts
property symbol

The underlying TypedSymbol node encapsulated by this meta node

property dimensions

Symbolic representation of the dimensions or indices.

property shape

Original allocated shape of the variable as a tuple of dimensions.

property init_arg_names
mapper_method = 'map_array'
clone(**kwargs)

Replicate the Array variable with the provided overrides.

Note, if dimensions is set to None and type updated to have no shape, this will create a Scalar variable.

rescope(scope)

Replicate the object with a new scope

This is a bespoke variant of clone() for rescoping symbols. The difference lies in the handling of the type information, making sure not to overwrite any existing symbol table entry in the provided scope.

class Variable(**kwargs)

Bases: object

Factory class for TypedSymbol or MetaSymbol classes

This is a convenience constructor to provide a uniform interface for instantiating different symbol types. It checks the symbol’s type (either the provided type or via a lookup in scope) and dimensions and dispatches the relevant class constructor.

The tier algorithm is as follows:

  1. type.dtype is ProcedureType: Instantiate a ProcedureSymbol;

  2. dimensions is not None or type.shape is not None: Instantiate an Array;

  3. type.dtype is not BasicType.DEFERRED: Instantiate a Scalar;

  4. None of the above: Instantiate a DeferredTypeSymbol

All objects created by this factory implement TypedSymbol. A TypedSymbol object can be associated with a specific Scope in which it is declared. In that case, all type information is cached in that scope’s SymbolTable. Creating TypedSymbol without attaching it to a scope stores the type information locally.

Note

Providing scope and type overwrites the corresponding entry in the scope’s symbol table. To not modify the type information omit type or use type=None.

Note that all TypedSymbol and MetaSymbol classes are intentionally quasi-immutable: Changing any of their attributes, including attaching them to a scope and modifying their type, should always be done via the clone() method:

var = Variable(name='foo')
var = var.clone(scope=scope, type=SymbolAttributes(BasicType.INTEGER))
var = var.clone(type=var.type.clone(dtype=BasicType.REAL))

Attaching a symbol to a new scope without updating any stored type information (but still inserting type information if it doesn’t exist, yet), can be done via the dedicated rescope() method. This is essentially a clone() invocation but without the type update:

var = Variable(name='foo', type=SymbolAttributes(BasicType.INTEGER), scope=scope)
unscoped_var = Variable(name='foo', type=SymbolAttributes(BasicType.REAL))
scoped_var = unscoped_var.rescope(scope)  # scoped_var will have INTEGER type
Parameters:
  • name (str) – The name of the variable.

  • scope (Scope) – The scope in which the variable is declared.

  • type (optional) – The type of that symbol. Defaults to BasicType.DEFERRED.

  • parent (Scalar or Array, optional) – The derived type variable this variable belongs to.

  • dimensions (ArraySubscript, optional) – The array subscript expression.

class FloatLiteral(value, **kwargs)

Bases: StrCompareMixin, _Literal

A floating point constant in an expression.

Note that its value is stored as a string to avoid any representation issues that could stem from converting it to a Python floating point number.

It can have a specific type associated, which backends can use to cast or annotate the constant to make sure the specified type is used.

Parameters:
  • value (str) – The value of that literal.

  • kind (optional) – The kind information for that literal.

init_arg_names = ('value', 'kind')
mapper_method = 'map_float_literal'
class IntLiteral(value, **kwargs)

Bases: StrCompareMixin, _Literal

An integer constant in an expression.

It can have a specific type associated, which backends can use to cast or annotate the constant to make sure the specified type is used.

Parameters:
  • value (int) – The value of that literal.

  • kind (optional) – The kind information for that literal.

init_arg_names = ('value', 'kind')
mapper_method = 'map_int_literal'
class LogicLiteral(value, **kwargs)

Bases: StrCompareMixin, _Literal

A boolean constant in an expression.

Parameters:

value (bool) – The value of that literal.

init_arg_names = ('value',)
mapper_method = 'map_logic_literal'
class StringLiteral(value, **kwargs)

Bases: StrCompareMixin, _Literal

A string constant in an expression.

Parameters:

value (str) – The value of that literal. Enclosing quotes are removed.

init_arg_names = ('value',)
mapper_method = 'map_string_literal'
class IntrinsicLiteral(value, **kwargs)

Bases: StrCompareMixin, _Literal

Any literal not represented by a dedicated class.

Its value is stored as string and returned unaltered. This is currently used for complex and BOZ constants and to retain array constructor expressions with type spec or implied-do.

Parameters:

value (str) – The value of that literal.

init_arg_names = ('value',)
mapper_method = 'map_intrinsic_literal'
class Literal(value, **kwargs)

Bases: object

Factory class to instantiate the best-matching literal node.

This always returns a IntLiteral, FloatLiteral, StringLiteral, LogicLiteral or, as a fallback, IntrinsicLiteral, selected by using any provided type information or inspecting the Python data type of :data: value.

Parameters:
  • value – The value of that literal.

  • kind (optional) – The kind information for that literal.

class LiteralList(values, dtype=None, **kwargs)

Bases: AlgebraicLeaf

A list of constant literals, e.g., as used in Array Initialization Lists.

mapper_method = 'map_literal_list'
make_stringifier(originating_stringifier=None)

Return a LokiStringifyMapper instance that can be used to generate a human-readable representation of self.

This is used as common abstraction for the make_stringifier() method in Pymbolic expression nodes.

class InlineDo(values, variable, bounds, **kwargs)

Bases: AlgebraicLeaf

An inlined do, e.g., implied-do as used in array constructors

mapper_method = 'map_inline_do'
make_stringifier(originating_stringifier=None)

Return a LokiStringifyMapper instance that can be used to generate a human-readable representation of self.

This is used as common abstraction for the make_stringifier() method in Pymbolic expression nodes.

class Sum(children)

Bases: StrCompareMixin, Sum

Representation of a sum.

class Product(children)

Bases: StrCompareMixin, Product

Representation of a product.

class Quotient(numerator, denominator=1)

Bases: StrCompareMixin, Quotient

Representation of a quotient.

class Power(base, exponent)

Bases: StrCompareMixin, Power

Representation of a power.

class Comparison(left, operator, right)

Bases: StrCompareMixin, Comparison

Representation of a comparison operation.

class LogicalAnd(children)

Bases: StrCompareMixin, LogicalAnd

Representation of an ‘and’ in a logical expression.

class LogicalOr(children)

Bases: StrCompareMixin, LogicalOr

Representation of an ‘or’ in a logical expression.

class LogicalNot(child)

Bases: StrCompareMixin, LogicalNot

Representation of a negation in a logical expression.

class InlineCall(function, parameters=None, kw_parameters=None, **kwargs)

Bases: CallWithKwargs

Internal representation of an in-line function call.

init_arg_names = ('function', 'parameters', 'kw_parameters')
mapper_method = 'map_inline_call'
make_stringifier(originating_stringifier=None)

Return a LokiStringifyMapper instance that can be used to generate a human-readable representation of self.

This is used as common abstraction for the make_stringifier() method in Pymbolic expression nodes.

property name
property procedure_type

Returns the underpinning procedure type if the type is know, BasicType.DEFFERED otherwise.

property arguments

Alias for parameters

property kwarguments

Alias for kw_parameters

property routine

The Subroutine object of the called routine

Shorthand for call.function.type.dtype.procedure

Returns:

If the ProcedureType object of the ProcedureSymbol in function is linked up to the target routine, this returns the corresponding Subroutine object, otherwise None.

Return type:

Subroutine or BasicType.DEFERRED

arg_iter()

Iterator that maps argument definitions in the target Subroutine to arguments and keyword arguments in the call.

Returns:

An iterator that traverses the mapping (arg name, call arg) for all positional and then keyword arguments.

Return type:

iterator

clone(**kwargs)

Replicate the object with the provided overrides.

class Cast(name, expression, kind=None, **kwargs)

Bases: Call

Internal representation of a data type cast.

mapper_method = 'map_cast'
property name
class Range(children, **kwargs)

Bases: StrCompareMixin, Slice

Internal representation of a loop or index range.

mapper_method = 'map_range'
property lower
property upper
class LoopRange(children, **kwargs)

Bases: Range

Internal representation of a loop range.

mapper_method = 'map_loop_range'
class RangeIndex(children, **kwargs)

Bases: Range

Internal representation of a subscript range.

mapper_method = 'map_range_index'
class ArraySubscript(aggregate, index)

Bases: StrCompareMixin, Subscript

Internal representation of an array subscript.

mapper_method = 'map_array_subscript'
class StringSubscript(aggregate, index)

Bases: StrCompareMixin, Subscript

Internal representation of a substring subscript operator.

mapper_method = 'map_string_subscript'
property symbol
class Reference(expression)

Bases: Expression

Internal representation of a Reference.

Warning

Experimental! Allowing compound Reference(Variable(...)) to appear with behaviour akin to a symbol itself for easier processing in mappers.

C/C++ only, no corresponding concept in Fortran. Referencing refers to taking the address of an existing variable (to set a pointer variable).

init_arg_names = ('expression',)
property name

Allowing the compound Reference(Variable(name)) to appear with behaviour akin to a symbol itself for easier processing in mappers.

property type

Allowing the compound Reference(Variable(type)) to appear with behaviour akin to a symbol itself for easier processing in mappers.

property scope

Allowing the compound Reference(Variable(scope)) to appear with behaviour akin to a symbol itself for easier processing in mappers.

property initial

Allowing the compound Reference(Variable(initial)) to appear with behaviour akin to a symbol itself for easier processing in mappers.

mapper_method = 'map_c_reference'
make_stringifier(originating_stringifier=None)

Return a LokiStringifyMapper instance that can be used to generate a human-readable representation of self.

This is used as common abstraction for the make_stringifier() method in Pymbolic expression nodes.

class Dereference(expression)

Bases: Expression

Internal representation of a Dereference.

Warning

Experimental! Allowing compound Dereference(Variable(...)) to appear with behaviour akin to a symbol itself for easier processing in mappers.

C/C++ only, no corresponding concept in Fortran. Dereferencing (a pointer) refers to retrieving the value from a memory address (that is pointed by the pointer).

init_arg_names = ('expression',)
property name

Allowing the compound Dereference(Variable(name)) to appear with behaviour akin to a symbol itself for easier processing in mappers.

property type

Allowing the compound Dereference(Variable(type)) to appear with behaviour akin to a symbol itself for easier processing in mappers.

property scope

Allowing the compound Dereference(Variable(scope)) to appear with behaviour akin to a symbol itself for easier processing in mappers.

property initial

Allowing the compound Dereference(Variable(initial)) to appear with behaviour akin to a symbol itself for easier processing in mappers.

mapper_method = 'map_c_dereference'
make_stringifier(originating_stringifier=None)

Return a LokiStringifyMapper instance that can be used to generate a human-readable representation of self.

This is used as common abstraction for the make_stringifier() method in Pymbolic expression nodes.