psyclone.core

This module provides access to various classes used in determining variable access information.

Submodules

Classes

  • AccessInfo: This class stores information about a single access

  • AccessType: A simple enum-class for the various valid access types.

  • ComponentIndices: This class stores index information for variable accesses. It stores

  • Signature: Given a variable access of the form a(i,j)%b(k,l)%c, the signature

  • SingleVariableAccessInfo: This class stores a list with all accesses to one variable.

  • SymbolicMaths: A wrapper around the symbolic maths package ‘sympy’. It

  • VariablesAccessInfo: This class stores all SingleVariableAccessInfo instances for all

class psyclone.core.AccessInfo(access_type, location, node, component_indices=None)

This class stores information about a single access pattern of one variable (e.g. variable is read at a certain location). A location is a number which can be used to compare different accesses (i.e. if one access happens before another). Each consecutive location will have an increasing location number, but read and write accesses in the same statement will have the same location number. If the variable accessed is an array, this class will also store the indices used in the access. Note that the name of the variable is not stored in this class. It is a helper class used in the SingleVariableAccessInfo class, which stores all AccessInfo objects for a variable, and it stores the name of the variable.

Parameters:

Inheritance

Inheritance diagram of AccessInfo
property access_type
Returns:

the access type.

Return type:

psyclone.core.access_type.AccessType

change_read_to_write()

This changes the access mode from READ to WRITE. This is used for processing assignment statements, where the LHS is first considered to be READ, and which is then changed to be WRITE.

Raises:

InternalError – if the variable originally does not have READ access.

property component_indices

This function returns the list of accesses used for each component as an instance of ComponentIndices. For example, a(i)%b(j,k)%c will return an instance of ComponentIndices representing [ [i], [j, k], [] ]. In the case of a simple scalar variable such as a, the component_indices will represent [ [] ].

Returns:

the indices used in this access for each component.

Return type:

psyclone.core.component_indices.ComponentIndices

is_array()

Test if any of the components has an index. E.g. an access like a(i)%b would still be considered an array.

Returns:

if any of the variable components uses an index, i.e. the variable is an array.

Return type:

bool

property location
Returns:

the location information for this access. Please see the Developers’ Guide for more information.

Return type:

int

property node
Returns:

the PSyIR node at which this access happens.

Return type:

psyclone.psyir.nodes.Node

class psyclone.core.AccessType(value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None)

A simple enum-class for the various valid access types.

Inheritance

Inheritance diagram of AccessType
static all_read_accesses()
Returns:

A list of all access types that involve reading an argument in some form.

Return type:

List of py:class:psyclone.core.access_type.AccessType.

static all_write_accesses()
Returns:

A list of all access types that involve writing to an argument in some form.

Return type:

List of py:class:psyclone.core.access_type.AccessType.

api_specific_name()

This convenience function returns the name of the type in the current API. E.g. in a dynamo0.3 API, WRITE –> “gh_write” :returns: The API specific name. :rtype: str

static from_string(access_string)

Convert a string (e.g. “read”) into the corresponding AccessType enum value (AccessType.READ).

Parameters:

access_string (str) – Access type as string.

Returns:

Corresponding AccessType enum.

Raises:

ValueError if access_string is not a valid access type.

static get_valid_reduction_modes()
Returns:

A list of valid reduction access modes.

Return type:

List of py:class:psyclone.core.access_type.AccessType.

static get_valid_reduction_names()
Returns:

A list of valid reduction access names.

Return type:

List of strings.

class psyclone.core.ComponentIndices(indices=None)

This class stores index information for variable accesses. It stores one index list for each component of a variable, e.g. for a(i)%b(j) it would store [ [i], [j] ]. Even for scalar accesses an empty list is stored, so a would have the component indices [ [] ], and a%b would have [ [], [] ]. Each member of this list of lists is the PSyIR node describing the array expression used.

As a shortcut, the indices parameter can be None or an empty list (which then creates the component indices as [[]], i.e. indicating a scalar access), a list l (which will then create the component indices as [l], i.e. a single component variable, which uses all the indices in the list l as array indices).

