psyclone.psyir.transformations.hoist_local_arrays_trans

This module contains the HoistLocalArraysTrans transformation.

Classes

class psyclone.psyir.transformations.hoist_local_arrays_trans.HoistLocalArraysTrans

This transformation takes a Routine and promotes any local, ‘automatic’ arrays to Container scope:

>>> from psyclone.psyir.backend.fortran import FortranWriter
>>> from psyclone.psyir.frontend.fortran import FortranReader
>>> from psyclone.psyir.nodes import Assignment
>>> from psyclone.psyir.transformations import HoistLocalArraysTrans
>>> code = ("module test_mod\n"
...         "contains\n"
...         "  subroutine test_sub(n)\n"
...         "  integer :: i,j,n\n"
...         "  real :: a(n,n)\n"
...         "  real :: value = 1.0\n"
...         "  do i=1,n\n"
...         "    do j=1,n\n"
...         "      a(i,j) = value\n"
...         "    end do\n"
...         "  end do\n"
...         "  end subroutine test_sub\n"
...         "end module test_mod\n")
>>> psyir = FortranReader().psyir_from_source(code)
>>> hoist = HoistLocalArraysTrans()
>>> hoist.apply(psyir.walk(Routine)[0])
>>> print(FortranWriter()(psyir).lower())
module test_mod
  implicit none
  real, allocatable, dimension(:,:), private :: a
  public

  public :: test_sub

  contains
  subroutine test_sub(n)
    integer :: n
    integer :: i
    integer :: j
    real :: value = 1.0

    if (.not.allocated(a) .or. ubound(a, 1) /= n .or. ubound(a, 2) /= n) then
      if (allocated(a)) then
        deallocate(a)
      end if
      allocate(a(1 : n, 1 : n))
    end if
    do i = 1, n, 1
      do j = 1, n, 1
        a(i,j) = value
      enddo
    enddo

  end subroutine test_sub

end module test_mod

By default, the target routine will be rejected if it is found to contain an ACCRoutineDirective since this usually implies that the routine will be launched in parallel on the OpenACC device. This check can be disabled by setting ‘allow_accroutine’ to True in the options dictionary.

Inheritance

Inheritance diagram of HoistLocalArraysTrans
apply(node, options=None)

Applies the transformation to the supplied Routine node, moving any local arrays up to Container scope and adding a suitable allocation when they are first accessed. If there are no local arrays or the supplied Routine is a program then this method does nothing.

Parameters:
  • node (psyclone.psyir.nodes.Routine) – target PSyIR node.

  • options (Optional[Dict[str, Any]]) – a dictionary with options for transformations.

  • options["allow_accroutine"] (bool) – permit the target routine to contain an ACCRoutineDirective. These are forbidden by default because their presence usually indicates that the routine will be run in parallel on the OpenACC device.

validate(node, options=None)

Checks that the supplied node is a valid target for a hoist- local-arrays transformation. It must be a Routine that is within a Container (that is not a FileContainer).

Parameters:
  • node (subclass of psyclone.psyir.nodes.Routine) – target PSyIR node.

  • options (Optional[Dict[str, Any]]) – any options for the transformation.

Raises:
  • TransformationError – if the supplied node is not a Routine.

  • TransformationError – if the Routine is not within a Container (that is not a FileContainer).

  • TransformationError – if the routine contains an OpenACC routine directive and options[‘allow_accroutine’] is not True.

  • TransformationError – if any symbols corresponding to local arrays have a tag that already exists in the table of the parent Container.