Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/psyclone/domain/gocean/transformations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,7 @@
import RaisePSyIR2GOceanKernTrans
from psyclone.domain.gocean.transformations.\
gocean_alg_invoke_2_psy_call_trans import GOceanAlgInvoke2PSyCallTrans
from psyclone.domain.gocean.transformations.gocean_omp_loop_trans import \
GOceanOMPLoopTrans
from psyclone.domain.gocean.transformations.gocean_omp_parallel_loop_trans \
import GOceanOMPParallelLoopTrans
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# -----------------------------------------------------------------------------
# BSD 3-Clause License
#
# Copyright (c) 2017-2025, Science and Technology Facilities Council.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# -----------------------------------------------------------------------------
# Authors R. W. Ford, A. R. Porter, S. Siso and N. Nobre, STFC Daresbury Lab
# A. B. G. Chalk and V. K. Atkinson, STFC Daresbury Lab
# J. Henrichs, Bureau of Meteorology
# Modified I. Kavcic, J. G. Wallwork, O. Brunt and L. Turner, Met Office
# S. Valat, Inria / Laboratoire Jean Kuntzmann
# M. Schreiber, Univ. Grenoble Alpes / Inria / Lab. Jean Kuntzmann
# J. Dendy, Met Office


from psyclone.psyir.transformations.omp_loop_trans import OMPLoopTrans
from psyclone.psyir.transformations.transformation_error import (
TransformationError)


class GOceanOMPLoopTrans(OMPLoopTrans):

''' GOcean-specific orphan OpenMP loop transformation. Adds GOcean
specific validity checks (that the node is either an inner or outer
Loop).

:param str omp_directive: choose which OpenMP loop directive to use. \
Defaults to "do".
:param str omp_schedule: the OpenMP schedule to use. Must be one of \
'runtime', 'static', 'dynamic', 'guided' or 'auto'. Defaults to \
'static'.

'''
def __init__(self, omp_directive="do", omp_schedule="static"):
super().__init__(omp_directive=omp_directive,
omp_schedule=omp_schedule)

def __str__(self):
return "Add the selected OpenMP loop directive to a GOcean loop"

def validate(self, node, options=None, **kwargs):
'''
Checks that the supplied node is a valid target for parallelisation
using OMP directives.

:param node: the candidate loop for parallelising using OMP Do.
:type node: :py:class:`psyclone.psyir.nodes.Loop`
:param options: a dictionary with options for transformations.
:type options: Optional[Dict[str, Any]]

:raises TransformationError: if the loop_type of the supplied Loop is \
not "inner" or "outer".

'''
super().validate(node, options=options)

# Check we are either an inner or outer loop
if node.loop_type not in ["inner", "outer"]:
raise TransformationError("Error in "+self.name+" transformation."
" The requested loop is not of type "
"inner or outer.")
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# -----------------------------------------------------------------------------
# BSD 3-Clause License
#
# Copyright (c) 2017-2025, Science and Technology Facilities Council.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# -----------------------------------------------------------------------------
# Authors R. W. Ford, A. R. Porter, S. Siso and N. Nobre, STFC Daresbury Lab
# A. B. G. Chalk and V. K. Atkinson, STFC Daresbury Lab
# J. Henrichs, Bureau of Meteorology
# Modified I. Kavcic, J. G. Wallwork, O. Brunt and L. Turner, Met Office
# S. Valat, Inria / Laboratoire Jean Kuntzmann
# M. Schreiber, Univ. Grenoble Alpes / Inria / Lab. Jean Kuntzmann
# J. Dendy, Met Office

from psyclone.psyir.transformations.omp_parallel_loop_trans import (
OMPParallelLoopTrans)
from psyclone.psyir.transformations.transformation_error import (
TransformationError)


class GOceanOMPParallelLoopTrans(OMPParallelLoopTrans):

'''GOcean specific OpenMP Do loop transformation. Adds GOcean
specific validity checks (that supplied Loop is an inner or outer
loop). Actual transformation is done by
:py:class:`base class <OMPParallelLoopTrans>`.

:param str omp_directive: choose which OpenMP loop directive to use. \
Defaults to "do".
:param str omp_schedule: the OpenMP schedule to use. Must be one of \
'runtime', 'static', 'dynamic', 'guided' or 'auto'. Defaults to \
'static'.

'''
def __init__(self, omp_directive="do", omp_schedule="static"):
super().__init__(omp_directive=omp_directive,
omp_schedule=omp_schedule)

def __str__(self):
return "Add an OpenMP Parallel Do directive to a GOcean loop"

def apply(self, node, options=None):
''' Perform GOcean-specific loop validity checks then call
:py:meth:`OMPParallelLoopTrans.apply`.

:param node: a Loop node from an AST.
:type node: :py:class:`psyclone.psyir.nodes.Loop`
:param options: a dictionary with options for transformations\
and validation.
:type options: Optional[Dict[str, Any]]

:raises TransformationError: if the supplied node is not an inner or\
outer loop.

'''
self.validate(node, options=options)

# Check we are either an inner or outer loop
if node.loop_type not in ["inner", "outer"]:
raise TransformationError(
"Error in "+self.name+" transformation. The requested loop"
" is not of type inner or outer.")

