37 '''Module providing a transformation from an Assignment node
38 containing an Array Reference node in its left-hand-side which in turn
39 has at least one PSyIR Range node specifying an access to an array
40 index (equivalent to an array assignment statement in Fortran) to the
41 equivalent loop representation using the required number of NemoLoop
45 from __future__
import absolute_import
50 import TransformationError
52 import NemoOuterArrayRange2LoopTrans
56 '''Provides a transformation for all PSyIR Array Ranges in an
57 assignment to PSyIR NemoLoops. For example:
59 >>> from psyclone.parse.algorithm import parse
60 >>> from psyclone.psyGen import PSyFactory
62 >>> filename = "tra_adv.F90" # examples/nemo/code
63 >>> ast, invoke_info = parse(filename, api=api)
64 >>> psy = PSyFactory(api).create(invoke_info)
65 >>> schedule = psy.invokes.invoke_list[0].schedule
67 >>> from psyclone.psyir.nodes import Assignment
68 >>> from psyclone.domain.nemo.transformations import \
69 NemoAllArrayRange2LoopTrans
71 >>> print(schedule.view())
72 >>> trans = NemoAllArrayRange2LoopTrans()
73 >>> for assignment in schedule.walk(Assignment):
74 >>> trans.apply(assignment)
75 >>> print(schedule.view())
78 def apply(self, node, options=None):
79 '''Apply the NemoAllArrayRange2Loop transformation to the specified
80 node if the node is an Assignment and the left-hand-side of
81 the assignment is an Array Reference containing at least one
82 Range node specifying an access to an array index. If this is
83 the case then all Range nodes within array references within
84 the assignment are replaced with references to the appropriate
85 loop indices. The appropriate number of NemoLoop loops are
86 also placed around the modified assignment statement.
88 The name of each loop index is taken from the PSyclone
89 configuration file if a name exists for the particular array
90 index, otherwise a new name is generated. The bounds of each
91 loop are taken from the Range node if they are provided. If
92 not, the loop bounds are taken from the PSyclone configuration
93 file if a bounds value is supplied. If not, the LBOUND or
94 UBOUND intrinsics are used as appropriate. The type of the
95 NemoLoop is also taken from the configuration file if it is
96 supplied for that index, otherwise it is specified as being
99 :param node: an Assignment node.
100 :type node: :py:class:`psyclone.psyir.nodes.Assignment`
101 :param options: a dictionary with options for transformations. No
102 options are used in this transformation. This is an optional
103 argument that defaults to None.
104 :param bool options["verbose"]: whether to print out the reason
105 why the inner transformation was not applied. This is useful
106 because this transfomation succeeds even if one of the inner
107 transformations fails, and therefor the reason why the inner
108 transformation failed is not propagated.
109 :type options: Optional[Dict[str, Any]]
110 :param bool options["allow_string"]: whether to allow the
111 transformation on a character type array range. Defaults to False.
116 trans = NemoOuterArrayRange2LoopTrans()
119 trans.apply(node, options)
120 except TransformationError
as err:
122 if options
and options.get(
"verbose",
False):
126 if "assignment node should be an expression with an array " \
127 "that has a Range node" not in errmsg
and \
128 "be a Reference that contains an array access somewhere" \
133 return (
"Convert all array ranges in a PSyIR assignment into "
139 :returns: the name of the transformation.
143 return type(self).__name__
146 '''Perform various checks to ensure that it is valid to apply the
147 NemoArrayRange2LoopTrans transformation to the supplied PSyIR Node.
149 :param node: the node that is being checked.
150 :type node: :py:class:`psyclone.psyir.nodes.Assignment`
151 :param options: a dictionary with options for \
152 transformations. No options are used in this \
153 transformation. This is an optional argument that defaults \
155 :type options: Optional[Dict[str, Any]]
157 :raises TransformationError: if the supplied node is not an \
162 if not isinstance(node, Assignment):
163 raise TransformationError(
164 f
"Error in NemoAllArrayRange2LoopTrans transformation. The "
165 f
"supplied node argument should be a PSyIR Assignment, but "
166 f
"found '{type(node).__name__}'.")
171 'NemoAllArrayRange2LoopTrans']
def validate(self, node, options=None)
def apply(self, node, options=None)