TODO #845 - the constructor should check that the things it is passed are PSyIR nodes. Currently it is sometimes given strings.

Parameters:

indices (None, [], a list or a list of lists of psyclone.psyir.nodes.Node) – the indices from which to create this object.

Raises:
  • InternalError – if the indices parameter is not None, a list or a list of lists.

  • InternalError – if the indices parameter is a list, and some but not all members are a list.

Inheritance

Inheritance diagram of ComponentIndices
get_subscripts_of(set_of_vars)

This function returns a flat list of which variable from the given set of variables is used in each subscript. For example, the access a(i+i2)%b(j*j+k,k)%c(l,5) would have the component_indices [[i+i2], [j*j+k,k], [l,5]]. If the set of variables is (i,j,k), then get_subscripts_of would return [{i},{j,k},{k},{l},{}].

Parameters:

set_of_vars (Set[str]) – set with name of all variables.

Returns:

a list of sets with all variables used in the corresponding array subscripts as strings.

Return type:

List[Set[str]]

property indices_lists
Returns:

the component indices list of lists.

Return type:

list of list of psyclone.psyir.nodes.Node

is_array()

Test whether there is an index used in any component. E.g. an access like a(i)%b with indices [ [i], [] ] would still be considered an array.

Returns:

whether any of the variable components uses an index, i.e. the variable is an array.

Return type:

bool

iterate()

Allows iterating over all component indices. It returns a tuple with two elements, the first one indicating the component, the second the dimension for which the index is. The return tuple can be used in a dictionary access (see __getitem__) of this object.

Returns:

a tuple of the component index and index.

Return type:

tuple(int, int)

class psyclone.core.Signature(variable, sub_sig=None)

Given a variable access of the form a(i,j)%b(k,l)%c, the signature of this access is the tuple (a,b,c). For a simple scalar variable a the signature would just be (a,). The signature is the key used in VariablesAccessInfo. In order to make sure two different signature objects containing the same variable can be used as a key, this class implements __hash__ and other special functions. The constructor also supports appending an existing signature to this new signature using the sub_sig argument. This is used in StructureReference to assemble the overall signature of a structure access.

Parameters:
  • variable (str or tuple of str or list of str) – the variable that is accessed.

  • sub_sig (psyclone.core.Signature) – a signature that is to be added to this new signature.

Inheritance

Inheritance diagram of Signature
property is_structure
Returns:

True if this signature represents a structure.

Return type:

bool

to_language(component_indices=None, language_writer=None)

Converts this signature with the provided indices to a string in the selected language.

TODO 1320 This subroutine can be removed when we stop supporting strings - then we can use a PSyIR writer for the ReferenceNode to provide the right string.

Parameters:
Raises:

InternalError – if the number of components in this signature is different from the number of indices in component_indices.

property var_name
Returns:

the actual variable name, i.e. the first component of the signature.

Return type:

str

class psyclone.core.SingleVariableAccessInfo(signature)

This class stores a list with all accesses to one variable.

Parameters:

signature (psyclone.core.Signature) – signature of the variable.

Inheritance

Inheritance diagram of SingleVariableAccessInfo
add_access_with_location(access_type, location, node, component_indices)

Adds access information to this variable.

Parameters:
property all_accesses
Returns:

a list with all AccessInfo data for this variable.

Return type:

List[psyclone.core.AccessInfo]

property all_read_accesses
Returns:

a list with all AccessInfo data for this variable that involve reading this variable.

Return type:

List[psyclone.core.AccessInfo]

property all_write_accesses
Returns:

a list with all AccessInfo data for this variable that involve writing this variable.

Return type:

List[psyclone.core.AccessInfo]

change_read_to_write()

This function is only used when analysing an assignment statement. The LHS has first all variables identified, which will be READ. This function is then called to change the assigned-to variable on the LHS to from READ to WRITE. Since the LHS is stored in a separate SingleVariableAccessInfo class, it is guaranteed that there is only one entry for the variable.

has_read_write()

Checks if this variable has at least one READWRITE access.

Returns:

True if this variable is read (at least once).

Return type:

bool

is_accessed_before(reference)

