Reference Guide  2.5.0
psyclone.transformations.OMPTaskloopTrans Class Reference
Inheritance diagram for psyclone.transformations.OMPTaskloopTrans:
Collaboration diagram for psyclone.transformations.OMPTaskloopTrans:

Public Member Functions

def __init__ (self, grainsize=None, num_tasks=None, nogroup=False)
 
def __str__ (self)
 
def omp_nogroup (self)
 
def omp_nogroup (self, nogroup)
 
def omp_grainsize (self)
 
def omp_grainsize (self, value)
 
def omp_num_tasks (self)
 
def omp_num_tasks (self, value)
 
def apply (self, node, options=None)
 
- Public Member Functions inherited from psyclone.psyir.transformations.parallel_loop_trans.ParallelLoopTrans
def validate (self, node, options=None)
 
- Public Member Functions inherited from psyclone.psyir.transformations.loop_trans.LoopTrans
def name (self)
 

Public Attributes

 omp_grainsize
 
 omp_num_tasks
 
 omp_nogroup
 

Additional Inherited Members

- Static Public Attributes inherited from psyclone.psyir.transformations.parallel_loop_trans.ParallelLoopTrans
tuple excluded_node_types = (nodes.Return, psyGen.HaloExchange, nodes.CodeBlock)
 
- Static Public Attributes inherited from psyclone.psyir.transformations.loop_trans.LoopTrans
tuple excluded_node_types = ()
 

Detailed Description

Adds an OpenMP taskloop directive to a loop. Only one of grainsize or
num_tasks must be specified.

TODO: #1364 Taskloops do not yet support reduction clauses.

:param grainsize: the grainsize to use in for this transformation.
:type grainsize: int or None
:param num_tasks: the num_tasks to use for this transformation.
:type num_tasks: int or None
:param bool nogroup: whether or not to use a nogroup clause for this
                     transformation. Default is False.

For example:

>>> from pysclone.parse.algorithm import parse
>>> from psyclone.psyGen import PSyFactory
>>> api = "gocean1.0"
>>> ast, invokeInfo = parse(GOCEAN_SOURCE_FILE, api=api)
>>> psy = PSyFactory(api).create(invokeInfo)
>>>
>>> from psyclone.transformations import OMPParallelTrans, OMPSingleTrans
>>> from psyclone.transformations import OMPTaskloopTrans
>>> from psyclone.psyir.transformations import OMPTaskwaitTrans
>>> singletrans = OMPSingleTrans()
>>> paralleltrans = OMPParallelTrans()
>>> tasklooptrans = OMPTaskloopTrans()
>>> taskwaittrans = OMPTaskwaitTrans()
>>>
>>> schedule = psy.invokes.get('invoke_0').schedule
>>> # Uncomment the following line to see a text view of the schedule
>>> # print(schedule.view())
>>>
>>> # Apply the OpenMP Taskloop transformation to *every* loop
>>> # in the schedule.
>>> # This ignores loop dependencies. These can be handled
>>> # by the OMPTaskwaitTrans
>>> for child in schedule.children:
>>>     tasklooptrans.apply(child)
>>> # Enclose all of these loops within a single OpenMP
>>> # SINGLE region
>>> singletrans.apply(schedule.children)
>>> # Enclose all of these loops within a single OpenMP
>>> # PARALLEL region
>>> paralleltrans.apply(schedule.children)
>>> # Ensure loop dependencies are satisfied
>>> taskwaittrans.apply(schedule.children)
>>> # Uncomment the following line to see a text view of the schedule
>>> # print(schedule.view())

Definition at line 109 of file transformations.py.

Member Function Documentation

◆ apply()

def psyclone.transformations.OMPTaskloopTrans.apply (   self,
  node,
  options = None 
)
Apply the OMPTaskloopTrans transformation to the specified node in
a Schedule. This node must be a Loop since this transformation
corresponds to wrapping the generated code with directives like so:

.. code-block:: fortran

  !$OMP TASKLOOP
  do ...
     ...
  end do
  !$OMP END TASKLOOP

At code-generation time (when
:py:meth:`OMPTaskloopDirective.gen_code` is called), this node must be
within (i.e. a child of) an OpenMP SERIAL region.

If the keyword "nogroup" is specified in the options, it will cause a
nogroup clause be generated if it is set to True. This will override
the value supplied to the constructor, but will only apply to the
apply call to which the value is supplied.

:param node: the supplied node to which we will apply the \
             OMPTaskloopTrans transformation
:type node: :py:class:`psyclone.psyir.nodes.Node`
:param options: a dictionary with options for transformations\
                and validation.
:type options: Optional[Dict[str, Any]]
:param bool options["nogroup"]:
        indicating whether a nogroup clause should be applied to
        this taskloop.

