# loki.expression.symbols module

Expression tree node classes for Expression tree.

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:

    - name (str) – The name of the variable.

    - scope (`Scope`, optional) – The scope in which the variable is declared.

    - type (`SymbolAttributes`, optional) – The type of that symbol. Defaults to `SymbolAttributes` with `BasicType.DEFERRED`.

  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 DerivedTypeSymbol(name, scope=None, type=None, **kwargs)

  Bases: `StrCompareMixin`, `TypedSymbol`, `_FunctionSymbol`

  Internal representation of a symbol that represents a named derived type.

  This is used to represent the derived type symbolically in `Import` statements and when defining derived types.

  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_derived_type_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.

  init_arg_names = ('values', 'dtype')
  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

  property arg_map

    A full map of all qualified argument matches from arguments and keyword arguments.

    Returns:

      An dictionary that mapping `arg name: call arg` for all positional and then keyword arguments.

    Return type:

      dict

  clone(**kwargs)

    Replicate the object with the provided overrides.

  is_kwargs_order_correct()

    Check whether kwarguments/kw_parameters are correctly ordered in respect to the arguments (`self.routine.arguments`).

  clone_with_sorted_kwargs()

    Sort and update the kwarguments/kw_parameters according to the order of the arguments (`self.routine.arguments`) and return the conveted clone/copy of the inline call.

  clone_with_kwargs_as_args()

    Convert all kwarguments/kw_parameters to arguments and return the converted clone/copy of the inline call.

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

  Bases: `Call`

  Internal representation of a data type cast.

  init_arg_names = ('name', 'expression', 'kind')
  mapper_method = 'map_cast'
  property name
  property expression

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'
  property num_iterations: Expression

    Returns total number of iterations of a loop.

    Given a loop, this returns an expression that computes the total number of iterations of the loop, i.e. (start,stop,step) -> ceil(stop-start/step)

  property normalized

    Returns the normalized `LoopRange` of a given `LoopRange`.

    Returns the normalized `LoopRange` which corresponds to a loop with the same number of iterations but starts at 1 and has stride 1, i.e. (start,stop,step) -> (1,num_iterations,1)

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.