Returns True if this variable is accessed before the specified reference, and False if not. This is equivalent to testing that ‘reference’ is the very first access, but this function will also verify that ‘reference’ is indeed in the list of accesses.

Parameters:

reference (psyclone.psyir.nodes.Reference) – the reference at which to stop for access checks.

Returns:

True if this variable is read before the specified reference, and False if not.

Return type:

bool

Raises:

ValueError – if the specified reference is not in the list of all accesses.

is_array(index_variable=None)

Checks if the variable is used as an array, i.e. if it has an index expression. If the optional index_variable is specified, this variable must be used in (at least one) index access in order for this variable to be considered as an array.

Parameters:

index_variable (str) – only considers this variable to be used as array if there is at least one access using this index_variable.

Returns:

true if there is at least one access to this variable that uses an index.

Return type:

bool

is_read()
Returns:

True if this variable is read (at least once).

Return type:

bool

is_read_before(reference)

Returns True if this variable is read before the specified reference, and False if not.

Parameters:

reference (psyclone.psyir.nodes.Reference) – the reference at which to stop for access checks.

Returns:

True if this variable is read before the specified reference, and False if not.

Return type:

bool

Raises:

ValueError – if the specified reference is not in the list of all accesses.

is_read_only()

Checks if this variable is always read, and never written.

Returns:

True if this variable is read only.

Return type:

bool

is_written()
Returns:

True if this variable is written (at least once).

Return type:

bool

is_written_before(reference)

Returns True if this variable is written before the specified reference, and False if not.

Parameters:

reference (psyclone.psyir.nodes.Reference) – the reference at which to stop for access checks.

Returns:

True if this variable is written before the specified reference, and False if not.

Return type:

bool

Raises:

ValueError – if the specified reference is not in the list of all accesses.

is_written_first()
Returns:

True if this variable is written in the first access (which indicates that this variable is not an input variable for a kernel).

Return type:

bool

property signature
Returns:

the signature for which the accesses are stored.

Return type:

psyclone.core.Signature

property var_name
Returns:

the name of the variable whose access info is managed.

Return type:

str

class psyclone.core.SymbolicMaths

A wrapper around the symbolic maths package ‘sympy’. It provides convenience functions for PSyclone. It has a Singleton access, e.g.:

>>> from psyclone.psyir.backend.fortran import FortranWriter
>>> from psyclone.core import SymbolicMaths
>>> sympy = SymbolicMaths.get()
>>> # Assume lhs is the PSyIR of 'i+j', and rhs is 'j+i'
>>> if sympy.equal(lhs, rhs):
...     writer = FortranWriter()
...     print(f"'{writer(lhs)}' and '{writer(rhs)}' are equal.")
'i + j' and 'j + i' are equal.

Inheritance

Inheritance diagram of SymbolicMaths
static equal(exp1, exp2)

Test if the two PSyIR expressions are symbolically equivalent.

Parameters:
Returns:

whether the two expressions are mathematically identical.

Return type:

bool

static expand(expr)

Expand a PSyIR expression. This is done by converting the PSyIR expression to a sympy expression, applying the expansion operation and then converting the resultant output back into PSyIR.

Currently does not work if the PSyIR expression contains Range nodes, see issue #1655.

Parameters:

expr (psyclone.psyir.nodes.Node) – the expression to be expanded.

static get()

Static function that creates (if necessary) and returns the singleton SymbolicMaths instance.

Returns:

the instance of the symbolic maths class.

Return type:

psyclone.core.SymbolicMaths

static never_equal(exp1, exp2)

Returns if the given SymPy expressions are guaranteed to be different regardless of the values of symbolic variables. E.g. n-1 and n are always different, but 5 and n are not always different.

Parameters:
Returns:

whether or not the expressions are never equal.

Return type:

bool

static solve_equal_for(exp1, exp2, symbol)

Returns all solutions of exp1==exp2, solved for the specified symbol. It restricts the solution domain to integer values. If there is an infinite number of solutions, it returns the string ‘independent’, indicating that the solution of exp1==exp2 does not depend on the specified symbol. This is done to avoid that the SymPy instance representing an infinite set is used elsewhere in PSyclone (i.e. creating a dependency in other modules to SymPy). Otherwise a standard Python set is returned that stores the solutions.

