# loki.transformations.temporaries.hoist_variables module

Multiple transformations to hoist variables especially to hoist temporary arrays.

E.g., the following source code

    subroutine driver(...)
        integer :: a
        a = 10
        call kernel(a)
    end subroutine driver

    subroutine kernel(a)
        integer, intent(in) :: a
        real :: array(a)
        ...
    end subroutine kernel

can be transformed/hoisted to

    subroutine driver(...)
        integer :: a
        real :: kernel_array(a)
        a = 10
        call kernel(a, kernel_array)
    end subroutine driver

    subroutine kernel(a, array)
        integer, intent(in) :: a
        real, intent(inout) :: array(a)
        ...
    end subroutine kernel

using

    # Transformation: Analysis
    scheduler.process(transformation=HoistTemporaryArraysAnalysis())
    # Transformation: Synthesis
    scheduler.process(transformation=HoistVariablesTransformation())

To achieve this two transformation are necessary, whereas the first one is responsible for the Analysis and the second one for the Synthesis. Two base classes

- `HoistVariablesAnalysis` - Analysis part, to be processed in reverse

    - specialise/implement `find_variables`

- `HoistVariablesTransformation`- Synthesis part

    - specialise/implement `driver_variable_declaration`

are provided to create derived classes for specialisation of the actual hoisting.

Warning

`HoistVariablesAnalysis` ensures that all local variables are hoisted! Please consider using a specialised class like `HoistTemporaryArraysAnalysis` or create a derived class yourself.

Note

If several of these transformations are carried out in succession, provide a unique `key` for each corresponding Analysis and Synthesis step!

    key = "UniqueKey"
    scheduler.process(transformation=HoistTemporaryArraysAnalysis(dim_vars=('b',), key=key))
    scheduler.process(transformation=HoistTemporaryArraysTransformation(key=key))
    key = "AnotherUniqueKey"
    scheduler.process(transformation=HoistTemporaryArraysAnalysis(dim_vars=('a',), key=key))
    scheduler.process(transformation=HoistTemporaryArraysTransformationAllocatable(key=key))

class HoistVariablesAnalysis

  Bases: `Transformation`

  Base class for the Analysis part of the hoist variables functionality/transformation.

  Traverses all subroutines to find the variables to be hoisted. Create a derived class and override `find_variables` to define which variables to be hoisted.

  reverse_traversal = True
  process_ignored_items = True
  transform_subroutine(routine, **kwargs)

    Analysis applied to `Subroutine` item.

    Collects all the variables to be hoisted, including renaming in order to grant for unique variable names.

    Parameters:

      - routine (`Subroutine`) – The subroutine to be transformed.

      - **kwargs (optional) – Keyword arguments for the transformation.

  find_variables(routine)

    Override: Find/Select all the variables to be hoisted.

    Selects all local variables that are not `parameter` to be hoisted.

    Parameters:

      routine (`Subroutine`) – The subroutine find the variables.

