Reference Guide  2.5.0
psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans Class Reference
Inheritance diagram for psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans:
Collaboration diagram for psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans:

Public Member Functions

def __init__ (self, omp_directive="do", omp_schedule="auto")
 
def __str__ (self)
 
def omp_directive (self)
 
def omp_directive (self, value)
 
def omp_schedule (self)
 
def omp_schedule (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_schedule
 
 omp_directive
 

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 directive to parallelise this loop. It can insert different
directives such as "omp do/for", "omp parallel do/for", "omp teams
distribute parallel do/for" or "omp loop" depending on the provided
parameters.
The OpenMP schedule to use can also be specified, but this will be ignored
in case of the "omp loop" (as the 'schedule' clause is not valid for this
specific directive). The configuration-defined 'reprod' parameter
also specifies whether a manual reproducible reproduction is to be used.
Note, reproducible in this case means obtaining the same results with the
same number of OpenMP threads, not for different numbers of OpenMP threads.

:param str omp_schedule: the OpenMP schedule to use. Defaults to 'auto'.
:param str omp_directive: choose which OpenMP loop directive to use. \
    Defaults to "omp do"

For example:

>>> from psyclone.psyir.frontend.fortran import FortranReader
>>> from psyclone.psyir.backend.fortran import FortranWriter
>>> from psyclone.psyir.nodes import Loop
>>> from psyclone.transformations import OMPLoopTrans, OMPParallelTrans
>>>
>>> psyir = FortranReader().psyir_from_source("""
...     subroutine my_subroutine()
...         integer, dimension(10, 10) :: A
...         integer :: i
...         integer :: j
...         do i = 1, 10
...             do j = 1, 10
...                 A(i, j) = 0
...             end do
...         end do
...     end subroutine
...     """)
>>> loop = psyir.walk(Loop)[0]
>>> omplooptrans1 = OMPLoopTrans(omp_schedule="dynamic",
...                              omp_directive="paralleldo")
>>> omplooptrans1.apply(loop)
>>> print(FortranWriter()(psyir))
subroutine my_subroutine()
  integer, dimension(10,10) :: a
  integer :: i
  integer :: j
<BLANKLINE>
  !$omp parallel do default(shared), private(i,j), schedule(dynamic)
  do i = 1, 10, 1
    do j = 1, 10, 1
      a(i,j) = 0
    enddo
  enddo
  !$omp end parallel do
<BLANKLINE>
end subroutine my_subroutine
<BLANKLINE>

Definition at line 55 of file omp_loop_trans.py.

Member Function Documentation

◆ apply()

def psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans.apply (   self,
  node,
  options = None 
)
Apply the OMPLoopTrans transformation to the specified PSyIR Loop.

:param node: the supplied node to which we will apply the \
             OMPLoopTrans 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["reprod"]:
        indicating whether reproducible reductions should be used. \
        By default the value from the config file will be used.

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

Reimplemented in psyclone.transformations.Dynamo0p3OMPLoopTrans, psyclone.transformations.GOceanOMPParallelLoopTrans, and psyclone.transformations.OMPParallelLoopTrans.

Definition at line 227 of file omp_loop_trans.py.

227  def apply(self, node, options=None):
228  '''Apply the OMPLoopTrans transformation to the specified PSyIR Loop.
229 
230  :param node: the supplied node to which we will apply the \
231  OMPLoopTrans transformation
232  :type node: :py:class:`psyclone.psyir.nodes.Node`
233  :param options: a dictionary with options for transformations\
234  and validation.
235  :type options: Optional[Dict[str, Any]]
236  :param bool options["reprod"]:
237  indicating whether reproducible reductions should be used. \
238  By default the value from the config file will be used.
239 
240  '''
241  if not options:
242  options = {}
243  self._reprod = options.get("reprod",
244  Config.get().reproducible_reductions)
245 
246  if self._reprod:
247  # When reprod is True, the variables th_idx and nthreads are
248  # expected to be declared in the scope.
249  root = node.ancestor(Routine)
250 
251  symtab = root.symbol_table
252  try:
253  symtab.lookup_with_tag("omp_thread_index")
254  except KeyError:
255  symtab.new_symbol(
256  "th_idx", tag="omp_thread_index",
257  symbol_type=DataSymbol, datatype=INTEGER_TYPE)
258  try:
259  symtab.lookup_with_tag("omp_num_threads")
260  except KeyError:
261  symtab.new_symbol(
262  "nthreads", tag="omp_num_threads",
263  symbol_type=DataSymbol, datatype=INTEGER_TYPE)
264 
265  super().apply(node, options)

References psyclone.psyir.nodes.omp_directives.OMPDoDirective._reprod, and psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans._reprod.

◆ omp_directive() [1/2]

def psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans.omp_directive (   self)
:returns: the type of OMP directive that this transformation will \
    insert.
:rtype: str

Definition at line 131 of file omp_loop_trans.py.

131  def omp_directive(self):
132  '''
133  :returns: the type of OMP directive that this transformation will \
134  insert.
135  :rtype: str
136  '''
137  return self._omp_directive
138 

References psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans._omp_directive.

◆ omp_directive() [2/2]

def psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans.omp_directive (   self,
  value 
)
:param str value: the type of OMP directive to add.

:raises TypeError: if the provided value is not a valid str.

Definition at line 140 of file omp_loop_trans.py.

140  def omp_directive(self, value):
141  '''
142  :param str value: the type of OMP directive to add.
143 
144  :raises TypeError: if the provided value is not a valid str.
145  '''
146  if not isinstance(value, str) or value not in VALID_OMP_DIRECTIVES:
147  raise TypeError(
148  f"The {type(self).__name__}.omp_directive property must be "
149  f"a str with the value of {VALID_OMP_DIRECTIVES}"
150  f" but found a '{type(value).__name__}' with value '{value}'.")
151  self._omp_directive = value
152 

References psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans._omp_directive.

◆ omp_schedule() [1/2]

def psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans.omp_schedule (   self)
:returns: the OpenMP schedule that will be specified by \
    this transformation.
:rtype: str

Definition at line 154 of file omp_loop_trans.py.

154  def omp_schedule(self):
155  '''
156  :returns: the OpenMP schedule that will be specified by \
157  this transformation.
158  :rtype: str
159 
160  '''
161  return self._omp_schedule
162 

References psyclone.psyir.nodes.omp_directives.OMPDoDirective._omp_schedule, and psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans._omp_schedule.

Here is the caller graph for this function:

◆ omp_schedule() [2/2]

def psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans.omp_schedule (   self,
  value 
)
:param str value: Sets the OpenMP schedule value that will be \
    specified by this transformation, unless adding an OMP Loop \
    directive (in which case it is not applicable).

:raises TypeError: if the provided value is not a string.
:raises ValueError: if the provided string is not a valid OpenMP \
    schedule format.

Definition at line 164 of file omp_loop_trans.py.

164  def omp_schedule(self, value):
165  '''
166  :param str value: Sets the OpenMP schedule value that will be \
167  specified by this transformation, unless adding an OMP Loop \
168  directive (in which case it is not applicable).
169 
170  :raises TypeError: if the provided value is not a string.
171  :raises ValueError: if the provided string is not a valid OpenMP \
172  schedule format.
173  '''
174 
175  if not isinstance(value, str):
176  raise TypeError(
177  f"The OMPLoopTrans.omp_schedule property must be a 'str'"
178  f" but found a '{type(value).__name__}'.")
179 
180  # Some schedules have an optional chunk size following a ','
181  value_parts = value.split(',')
182  if value_parts[0].lower() not in OMPScheduleClause.VALID_OMP_SCHEDULES:
183  raise ValueError(
184  f"Valid OpenMP schedules are "
185  f"{OMPScheduleClause.VALID_OMP_SCHEDULES} but got "
186  f"'{value_parts[0]}'.")
187 
188  if len(value_parts) > 1:
189  if value_parts[0] == "auto":
190  raise ValueError("Cannot specify a chunk size when using an "
191  "OpenMP schedule of 'auto'.")
192  try:
193  int(value_parts[1].strip())
194  except ValueError as err:
195  raise ValueError(f"Supplied OpenMP schedule '{value}' has an "
196  f"invalid chunk-size.") from err
197 
198  self._omp_schedule = value
199 

References psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans._omp_directive, psyclone.psyir.nodes.omp_directives.OMPDoDirective._omp_schedule, psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans._omp_schedule, psyclone.psyir.nodes.omp_directives.OMPDoDirective._reprod, and psyclone.psyir.transformations.omp_loop_trans.OMPLoopTrans._reprod.

Here is the caller graph for this function:

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