Parameters:
  • exp1 (sympy.core.basic.Basic) – the first expression.

  • exp2 (sympy.core.basic.Basic) – the second expression.

  • symbol (sympy.core.symbol.Symbol) – the symbol for which to solve.

Returns:

a set of solutions, or the string “independent”.

Return type:

Union[set, str]

class psyclone.core.VariablesAccessInfo(nodes=None, options=None)

This class stores all SingleVariableAccessInfo instances for all variables in the corresponding code section. It maintains ‘location’ information, which is an integer number that is increased for each new statement. It can be used to easily determine if one access is before another.

Parameters:
  • nodes (Optional[psyclone.psyir.nodes.Node | List[psyclone.psyir.nodes.Node]]) – optional, a single PSyIR node or list of nodes from which to initialise this object.

  • options (Dict[str, Any]) – a dictionary with options to influence which variable accesses are to be collected.

  • options["COLLECT-ARRAY-SHAPE-READS"] (Any) – if this option is set to a True value, arrays used as first parameter to the PSyIR query operators lbound, ubound, or size will be reported as ‘read’. Otherwise, these accesses will be ignored.

  • options["USE-ORIGINAL-NAMES"] (Any) – if this option is set to a True value, an imported symbol that is renamed (use mod, a=>b) will be reported using the original name (b in the example). Otherwise these symbols will be reported using the renamed name (a).

Raises:

Inheritance

Inheritance diagram of VariablesAccessInfo
add_access(signature, access_type, node, component_indices=None)

Adds access information for the variable with the given signature. If the component_indices parameter is not an instance of ComponentIndices, it is used to construct an instance. Therefore it can be None, a list or a list of lists of PSyIR nodes. In the case of a list of lists, this will be used unmodified to construct the ComponentIndices structures. If it is a simple list, it is assumed that it contains the indices used in accessing the last component of the signature. For example, for a%b with component_indices=[i,j], it will create [[], [i,j] as component indices, indicating that no index is used in the first component a. If the access is supposed to be for a(i)%b(j), then the component_indices argument must be specified as a list of lists, i.e. [[i], [j]].

Parameters:
property all_signatures
Returns:

all signatures contained in this instance, sorted (in order to make test results reproducible).

Return type:

List[psyclone.core.signature]

has_read_write(signature)

Checks if the specified variable signature has at least one READWRITE access (which is typically only used in a function call).

Parameters:

signature (psyclone.core.Signature) – signature of the variable

Returns:

True if the specified variable name has (at least one) READWRITE access.

Return type:

bool

Raises:

KeyError if the signature cannot be found.

is_read(signature)

Checks if the specified variable signature is at least read once.

Parameters:

signature (psyclone.core.Signature) – signature of the variable

Returns:

True if the specified variable name is read (at least once).

Return type:

bool

Raises:

KeyError if the signature cannot be found.

is_written(signature)

Checks if the specified variable signature is at least written once.

Parameters:

signature (psyclone.core.Signature) – signature of the variable.

Returns:

True if the specified variable is written (at least once).

Return type:

bool

Raises:

KeyError if the signature name cannot be found.

property location

Returns the current location of this instance, which is the location at which the next accesses will be stored. See the Developers’ Guide for more information.

Returns:

the current location of this object.

Return type:

int

merge(other_access_info)

Merges data from a VariablesAccessInfo instance to the information in this instance.

Parameters:

other_access_info (psyclone.core.VariablesAccessInfo) – the other VariablesAccessInfo instance.

next_location()

Increases the location number.

options(key=None)

Returns the value of the options for a specified key, or None if the key is not specified in the options. If no key is specified, the whole option dictionary is returned.

Parameters:

key (Optional[str]) – the option to query, or None if all options should be returned.

Returns:

the value of the option associated with the provided key or the whole option dictionary if it is not supplied.

Return type:

Union[None, Any, dict]

Raises:

InternalError – if an invalid key is specified.