class HoistVariablesTransformation(as_kwarguments=False, remap_dimensions=True)

  Bases: `Transformation`

  Base class for the Synthesis part of the hoist variables functionality/transformation.

  Traverses all subroutines to hoist the variables. Create a derived class and override `find_variables` to define which variables to be hoisted.

  Note

  Needs the Analysis part to be processed first in order to hoist all already found variables.

  Parameters:

    - as_kwarguments (boolean) – Whether to pass the hoisted arguments as args or kwargs.

    - remap_dimensions (boolean) – Remap dimensions based on variables that are used for initializing other variables that could end up as dimensions for hoisted arrays. Thus, account for possibly uninitialized variables used as dimensions.

  transform_subroutine(routine, **kwargs)

    Transformation applied to `Subroutine` item.

    Hoists all to be hoisted variables which includes

    - appending the arguments for each subroutine

    - appending the arguments for each subroutine call

    - modifying the variable declaration in the subroutine

    - adding the variable declaration in the driver

    Parameters:

      - routine (`Subroutine`) – The subroutine to be transformed.

      - **kwargs (optional) – Keyword arguments for the transformation.

  driver_variable_declaration(routine, variables)

    Override: Define the variable declaration (and possibly allocation, de-allocation, …) for each variable to be hoisted.

    Declares hoisted variables with a re-scope.

    Parameters:

      - routine (`Subroutine`) – The subroutine to add the variable declaration to.

      - variables (tuple of `Variable`) – The tuple of variables to be declared.

  static driver_variable_declaration_dim_remapping(routine, variables)

    Take a list of variables and remap their dimensions for those being arrays to account for possibly uninitialized variables/dimensions.

    Parameters:

      - routine (`Subroutine`) – The relevant subroutine.

      - variables (tuple of `Variable`) – The tuple of variables for remapping.

  driver_call_argument_remapping(routine, call, variables)

    Callback method to re-map hoisted arguments for the driver-level routine.

    The callback will simply add all the hoisted variable arrays to the call without dimension range symbols.

    This callback is used to adjust the argument variable mapping, so that the call signature in the driver can be adjusted to the declaration scheme of subclassed variants of the basic hoisting tnansformation. Potentially, different variants of the hoist transformation can override the behaviour here to map to a differnt call invocation scheme.

    Parameters:

      - routine (`Subroutine`) – The subroutine to add the variable declaration to.

      - call (`CallStatement`) – Call object to which hoisted variables will be added.

      - variables (tuple of `Variable`) – The tuple of variables to be declared.

      - as_kwarguments (boolean) – Whether to pass the hoisted arguments as args or kwargs.

  kernel_call_argument_remapping(routine, call, variables)

    Callback method to re-map hoisted arguments in kernel-to-kernel calls.

    The callback will simply add all the hoisted variable arrays to the call without dimension range symbols. This callback is used to adjust the argument variable mapping, so that the call signature can be adjusted to the declaration scheme of subclassed variants of the basic hoisting transformation. Potentially, different variants of the hoist transformation can override the behaviour here to map to a different call invocation scheme.

    Parameters:

      - routine (`Subroutine`) – The subroutine to add the variable declaration to.

      - call (`CallStatement`) – Call object to which hoisted variables will be added.

      - variables (tuple of `Variable`) – The tuple of variables to be declared.

  kernel_inline_call_argument_remapping(routine, call, variables)

    Append hoisted temporaries to inline function call arguments.

    Parameters:

      - routine (`Subroutine`) – The subroutine to add the variable declaration to.

      - call (`InlineCall`) – ProcedureSymbol to which hoisted variables will be added.

      - variables (tuple of `Variable`) – The tuple of variables to be declared.

class HoistTemporaryArraysAnalysis(dim_vars=None)

  Bases: `HoistVariablesAnalysis`

  Specialisation for the Analysis part of the hoist variables functionality/transformation, to hoist only temporary arrays and if provided only temporary arrays with specific variables/variable names within the array dimensions.

  Parameters:

    dim_vars (tuple of str, optional) – Variables to be within the dimensions of the arrays to be hoisted. If not provided, no checks will be done for the array dimensions.

  reverse_traversal = True
  find_variables(routine)

    Selects temporary arrays to be hoisted.

    - if `dim_vars` is `None` (default) all temporary arrays will be hoisted

    - if `dim_vars` is defined, all arrays with the corresponding dimensions will be hoisted

    Parameters:

      routine (`Subroutine`) – The subroutine find the variables.

class HoistTemporaryArraysTransformationAllocatable(as_kwarguments=False, remap_dimensions=True)

  Bases: `HoistVariablesTransformation`

  Specialisation for the Synthesis part of the hoist variables functionality/transformation, to hoist temporary arrays and make them `allocatable`, including the actual allocation and de-allocation.

  driver_variable_declaration(routine, variables)

    Declares hoisted arrays as `allocatable`, including allocation and de-allocation.

    Parameters:

      - routine (`Subroutine`) – The subroutine to add the variable declaration to.

      - variables (tuple of `Variable`) – The array to be declared, allocated and de-allocated.