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

Public Member Functions

def name (self)
 
def apply (self, node, options=None)
 
def validate (self, nodes, options)
 
- Public Member Functions inherited from psyclone.psyir.transformations.region_trans.RegionTrans
def get_node_list (self, nodes)
 

Static Public Attributes

tuple excluded_node_types = (CodeBlock, Return, PSyDataNode)
 
- Static Public Attributes inherited from psyclone.psyir.transformations.region_trans.RegionTrans
tuple excluded_node_types = ()
 

Detailed Description

Add an OpenACC data region around a list of nodes in the PSyIR.
COPYIN, COPYOUT and COPY clauses are added as required.

For example:

>>> from psyclone.parse.algorithm import parse
>>> from psyclone.psyGen import PSyFactory
>>> api = "nemo"
>>> ast, invokeInfo = parse(NEMO_SOURCE_FILE, api=api)
>>> psy = PSyFactory(api).create(invokeInfo)
>>>
>>> from psyclone.transformations import ACCKernelsTrans, ACCDataTrans
>>> ktrans = ACCKernelsTrans()
>>> dtrans = ACCDataTrans()
>>>
>>> schedule = psy.invokes.get('tra_adv').schedule
>>> # Uncomment the following line to see a text view of the schedule
>>> # print(schedule.view())
>>>
>>> # Add a kernels construct for execution on the device
>>> kernels = schedule.children[9]
>>> ktrans.apply(kernels)
>>>
>>> # Enclose the kernels in a data construct
>>> kernels = schedule.children[9]
>>> dtrans.apply(kernels)

Definition at line 2710 of file transformations.py.

Member Function Documentation

◆ apply()

def psyclone.transformations.ACCDataTrans.apply (   self,
  node,
  options = None 
)
Put the supplied node or list of nodes within an OpenACC data region.

:param node: the PSyIR node(s) to enclose in the data region.
:type node: (list of) :py:class:`psyclone.psyir.nodes.Node`
:param options: a dictionary with options for transformations.
:type options: Optional[Dict[str, Any]]

Reimplemented from psyclone.psyGen.Transformation.

Definition at line 2751 of file transformations.py.

2751  def apply(self, node, options=None):
2752  '''
2753  Put the supplied node or list of nodes within an OpenACC data region.
2754 
2755  :param node: the PSyIR node(s) to enclose in the data region.
2756  :type node: (list of) :py:class:`psyclone.psyir.nodes.Node`
2757  :param options: a dictionary with options for transformations.
2758  :type options: Optional[Dict[str, Any]]
2759 
2760  '''
2761  # Ensure we are always working with a list of nodes, even if only
2762  # one was supplied via the `node` argument.
2763  node_list = self.get_node_list(node)
2764 
2765  self.validate(node_list, options)
2766 
2767  parent = node_list[0].parent
2768  start_index = node_list[0].position
2769 
2770  # Create a directive containing the nodes in node_list and insert it.
2771  directive = ACCDataDirective(
2772  parent=parent, children=[node.detach() for node in node_list])
2773 
2774  parent.children.insert(start_index, directive)
2775 

References psyclone.psyir.transformations.region_trans.RegionTrans.get_node_list(), 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.ACCDataTrans.name (   self)
:returns: the name of this transformation.
:rtype: str

Reimplemented from psyclone.psyGen.Transformation.

Definition at line 2743 of file transformations.py.

2743  def name(self):
2744  '''
2745  :returns: the name of this transformation.
2746  :rtype: str
2747 
2748  '''
2749  return "ACCDataTrans"
2750 
Here is the caller graph for this function:

◆ validate()

def psyclone.transformations.ACCDataTrans.validate (   self,
  nodes,
  options 
)
Check that we can safely add a data region around the supplied list
of nodes.

:param nodes: the proposed node(s) to enclose in a data region.
:type nodes: List[:py:class:`psyclone.psyir.nodes.Node`] |
    :py:class:`psyclone.psyir.nodes.Node`
:param options: a dictionary with options for transformations.
:type options: Optional[Dict[str, Any]]

:raises TransformationError: if the Schedule to which the nodes
    belong already has an 'enter data' directive.
:raises TransformationError: if any of the nodes are themselves
    data directives.
:raises TransformationError: if an array of structures needs to be
    deep copied (this is not currently supported).

Reimplemented from psyclone.psyir.transformations.region_trans.RegionTrans.

Definition at line 2776 of file transformations.py.

2776  def validate(self, nodes, options):
2777  # pylint: disable=signature-differs
2778  '''
2779  Check that we can safely add a data region around the supplied list
2780  of nodes.
2781 
2782  :param nodes: the proposed node(s) to enclose in a data region.
2783  :type nodes: List[:py:class:`psyclone.psyir.nodes.Node`] |
2784  :py:class:`psyclone.psyir.nodes.Node`
2785  :param options: a dictionary with options for transformations.
2786  :type options: Optional[Dict[str, Any]]
2787 
2788  :raises TransformationError: if the Schedule to which the nodes
2789  belong already has an 'enter data' directive.
2790  :raises TransformationError: if any of the nodes are themselves
2791  data directives.
2792  :raises TransformationError: if an array of structures needs to be
2793  deep copied (this is not currently supported).
2794 
2795  '''
2796  # Ensure we are always working with a list of nodes, even if only
2797  # one was supplied via the `nodes` argument.
2798  node_list = self.get_node_list(nodes)
2799 
2800  super().validate(node_list, options)
2801 
2802  # Check that the Schedule to which the nodes belong does not already
2803  # have an 'enter data' directive.
2804  schedule = node_list[0].root
2805  acc_dirs = schedule.walk(ACCEnterDataDirective)
2806  if acc_dirs:
2807  raise TransformationError(
2808  "Cannot add an OpenACC data region to a schedule that "
2809  "already contains an 'enter data' directive.")
2810  # Check that we don't have any accesses to arrays of derived types
2811  # that we can't yet deep copy.
2812  for node in node_list:
2813  for sref in node.walk(StructureReference):
2814 
2815  # Find the loop variables for all Loops that contain this
2816  # access and are themselves within the data region.
2817  loop_vars = []
2818  cursor = sref.ancestor(Loop, limit=node)
2819  while cursor:
2820  loop_vars.append(Signature(cursor.variable.name))
2821  cursor = cursor.ancestor(Loop)
2822 
2823  # Now check whether any of these loop variables appear within
2824  # the structure reference.
2825  # Loop over each component of the structure reference that is
2826  # an array access.
2827  array_accesses = sref.walk(ArrayMixin)
2828  for access in array_accesses:
2829  if not isinstance(access, StructureMember):
2830  continue
2831  var_accesses = VariablesAccessInfo(access.indices)
2832  for var in loop_vars:
2833  if var not in var_accesses.all_signatures:
2834  continue
2835  # For an access such as my_struct(ii)%my_array(ji)
2836  # then if we're inside a loop over it we would actually
2837  # need a loop to do the deep copy:
2838  # do ii = 1, N
2839  # !$acc data copyin(my_struct(ii)%my_array)
2840  # end do
2841  raise TransformationError(
2842  f"Data region contains a structure access "
2843  f"'{sref.debug_string()}' where component "
2844  f"'{access.name}' is an array and is iterated over"
2845  f" (variable '{var}'). Deep copying of data for "
2846  f"structures is only supported where the deepest "
2847  f"component is the one being iterated over.")
2848 
2849 

References psyclone.psyir.transformations.region_trans.RegionTrans.get_node_list().

Here is the call graph for this function:
Here is the caller graph for this function:

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