Reference Guide  2.5.0
psyclone.psyGen.Kern Class Reference
Inheritance diagram for psyclone.psyGen.Kern:
Collaboration diagram for psyclone.psyGen.Kern:

Public Member Functions

def __init__ (self, parent, call, name, ArgumentsClass, check=True)
 
def args (self)
 
def node_str (self, colour=True)
 
def reference_accesses (self, var_accesses)
 
def is_reduction (self)
 
def reduction_arg (self)
 
def reprod_reduction (self)
 
def local_reduction_name (self)
 
def zero_reduction_variable (self, parent, position=None)
 
def reduction_sum_loop (self, parent)
 
def arg_descriptors (self)
 
def arg_descriptors (self, obj)
 
def arguments (self)
 
def name (self)
 
def name (self, value)
 
def is_coloured (self)
 
def iterates_over (self)
 
def local_vars (self)
 
def gen_code (self, parent)
 

Detailed Description

Base class representing a call to a sub-program unit from within the
PSy layer. It is possible for this unit to be in-lined within the
PSy layer.

:param parent: parent of this node in the PSyIR.
:type parent: sub-class of :py:class:`psyclone.psyir.nodes.Node`
:param call: information on the call itself, as obtained by parsing \
             the Algorithm layer code.
:type call: :py:class:`psyclone.parse.algorithm.KernelCall`
:param str name: the name of the routine being called.
:param ArgumentsClass: class to create the object that holds all \
    information on the kernel arguments, as extracted from kernel \
    meta-data (and accessible here via call.ktype).
:type ArgumentsClass: type of :py:class:`psyclone.psyGen.Arguments`
:param bool check: whether to check for consistency between the \
    kernel metadata and the algorithm layer. Defaults to True.

:raises GenerationError: if any of the arguments to the call are \
                         duplicated.

Definition at line 1015 of file psyGen.py.

Member Function Documentation

◆ args()

def psyclone.psyGen.Kern.args (   self)
Return the list of arguments associated with this node. Overide the
base method and simply return our arguments. 

Definition at line 1080 of file psyGen.py.

1080  def args(self):
1081  '''Return the list of arguments associated with this node. Overide the
1082  base method and simply return our arguments. '''
1083  return self.arguments.args
1084 

References psyclone.psyGen.Kern.arguments(), and psyclone.psyir.nodes.call.Call.arguments().

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

◆ is_coloured()

def psyclone.psyGen.Kern.is_coloured (   self)
:returns: True if this kernel is being called from within a \
          coloured loop.
:rtype: bool

Definition at line 1329 of file psyGen.py.

1329  def is_coloured(self):
1330  '''
1331  :returns: True if this kernel is being called from within a \
1332  coloured loop.
1333  :rtype: bool
1334  '''
1335  parent_loop = self.ancestor(Loop)
1336  while parent_loop:
1337  if parent_loop.loop_type == "colour":
1338  return True
1339  parent_loop = parent_loop.ancestor(Loop)
1340  return False
1341 

References psyclone.domain.common.psylayer.psyloop.PSyLoop._iterates_over, psyclone.domain.gocean.kernel.psyir.GOceanKernelMetadata._iterates_over, psyclone.parse.kernel.KernelType._iterates_over, psyclone.psyGen.Kern._iterates_over, and psyclone.psyir.nodes.node.Node.ancestor().

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

◆ is_reduction()

def psyclone.psyGen.Kern.is_reduction (   self)
:returns: whether this kernel/built-in contains a reduction variable.
:rtype: bool

Definition at line 1111 of file psyGen.py.

1111  def is_reduction(self):
1112  '''
1113  :returns: whether this kernel/built-in contains a reduction variable.
1114  :rtype: bool
1115 
1116  '''
1117  return self._reduction
1118 

References psyclone.psyGen.Kern._reduction, and psyclone.psyGen.BuiltIn._reduction.

◆ local_reduction_name()

def psyclone.psyGen.Kern.local_reduction_name (   self)
:returns: a local reduction variable name that is unique for the
          current reduction argument name. This is used for
          thread-local reductions with reproducible reductions.