Reimplemented from psyclone.psyir.transformations.parallel_loop_trans.ParallelLoopTrans.

Definition at line 309 of file transformations.py.

309  def apply(self, node, options=None):
310  '''Apply the OMPTaskloopTrans transformation to the specified node in
311  a Schedule. This node must be a Loop since this transformation
312  corresponds to wrapping the generated code with directives like so:
313 
314  .. code-block:: fortran
315 
316  !$OMP TASKLOOP
317  do ...
318  ...
319  end do
320  !$OMP END TASKLOOP
321 
322  At code-generation time (when
323  :py:meth:`OMPTaskloopDirective.gen_code` is called), this node must be
324  within (i.e. a child of) an OpenMP SERIAL region.
325 
326  If the keyword "nogroup" is specified in the options, it will cause a
327  nogroup clause be generated if it is set to True. This will override
328  the value supplied to the constructor, but will only apply to the
329  apply call to which the value is supplied.
330 
331  :param node: the supplied node to which we will apply the \
332  OMPTaskloopTrans transformation
333  :type node: :py:class:`psyclone.psyir.nodes.Node`
334  :param options: a dictionary with options for transformations\
335  and validation.
336  :type options: Optional[Dict[str, Any]]
337  :param bool options["nogroup"]:
338  indicating whether a nogroup clause should be applied to
339  this taskloop.
340 
341  '''
342  if not options:
343  options = {}
344  current_nogroup = self.omp_nogroup
345  # If nogroup is specified it overrides that supplied to the
346  # constructor of the Transformation, but will be reset at the
347  # end of this function
348  self.omp_nogroup = options.get("nogroup", current_nogroup)
349 
350  try:
351  super().apply(node, options)
352  finally:
353  # Reset the nogroup value to the original value
354  self.omp_nogroup = current_nogroup
355 
356 

References psyclone.transformations.OMPTaskloopTrans.omp_nogroup.

◆ omp_grainsize() [1/2]

def psyclone.transformations.OMPTaskloopTrans.omp_grainsize (   self)
Returns the grainsize that will be specified by
this transformation. By default the grainsize
clause is not applied, so grainsize is None.

:returns: The grainsize specified by this transformation.
:rtype: int or None

Definition at line 201 of file transformations.py.

201  def omp_grainsize(self):
202  '''
203  Returns the grainsize that will be specified by
204  this transformation. By default the grainsize
205  clause is not applied, so grainsize is None.
206 
207  :returns: The grainsize specified by this transformation.
208  :rtype: int or None
209  '''
210  return self._grainsize
211 

References psyclone.psyir.nodes.omp_directives.OMPTaskloopDirective._grainsize, and psyclone.transformations.OMPTaskloopTrans._grainsize.

Here is the caller graph for this function:

◆ omp_grainsize() [2/2]

def psyclone.transformations.OMPTaskloopTrans.omp_grainsize (   self,
  value 
)
Sets the grainsize that will be specified by
this transformation. Checks the grainsize is
a positive integer value or None.

:param value: integer value to use in the grainsize clause.
:type value: int or None

:raises TransformationError: if value is not an int and is not None.
:raises TransformationError: if value is negative.
:raises TransformationError: if grainsize and num_tasks are \
                             both specified.

Definition at line 213 of file transformations.py.

213  def omp_grainsize(self, value):
214  '''
215  Sets the grainsize that will be specified by
216  this transformation. Checks the grainsize is
217  a positive integer value or None.
218 
219  :param value: integer value to use in the grainsize clause.
220  :type value: int or None
221 
222  :raises TransformationError: if value is not an int and is not None.
223  :raises TransformationError: if value is negative.
224  :raises TransformationError: if grainsize and num_tasks are \
225  both specified.
226  '''
227  if (not isinstance(value, int)) and (value is not None):
228  raise TransformationError(f"grainsize must be an integer or None, "
229  f"got {type(value).__name__}")
230 
231  if (value is not None) and (value <= 0):
232  raise TransformationError(f"grainsize must be a positive "
233  f"integer, got {value}")
234 
235  if value is not None and self.omp_num_tasks is not None:
236  raise TransformationError(
237  "The grainsize and num_tasks clauses would both "
238  "be specified for this Taskloop transformation")
239  self._grainsize = value
240 

References psyclone.psyir.nodes.omp_directives.OMPTaskloopDirective._grainsize, psyclone.transformations.OMPTaskloopTrans._grainsize, and psyclone.transformations.OMPTaskloopTrans.omp_num_tasks.

Here is the caller graph for this function:

◆ omp_nogroup() [1/2]

def psyclone.transformations.OMPTaskloopTrans.omp_nogroup (   self)
Returns whether the nogroup clause should be specified for
this transformation. By default the nogroup clause is applied.

