Source code for psyclone.psyir.transformations.move_trans

# -----------------------------------------------------------------------------
# BSD 3-Clause License
#
# Copyright (c) 2017-2026, 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 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
'''This module provides the MoveTrans transformation.'''

import warnings

from psyclone.psyGen import Transformation
from psyclone.psyir.nodes import Node
from psyclone.psyir.transformations.transformation_error import (
    TransformationError
)
from psyclone.utils import transformation_documentation_wrapper


[docs] @transformation_documentation_wrapper class MoveTrans(Transformation): '''Provides a transformation to move a node in the tree. For example: >>> from psyclone.parse.algorithm import parse >>> from psyclone.psyGen import PSyFactory >>> ast,invokeInfo=parse("lfric.F90") >>> psy=PSyFactory("lfric").create(invokeInfo) >>> schedule=psy.invokes.get('invoke_v3_kernel_type').schedule >>> # Uncomment the following line to see a text view of the schedule >>> # print(schedule.view()) >>> >>> from psyclone.transformations import MoveTrans >>> trans=MoveTrans() >>> trans.apply(schedule.children[0], schedule.children[2], ... options = {"position":"after") >>> # Uncomment the following line to see a text view of the schedule >>> # print(schedule.view()) Nodes may only be moved to a new location with the same parent and must not break any dependencies otherwise an exception is raised.''' def __str__(self): return "Move a node to a different location"
[docs] def validate(self, node: Node, location: Node, options=None, **kwargs): # pylint: disable=arguments-differ ''' validity checks for input arguments. :param node: the node to be moved. :param options: a dictionary with options for transformations. :type options: Optional[Dict[str, Any]] :param str options["position"]: either 'before' or 'after'. :raises TransformationError: if the given node is not an instance of :py:class:`psyclone.psyir.nodes.Node` :raises TransformationError: if the location is not valid. ''' if not options: self.validate_options(**kwargs) position = self.get_option("position", **kwargs) else: # TODO #2668: Deprecate options dictionary. position = options.get("position", "before") # Check that the first argument is a Node if not isinstance(node, Node): raise TransformationError( f"The node argument to {self.name} should be a Node but got " f"'{type(node).__name__}'." ) # Check new location conforms to any data dependencies # This also checks the location and position arguments if not node.is_valid_location(location, position=position): raise TransformationError( f"In {self.name}, data dependencies " f"forbid the move to the new location")
[docs] def apply(self, node: Node, location: Node, position: str = "before", options=None, **kwargs): '''Move the node represented by :py:obj:`node` before location :py:obj:`location` (which is also a node) by default and after if the optional `position` argument is set to 'after'. :param node: the node to be moved. :param location: node before or after which the given node should be moved. :param position: whether to place the moved node before or after the location. This must be 'before' or 'after'. :param options: a dictionary with options for transformations. :type options: Optional[Dict[str, Any]] :param str options["position"]: either 'before' or 'after'. :raises TransformationError: if the given node is not an instance of :py:class:`psyclone.psyir.nodes.Node` :raises TransformationError: if the location is not valid. ''' # pylint:disable=arguments-differ self.validate(node, location, options=options, position=position) if options: # TODO #2668: Deprecate options dictionary. position = options.get("position", "before") warnings.warn(self._deprecation_warning, DeprecationWarning, 2) parent = node.parent my_node = parent.children.pop(node.position) location_index = location.position if position == "before": location.parent.children.insert(location_index, my_node) else: location.parent.children.insert(location_index+1, my_node)
__all__ = ["MoveTrans"]