:rtype: str

Definition at line 1145 of file psyGen.py.

1145  def local_reduction_name(self):
1146  '''
1147  :returns: a local reduction variable name that is unique for the
1148  current reduction argument name. This is used for
1149  thread-local reductions with reproducible reductions.
1150  :rtype: str
1151 
1152  '''
1153  # TODO #2381: Revisit symbol creation, now moved to the
1154  # Kern._reduction_reference() method, and try to associate it
1155  # with the PSy-layer generation or relevant transformation.
1156  return "l_" + self.reduction_arg.name
1157 

References psyclone.psyGen.Kern.reduction_arg().

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

◆ name() [1/2]

◆ name() [2/2]

◆ node_str()

def psyclone.psyGen.Kern.node_str (   self,
  colour = True 
)
 Returns the name of this node with (optional) control codes
to generate coloured output in a terminal that supports it.

:param bool colour: whether or not to include colour control codes.

:returns: description of this node, possibly coloured.
:rtype: str

Reimplemented in psyclone.psyGen.InlinedKern, and psyclone.psyGen.CodedKern.

Definition at line 1085 of file psyGen.py.

1085  def node_str(self, colour=True):
1086  ''' Returns the name of this node with (optional) control codes
1087  to generate coloured output in a terminal that supports it.
1088 
1089  :param bool colour: whether or not to include colour control codes.
1090 
1091  :returns: description of this node, possibly coloured.
1092  :rtype: str
1093  '''
1094  return (self.coloured_name(colour) + " " + self.name +
1095  "(" + self.arguments.names + ")")
1096 

References psyclone.psyGen.Kern.arguments(), psyclone.psyir.nodes.call.Call.arguments(), psyclone.psyir.nodes.node.Node.coloured_name(), psyclone.domain.gocean.kernel.psyir.GOceanKernelMetadata.name, psyclone.domain.gocean.kernel.psyir.GOceanKernelMetadata.GridArg.name, psyclone.domain.gocean.transformations.gocean_const_loop_bounds_trans.GOConstLoopBoundsTrans.name(), psyclone.domain.gocean.transformations.gocean_move_iteration_boundaries_inside_kernel_trans.GOMoveIterationBoundariesInsideKernelTrans.name(), psyclone.domain.gocean.transformations.gocean_opencl_trans.GOOpenCLTrans.name(), psyclone.domain.lfric.kernel.lfric_kernel_metadata.LFRicKernelMetadata.name, psyclone.domain.nemo.transformations.create_nemo_invoke_schedule_trans.CreateNemoInvokeScheduleTrans.name(), psyclone.domain.nemo.transformations.create_nemo_loop_trans.CreateNemoLoopTrans.name(), psyclone.domain.nemo.transformations.create_nemo_psy_trans.CreateNemoPSyTrans.name(), psyclone.domain.nemo.transformations.nemo_allarrayrange2loop_trans.NemoAllArrayRange2LoopTrans.name(), psyclone.domain.nemo.transformations.nemo_arrayrange2loop_trans.NemoArrayRange2LoopTrans.name(), psyclone.domain.nemo.transformations.nemo_outerarrayrange2loop_trans.NemoOuterArrayRange2LoopTrans.name(), psyclone.dynamo0p3.DynamoPSy.name(), psyclone.expression.FunctionVar.name, psyclone.expression.NamedArg.name(), psyclone.gocean1p0.GOKernelGridArgument.name(), psyclone.gocean1p0.GOStencil.name(), psyclone.parse.algorithm.FileInfo.name(), psyclone.parse.algorithm.InvokeCall.name(), psyclone.parse.kernel.KernelProcedure.name(), psyclone.parse.kernel.KernelType.name(), psyclone.parse.module_info.ModuleInfo.name(), psyclone.psyad.transformations.assignment_trans.AssignmentTrans.name(), psyclone.psyGen.PSy.name(), psyclone.psyGen.Invoke.name(), psyclone.psyGen.Kern.name(), psyclone.psyGen.CodedKern.name, psyclone.psyGen.Argument.name(), psyclone.psyGen.Transformation.name(), psyclone.psyGen.DummyTransformation.name(), psyclone.psyir.nodes.container.Container.name, psyclone.psyir.nodes.member.Member.name, psyclone.psyir.nodes.reference.Reference.name(), psyclone.psyir.nodes.routine.Routine.name, psyclone.psyir.symbols.symbol.Symbol.name(), psyclone.psyir.transformations.allarrayaccess2loop_trans.AllArrayAccess2LoopTrans.name(), psyclone.psyir.transformations.arrayrange2loop_trans.ArrayRange2LoopTrans.name(), psyclone.psyir.transformations.fold_conditional_return_expressions_trans.FoldConditionalReturnExpressionsTrans.name(), psyclone.psyir.transformations.loop_trans.LoopTrans.name(), psyclone.psyir.transformations.omp_task_trans.OMPTaskTrans.name(), psyclone.psyir.transformations.psy_data_trans.PSyDataTrans.name(), psyclone.transformations.OMPSingleTrans.name(), psyclone.transformations.OMPMasterTrans.name(), psyclone.transformations.OMPParallelTrans.name(), psyclone.transformations.MoveTrans.name(), psyclone.transformations.Dynamo0p3AsyncHaloExchangeTrans.name(), psyclone.transformations.Dynamo0p3KernelConstTrans.name(), psyclone.transformations.ACCEnterDataTrans.name(), psyclone.transformations.ACCRoutineTrans.name(), psyclone.transformations.ACCKernelsTrans.name(), psyclone.transformations.ACCDataTrans.name(), and psyclone.transformations.KernelImportsToArguments.name().

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

