loki.ir.pragma_utils

Functions

attach_pragma_regions(ir)

Create PragmaRegion node objects for all matching pairs of region pragmas.

attach_pragmas(ir, node_type[, ...])

Find pragmas and merge them onto the given node type(s).

detach_pragma_regions(ir)

Remove any PragmaRegion node objects and replace each with a tuple of (r.pragma, r.body, r.pragma_post), where r is the PragmaRegion node object.

detach_pragmas(ir, node_type[, ...])

Revert the inlining of pragmas, e.g. as done by attach_pragmas.

get_matching_region_pragmas(pragmas)

Given a list of Pragma objects return a list of matching pairs that define a pragma region.

get_pragma_parameters(pragma[, starts_with, ...])

Parse the pragma content for parameters in the form <command>[(<arg>)] and return them as a map {<command>: <arg> or None}.

is_loki_pragma(pragma[, starts_with])

Checks for a pragma annotation and, if it exists, for the loki keyword.

pragma_regions_attached(module_or_routine)

Create a context in which PragmaRegion node objects are inserted into the IR to define code regions marked by matching pairs of pragmas.

pragmas_attached(module_or_routine, node_type)

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.

process_dimension_pragmas(ir[, scope])

Process any !$loki dimension pragmas to override deferred dimensions

Classes

PragmaAttacher(node_type[, attach_pragma_post])

Utility visitor that finds pragmas preceding (or optionally also trailing) nodes of given types and attaches them to these nodes as pragma property.

PragmaDetacher(node_type[, detach_pragma_post])

Utility visitor that detaches inlined pragmas from nodes of given types and inserts them before/after the nodes into the IR.

PragmaParameters()

Utility class to parse strings for parameters in the form <command>[(<arg>)] and return them as a map {<command>: <arg> or None}.

PragmaRegionAttacher([pragma_pairs])

Utility transformer that inserts PragmaRegion objects to mark code section between matching Pragma pairs.

PragmaRegionDetacher([mapper, ...])

Remove any PragmaRegion node objects and insert the tuple of (r.pragma, r.body, r.pragma_post) in the enclosing tuple.

is_loki_pragma(pragma, starts_with=None)

Checks for a pragma annotation and, if it exists, for the loki keyword. Optionally, the pragma content is tested for a specific start.

Parameters:
  • pragma (Pragma or list/tuple of Pragma or None) – the pragma or list of pragmas to check.

  • starts_with (str, optional) – the keyword the pragma content must start with.

get_pragma_parameters(pragma, starts_with=None, only_loki_pragmas=True)

Parse the pragma content for parameters in the form <command>[(<arg>)] and return them as a map {<command>: <arg> or None}.

Optionally, look only at the pragma with the given keyword at the beginning.

Note that if multiple pragma are given as a tuple/list, arguments with the same name will overwrite previous definitions.

Parameters:
  • pragma (Pragma or list/tuple of Pragma or None) – the pragma or list of pragmas to check.

  • starts_with (str, optional) – the keyword the pragma content should start with.

  • only_loki_pragmas (bool, optional) – restrict parameter extraction to loki pragmas only.

Returns:

Mapping of parameters {<command>: <arg> or <None>} with the values being a list when multiple entries have the same key

Return type:

dict

process_dimension_pragmas(ir, scope=None)

Process any !$loki dimension pragmas to override deferred dimensions

Note that this assumes attach_pragmas has been run on ir to attach any pragmas to the VariableDeclaration nodes.

Parameters:

ir (Node) – Root node of the (section of the) internal representation to process

attach_pragmas(ir, node_type, attach_pragma_post=True)

Find pragmas and merge them onto the given node type(s).

This can be done for all IR nodes that have a pragma property (VariableDeclaration, Loop, WhileLoop, CallStatement). Optionally, attaching pragmas after nodes as pragma_post can be disabled by setting attach_pragma_post to False (relevant only for Loop and WhileLoop).

Note

Pragmas are not discovered by FindNodes while attached to IR nodes.

This is implemented using PragmaAttacher. Therefore, the IR is not rebuilt but updated and existing references should remain valid.

Parameters:
  • ir (Node) – the root of (a section of the) intermediate representation in which pragmas are to be attached.

  • node_type (list) – the (list of) Node types pragmas should be attached to.

  • attach_pragma_post (bool, optional) – process pragma_post attachments.

detach_pragmas(ir, node_type, detach_pragma_post=True)

Revert the inlining of pragmas, e.g. as done by attach_pragmas.

This can be done for all IR nodes that have a pragma property (:class:Declaration, :class:Loop, :class:WhileLoop`, :class:``CallStatement). Optionally, detaching of pragmas after nodes (for nodes with a pragma_post property) can be disabled by setting detach_pragma_post to False (relevant only for Loop and WhileLoop).

This is implemented using PragmaDetacher. Therefore, the IR is not rebuilt but updated and existing references should remain valid.

Parameters:
  • ir (Node) – the root node of the (section of the) intermediate representation in which pragmas are to be detached.

  • node_type – the (list of) Node types that pragmas should be detached from.

  • detach_pragma_post (bool, optional) – process pragma_post attachments.

pragmas_attached(module_or_routine, node_type, attach_pragma_post=True)

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.

This can be done for all IR nodes that have a pragma property (VariableDeclaration, ProcedureDeclaration, Loop, WhileLoop, CallStatement). Inside the created context, attached pragmas are no longer standalone IR nodes but accessible via the corresponding node’s pragma property.

Pragmas after nodes are attached as pragma_post, which can be disabled by setting attach_pragma_post to False (for Loop and WhileLoop).

Note

Pragmas are not discovered by FindNodes while attached to IR nodes.

When leaving the context all pragmas for nodes of the given type are detached, irrespective of whether they had already been attached or not when entering the context.

Note

Pragma attachment is only done for the object itself (i.e. its spec and body), not for any contained subroutines.

This is implemented using PragmaAttacher and PragmaDetacher, respectively. Therefore, the IR is not rebuilt but updated and existing references should remain valid when entering the context and stay valid beyond exiting the context.

Example:

loop_of_interest = None
with pragmas_attached(routine, Loop):
    for loop in FindNodes(Loop).visit(routine.body):
        if is_loki_pragma(loop.pragma, starts_with='foobar'):
            loop_of_interest = loop
            break
# Do something with that loop
loop_body = loop_of_interest.body
# Note that loop_body.pragma == None!
Parameters:
  • module_or_routine (Module or Subroutine) – the program unit in which pragmas are to be inlined.

  • node_type – the (list of) Node types, that pragmas should be attached to.

  • attach_pragma_post (bool, optional) – process pragma_post attachments.

attach_pragma_regions(ir)

Create PragmaRegion node objects for all matching pairs of region pragmas.

Matching pragma pairs are assumed to be of the form !$<keyword> <marker> and !$<keyword> end <marker>.

The defining Pragma nodes are accessible via the pragma and pragma_post attributes of the region object. Insertion is performed in-place, without rebuilding any IR nodes.

detach_pragma_regions(ir)

Remove any PragmaRegion node objects and replace each with a tuple of (r.pragma, r.body, r.pragma_post), where r is the PragmaRegion node object.

All replacements are performed in-place, without rebuilding any IR nodes.

pragma_regions_attached(module_or_routine)

Create a context in which PragmaRegion node objects are inserted into the IR to define code regions marked by matching pairs of pragmas.

Matching pragma pairs are assumed to be of the form !$<keyword> <marker> and !$<keyword> end <marker>.

In the resulting context FindNodes(PragmaRegion).visit(ir) can be used to select code regions marked by pragma pairs as node objects.

The defining Pragma nodes are accessible via the pragma and pragma_post attributes of the region object. Importantly, Pragmas are not discovered by FindNodes while attached to IR nodes.

When leaving the context all PragmaRegion objects are replaced with a tuple of (r.pragma, r.body, r.pragma_post), where r is the PragmaRegion node object.

Throughout the setup and teardown of the context IR nodes are only updated, never rebuild, meaning node mappings from inside the context are valid outside of it.

Example:

with pragma_regions_attached(routine):
    for region in FindNodes(PragmaRegion).visit(routine.body):
        if is_loki_pragma(region.pragma, starts_with='foobar'):
            <transform code in region.body>
Parameters:

module_or_routine (Module or Subroutine in) – which PragmaRegion objects are to be inserted.

class PragmaAttacher(node_type, attach_pragma_post=True)

Bases: Visitor

Utility visitor that finds pragmas preceding (or optionally also trailing) nodes of given types and attaches them to these nodes as pragma property.

Note that this operates by updating (instead of rebuilding) the relevant nodes, thus only nodes to which pragmas are attached get modified and the tree as a whole is not modified if no pragmas are found. This means existing node references should remain valid.

Note

When using attach_pragma_post and two nodes qualifying according to node_type are separated only by Pragma nodes inbetween, it is not possible to decide to which node these pragmas belong. In such cases, they are attached to the second node as pragma property takes precedence. Such situations can only be resolved by full knowledge about the pragma language specification (_way_ out of scope) or modifying the original source, e.g. by inserting a comment between the relevant pragmas.

Parameters:
  • node_type – the IR node type (or a list of them) to attach pragmas to.

  • attach_pragma_post (bool, optional) – look for pragmas after the node, too, and attach as pragma_post if applicable.

visit_tuple(o, **kwargs)

Visit all elements in a tuple and return the results as a tuple.

visit_list(o, **kwargs)

Visit all elements in a tuple and return the results as a tuple.

visit_Node(o, **kwargs)

Visit all children of a Node.

visit_object(o, **kwargs)

Fallback method for objects that do not match any handler.

Parameters:
  • o – The object to visit.

  • **kwargs – Optional keyword arguments passed to the visit methods.

Returns:

The default return value.

Return type:

GenericVisitor.default_retval()

class PragmaDetacher(node_type, detach_pragma_post=False)

Bases: Visitor

Utility visitor that detaches inlined pragmas from nodes of given types and inserts them before/after the nodes into the IR.

Note that this operates by updating (instead of rebuilding) the relevant nodes, thus only nodes to which pragmas are attached get modified and the tree as a whole is not modified if no pragmas are found. This means existing node references should remain valid.

Parameters:
  • node_type – the IR node type (or a list of them) to detach pragmas from.

  • detach_pragma_post (bool, optional) – detach pragma_post properties, if applicable.

visit_tuple(o, **kwargs)

Visit all elements in a tuple and return the results as a tuple.

visit_list(o, **kwargs)

Visit all elements in a tuple and return the results as a tuple.

visit_Node(o, **kwargs)

Visit all children of a Node.

visit_object(o, **kwargs)

Fallback method for objects that do not match any handler.

Parameters:
  • o – The object to visit.

  • **kwargs – Optional keyword arguments passed to the visit methods.

Returns:

The default return value.

Return type:

GenericVisitor.default_retval()