Reference Guide  2.5.0
psyclone.transformations.KernelImportsToArguments Class Reference
Inheritance diagram for psyclone.transformations.KernelImportsToArguments:
Collaboration diagram for psyclone.transformations.KernelImportsToArguments:

Public Member Functions

def name (self)
 
def __str__ (self)
 
def validate (self, node, options=None)
 
def apply (self, node, options=None)
 

Detailed Description

Transformation that removes any accesses of imported data from the supplied
kernel and places them in the caller. The values/references are then passed
by argument into the kernel.

Definition at line 2850 of file transformations.py.

Member Function Documentation

◆ apply()

def psyclone.transformations.KernelImportsToArguments.apply (   self,
  node,
  options = None 
)
Convert the imported variables used inside the kernel into arguments
and modify the InvokeSchedule to pass the same imported variables to
the kernel call.

:param node: a kernel call.
:type node: :py:class:`psyclone.psyGen.CodedKern`
:param options: a dictionary with options for transformations.
:type options: Optional[Dict[str, Any]]

Reimplemented from psyclone.psyGen.Transformation.

Definition at line 2916 of file transformations.py.

2916  def apply(self, node, options=None):
2917  '''
2918  Convert the imported variables used inside the kernel into arguments
2919  and modify the InvokeSchedule to pass the same imported variables to
2920  the kernel call.
2921 
2922  :param node: a kernel call.
2923  :type node: :py:class:`psyclone.psyGen.CodedKern`
2924  :param options: a dictionary with options for transformations.
2925  :type options: Optional[Dict[str, Any]]
2926 
2927  '''
2928 
2929  self.validate(node, options)
2930 
2931  kernel = node.get_kernel_schedule()
2932  symtab = kernel.symbol_table
2933  invoke_symtab = node.ancestor(InvokeSchedule).symbol_table
2934  count_imported_vars_removed = 0
2935 
2936  # Transform each imported variable into an argument.
2937  # TODO #11: When support for logging is added, we could warn the user
2938  # if no imports are found in the kernel.
2939  for imported_var in kernel.symbol_table.imported_symbols[:]:
2940  count_imported_vars_removed += 1
2941 
2942  # Resolve the data type information if it is not available
2943  # pylint: disable=unidiomatic-typecheck
2944  if (type(imported_var) is Symbol or
2945  isinstance(imported_var.datatype, UnresolvedType)):
2946  updated_sym = imported_var.resolve_type()
2947  # If we have a new symbol then we must update the symbol table
2948  if updated_sym is not imported_var:
2949  kernel.symbol_table.swap(imported_var, updated_sym)
2950  # pylint: enable=unidiomatic-typecheck
2951 
2952  # Copy the imported symbol into the InvokeSchedule SymbolTable
2953  invoke_symtab.copy_external_import(
2954  updated_sym, tag="AlgArgs_" + updated_sym.name)
2955 
2956  # Keep a reference to the original container so that we can
2957  # update it after the interface has been updated.
2958  container = updated_sym.interface.container_symbol
2959 
2960  # Convert the symbol to an argument and add it to the argument list
2961  current_arg_list = symtab.argument_list
2962  # An argument does not have an initial value.
2963  was_constant = updated_sym.is_constant
2964  updated_sym.is_constant = False
2965  updated_sym.initial_value = None
2966  if was_constant:
2967  # Imported constants lose the constant value but are read-only
2968  # TODO: When #633 and #11 are implemented, warn the user that
2969  # they should transform the constants to literal values first.
2970  updated_sym.interface = ArgumentInterface(
2971  ArgumentInterface.Access.READ)
2972  else:
2973  updated_sym.interface = ArgumentInterface(
2974  ArgumentInterface.Access.READWRITE)
2975  current_arg_list.append(updated_sym)
2976  symtab.specify_argument_list(current_arg_list)
2977 
2978  # Convert PSyIR DataTypes to Gocean VALID_SCALAR_TYPES
2979  # TODO #678: Ideally this strings should be provided by the GOcean
2980  # API configuration.
2981  go_space = ""
2982  if updated_sym.datatype.intrinsic == ScalarType.Intrinsic.REAL:
2983  go_space = "go_r_scalar"
2984  elif (updated_sym.datatype.intrinsic ==
2985  ScalarType.Intrinsic.INTEGER):
2986  go_space = "go_i_scalar"
2987  else:
2988  raise TypeError(
2989  f"The imported variable '{updated_sym.name}' could not be "
2990  f"promoted to an argument because the GOcean "
2991  f"infrastructure does not have any scalar type equivalent "
2992  f"to the PSyIR {updated_sym.datatype} type.")
2993 
2994  # Add the imported variable in the call argument list
2995  node.arguments.append(updated_sym.name, go_space)
2996 
2997  # Check whether we still need the Container symbol from which
2998  # this import was originally accessed
2999  if not kernel.symbol_table.symbols_imported_from(container) and \
3000  not container.wildcard_import:
3001  kernel.symbol_table.remove(container)
3002 
3003  if count_imported_vars_removed > 0:
3004  node.modified = True
3005 
3006 
3007 # For Sphinx AutoAPI documentation generation

References psyclone.domain.lfric.kernel.lfric_kernel_metadata.LFRicKernelMetadata.validate(), psyclone.transformations.MoveTrans.validate(), psyclone.transformations.Dynamo0p3AsyncHaloExchangeTrans.validate(), psyclone.domain.common.transformations.alg_invoke_2_psy_call_trans.AlgInvoke2PSyCallTrans.validate(), psyclone.domain.common.transformations.alg_trans.AlgTrans.validate(), psyclone.domain.common.transformations.kernel_module_inline_trans.KernelModuleInlineTrans.validate(), psyclone.domain.common.transformations.raise_psyir_2_alg_trans.RaisePSyIR2AlgTrans.validate(), psyclone.domain.gocean.transformations.gocean_const_loop_bounds_trans.GOConstLoopBoundsTrans.validate(), psyclone.domain.gocean.transformations.gocean_move_iteration_boundaries_inside_kernel_trans.GOMoveIterationBoundariesInsideKernelTrans.validate(), psyclone.domain.gocean.transformations.gocean_opencl_trans.GOOpenCLTrans.validate(), psyclone.domain.gocean.transformations.raise_psyir_2_gocean_kern_trans.RaisePSyIR2GOceanKernTrans.validate(), psyclone.domain.lfric.transformations.lfric_alg_invoke_2_psy_call_trans.LFRicAlgInvoke2PSyCallTrans.validate(), psyclone.domain.lfric.transformations.raise_psyir_2_lfric_kern_trans.RaisePSyIR2LFRicKernTrans.validate(), psyclone.domain.nemo.transformations.create_nemo_invoke_schedule_trans.CreateNemoInvokeScheduleTrans.validate(), psyclone.domain.nemo.transformations.create_nemo_psy_trans.CreateNemoPSyTrans.validate(), psyclone.domain.nemo.transformations.nemo_allarrayrange2loop_trans.NemoAllArrayRange2LoopTrans.validate(), psyclone.domain.nemo.transformations.nemo_arrayrange2loop_trans.NemoArrayRange2LoopTrans.validate(), psyclone.domain.nemo.transformations.nemo_outerarrayrange2loop_trans.NemoOuterArrayRange2LoopTrans.validate(), psyclone.psyad.transformations.assignment_trans.AssignmentTrans.validate(), psyclone.psyGen.Transformation.validate(), psyclone.psyir.transformations.acc_update_trans.ACCUpdateTrans.validate(), psyclone.psyir.transformations.allarrayaccess2loop_trans.AllArrayAccess2LoopTrans.validate(), psyclone.psyir.transformations.arrayaccess2loop_trans.ArrayAccess2LoopTrans.validate(), psyclone.psyir.transformations.arrayrange2loop_trans.ArrayRange2LoopTrans.validate(), psyclone.psyir.transformations.chunk_loop_trans.ChunkLoopTrans.validate(), psyclone.psyir.transformations.fold_conditional_return_expressions_trans.FoldConditionalReturnExpressionsTrans.validate(), psyclone.psyir.transformations.hoist_local_arrays_trans.HoistLocalArraysTrans.validate(), psyclone.psyir.transformations.hoist_loop_bound_expr_trans.HoistLoopBoundExprTrans.validate(), psyclone.psyir.transformations.hoist_trans.HoistTrans.validate(), psyclone.psyir.transformations.inline_trans.InlineTrans.validate(), psyclone.psyir.transformations.intrinsics.array_reduction_base_trans.ArrayReductionBaseTrans.validate(), psyclone.psyir.transformations.intrinsics.dotproduct2code_trans.DotProduct2CodeTrans.validate(), psyclone.psyir.transformations.intrinsics.intrinsic2code_trans.Intrinsic2CodeTrans.validate(), psyclone.psyir.transformations.intrinsics.matmul2code_trans.Matmul2CodeTrans.validate(), psyclone.psyir.transformations.loop_swap_trans.LoopSwapTrans.validate(), psyclone.psyir.transformations.loop_tiling_2d_trans.LoopTiling2DTrans.validate(), psyclone.psyir.transformations.loop_trans.LoopTrans.validate(), psyclone.psyir.transformations.omp_task_trans.OMPTaskTrans.validate(), psyclone.psyir.transformations.omp_taskwait_trans.OMPTaskwaitTrans.validate(), psyclone.psyir.transformations.parallel_loop_trans.ParallelLoopTrans.validate(), psyclone.psyir.transformations.reference2arrayrange_trans.Reference2ArrayRangeTrans.validate(), psyclone.psyir.transformations.replace_induction_variables_trans.ReplaceInductionVariablesTrans.validate(), psyclone.transformations.OMPDeclareTargetTrans.validate(), psyclone.transformations.DynamoOMPParallelLoopTrans.validate(), psyclone.transformations.Dynamo0p3OMPLoopTrans.validate(), psyclone.transformations.GOceanOMPLoopTrans.validate(), psyclone.transformations.Dynamo0p3RedundantComputationTrans.validate(), psyclone.transformations.Dynamo0p3KernelConstTrans.validate(), psyclone.transformations.ACCRoutineTrans.validate(), psyclone.transformations.KernelImportsToArguments.validate(), psyclone.domain.gocean.transformations.gocean_loop_fuse_trans.GOceanLoopFuseTrans.validate(), psyclone.domain.lfric.transformations.lfric_loop_fuse_trans.LFRicLoopFuseTrans.validate(), psyclone.psyir.transformations.loop_fuse_trans.LoopFuseTrans.validate(), psyclone.domain.gocean.transformations.gocean_extract_trans.GOceanExtractTrans.validate(), psyclone.domain.lfric.transformations.lfric_extract_trans.LFRicExtractTrans.validate(), psyclone.psyir.transformations.extract_trans.ExtractTrans.validate(), psyclone.psyir.transformations.nan_test_trans.NanTestTrans.validate(), psyclone.psyir.transformations.read_only_verify_trans.ReadOnlyVerifyTrans.validate(), psyclone.transformations.ParallelRegionTrans.validate(), psyclone.transformations.OMPParallelTrans.validate(), psyclone.transformations.ACCParallelTrans.validate(), psyclone.transformations.ACCKernelsTrans.validate(), psyclone.transformations.ACCDataTrans.validate(), psyclone.psyir.transformations.psy_data_trans.PSyDataTrans.validate(), psyclone.psyir.transformations.region_trans.RegionTrans.validate(), and psyclone.transformations.ACCEnterDataTrans.validate().

Here is the call graph for this function:

◆ name()

def psyclone.transformations.KernelImportsToArguments.name (   self)
:returns: the name of this transformation.
:rtype: str

Reimplemented from psyclone.psyGen.Transformation.

Definition at line 2857 of file transformations.py.

2857  def name(self):
2858  '''
2859  :returns: the name of this transformation.
2860  :rtype: str
2861  '''
2862  return "KernelImportsToArguments"
2863 
Here is the caller graph for this function:

◆ validate()

def psyclone.transformations.KernelImportsToArguments.validate (   self,
  node,
  options = None 
)
Check that the supplied node is a valid target for this transformation.

:param node: the PSyIR node to validate.
:type node: :py:class:`psyclone.psyGen.CodedKern`
:param options: a dictionary with options for transformations.
:type options: Optional[Dict[str, Any]]

:raises TransformationError: if the supplied node is not a CodedKern.
:raises TransformationError: if this transformation is not applied to \
    a Gocean API Invoke.
:raises TransformationError: if the supplied kernel contains wildcard \
    imports of symbols from one or more containers (e.g. a USE without\
    an ONLY clause in Fortran).

Reimplemented from psyclone.psyGen.Transformation.

Definition at line 2869 of file transformations.py.

2869  def validate(self, node, options=None):
2870  '''
2871  Check that the supplied node is a valid target for this transformation.
2872 
2873  :param node: the PSyIR node to validate.
2874  :type node: :py:class:`psyclone.psyGen.CodedKern`
2875  :param options: a dictionary with options for transformations.
2876  :type options: Optional[Dict[str, Any]]
2877 
2878  :raises TransformationError: if the supplied node is not a CodedKern.
2879  :raises TransformationError: if this transformation is not applied to \
2880  a Gocean API Invoke.
2881  :raises TransformationError: if the supplied kernel contains wildcard \
2882  imports of symbols from one or more containers (e.g. a USE without\
2883  an ONLY clause in Fortran).
2884  '''
2885  if not isinstance(node, CodedKern):
2886  raise TransformationError(
2887  f"The {self.name} transformation can only be applied to "
2888  f"CodedKern nodes but found '{type(node).__name__}' instead.")
2889 
2890  invoke_schedule = node.ancestor(InvokeSchedule)
2891  if not isinstance(invoke_schedule, GOInvokeSchedule):
2892  raise TransformationError(
2893  f"The {self.name} transformation is currently only supported "
2894  f"for the GOcean API but got an InvokeSchedule of type: "
2895  f"'{type(invoke_schedule).__name__}'")
2896 
2897  # Check that there are no unqualified imports or undeclared symbols
2898  try:
2899  kernel = node.get_kernel_schedule()
2900  except SymbolError as err:
2901  raise TransformationError(
2902  f"Kernel '{node.name}' contains undeclared symbol: "
2903  f"{err.value}") from err
2904 
2905  symtab = kernel.symbol_table
2906  for container in symtab.containersymbols:
2907  if container.wildcard_import:
2908  raise TransformationError(
2909  f"Kernel '{node.name}' has a wildcard import of symbols "
2910  f"from container '{container.name}'. This is not "
2911  f"supported.")
2912 
2913  # TODO #649. Check for variables accessed by the kernel but declared
2914  # in an outer scope.
2915 
Here is the caller graph for this function:

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