:returns: whether the nogroup clause should be specified by
          this transformation.
:rtype: bool

Definition at line 173 of file transformations.py.

173  def omp_nogroup(self):
174  '''
175  Returns whether the nogroup clause should be specified for
176  this transformation. By default the nogroup clause is applied.
177 
178  :returns: whether the nogroup clause should be specified by
179  this transformation.
180  :rtype: bool
181  '''
182  return self._nogroup
183 

References psyclone.psyir.nodes.omp_directives.OMPTaskloopDirective._nogroup, and psyclone.transformations.OMPTaskloopTrans._nogroup.

Here is the caller graph for this function:

◆ omp_nogroup() [2/2]

def psyclone.transformations.OMPTaskloopTrans.omp_nogroup (   self,
  nogroup 
)
Sets whether the nogroup clause should be specified for this
transformation.

:param bool nogroup: value to set whether the nogroup clause should be
                     used for this transformation.

raises TypeError: if the nogroup parameter is not a bool.

Definition at line 185 of file transformations.py.

185  def omp_nogroup(self, nogroup):
186  '''
187  Sets whether the nogroup clause should be specified for this
188  transformation.
189 
190  :param bool nogroup: value to set whether the nogroup clause should be
191  used for this transformation.
192 
193  raises TypeError: if the nogroup parameter is not a bool.
194  '''
195  if not isinstance(nogroup, bool):
196  raise TypeError(f"Expected nogroup to be a bool "
197  f"but got a {type(nogroup).__name__}")
198  self._nogroup = nogroup
199 

References psyclone.psyir.nodes.omp_directives.OMPTaskloopDirective._nogroup, and psyclone.transformations.OMPTaskloopTrans._nogroup.

Here is the caller graph for this function:

◆ omp_num_tasks() [1/2]

def psyclone.transformations.OMPTaskloopTrans.omp_num_tasks (   self)
Returns the num_tasks that will be specified
by this transformation. By default the num_tasks
clause is not applied so num_tasks is None.

:returns: The grainsize specified by this transformation.
:rtype: int or None

Definition at line 242 of file transformations.py.

242  def omp_num_tasks(self):
243  '''
244  Returns the num_tasks that will be specified
245  by this transformation. By default the num_tasks
246  clause is not applied so num_tasks is None.
247 
248  :returns: The grainsize specified by this transformation.
249  :rtype: int or None
250  '''
251  return self._num_tasks
252 

References psyclone.psyir.nodes.omp_directives.OMPTaskloopDirective._num_tasks, and psyclone.transformations.OMPTaskloopTrans._num_tasks.

Here is the caller graph for this function:

◆ omp_num_tasks() [2/2]

def psyclone.transformations.OMPTaskloopTrans.omp_num_tasks (   self,
  value 
)
Sets the num_tasks that will be specified by
this transformation. Checks that num_tasks is
a positive integer value or None.

:param value: integer value to use in the num_tasks clause.
:type value: int or None

:raises TransformationError: if value is not an int and is not None.
:raises TransformationError: if value is negative.
:raises TransformationError: if grainsize and num_tasks are \
                             both specified.

Definition at line 254 of file transformations.py.

254  def omp_num_tasks(self, value):
255  '''
256  Sets the num_tasks that will be specified by
257  this transformation. Checks that num_tasks is
258  a positive integer value or None.
259 
260  :param value: integer value to use in the num_tasks clause.
261  :type value: int or None
262 
263  :raises TransformationError: if value is not an int and is not None.
264  :raises TransformationError: if value is negative.
265  :raises TransformationError: if grainsize and num_tasks are \
266  both specified.
267 
268  '''
269  if (not isinstance(value, int)) and (value is not None):
270  raise TransformationError(f"num_tasks must be an integer or None,"
271  f" got {type(value).__name__}")
272 
273  if (value is not None) and (value <= 0):
274  raise TransformationError(f"num_tasks must be a positive "
275  f"integer, got {value}")
276 
277  if value is not None and self.omp_grainsize is not None:
278  raise TransformationError(
279  "The grainsize and num_tasks clauses would both "
280  "be specified for this Taskloop transformation")
281  self._num_tasks = value
282 

References psyclone.psyir.nodes.omp_directives.OMPTaskloopDirective._num_tasks, psyclone.transformations.OMPTaskloopTrans._num_tasks, psyclone.transformations.OMPTaskloopTrans.omp_grainsize, psyclone.transformations.OMPTaskloopTrans.omp_nogroup, and psyclone.transformations.OMPTaskloopTrans.omp_num_tasks.

Here is the caller graph for this function:

The documentation for this class was generated from the following file: