36 ''' This module provides the OMPTaskTrans transformation.'''
42 import FoldConditionalReturnExpressionsTrans
53 ''' Apply an OpenMP Task Transformation to a Loop. The Loop must
54 be within an OpenMP Serial region (Single or Master) at codegen time.
55 Once lowering begins, no more modifications to the tree should occur
56 as the task directives do not recompute dependencies after lowering.
57 In the future it may be possible to do this through an _update_node
62 return "Adds an 'OMP TASK' directive to a statement"
67 :returns: the name of this transformation.
74 Validity checks for input arguments.
76 :param node: the Loop node to validate.
77 :type node: :py:class:`psyclone.psyir.nodes.Loop`
78 :param options: a dictionary with options for transformations.
79 :type options: dict of string:values or None
82 if any(node.walk(CodeBlock)):
84 "OMPTaskTransformation cannot be applied to a region "
85 "containing a code block")
90 root_ancestor = node.root
91 path_to_node = node.path_from(root_ancestor)
92 routine_copy = root_ancestor.copy()
93 node_copy = routine_copy
94 for index
in path_to_node:
95 node_copy = node_copy.children[index]
97 kerns = node_copy.walk(Kern)
99 cond_trans = FoldConditionalReturnExpressionsTrans()
102 kintrans.validate(kern)
103 cond_trans.validate(kern.get_kernel_schedule())
107 cond_trans.apply(kern.get_kernel_schedule())
108 kern.lower_to_language_level()
110 calls = node_copy.walk(Call)
113 if isinstance(call, IntrinsicCall):
115 intrans.validate(call)
117 def _directive(self, children, collapse=None):
119 Creates the type of directive needed for this sub-class of
122 :param children: list of Nodes that will be the children of \
123 the created directive.
124 :type children: List[:py:class:`psyclone.psyir.nodes.Node`]
125 :param collapse: A required parameter from parent class. Must
126 never be set for TaskTrans (is None).
127 :type collapse: None.
129 :raises TransformationError: if the collapse attribute is set.
131 :returns: The directive created for the OpenMP Task Directive
132 :rtype: :py:class:`psyclone.psyGen.DynamicOMPTaskDirective`
135 if collapse
is not None:
142 def _inline_kernels(self, node):
144 Searches the PsyIR tree inside the directive and inlines any kern
146 This is a multi-step process:
147 1. Module inline any kernels found.
148 2. Fold any conditional return expressions.
149 3. Lower kernels to language level, resulting in Call nodes.
150 4. Inline all the Call operations found.
152 :param node: The node this transformation is operating on.
153 :type node: :py:class:`psyclone.psyir.nodes.Loop`
156 kerns = node.walk(Kern)
158 cond_trans = FoldConditionalReturnExpressionsTrans()
162 cond_trans.apply(kern.get_kernel_schedule())
163 kern.lower_to_language_level()
165 calls = node.walk(Call)
168 if isinstance(call, IntrinsicCall):
172 def apply(self, node, options=None):
173 '''Apply the OMPTaskTrans to the specified node in a Schedule.
175 Can only be applied to a Loop.
177 The specified node is wrapped by directives during code generation
180 .. code-block:: fortran
186 At code-generation time, this node must be
187 within (i.e. a child of) an OpenMP Serial region (OpenMP Single or
190 Any kernels or Calls will be inlined into the region before the task
191 transformation is applied.
193 :param node: the supplied node to which we will apply the \
194 OMPTaskTrans transformation
195 :type node: :py:class:`psyclone.psyir.nodes.Loop`
196 :param options: a dictionary with options for transformations\
198 :type options: dictionary of string:values or None
204 super().
apply(node, options)