◆ reduction_arg()

def psyclone.psyGen.Kern.reduction_arg (   self)
:returns: the reduction variable if this kernel/built-in
          contains one and `None` otherwise.
:rtype: :py:class:`psyclone.psyGen.KernelArgument` or `NoneType`

Definition at line 1120 of file psyGen.py.

1120  def reduction_arg(self):
1121  '''
1122  :returns: the reduction variable if this kernel/built-in
1123  contains one and `None` otherwise.
1124  :rtype: :py:class:`psyclone.psyGen.KernelArgument` or `NoneType`
1125 
1126  '''
1127  return self._reduction_arg
1128 

References psyclone.psyGen.Kern._reduction_arg.

Here is the caller graph for this function:

◆ reduction_sum_loop()

def psyclone.psyGen.Kern.reduction_sum_loop (   self,
  parent 
)
Generate the appropriate code to place after the end parallel
region.

:param parent: the Node in the f2pygen AST to which to add new code.
:type parent: :py:class:`psyclone.f2pygen.SubroutineGen`

:raises GenerationError: for an unsupported reduction access in \
                         LFRicBuiltIn.

Definition at line 1224 of file psyGen.py.

1224  def reduction_sum_loop(self, parent):
1225  '''
1226  Generate the appropriate code to place after the end parallel
1227  region.
1228 
1229  :param parent: the Node in the f2pygen AST to which to add new code.
1230  :type parent: :py:class:`psyclone.f2pygen.SubroutineGen`
1231 
1232  :raises GenerationError: for an unsupported reduction access in \
1233  LFRicBuiltIn.
1234 
1235  '''
1236  var_name = self._reduction_arg.name
1237  local_var_name = self.local_reduction_name
1238  # A non-reproducible reduction requires a single-valued argument
1239  local_var_ref = self._reduction_reference().name
1240  # A reproducible reduction requires multi-valued argument stored
1241  # as a padded array separately for each thread
1242  if self.reprod_reduction:
1243  local_var_ref = FortranWriter().arrayreference_node(
1244  self._reduction_reference())
1245  reduction_access = self._reduction_arg.access
1246  try:
1247  reduction_operator = REDUCTION_OPERATOR_MAPPING[reduction_access]
1248  except KeyError as err:
1249  api_strings = [access.api_specific_name()
1250  for access in REDUCTION_OPERATOR_MAPPING]
1251  raise GenerationError(
1252  f"Unsupported reduction access "
1253  f"'{reduction_access.api_specific_name()}' found in "
1254  f"LFRicBuiltIn:reduction_sum_loop(). Expected one of "
1255  f"{api_strings}.") from err
1256  symtab = self.scope.symbol_table
1257  thread_idx = symtab.lookup_with_tag("omp_thread_index").name
1258  nthreads = symtab.lookup_with_tag("omp_num_threads").name
1259  do_loop = DoGen(parent, thread_idx, "1", nthreads)
1260  do_loop.add(AssignGen(do_loop, lhs=var_name, rhs=var_name +
1261  reduction_operator + local_var_ref))
1262  parent.add(do_loop)
1263  parent.add(DeallocateGen(parent, local_var_name))
1264 

References psyclone.domain.lfric.lfric_kern_metadata.LFRicKernMetadata._arg_descriptors, psyclone.gocean1p0.GOKernelType1p0._arg_descriptors, psyclone.parse.kernel.KernelType._arg_descriptors, psyclone.psyGen.Kern._arg_descriptors, psyclone.psyGen.BuiltIn._arg_descriptors, psyclone.domain.lfric.lfric_kern.LFRicKern._arguments, psyclone.psyGen.Kern._arguments, psyclone.psyGen.InlinedKern._arguments, psyclone.psyGen.Kern._reduction_arg, psyclone.psyGen.Kern._reduction_reference(), psyclone.psyGen.Kern.local_reduction_name(), psyclone.psyGen.Kern.reduction_arg(), psyclone.psyGen.Kern.reprod_reduction(), psyclone.psyir.nodes.node.Node.scope(), and psyclone.psyir.symbols.symbol_table.SymbolTable.scope().

Here is the call graph for this function:

◆ reference_accesses()

def psyclone.psyGen.Kern.reference_accesses (   self,
  var_accesses 
)
Get all variable access information. The API specific classes
add the accesses to the arguments. So the code here only calls
the baseclass, and increases the location.

:param var_accesses: VariablesAccessInfo instance that stores the \
    information about variable accesses.
:type var_accesses: \
    :py:class:`psyclone.core.VariablesAccessInfo`

Reimplemented in psyclone.gocean1p0.GOKern, psyclone.domain.lfric.lfric_kern.LFRicKern, and psyclone.domain.lfric.lfric_builtins.LFRicBuiltIn.

Definition at line 1097 of file psyGen.py.

1097  def reference_accesses(self, var_accesses):
1098  '''Get all variable access information. The API specific classes
1099  add the accesses to the arguments. So the code here only calls
1100  the baseclass, and increases the location.
1101 
1102  :param var_accesses: VariablesAccessInfo instance that stores the \
1103  information about variable accesses.
1104  :type var_accesses: \
1105  :py:class:`psyclone.core.VariablesAccessInfo`
1106  '''
1107  super().reference_accesses(var_accesses)
1108  var_accesses.next_location()
1109 
Here is the caller graph for this function:

◆ reprod_reduction()

def psyclone.psyGen.Kern.reprod_reduction (   self)
:returns: whether this kernel/built-in is enclosed within an OpenMP
          do loop. If so report whether it has the reproducible flag
          set. Note, this also catches OMPParallelDo Directives but
          they have reprod set to False so it is OK.
:rtype: bool

Definition at line 1130 of file psyGen.py.

1130  def reprod_reduction(self):
1131  '''
1132  :returns: whether this kernel/built-in is enclosed within an OpenMP
1133  do loop. If so report whether it has the reproducible flag
1134  set. Note, this also catches OMPParallelDo Directives but
1135  they have reprod set to False so it is OK.
1136  :rtype: bool
1137 
1138  '''
1139  ancestor = self.ancestor(OMPDoDirective)
1140  if ancestor:
1141  return ancestor.reprod
1142  return False
1143 

References psyclone.psyir.nodes.node.Node.ancestor().

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

◆ zero_reduction_variable()

