psyclone.psyir.nodes.node

This module contains the abstract Node implementation as well as ChildrenList - a custom implementation of list.

Functions

  • colored(): Returns the supplied text argument unchanged. This is a swap-in

psyclone.psyir.nodes.node.colored(text, _)

Returns the supplied text argument unchanged. This is a swap-in replacement for when termcolor.colored is not available.

Parameters:
  • text (str) – text to return.

  • _ – fake argument, only required to match interface provided by termcolor.colored.

Returns:

the supplied text, unchanged.

Return type:

str

Classes

  • ChildrenList: Customized list to keep track of the children nodes. It is initialised with

  • Node: Base class for a PSyIR node.

class psyclone.psyir.nodes.node.ChildrenList(node, validation_function, validation_text)

Customized list to keep track of the children nodes. It is initialised with a callback function that allows the validation of the inserted children. Since this is a subclass of the standard list, all operations (e.g. append, insert, extend, comparisons, list arithmetic operations) are conserved and make use of the validation. They also trigger an update of all ancestor nodes so that action can be taken in order to keep the tree consistent when necessary (e.g. to update the data-movement clauses on an OpenACC data region).

Parameters:
  • node (psyclone.psyir.nodes.Node) – reference to the node where the list belongs.

  • validation_function (function(int, psyclone.psyir.nodes.Node)) – callback function to the validation method.

  • validation_text (str) – textual representation of the valid children.

Inheritance

Inheritance diagram of ChildrenList
append(item)

Extends list append method with children node validation.

Parameters:

item (psyclone.psyir.nodes.Node) – item to be appened to the list.

clear()

Wipes the list.

extend(items)

Extends list extend method with children node validation.

Parameters:

items (list of psyclone.psyir.nodes.Node) – list of items to be appened to the list.

insert(index, item)

Extends list insert method with children node validation.

Parameters:
pop(index=-1)

Extends list pop method with children node validation.

Parameters:

index (int) – position of the item that is popped out, if not given, the last element is popped out.

Returns:

the last value or the given index value from the list.

Return type:

psyclone.psyir.nodes.Node

remove(item)

Extends list remove method with children node validation.

Parameters:

item (psyclone.psyir.nodes.Node) – item to be deleted the list.

reverse()

Extends list reverse method with children node validation.

sort(reverse=False, key=None)

Override the default sort() implementation as this is not supported for a ChildrenList.

Raises:

NotImplementedError – it makes no sense to sort the Children of a Node.

class psyclone.psyir.nodes.node.Node(ast=None, children=None, parent=None, annotations=None)

Base class for a PSyIR node.

Parameters:
  • ast (sub-class of fparser.two.Fortran2003.Base) – reference into the fparser2 AST corresponding to this node.

  • children (list of psyclone.psyir.nodes.Node) – the PSyIR nodes that are children of this node.

  • parent (psyclone.psyir.nodes.Node) – that parent of this node in the PSyIR tree.

  • annotations (list of str) – Tags that provide additional information about the node. The node should still be functionally correct when ignoring these tags.

Raises:
  • TypeError – if a parent is supplied that is not an instance of Node.

  • InternalError – if an invalid annotation tag is supplied.

Inheritance

Inheritance diagram of Node
property abs_position

Find a Node’s absolute position in the tree (starting with 0 if it is the root). Needs to be computed dynamically from the starting position (0) as its position may change.

Returns:

absolute position of a Node in the tree.

Return type:

int

Raises:

InternalError – if the absolute position cannot be found.

addchild(child, index=None)

Adds the supplied node as a child of this node (at position index if supplied). The supplied node must not have an existing parent.

Parameters:
  • child (psyclone.psyir.nodes.Node) – the node to add as a child of this one.

  • index (Optional[int]) – optional position at which to insert new child. Default is to append new child to the list of existing children.

ancestor(my_type, excluding=None, include_self=False, limit=None, shared_with=None)

Search back up the tree and check whether this node has an ancestor that is an instance of the supplied type. If it does then we return it otherwise we return None. An individual (or tuple of) (sub-) class(es) to ignore may be provided via the excluding argument. If include_self is True then the current node is included in the search. If limit is provided then the search ceases if/when the supplied node is encountered. If shared_with is provided, then the ancestor search will find an ancestor of both this node and the node provided as shared_with if such an ancestor exists.