OMPParallelLoopTrans.apply(self, node)
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@
from psyclone.psyir.transformations import (
LoopFuseTrans, LoopTrans, TransformationError, ACCLoopTrans)
from psyclone.transformations import (
ACCRoutineTrans, OMPParallelTrans, GOceanOMPParallelLoopTrans,
GOceanOMPLoopTrans, OMPLoopTrans, ACCParallelTrans, ACCEnterDataTrans)
from psyclone.domain.gocean.transformations import GOConstLoopBoundsTrans
ACCRoutineTrans, OMPParallelTrans,
OMPLoopTrans, ACCParallelTrans, ACCEnterDataTrans)
from psyclone.domain.gocean.transformations import (
GOConstLoopBoundsTrans, GOceanOMPLoopTrans, GOceanOMPParallelLoopTrans)
from psyclone.tests.gocean_build import GOceanBuild
from psyclone.tests.utilities import count_lines, get_invoke, get_base_path

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,9 @@
from psyclone.psyir.transformations import (PSyDataTrans, TransformationError,
ACCLoopTrans)
from psyclone.transformations import (ACCParallelTrans, ACCEnterDataTrans,
GOceanOMPLoopTrans,
GOceanOMPParallelLoopTrans,
OMPParallelTrans)
from psyclone.domain.gocean.transformations import GOConstLoopBoundsTrans
from psyclone.domain.gocean.transformations import (
GOConstLoopBoundsTrans, GOceanOMPLoopTrans, GOceanOMPParallelLoopTrans)
from psyclone.tests.utilities import get_invoke

# API names
Expand Down
4 changes: 2 additions & 2 deletions src/psyclone/tests/psyir/transformations/profile_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
from psyclone.psyir.transformations import (ACCKernelsTrans, ProfileTrans,
TransformationError)
from psyclone.tests.utilities import get_invoke
from psyclone.transformations import (GOceanOMPLoopTrans,
OMPParallelTrans)
from psyclone.transformations import OMPParallelTrans
from psyclone.domain.gocean.transformations import GOceanOMPLoopTrans


# -----------------------------------------------------------------------------
Expand Down
91 changes: 0 additions & 91 deletions src/psyclone/transformations.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,52 +173,6 @@ def validate(self, node, options=None):
super().validate(node, options=local_options)


class GOceanOMPParallelLoopTrans(OMPParallelLoopTrans):

'''GOcean specific OpenMP Do loop transformation. Adds GOcean
specific validity checks (that supplied Loop is an inner or outer
loop). Actual transformation is done by
:py:class:`base class <OMPParallelLoopTrans>`.

:param str omp_directive: choose which OpenMP loop directive to use. \
Defaults to "do".
:param str omp_schedule: the OpenMP schedule to use. Must be one of \
'runtime', 'static', 'dynamic', 'guided' or 'auto'. Defaults to \
'static'.

'''
def __init__(self, omp_directive="do", omp_schedule="static"):
super().__init__(omp_directive=omp_directive,
omp_schedule=omp_schedule)

def __str__(self):
return "Add an OpenMP Parallel Do directive to a GOcean loop"

def apply(self, node, options=None):
''' Perform GOcean-specific loop validity checks then call
:py:meth:`OMPParallelLoopTrans.apply`.

:param node: a Loop node from an AST.
:type node: :py:class:`psyclone.psyir.nodes.Loop`
:param options: a dictionary with options for transformations\
and validation.
:type options: Optional[Dict[str, Any]]

:raises TransformationError: if the supplied node is not an inner or\
outer loop.

'''
self.validate(node, options=options)

# Check we are either an inner or outer loop
if node.loop_type not in ["inner", "outer"]:
raise TransformationError(
"Error in "+self.name+" transformation. The requested loop"
" is not of type inner or outer.")

OMPParallelLoopTrans.apply(self, node)


class LFRicOMPLoopTrans(OMPLoopTrans):

''' LFRic specific orphan OpenMP loop transformation. Adds
Expand Down Expand Up @@ -303,49 +257,6 @@ def apply(self, node, options=None, **kwargs):
super().apply(node, options)


class GOceanOMPLoopTrans(OMPLoopTrans):

''' GOcean-specific orphan OpenMP loop transformation. Adds GOcean
specific validity checks (that the node is either an inner or outer
Loop).

:param str omp_directive: choose which OpenMP loop directive to use. \
Defaults to "do".
:param str omp_schedule: the OpenMP schedule to use. Must be one of \
'runtime', 'static', 'dynamic', 'guided' or 'auto'. Defaults to \
'static'.

'''
def __init__(self, omp_directive="do", omp_schedule="static"):
super().__init__(omp_directive=omp_directive,
omp_schedule=omp_schedule)

def __str__(self):
return "Add the selected OpenMP loop directive to a GOcean loop"

def validate(self, node, options=None, **kwargs):
'''
Checks that the supplied node is a valid target for parallelisation
using OMP directives.

:param node: the candidate loop for parallelising using OMP Do.
:type node: :py:class:`psyclone.psyir.nodes.Loop`
:param options: a dictionary with options for transformations.
:type options: Optional[Dict[str, Any]]

:raises TransformationError: if the loop_type of the supplied Loop is \
not "inner" or "outer".

'''
super().validate(node, options=options)

# Check we are either an inner or outer loop
if node.loop_type not in ["inner", "outer"]:
raise TransformationError("Error in "+self.name+" transformation."
" The requested loop is not of type "
"inner or outer.")


class ColourTrans(LoopTrans):
'''
Apply a colouring transformation to a loop (in order to permit a
Expand Down Expand Up @@ -2435,8 +2346,6 @@ def __new__(cls):
"LFRicOMPLoopTrans",
"LFRicRedundantComputationTrans",
"LFRicOMPParallelLoopTrans",
"GOceanOMPLoopTrans",
"GOceanOMPParallelLoopTrans",
"KernelImportsToArguments",
"MoveTrans",
"OMPMasterTrans",
Expand Down