def psyclone.psyGen.Kern.zero_reduction_variable (   self,
  parent,
  position = None 
)
Generate code to zero the reduction variable and to zero the local
reduction variable if one exists. The latter is used for reproducible
reductions, if specified.

:param parent: the Node in the AST to which to add new code.
:type parent: :py:class:`psyclone.psyir.nodes.Node`
:param str position: where to position the new code in the AST.

:raises GenerationError: if the variable to zero is not a scalar.
:raises GenerationError: if the reprod_pad_size (read from the \
                         configuration file) is less than 1.
:raises GenerationError: for a reduction into a scalar that is \
                         neither 'real' nor 'integer'.

Definition at line 1158 of file psyGen.py.

1158  def zero_reduction_variable(self, parent, position=None):
1159  '''
1160  Generate code to zero the reduction variable and to zero the local
1161  reduction variable if one exists. The latter is used for reproducible
1162  reductions, if specified.
1163 
1164  :param parent: the Node in the AST to which to add new code.
1165  :type parent: :py:class:`psyclone.psyir.nodes.Node`
1166  :param str position: where to position the new code in the AST.
1167 
1168  :raises GenerationError: if the variable to zero is not a scalar.
1169  :raises GenerationError: if the reprod_pad_size (read from the \
1170  configuration file) is less than 1.
1171  :raises GenerationError: for a reduction into a scalar that is \
1172  neither 'real' nor 'integer'.
1173 
1174  '''
1175  if not position:
1176  position = ["auto"]
1177  var_name = self._reduction_arg.name
1178  local_var_name = self.local_reduction_name
1179  var_arg = self._reduction_arg
1180  # Check for a non-scalar argument
1181  if not var_arg.is_scalar:
1182  raise GenerationError(
1183  f"Kern.zero_reduction_variable() should be a scalar but "
1184  f"found '{var_arg.argument_type}'.")
1185  # Generate the reduction variable
1186  var_data_type = var_arg.intrinsic_type
1187  if var_data_type == "real":
1188  data_value = "0.0"
1189  elif var_data_type == "integer":
1190  data_value = "0"
1191  else:
1192  raise GenerationError(
1193  f"Kern.zero_reduction_variable() should be either a 'real' or "
1194  f"an 'integer' scalar but found scalar of type "
1195  f"'{var_arg.intrinsic_type}'.")
1196  # Retrieve the precision information (if set) and append it
1197  # to the initial reduction value
1198  if var_arg.precision:
1199  kind_type = var_arg.precision
1200  zero_sum_variable = "_".join([data_value, kind_type])
1201  else:
1202  kind_type = ""
1203  zero_sum_variable = data_value
1204  parent.add(AssignGen(parent, lhs=var_name, rhs=zero_sum_variable),
1205  position=position)
1206  if self.reprod_reduction:
1207  parent.add(DeclGen(parent, datatype=var_data_type,
1208  entity_decls=[local_var_name],
1209  allocatable=True, kind=kind_type,
1210  dimension=":,:"))
1211  nthreads = \
1212  self.scope.symbol_table.lookup_with_tag("omp_num_threads").name
1213  if Config.get().reprod_pad_size < 1:
1214  raise GenerationError(
1215  f"REPROD_PAD_SIZE in {Config.get().filename} should be a "
1216  f"positive integer, but it is set to "
1217  f"'{Config.get().reprod_pad_size}'.")
1218  pad_size = str(Config.get().reprod_pad_size)
1219  parent.add(AllocateGen(parent, local_var_name + "(" + pad_size +
1220  "," + nthreads + ")"), position=position)
1221  parent.add(AssignGen(parent, lhs=local_var_name,
1222  rhs=zero_sum_variable), position=position)
1223 

References psyclone.psyGen.Kern._reduction_arg, psyclone.psyGen.Kern.local_reduction_name(), psyclone.psyGen.Kern.reprod_reduction(), psyclone.psyir.nodes.node.Node.scope(), and psyclone.psyir.symbols.symbol_table.SymbolTable.scope().

Here is the call graph for this function:

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