Parameters:
  • my_type (type | Tuple[type, ...]) – class(es) to search for.

  • excluding (Optional[type | Tuple[type, ...]]) – (sub-)class(es) to ignore or None.

  • include_self (bool) – whether or not to include this node in the search.

  • limit (Optional[psyclone.psyir.nodes.Node]) – an optional node at which to stop the search.

  • shared_with (Optional[psyclone.psyir.nodes.Node]) – an optional node which must also have the found node as an ancestor.

Returns:

First ancestor Node that is an instance of any of the requested classes or None if not found.

Return type:

Optional[psyclone.psyir.nodes.Node]

Raises:
  • TypeError – if excluding is provided but is not a type or tuple of types.

  • TypeError – if limit is provided but is not an instance of Node.

property annotations

Return the list of annotations attached to this Node.

Returns:

List of anotations

Return type:

list of str

property args

Return the list of arguments associated with this Node. The default implementation assumes the Node has no directly associated arguments (i.e. is not a Kern class or subclass). Arguments of any of this nodes descendants are considered to be associated.

property ast
Returns:

a reference to that part of the fparser2 parse tree that this node represents or None.

Return type:

sub-class of fparser.two.utils.Base

property ast_end
Returns:

a reference to the last node in the fparser2 parse tree that represents a child of this PSyIR node or None.

Return type:

sub-class of fparser.two.utils.Base

backward_dependence()

Returns the closest preceding Node that this Node has a direct dependence with or None if there is not one. Only Nodes with the same parent as self are returned. Nodes inherit their descendants’ dependencies. The reason for this is that for correctness a node must maintain its parent if it is moved. For example a halo exchange and a kernel call may have a dependence between them but it is the loop body containing the kernel call that the halo exchange must not move beyond i.e. the loop body inherits the dependencies of the routines within it.

property children
Returns:

the immediate children of this Node.

Return type:

List[psyclone.psyir.nodes.Node]

coded_kernels()

Returns a list of all of the user-supplied kernels (as opposed to builtins) that are beneath this node in the PSyIR.

Returns:

all user-supplied kernel calls below this node.

Return type:

List[psyclone.psyGen.CodedKern]

coloured_name(colour=True)

Returns the display name of this Node, optionally with colour control codes (requires that the termcolor package be installed).

Parameters:

colour (bool) – whether or not to include colour control codes in the result.

Returns:

the name of this node, optionally with colour control codes.

Return type:

str

copy()

Return a copy of this node. This is a bespoke implementation for PSyIR nodes that will deepcopy some of its recursive data-structure (e.g. the children tree), while not copying other attributes (e.g. top-level parent reference).

Returns:

a copy of this node and its children.

Return type:

psyclone.psyir.node.Node

dag(file_name='dag', file_format='svg')

Create a dag of this node and its children, write it to file and return the graph object.

Parameters:
  • file_name (str) – name of the file to create.

  • file_format (str) – format of the file to create. (Must be one recognised by Graphviz.)

Returns:

the graph object or None (if the graphviz bindings are not installed).

Return type:

graphviz.Digraph or NoneType

Raises:

GenerationError – if the specified file format is not recognised by Graphviz.

dag_gen(graph)

Output my node’s graph (dag) information and call any children. Nodes with children are represented as two vertices, a start and an end. Forward dependencies are represented as green edges, backward dependencies are represented as red edges (but their direction is reversed so the layout looks reasonable) and parent child dependencies are represented as blue edges.

property dag_name

Return the dag name for this node. This includes the name of the class and the index of its relative position to the parent Routine. If no parent Routine is found, the index used is the absolute position in the tree.

Returns:

the dag name for this node.

Return type:

str

debug_string()

Generates a Fortran-like output representation but without lowering high-level nodes. This is fast to generate because it doesn’t deepcopy the tree like the Language backends and its output, although not compilable, is readable for error messages.

Returns:

a Fortran-like output representation of the tree.

Return type:

str

property depth

Returns this Node’s depth in the tree: 1 for the Schedule and increasing for its descendants at each level. :returns: depth of the Node in the tree :rtype: int

detach()

Detach this node from the tree it belongs to. This is necessary as a precursor to inserting it as the child of another node.

Returns:

this node detached from its parent.

Return type:

psyclone.psyir.node.Node

following(routine=True)

Return all psyclone.psyir.nodes.Node nodes after this node. Ordering is depth first. If the routine argument is set to True then nodes are only returned if they are descendents of this node’s closest ancestor routine if one exists.

Parameters:

routine (bool) – an optional (default True) argument that only returns nodes that are within this node’s closest ancestor Routine node if one exists.

Returns:

a list of nodes.

Return type:

list() of psyclone.psyir.nodes.Node

forward_dependence()

Returns the closest following Node that this Node has a direct dependence with or None if there is not one. Only Nodes with the same parent as self are returned. Nodes inherit their descendants’ dependencies. The reason for this is that for correctness a node must maintain its parent if it is moved. For example a halo exchange and a kernel call may have a dependence between them but it is the loop body containing the kernel call that the halo exchange must not move beyond i.e. the loop body inherits the dependencies of the routines within it.

get_sibling_lists(my_type, stop_type=None)

Recurse through the PSyIR tree and return lists of Nodes that are instances of ‘my_type’ and are immediate siblings. Here ‘my_type’ is either a single class or a tuple of classes. In the latter case all nodes are returned that are instances of any classes in the tuple. The recursion into the tree is stopped if an instance of ‘stop_type’ (which is either a single class or a tuple of classes) is found.

Parameters:
  • my_type (type | Tuple[type, ...]) – the class(es) for which the instances are collected.

  • stop_type (Optional[type | Tuple[type, ...]]) – class(es) at which recursion is halted (optional).

Returns:

list of lists, each of which containing nodes that are instances of my_type and are immediate siblings, starting at and including this node.

Return type:

List[List[psyclone.psyir.nodes.Node]]

property has_constructor_parent
Returns:

whether the constructor has predefined a parent connection but the parent’s children list doesn’t include this node yet.

Return type:

bool

immediately_follows(node_1)
Returns:

True if this node immediately follows node_1, False otherwise

Return type:

bool

immediately_precedes(node_2)
Returns:

True if this node immediately precedes node_2, False otherwise

Return type:

bool

is_openmp_parallel()
Returns:

True if this Node is within an OpenMP parallel region, False otherwise.

Return type:

bool

is_valid_location(new_node, position='before')

If this Node can be moved to the new_node (where position determines whether it is before of after the new_node) without breaking any data dependencies then return True, otherwise return False.

Parameters:
  • new_node (psyclone.psyir.nodes.Node) – Node to which this node should be moved.

  • position (str) – either ‘before’ or ‘after’.

Raises:
Returns:

whether or not the specified location is valid for this node.

Return type:

bool

kernels()
Returns:

all kernels that are descendants of this node in the PSyIR.

Return type:

List[psyclone.psyGen.Kern]

loops()
Returns:

all loops currently in this schedule.

Return type:

List[psyclone.psyir.nodes.Loop]

lower_to_language_level()

In-place replacement of high-level concepts into generic language PSyIR constructs. This generic implementation only recurses down to its children, but this method must be re-implemented by Nodes that represent high-level concepts.

Returns:

the lowered version of this node.

Return type:

psyclone.psyir.node.Node

node_str(colour=True)
Parameters:

colour (bool) – whether or not to include control codes for coloured text.

Returns:

a text description of this node. Will typically be overridden by sub-class.

Return type:

str

origin_string()

Generates a string with the available information about where this node has been created. It currently only works with Fortran Statements or subchildren of them.

Returns:

a string specifing the origin of this node.

Return type:

str

property parent
Returns:

the parent node.

Return type:

psyclone.psyir.nodes.Node or NoneType

path_from(ancestor)

Find the path in the psyir tree between ancestor and node and returns a list containing the path.

The result of this method can be used to find the node from its ancestor for example by:

>>> index_list = node.path_from(ancestor)
>>> cursor = ancestor
>>> for index in index_list:
>>>    cursor = cursor.children[index]
>>> assert cursor is node
Parameters:

ancestor (psyclone.psyir.nodes.Node) – an ancestor node of self to find the path from.

Raises:

ValueError – if ancestor is not an ancestor of self.

Returns:

a list of child indices representing the path between ancestor and self.

Return type:

List[int]

pop_all_children()

Remove all children of this node and return them as a list.

Returns:

all the children of this node as orphan nodes.

Return type:

list of psyclone.psyir.node.Node

property position

Find a Node’s position relative to its parent Node (starting with 0 if it does not have a parent).

Returns:

relative position of a Node to its parent

Return type:

int

preceding(reverse=False, routine=True)

Return all psyclone.psyir.nodes.Node nodes before this node. Ordering is depth first. If the reverse argument is set to True then the node ordering is reversed i.e. returning the nodes closest to this node first. if the routine argument is set to True then nodes are only returned if they are descendents of this node’s closest ancestor routine if one exists.

Parameters:
  • reverse (bool) – an optional (default False) argument that reverses the order of any returned nodes (i.e. makes them ‘closest first’ if set to true.

  • routine (bool) – an optional (default True) argument that only returns nodes that are within this node’s closest ancestor Routine node if one exists.

Returns:

a list of nodes.

Return type:

list() of psyclone.psyir.nodes.Node

reductions(reprod=None)

Return all kernels that have reductions and are decendents of this node. If reprod is not provided, all reductions are returned. If reprod is False, all builtin reductions that are not set to reproducible are returned. If reprod is True, all builtins that are set to reproducible are returned.

Parameters:

reprod (Optional[bool]) – if provided, filter reductions by whether or not they are set to be reproducible.

Returns:

all kernels involving reductions that are descendants of this node.

Return type:

List[psyclone.psyir.nodes.Kern]

reference_accesses(var_accesses)

Get all variable access information. The default implementation just recurses down to all children.

Parameters:

var_accesses (psyclone.core.VariablesAccessInfo) – Stores the output results.

replace_with(node, keep_name_in_context=True)

Removes self, and its descendants, from the PSyIR tree to which it is connected, and replaces it with the supplied node (and its descendants).

Parameters:
  • node (psyclone.psyir.nodes.node) – the node that will replace self in the PSyIR tree.

  • keep_name_in_context (bool) – whether to conserve the name referencing this node.

Raises:
  • TypeError – if the argument ‘node’ is not a Node.

  • TypeError – if the argument ‘keep_name_in_context’ is not bool.

  • GenerationError – if this node does not have a parent.

  • GenerationError – if the argument ‘node’ has a parent.

property root
Returns:

the root node of the PSyIR tree.

Return type:

psyclone.psyir.nodes.Node

sameParent(node_2)
Returns:

True if node_2 has the same parent as this node, False otherwise.

Return type:

bool

property scope

Some nodes (e.g. Schedule and Container) allow symbols to be scoped via an attached symbol table. This property returns the closest ScopingNode node including self.

Returns:

the closest ancestor ScopingNode node.

Return type:

psyclone.psyir.node.ScopingNode

Raises:

SymbolError – if there is no ScopingNode ancestor.

property siblings
Returns:

list of sibling nodes, including self.

Return type:

List[psyclone.psyir.nodes.Node]

update_signal()

Called whenever there is a change in the PSyIR tree below this node. It is responsible for ensuring that this method does not get called recursively and then calls the _update_node() method of the current node (which is the only part that subclasses should specialise). Finally, it propagates the update signal up to the parent node (if any).

validate_global_constraints()

Validates this Node in the context of the whole PSyIR tree. Although there are validation checks for the parent<->child relationships, there are other constraints that can only be checked once the tree is complete and all transformations have been applied. (One example is that an OMP Do directive must be within the scope of an OMP Parallel directive.)

By default, this routine does nothing. It must be overridden appropriately in any sub-classes to which constraints apply. If an error is found then a GenerationError should be raised.

view(depth=0, colour=True, indent='    ', _index=None)

Output a human readable description of the current node and all of its descendents as a string.

Parameters:
  • depth (int) – depth of the tree hierarchy for output text. Defaults to 0.

  • colour (bool) – whether to include colour coding in the output. Defaults to True.

  • indent (str) – the indent to apply as the depth increases. Defaults to 4 spaces.

  • _index (int) – the position of this node wrt its siblings or None. Defaults to None.

Returns:

a representation of this node and its descendents.

Return type:

str

Raises:
  • TypeError – if one of the arguments is the wrong type.

  • ValueError – if the depth argument is negative.

walk(my_type, stop_type=None, depth=None)

Recurse through the PSyIR tree and return all objects that are an instance of ‘my_type’, which is either a single class or a tuple of classes. In the latter case all nodes are returned that are instances of any classes in the tuple. The recursion into the tree is stopped if an instance of ‘stop_type’ (which is either a single class or a tuple of classes) is found. This can be used to avoid analysing e.g. inlined kernels, or as performance optimisation to reduce the number of recursive calls. The recursion into the tree is also stopped if the (optional) ‘depth’ level is reached.

Parameters:
  • my_type (type | Tuple[type, ...]) – the class(es) for which the instances are collected.

  • stop_type (Optional[type | Tuple[type, ...]]) – class(es) at which recursion is halted (optional).

  • depth (Optional[int]) – the depth value the instances must have (optional).

Returns:

list with all nodes that are instances of my_type starting at and including this node.

Return type:

List[psyclone.psyir.nodes.Node]