39 ''' This module implements the support for 'built-in' operations in the
40 PSyclone LFRic (Dynamo 0.3) API. Each supported built-in is implemented
41 as a different Python class, all inheriting from the LFRicBuiltIn class.
42 The LFRicBuiltInCallFactory creates the Python object required for
43 a given built-in call. '''
48 from psyclone.core import AccessType, Signature, VariablesAccessInfo
51 LFRicKernelMetadata, FieldArgMetadata, ScalarArgMetadata,
52 FieldVectorArgMetadata)
57 Reference, IntrinsicCall)
62 BUILTIN_DEFINITIONS_FILE =
"lfric_builtins_mod.f90"
69 def get_lowercase_builtin_map(builtin_map_capitalised_dict):
71 Convert the names of the supported built-in operations to lowercase
72 for comparison and invoke-generation purpose.
74 :param builtin_map_capitalised_dict: a dictionary of built-in names.
75 :type builtin_map_capitalised_dict: dict of str
77 :returns: a dictionary of lowercase Fortran built-in names as keys \
78 and case-sensitive Python built-in names as values.
83 for fortran_name
in builtin_map_capitalised_dict:
84 python_name = builtin_map_capitalised_dict[fortran_name]
85 builtin_map_dict[fortran_name.lower()] = python_name
86 return builtin_map_dict
90 '''Creates the necessary framework for a call to an LFRic built-in,
91 This consists of the operation itself and the loop over unique
97 return "Factory for a call to an LFRic built-in."
102 Create the objects needed for a call to the built-in described in
103 the call (BuiltInCall) object.
105 :param call: details of the call to this built-in in the \
107 :type call: :py:class:`psyclone.parse.algorithm.BuiltInCall`
108 :param parent: the schedule instance to which the built-in call \
110 :type parent: :py:class:`psyclone.dynamo0p3.DynInvokeSchedule`
112 :raises ParseError: if the name of the function being called is \
113 not a recognised built-in.
114 :raises InternalError: if the built-in does not iterate over DoFs.
117 if call.func_name
not in BUILTIN_MAP:
119 f
"Unrecognised built-in call in LFRic API: found "
120 f
"'{call.func_name}' but expected one of "
121 f
"{list(BUILTIN_MAP_CAPITALISED.keys())}.")
125 builtin = BUILTIN_MAP[call.func_name]()
132 if call.ktype.iterates_over ==
"dof":
136 f
"An LFRic built-in must iterate over DoFs but kernel "
137 f
"'{call.func_name}' iterates over "
138 f
"'{call.ktype.iterates_over}'")
139 dofloop =
LFRicLoop(parent=parent, loop_type=loop_type)
143 builtin.load(call, parent=dofloop.loop_body)
146 dofloop.load(builtin)
150 dofloop.loop_body.addchild(builtin)
157 '''Abstract base class for a node representing a call to an LFRic
160 :raises NotImplementedError: if a subclass of this abstract class \
161 does not set the value of '_datatype'.
174 raise NotImplementedError(
175 "An LFRicBuiltIn should be overridden by a subclass that "
176 "sets the value of '_datatype', but '_datatype' is not set.")
182 '''Must be overridden by subclass.'''
185 def _builtin_metadata(cls, meta_args):
186 '''Utility to take 'meta_args' metadata and return LFRic kernel
187 metadata for a built-in. Assumes the metadata describes a
188 built-in kernel that operates on a DoF and that the naming
189 protocol uses the name of the metadata type and adds '_code'
190 to it for the name of the subroutine.
192 :param meta_args: a list of 'meta_args' metadata.
193 :type meta_args: List[subclass of \
194 :py:class:`psyclone.domain.lfric.kernel.CommonArgMetadata`]
196 :returns: LFRic kernel metadata for this built-in.
197 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
203 procedure_name=f
"{cls._case_name}_code",
211 if len(metadata.meta_args_get([
212 FieldArgMetadata, FieldVectorArgMetadata])) > 1:
214 return (f
"Built-in: {self._case_name} ("
215 f
"{self._datatype}-valued field{plural})")
218 '''Get all variable access information from this node. The assigned-to
219 variable will be set to 'WRITE'.
221 :param var_accesses: VariablesAccessInfo instance that stores the \
222 information about variable accesses.
223 :type var_accesses: \
224 :py:class:`psyclone.core.VariablesAccessInfo`
226 :raises InternalError: if an unsupported argument type is encountered.
229 table = self.scope.symbol_table
235 for arg
in self.
argsargs:
236 if arg.form
in [
"variable",
"indexed_variable"]:
238 sym = table.lookup_with_tag(
239 f
"{arg.name}:{suffix_map[arg.argument_type]}")
242 name = arg.declaration_name
245 f
"LFRicBuiltin.reference_accesses only supports field "
246 f
"and scalar arguments but got '{arg.name}' of type "
247 f
"'{arg.argument_type}'")
248 if arg.access == AccessType.WRITE:
249 written.add_access(
Signature(name), arg.access, self)
251 var_accesses.add_access(
Signature(name), arg.access, self)
253 var_accesses.merge(written)
256 var_accesses.next_location()
258 def load(self, call, parent=None):
260 Populate the state of this object using the supplied call object.
262 :param call: The BuiltIn object from which to extract information \
263 about this built-in call.
264 :type call: :py:class:`psyclone.parse.algorithm.BuiltInCall`
265 :param parent: The parent node of the kernel call in the PSyIR \
266 we are constructing. This will be a loop.
267 :type parent: :py:class:`psyclone.domain.lfric.LFRicLoop`
273 BuiltIn.load(self, call, DynKernelArguments, parent)
283 Check that this built-in conforms to the LFRic API.
285 :raises ParseError: if a built-in call does not iterate over DoFs.
286 :raises ParseError: if an argument to a built-in kernel is not \
287 one of valid argument types.
288 :raises ParseError: if an argument to a built-in kernel has \
289 an invalid data type.
290 :raises ParseError: if a built-in kernel writes to more than \
292 :raises ParseError: if a built-in kernel does not have at least \
294 :raises ParseError: if all field arguments are not on the same space.
295 :raises ParseError: if all field arguments of a non-conversion \
296 built-in do not have the same data type.
301 if self.
iterates_overiterates_over
not in const.BUILTIN_ITERATION_SPACES:
303 f
"In the LFRic API built-in calls must operate on one of "
304 f
"{const.BUILTIN_ITERATION_SPACES} but found "
305 f
"'{self.iterates_over}' for {self}.")
314 if arg.argument_type
not in const.VALID_BUILTIN_ARG_TYPES:
316 f
"In the LFRic API an argument to a built-in kernel "
317 f
"must be one of {const.VALID_BUILTIN_ARG_TYPES} but "
318 f
"kernel '{self.name}' has an argument of type "
319 f
"'{arg.argument_type}'.")
321 if arg.data_type
not in const.VALID_BUILTIN_DATA_TYPES:
323 f
"In the LFRic API an argument to a built-in kernel "
324 f
"must have one of {const.VALID_BUILTIN_DATA_TYPES} as "
325 f
"a data type but kernel '{self.name}' has an argument "
326 f
"of data type '{arg.data_type}'.")
329 if arg.access
in [AccessType.WRITE, AccessType.SUM,
330 AccessType.READWRITE]:
332 if arg.argument_type
in const.VALID_FIELD_NAMES:
334 spaces.add(arg.function_space)
335 data_types.add(arg.data_type)
338 raise ParseError(f
"A built-in kernel in the LFRic API must "
339 f
"have one and only one argument that is "
340 f
"written to but found {write_count} for "
341 f
"kernel '{self.name}'.")
343 raise ParseError(f
"A built-in kernel in the LFRic API must have "
344 f
"at least one field as an argument but "
345 f
"kernel '{self.name}' has none.")
347 spaces_str = [str(x)
for x
in sorted(spaces)]
349 f
"All field arguments to a built-in in the LFRic API "
350 f
"must be on the same space. However, found spaces "
351 f
"{spaces_str} for arguments to '{self.name}'")
353 conversion_builtins = [
"real_to_int_X",
356 conversion_builtins_lower = [x.lower()
for x
in conversion_builtins]
357 if len(data_types) != 1
and self.
namenamename
not in conversion_builtins_lower:
358 data_types_str = [str(x)
for x
in sorted(data_types)]
360 f
"In the LFRic API only the data type conversion built-ins "
361 f
"{conversion_builtins} are allowed to have field arguments of"
362 f
" different data types. However, found different data types "
363 f
"{data_types_str} for field arguments to '{self.name}'.")
368 Dynamically looks up the name of the 'undf' variable for the
369 space that this kernel updates.
371 :returns: the name of the undf variable.
375 field = self.
_arguments_arguments.iteration_space_arg()
376 return field.function_space.undf_name
381 Built-ins do not currently require quadrature.
392 Built-ins do not require reference-element properties.
403 Built-ins do not perform operations with Column-Matrix-Assembly
415 We don't have any inter-grid built-ins.
426 :returns: a list of function space descriptor objects which \
427 contain information about the function spaces.
428 :rtype: list of :py:class:`psyclone.dynamo0p3.FSDescriptor`
435 Finds or creates the symbol representing the index in any loops
438 :returns: symbol representing the DoF loop index.
439 :rtype: :py:class:`psyclone.psyir.symbols.DataSymbol`
442 table = self.scope.symbol_table
445 return table.find_or_create_integer_symbol(
446 "df", tag=
"dof_loop_idx")
450 Creates a DoF-indexed StructureReference for each of the field
451 arguments to this Built-In kernel. e.g. if the kernel has a field
452 argument named 'fld1' then this routine will create an
453 ArrayReference for 'fld1_data(df)' where 'df' is the DoF-loop
454 variable and 'fld1_data' is the pointer to the data array within
457 :returns: a reference to the 'df'th element of each kernel argument
459 :rtype: List[:py:class:`psyclone.psyir.nodes.ArrayReference`]
462 table = self.scope.symbol_table
470 sym = table.lookup_with_tag(
471 f
"{arg.name}:{suffixes[arg.argument_type]}")
472 refs.append(ArrayReference.create(sym, [Reference(idx_sym)]))
477 Finds or creates either a Reference (for a symbol) or PSyIR (for a
478 literal expression) for any scalar arguments to this Built-In kernel.
480 :returns: a Reference or PSyIR expression for each scalar kernel
482 :rtype: list of subclasses of `:py:class:`psyclone.psyir.nodes.Node`
485 return [arg.psyir_expression()
for arg
in self.
_arguments_arguments.args
488 def _replace_with_assignment(self, lhs, rhs):
490 Creates an assignment from the left- and right-hand-side nodes, then
491 replaces this Builtin with the newly-created Assignment node.
493 :param lhs: The left-hand side of the assignment to be created.
494 :type lhs: :py:class:`psyclone.psyir.nodes.ArrayReference`
495 :param rhs: The right-hand side of the assignment to be created.
496 :type rhs: :py:class:`psyclone.psyir.nodes.DataNode`
498 :returns: the new Assignment node.
499 :rtype: :py:class:`psyclone.psyir.nodes.Assignment`
502 assign = Assignment.create(lhs, rhs)
504 assign.preceding_comment = str(self)
505 self.replace_with(assign)
520 ''' Add one, real-valued, field to another and return the result as
521 a third, real-valued, field.
524 _case_name =
"X_plus_Y"
529 '''Returns the kernel metadata describing this built-in. Implemented in
530 a datatype-independent way to allow for re-use.
532 :returns: kernel metadata describing this built-in.
533 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
545 return (f
"Built-in: {self._case_name} (add "
546 f
"{self._datatype}-valued fields)")
550 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
551 This Built-In node is replaced by an Assignment node.
553 :returns: the lowered version of this node.
554 :rtype: :py:class:`psyclone.psyir.node.Node`
563 rhs = BinaryOperation.create(BinaryOperation.Operator.ADD,
564 arg_refs[1], arg_refs[2])
571 ''' Add the second, real-valued, field to the first field and return it.
574 _case_name =
"inc_X_plus_Y"
579 '''Returns the kernel metadata describing this built-in.
581 :returns: kernel metadata describing this built-in.
582 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
591 return (f
"Built-in: {self._case_name} (increment "
592 f
"{a_or_an(self._datatype)} {self._datatype}-valued field)")
596 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
597 This BuiltIn node is replaced by an Assignment node.
599 :returns: the lowered version of this node.
600 :rtype: :py:class:`psyclone.psyir.node.Node`
609 rhs = BinaryOperation.create(BinaryOperation.Operator.ADD,
610 lhs.copy(), arg_refs[1])
617 ''' `Y = a + X` where `a` is a real scalar and `X` and `Y` are
618 real-valued fields (DoF-wise addition of a scalar value).
621 _case_name =
"a_plus_X"
626 '''Returns the kernel metadata describing this built-in.
628 :returns: kernel metadata describing this built-in.
629 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
640 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
641 This BuiltIn node is replaced by an Assignment node.
643 :returns: the lowered version of this node.
644 :rtype: :py:class:`psyclone.psyir.node.Node`
655 rhs = BinaryOperation.create(BinaryOperation.Operator.ADD,
656 scalar_args[0], arg_refs[1])
663 ''' `X = a + X` where `a` is a real scalar and `X` is a real-valued
664 field (DoF-wise addition of a scalar value).
667 _case_name =
"inc_a_plus_X"
672 '''Returns the kernel metadata describing this built-in.
674 :returns: kernel metadata describing this built-in.
675 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
685 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
686 This BuiltIn node is replaced by an Assignment node.
688 :returns: the lowered version of this node.
689 :rtype: :py:class:`psyclone.psyir.node.Node`
700 rhs = BinaryOperation.create(BinaryOperation.Operator.ADD,
701 scalar_args[0], lhs.copy())
708 ''' `Z = a*X + Y` where `a` is a real scalar and `Z`, `X` and
709 `Y` are real-valued fields.
712 _case_name =
"aX_plus_Y"
717 '''Returns the kernel metadata describing this built-in.
719 :returns: kernel metadata describing this built-in.
720 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
732 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
733 This BuiltIn node is replaced by an Assignment node.
735 :returns: the lowered version of this node.
736 :rtype: :py:class:`psyclone.psyir.node.Node`
747 mult_op = BinaryOperation.create(BinaryOperation.Operator.MUL,
748 scalar_args[0], arg_refs[1])
749 rhs = BinaryOperation.create(BinaryOperation.Operator.ADD,
750 mult_op, arg_refs[2])
757 ''' `X = a*X + Y` where `a` is a real scalar and `X` and `Y` are
761 _case_name =
"inc_aX_plus_Y"
766 '''Returns the kernel metadata describing this built-in.
768 :returns: kernel metadata describing this built-in.
769 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
780 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
781 This BuiltIn node is replaced by an Assignment node.
783 :returns: the lowered version of this node.
784 :rtype: :py:class:`psyclone.psyir.node.Node`
795 mult_op = BinaryOperation.create(BinaryOperation.Operator.MUL,
796 scalar_args[0], lhs.copy())
797 rhs = BinaryOperation.create(BinaryOperation.Operator.ADD,
798 mult_op, arg_refs[1])
805 ''' `X = X + b*Y` where `b` is a real scalar and `X` and `Y` are
809 _case_name =
"inc_X_plus_bY"
814 '''Returns the kernel metadata describing this built-in.
816 :returns: kernel metadata describing this built-in.
817 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
828 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
829 This BuiltIn node is replaced by an Assignment node.
831 :returns: the lowered version of this node.
832 :rtype: :py:class:`psyclone.psyir.node.Node`
843 mult_op = BinaryOperation.create(BinaryOperation.Operator.MUL,
844 scalar_args[0], arg_refs[1])
845 rhs = BinaryOperation.create(BinaryOperation.Operator.ADD,
853 ''' `Z = a*X + b*Y` where `a` and `b` are real scalars and `Z`, `X` and
854 `Y` are real-valued fields.
857 _case_name =
"aX_plus_bY"
862 '''Returns the kernel metadata describing this built-in.
864 :returns: kernel metadata describing this built-in.
865 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
878 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
879 This BuiltIn node is replaced by an Assignment node.
881 :returns: the lowered version of this node.
882 :rtype: :py:class:`psyclone.psyir.node.Node`
894 mult_op_a = BinaryOperation.create(BinaryOperation.Operator.MUL,
895 scalar_args[0], arg_refs[1])
896 mult_op_b = BinaryOperation.create(BinaryOperation.Operator.MUL,
897 scalar_args[1], arg_refs[2])
898 rhs = BinaryOperation.create(BinaryOperation.Operator.ADD,
899 mult_op_a, mult_op_b)
906 ''' `X = a*X + b*Y` where `a` and `b` are real scalars and `X` and `Y`
907 are real-valued fields.
910 _case_name =
"inc_aX_plus_bY"
915 '''Returns the kernel metadata describing this built-in.
917 :returns: kernel metadata describing this built-in.
918 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
930 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
931 This BuiltIn node is replaced by an Assignment node.
933 :returns: the lowered version of this node.
934 :rtype: :py:class:`psyclone.psyir.node.Node`
946 mult_op_a = BinaryOperation.create(BinaryOperation.Operator.MUL,
947 scalar_args[0], lhs.copy())
948 mult_op_b = BinaryOperation.create(BinaryOperation.Operator.MUL,
949 scalar_args[1], arg_refs[1])
950 rhs = BinaryOperation.create(BinaryOperation.Operator.ADD,
951 mult_op_a, mult_op_b)
958 ''' `Z = a*X + a*Y = a*(X + Y)` where `a` is a real scalar and `Z`,
959 `X` and `Y` are real-valued fields.
962 _case_name =
"aX_plus_aY"
967 '''Returns the kernel metadata describing this built-in.
969 :returns: kernel metadata describing this built-in.
970 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
982 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
983 This BuiltIn node is replaced by an Assignment node.
985 :returns: the lowered version of this node.
986 :rtype: :py:class:`psyclone.psyir.node.Node`
997 add_op = BinaryOperation.create(BinaryOperation.Operator.ADD,
998 arg_refs[1], arg_refs[2])
999 rhs = BinaryOperation.create(BinaryOperation.Operator.MUL,
1000 scalar_args[0], add_op)
1012 ''' Subtract one, real-valued, field from another and return the
1013 result as a third, real-valued, field.
1016 _case_name =
"X_minus_Y"
1021 '''Returns the kernel metadata describing this built-in.
1023 :returns: kernel metadata describing this built-in.
1024 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1034 return (f
"Built-in: {self._case_name} (subtract "
1035 f
"{self._datatype}-valued fields)")
1039 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1040 This BuiltIn node is replaced by an Assignment node.
1042 :returns: the lowered version of this node.
1043 :rtype: :py:class:`psyclone.psyir.node.Node`
1052 rhs = BinaryOperation.create(BinaryOperation.Operator.SUB,
1053 arg_refs[1], arg_refs[2])
1060 ''' Subtract the second, real-valued, field from the first field
1064 _case_name =
"inc_X_minus_Y"
1069 '''Returns the kernel metadata describing this built-in.
1071 :returns: kernel metadata describing this built-in.
1072 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1081 return (f
"Built-in: {self._case_name} (decrement "
1082 f
"{a_or_an(self._datatype)} {self._datatype}-valued field)")
1086 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1087 This BuiltIn node is replaced by an Assignment node.
1089 :returns: the lowered version of this node.
1090 :rtype: :py:class:`psyclone.psyir.node.Node`
1099 rhs = BinaryOperation.create(BinaryOperation.Operator.SUB,
1100 lhs.copy(), arg_refs[1])
1107 ''' `Y = a - X` where `a` is a real scalar and `X` and `Y` are real-valued
1108 fields (DoF-wise subtraction of field elements from a scalar value).
1111 _case_name =
"a_minus_X"
1116 '''Returns the kernel metadata describing this built-in.
1118 :returns: kernel metadata describing this built-in.
1119 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1130 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1131 This BuiltIn node is replaced by an Assignment node.
1133 :returns: the lowered version of this node.
1134 :rtype: :py:class:`psyclone.psyir.node.Node`
1145 rhs = BinaryOperation.create(BinaryOperation.Operator.SUB,
1146 scalar_args[0], arg_refs[1])
1153 ''' `X = a - X` where `a` is a real scalar and `X` is a real-valued
1154 field (DoF-wise subtraction of field elements from a scalar value).
1157 _case_name =
"inc_a_minus_X"
1162 '''Returns the kernel metadata describing this built-in.
1164 :returns: kernel metadata describing this built-in.
1165 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1175 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1176 This BuiltIn node is replaced by an Assignment node.
1178 :returns: the lowered version of this node.
1179 :rtype: :py:class:`psyclone.psyir.node.Node`
1190 rhs = BinaryOperation.create(BinaryOperation.Operator.SUB,
1191 scalar_args[0], lhs.copy())
1198 ''' `Y = X - a` where `a` is a real scalar and `X` and `Y` are real-valued
1199 fields (DoF-wise subtraction of a scalar value from field elements).
1202 _case_name =
"X_minus_a"
1207 '''Returns the kernel metadata describing this built-in.
1209 :returns: kernel metadata describing this built-in.
1210 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1221 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1222 This BuiltIn node is replaced by an Assignment node.
1224 :returns: the lowered version of this node.
1225 :rtype: :py:class:`psyclone.psyir.node.Node`
1236 rhs = BinaryOperation.create(BinaryOperation.Operator.SUB,
1237 arg_refs[1], scalar_args[0])
1244 ''' `X = X - a` where `a` is a real scalar and `X` is a real-valued
1245 field (DoF-wise subtraction of a scalar value from field elements).
1248 _case_name =
"inc_X_minus_a"
1253 '''Returns the kernel metadata describing this built-in.
1255 :returns: kernel metadata describing this built-in.
1256 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1266 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1267 This BuiltIn node is replaced by an Assignment node.
1269 :returns: the lowered version of this node.
1270 :rtype: :py:class:`psyclone.psyir.node.Node`
1281 rhs = BinaryOperation.create(BinaryOperation.Operator.SUB,
1282 lhs.copy(), scalar_args[0])
1289 ''' `Z = a*X - Y` where `a` is a real scalar and `Z`, `X` and
1290 `Y` are real-valued fields.
1293 _case_name =
"aX_minus_Y"
1298 '''Returns the kernel metadata describing this built-in.
1300 :returns: kernel metadata describing this built-in.
1301 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1313 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1314 This BuiltIn node is replaced by an Assignment node.
1316 :returns: the lowered version of this node.
1317 :rtype: :py:class:`psyclone.psyir.node.Node`
1328 mult_op = BinaryOperation.create(BinaryOperation.Operator.MUL,
1329 scalar_args[0], arg_refs[1])
1330 rhs = BinaryOperation.create(BinaryOperation.Operator.SUB,
1331 mult_op, arg_refs[2])
1338 ''' `Z = X - b*Y` where `b` is a real scalar and `Z`, `X` and
1339 `Y` are real-valued fields.
1342 _case_name =
"X_minus_bY"
1347 '''Returns the kernel metadata describing this built-in.
1349 :returns: kernel metadata describing this built-in.
1350 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1362 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1363 This BuiltIn node is replaced by an Assignment node.
1365 :returns: the lowered version of this node.
1366 :rtype: :py:class:`psyclone.psyir.node.Node`
1377 mult_op = BinaryOperation.create(BinaryOperation.Operator.MUL,
1378 scalar_args[0], arg_refs[2])
1379 rhs = BinaryOperation.create(BinaryOperation.Operator.SUB,
1380 arg_refs[1], mult_op)
1387 ''' `X = X - b*Y` where `b` is a real scalar and `X` and `Y` are
1391 _case_name =
"inc_X_minus_bY"
1396 '''Returns the kernel metadata describing this built-in.
1398 :returns: kernel metadata describing this built-in.
1399 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1410 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1411 This BuiltIn node is replaced by an Assignment node.
1413 :returns: the lowered version of this node.
1414 :rtype: :py:class:`psyclone.psyir.node.Node`
1425 mult_op = BinaryOperation.create(BinaryOperation.Operator.MUL,
1426 scalar_args[0], arg_refs[1])
1427 rhs = BinaryOperation.create(BinaryOperation.Operator.SUB,
1428 lhs.copy(), mult_op)
1435 ''' `Z = a*X - b*Y` where `a` and `b` are real scalars and `Z`, `X` and
1436 `Y` are real-valued fields.
1439 _case_name =
"aX_minus_bY"
1444 '''Returns the kernel metadata describing this built-in.
1446 :returns: kernel metadata describing this built-in.
1447 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1460 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1461 This BuiltIn node is replaced by an Assignment node.
1463 :returns: the lowered version of this node.
1464 :rtype: :py:class:`psyclone.psyir.node.Node`
1476 mult_op_a = BinaryOperation.create(BinaryOperation.Operator.MUL,
1477 scalar_args[0], arg_refs[1])
1478 mult_op_b = BinaryOperation.create(BinaryOperation.Operator.MUL,
1479 scalar_args[1], arg_refs[2])
1480 rhs = BinaryOperation.create(BinaryOperation.Operator.SUB,
1481 mult_op_a, mult_op_b)
1493 ''' DoF-wise product of one, real-valued, field with another with
1494 the result returned as a third, real-valued, field.
1497 _case_name =
"X_times_Y"
1502 '''Returns the kernel metadata describing this built-in.
1504 :returns: kernel metadata describing this built-in.
1505 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1515 return (f
"Built-in: {self._case_name} (multiply "
1516 f
"{self._datatype}-valued fields)")
1520 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1521 This BuiltIn node is replaced by an Assignment node.
1523 :returns: the lowered version of this node.
1524 :rtype: :py:class:`psyclone.psyir.node.Node`
1533 rhs = BinaryOperation.create(BinaryOperation.Operator.MUL,
1534 arg_refs[1], arg_refs[2])
1541 ''' Multiply the first, real-valued, field by the second and return it.
1544 _case_name =
"inc_X_times_Y"
1549 '''Returns the kernel metadata describing this built-in.
1551 :returns: kernel metadata describing this built-in.
1552 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1561 return (f
"Built-in: {self._case_name} (multiply one "
1562 f
"{self._datatype}-valued field by another)")
1566 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1567 This BuiltIn node is replaced by an Assignment node.
1569 :returns: the lowered version of this node.
1570 :rtype: :py:class:`psyclone.psyir.node.Node`
1579 rhs = BinaryOperation.create(BinaryOperation.Operator.MUL,
1580 lhs.copy(), arg_refs[1])
1587 ''' `X = a*X*Y` where `a` is a real scalar and `X` and `Y` are
1591 _case_name =
"inc_aX_times_Y"
1596 '''Returns the kernel metadata describing this built-in.
1598 :returns: kernel metadata describing this built-in.
1599 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1610 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1611 This BuiltIn node is replaced by an Assignment node.
1613 :returns: the lowered version of this node.
1614 :rtype: :py:class:`psyclone.psyir.node.Node`
1625 mult_op = BinaryOperation.create(BinaryOperation.Operator.MUL,
1626 scalar_args[0], lhs.copy())
1627 rhs = BinaryOperation.create(BinaryOperation.Operator.MUL,
1628 mult_op, arg_refs[1])
1640 ''' Multiply the first, real-valued, field by a real scalar and
1641 return the result as a second, real-valued, field (`Y = a*X`).
1644 _case_name =
"a_times_X"
1649 '''Returns the kernel metadata describing this built-in.
1651 :returns: kernel metadata describing this built-in.
1652 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1662 return (f
"Built-in: {self._case_name} (copy a scaled "
1663 f
"{self._datatype}-valued field)")
1667 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1668 This BuiltIn node is replaced by an Assignment node.
1670 :returns: the lowered version of this node.
1671 :rtype: :py:class:`psyclone.psyir.node.Node`
1682 rhs = BinaryOperation.create(BinaryOperation.Operator.MUL,
1683 scalar_args[0], arg_refs[1])
1690 ''' Multiply a real-valued field by a real scalar and return it.
1693 _case_name =
"inc_a_times_X"
1698 '''Returns the kernel metadata describing this built-in.
1700 :returns: kernel metadata describing this built-in.
1701 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1710 return (f
"Built-in: {self._case_name} (scale "
1711 f
"{a_or_an(self._datatype)} {self._datatype}-valued field)")
1715 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1716 This BuiltIn node is replaced by an Assignment node.
1718 :returns: the lowered version of this node.
1719 :rtype: :py:class:`psyclone.psyir.node.Node`
1730 rhs = BinaryOperation.create(BinaryOperation.Operator.MUL,
1731 scalar_args[0], lhs.copy())
1742 ''' Divide the first, real-valued, field by the second and return
1743 the result as a third, real-valued, field.
1746 _case_name =
"X_divideby_Y"
1751 '''Returns the kernel metadata describing this built-in.
1753 :returns: kernel metadata describing this built-in.
1754 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1764 return (f
"Built-in: {self._case_name} (divide "
1765 f
"{self._datatype}-valued fields)")
1769 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1770 This BuiltIn node is replaced by an Assignment node.
1772 :returns: the lowered version of this node.
1773 :rtype: :py:class:`psyclone.psyir.node.Node`
1782 rhs = BinaryOperation.create(BinaryOperation.Operator.DIV,
1783 arg_refs[1], arg_refs[2])
1790 ''' Divide the first, real-valued, field by the second and return it.
1793 _case_name =
"inc_X_divideby_Y"
1798 '''Returns the kernel metadata describing this built-in.
1800 :returns: kernel metadata describing this built-in.
1801 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1810 return (f
"Built-in: {self._case_name} (divide one "
1811 f
"{self._datatype}-valued field by another)")
1815 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1816 This BuiltIn node is replaced by an Assignment node.
1818 :returns: the lowered version of this node.
1819 :rtype: :py:class:`psyclone.psyir.node.Node`
1828 rhs = BinaryOperation.create(BinaryOperation.Operator.DIV,
1829 lhs.copy(), arg_refs[1])
1836 ''' Divide a real-valued field by a real scalar and return the
1837 result in another, real-valued, field.
1840 _case_name =
"X_divideby_a"
1845 '''Returns the kernel metadata describing this built-in.
1847 :returns: kernel metadata describing this built-in.
1848 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1858 return (f
"Built-in: {self._case_name} (divide a real-valued field "
1859 f
"by {a_or_an(self._datatype)} {self._datatype} scalar "
1864 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1865 This BuiltIn node is replaced by an Assignment node.
1867 :returns: the lowered version of this node.
1868 :rtype: :py:class:`psyclone.psyir.node.Node`
1879 rhs = BinaryOperation.create(BinaryOperation.Operator.DIV,
1880 arg_refs[1], scalar_args[0])
1887 ''' Divide a real-valued field by a real scalar and return it.
1890 _case_name =
"inc_X_divideby_a"
1895 '''Returns the kernel metadata describing this built-in.
1897 :returns: kernel metadata describing this built-in.
1898 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1907 return (f
"Built-in: {self._case_name} (divide a real-valued field "
1908 f
"by {a_or_an(self._datatype)} {self._datatype} scalar "
1913 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1914 This BuiltIn node is replaced by an Assignment node.
1916 :returns: the lowered version of this node.
1917 :rtype: :py:class:`psyclone.psyir.node.Node`
1928 rhs = BinaryOperation.create(BinaryOperation.Operator.DIV,
1929 lhs.copy(), scalar_args[0])
1940 ''' DoF-wise division of a scalar value `a` by the elements
1941 of a real-valued field, `X`, storing the result in another,
1942 real-valued, field, `Y` (`Y = a/X`).
1945 _case_name =
"a_divideby_X"
1950 '''Returns the kernel metadata describing this built-in.
1952 :returns: kernel metadata describing this built-in.
1953 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
1963 return (f
"Built-in: {self._case_name} (inverse scaling of "
1964 f
"{a_or_an(self._datatype)} {self._datatype}-valued "
1965 f
"field (Y = a/X))")
1969 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
1970 This BuiltIn node is replaced by an Assignment node.
1972 :returns: the lowered version of this node.
1973 :rtype: :py:class:`psyclone.psyir.node.Node`
1984 rhs = BinaryOperation.create(BinaryOperation.Operator.DIV,
1985 scalar_args[0], arg_refs[1])
1992 ''' DoF-wise division of a scalar value `a` by the elements
1993 of a real-valued field, `X`, storing the result in the same
1997 _case_name =
"inc_a_divideby_X"
2002 '''Returns the kernel metadata describing this built-in.
2004 :returns: kernel metadata describing this built-in.
2005 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2014 return (f
"Built-in: {self._case_name} (inverse scaling of "
2015 f
"{a_or_an(self._datatype)} {self._datatype}-valued "
2016 f
"field (X = a/X))")
2020 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2021 This BuiltIn node is replaced by an Assignment node.
2023 :returns: the lowered version of this node.
2024 :rtype: :py:class:`psyclone.psyir.node.Node`
2035 rhs = BinaryOperation.create(BinaryOperation.Operator.DIV,
2036 scalar_args[0], lhs.copy())
2048 ''' Raise a real-valued field to a real power and return it.
2051 _case_name =
"inc_X_powreal_a"
2056 '''Returns the kernel metadata describing this built-in.
2058 :returns: kernel metadata describing this built-in.
2059 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2068 return (f
"Built-in: {self._case_name} (raise "
2069 f
"{a_or_an(self._datatype)} {self._datatype}-valued field "
2070 f
"to a real power)")
2074 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2075 This BuiltIn node is replaced by an Assignment node.
2077 :returns: the lowered version of this node.
2078 :rtype: :py:class:`psyclone.psyir.node.Node`
2088 rhs = BinaryOperation.create(BinaryOperation.Operator.POW,
2089 lhs.copy(), scalar_args[0])
2096 ''' Raise a real-valued field to an integer power and return it.
2099 _case_name =
"inc_X_powint_n"
2104 '''Returns the kernel metadata describing this built-in.
2106 :returns: kernel metadata describing this built-in.
2107 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2116 return (f
"Built-in: {self._case_name} (raise "
2117 f
"{a_or_an(self._datatype)} {self._datatype}-valued field "
2118 f
"to an integer power)")
2122 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2123 This BuiltIn node is replaced by an Assignment node.
2125 :returns: the lowered version of this node.
2126 :rtype: :py:class:`psyclone.psyir.node.Node`
2136 rhs = BinaryOperation.create(BinaryOperation.Operator.POW,
2137 lhs.copy(), scalar_args[0])
2149 ''' Set a real-valued field equal to a real scalar value.
2152 _case_name =
"setval_c"
2157 '''Returns the kernel metadata describing this built-in.
2159 :returns: kernel metadata describing this built-in.
2160 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2169 return (f
"Built-in: {self._case_name} (set {a_or_an(self._datatype)} "
2170 f
"{self._datatype}-valued field to a {self._datatype} "
2175 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2176 This BuiltIn node is replaced by an Assignment node.
2178 :returns: the lowered version of this node.
2179 :rtype: :py:class:`psyclone.psyir.node.Node`
2190 rhs = scalar_args[0]
2197 ''' Set a real-valued field equal to another, real-valued, field.
2200 _case_name =
"setval_X"
2205 '''Returns the kernel metadata describing this built-in.
2207 :returns: kernel metadata describing this built-in.
2208 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2217 return (f
"Built-in: {self._case_name} (set {a_or_an(self._datatype)} "
2218 f
"{self._datatype}-valued field equal to another such field)")
2222 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2223 This BuiltIn node is replaced by an Assignment node.
2225 :returns: the lowered version of this node.
2226 :rtype: :py:class:`psyclone.psyir.node.Node`
2242 ''' Fill a real-valued field with pseudo-random numbers.
2245 _case_name =
"setval_random"
2250 '''Returns the kernel metadata describing this built-in.
2252 :returns: kernel metadata describing this built-in.
2253 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2261 return (f
"Built-in: {self._case_name} (fill {a_or_an(self._datatype)} "
2262 f
"{self._datatype}-valued field with pseudo-random numbers)")
2266 Lowers this LFRic built-in kernel to language-level PSyIR.
2267 This BuiltIn node is replaced by an IntrinsicCall node.
2269 :returns: the lowered version of this node.
2270 :rtype: :py:class:`psyclone.psyir.node.IntrinsicCall`
2278 call = IntrinsicCall.create(IntrinsicCall.Intrinsic.RANDOM_NUMBER,
2281 call.preceding_comment = str(self)
2283 self.replace_with(call)
2292 ''' Calculates the inner product of two real-valued fields,
2293 `innprod = SUM( X(:)*Y(:) )`.
2296 _case_name =
"X_innerproduct_Y"
2301 '''Returns the kernel metadata describing this built-in.
2303 :returns: kernel metadata describing this built-in.
2304 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2315 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2316 This BuiltIn node is replaced by an Assignment node.
2318 :returns: the lowered version of this node.
2319 :rtype: :py:class:`psyclone.psyir.node.Node`
2328 mult_op = BinaryOperation.create(BinaryOperation.Operator.MUL,
2329 arg_refs[0], arg_refs[1])
2330 rhs = BinaryOperation.create(BinaryOperation.Operator.ADD,
2331 lhs.copy(), mult_op)
2338 ''' Calculates the inner product of one real-valued field by itself,
2339 `innprod = SUM( X(:)*X(:) )`.
2342 _case_name =
"X_innerproduct_X"
2347 '''Returns the kernel metadata describing this built-in.
2349 :returns: kernel metadata describing this built-in.
2350 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2360 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2361 This BuiltIn node is replaced by an Assignment node.
2363 :returns: the lowered version of this node.
2364 :rtype: :py:class:`psyclone.psyir.node.Node`
2373 mult_op = BinaryOperation.create(BinaryOperation.Operator.MUL,
2374 arg_refs[0].copy(), arg_refs[0])
2375 rhs = BinaryOperation.create(BinaryOperation.Operator.ADD,
2376 lhs.copy(), mult_op)
2388 ''' Computes the sum of the elements of a real-valued field.
2391 _case_name =
"sum_X"
2396 '''Returns the kernel metadata describing this built-in.
2398 :returns: kernel metadata describing this built-in.
2399 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2408 return (f
"Built-in: {self._case_name} (sum {a_or_an(self._datatype)} "
2409 f
"{self._datatype}-valued field)")
2413 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2414 This BuiltIn node is replaced by an Assignment node.
2416 :returns: the lowered version of this node.
2417 :rtype: :py:class:`psyclone.psyir.node.Node`
2426 rhs = BinaryOperation.create(BinaryOperation.Operator.ADD,
2427 lhs.copy(), arg_refs[0])
2439 ''' Returns the sign of a real-valued field elements using the
2440 Fortran intrinsic `sign` function, `Y = sign(a, X)`.
2443 _case_name =
"sign_X"
2448 '''Returns the kernel metadata describing this built-in.
2450 :returns: kernel metadata describing this built-in.
2451 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2461 return (f
"Built-in: {self._case_name} (sign of "
2462 f
"{a_or_an(self._datatype)} {self._datatype}-valued field)")
2466 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2467 This BuiltIn node is replaced by an Assignment node.
2469 :returns: the lowered version of this node.
2470 :rtype: :py:class:`psyclone.psyir.node.Node`
2481 rhs = IntrinsicCall.create(IntrinsicCall.Intrinsic.SIGN,
2482 [scalar_args[0], arg_refs[1]])
2494 ''' Returns the maximum of a real scalar and real-valued field
2495 elements. The result is stored as another, real-valued, field:
2499 _case_name =
"max_aX"
2504 '''Returns the kernel metadata describing this built-in.
2506 :returns: kernel metadata describing this built-in.
2507 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2518 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2519 This BuiltIn node is replaced by an Assignment node.
2521 :returns: the lowered version of this node.
2522 :rtype: :py:class:`psyclone.psyir.node.Node`
2533 rhs = IntrinsicCall.create(IntrinsicCall.Intrinsic.MAX,
2534 [scalar_args[0], arg_refs[1]])
2541 ''' Returns the maximum of a real scalar and real-valued field
2542 elements. The result is stored in the same, real-valued, field:
2546 _case_name =
"inc_max_aX"
2551 '''Returns the kernel metadata describing this built-in.
2553 :returns: kernel metadata describing this built-in.
2554 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2564 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2565 This BuiltIn node is replaced by an Assignment node.
2567 :returns: the lowered version of this node.
2568 :rtype: :py:class:`psyclone.psyir.node.Node`
2579 rhs = IntrinsicCall.create(IntrinsicCall.Intrinsic.MAX,
2580 [scalar_args[0], lhs.copy()])
2591 ''' Returns the minimum of a real scalar and real-valued field
2592 elements. The result is stored as another, real-valued, field:
2596 _case_name =
"min_aX"
2601 '''Returns the kernel metadata describing this built-in.
2603 :returns: kernel metadata describing this built-in.
2604 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2615 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2616 This BuiltIn node is replaced by an Assignment node.
2618 :returns: the lowered version of this node.
2619 :rtype: :py:class:`psyclone.psyir.node.Node`
2630 rhs = IntrinsicCall.create(IntrinsicCall.Intrinsic.MIN,
2631 [scalar_args[0], arg_refs[1]])
2638 ''' Returns the minimum of a real scalar and real-valued field
2639 elements. The result is stored in the same, real-valued, field:
2643 _case_name =
"inc_min_aX"
2648 '''Returns the kernel metadata describing this built-in.
2650 :returns: kernel metadata describing this built-in.
2651 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2661 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2662 This BuiltIn node is replaced by an Assignment node.
2664 :returns: the lowered version of this node.
2665 :rtype: :py:class:`psyclone.psyir.node.Node`
2676 rhs = IntrinsicCall.create(IntrinsicCall.Intrinsic.MIN,
2677 [scalar_args[0], lhs.copy()])
2688 ''' Converts real-valued field elements to integer-valued
2689 field elements using the Fortran intrinsic `INT` function,
2690 `Y = INT(X, kind=i_<prec>)`. Here `Y` is an integer-valued
2691 field of precision `i_<prec>` and `X` is the real-valued
2692 field being converted.
2695 _datatype =
"integer"
2696 _case_name =
"real_to_int_X"
2700 '''Returns the kernel metadata describing this built-in.
2702 :returns: kernel metadata describing this built-in.
2703 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2711 return (f
"Built-in: {self._case_name} (convert a real-valued to "
2712 f
"an integer-valued field)")
2716 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2717 This BuiltIn node is replaced by an Assignment node.
2719 :returns: the lowered version of this node.
2720 :rtype: :py:class:`psyclone.psyir.node.Node`
2729 i_precision = arg_refs[0].datatype.precision
2730 rhs = IntrinsicCall.create(
2731 IntrinsicCall.Intrinsic.INT,
2732 [arg_refs[1], (
"kind", Reference(i_precision))])
2743 ''' Converts real-valued field elements to real-valued field elements
2744 of a different precision using the Fortran intrinsic `REAL` function,
2745 `Y = REAL(X, kind=r_<prec>)`. Here `Y` is a real-valued field of
2746 precision `kind=r_<prec>` and `X` is the real-valued field whose
2747 values are to be converted from their defined precision.
2751 _case_name =
"real_to_real_X"
2755 '''Returns the kernel metadata describing this built-in.
2757 :returns: kernel metadata describing this built-in.
2758 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
2766 return (f
"Built-in: {self._case_name} (convert a real-valued "
2767 f
"to a real-valued field)")
2771 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
2772 This BuiltIn node is replaced by an Assignment node.
2774 :returns: the lowered version of this node.
2775 :rtype: :py:class:`psyclone.psyir.node.Node`
2784 r_precision = arg_refs[0].datatype.precision
2785 rhs = IntrinsicCall.create(
2786 IntrinsicCall.Intrinsic.REAL,
2787 [arg_refs[1], (
"kind", Reference(r_precision))])
2802 ''' Add corresponding elements of two, integer-valued, fields, `X`
2803 and `Y`, and return the result as a third, integer-valued, field, `Z`.
2804 Inherits the `lower_to_language_level` method from the real-valued
2805 built-in equivalent `LFRicXPlusYKern`.
2808 _case_name =
"int_X_plus_Y"
2809 _datatype =
"integer"
2813 ''' Add each element of an integer-valued field, `X`, to the
2814 corresponding element of another integer-valued field, `Y`, and
2815 store the result back in `X`.
2816 Inherits the `lower_to_language_level` method from the real-valued
2817 built-in equivalent `LFRicIncXPlusYKern`.
2820 _case_name =
"int_inc_X_plus_Y"
2821 _datatype =
"integer"
2825 ''' Add an integer scalar value, `a`, to each element of an
2826 integer-valued field, `X`, and return the result as a second,
2827 integer-valued, field, `Y`.
2828 Inherits the `lower_to_language_level` method from the real-valued
2829 built-in equivalent `LFRicAPlusXKern`.
2832 _case_name =
"int_a_plus_X"
2833 _datatype =
"integer"
2837 ''' Add an integer scalar value, `a`, to each element of an
2838 integer-valued field, `X`, and return the result in the
2840 Inherits the `lower_to_language_level` method from the real-valued
2841 built-in equivalent `LFRicIncAPlusXKern`.
2844 _case_name =
"int_inc_a_plus_X"
2845 _datatype =
"integer"
2854 ''' Subtract each element of an integer-valued field, `Y`, from
2855 the corresponding element of another, integer-valued, field, `X`,
2856 and return the result as a third, integer-valued, field, `Z`.
2857 Inherits the `lower_to_language_level` method from the real-valued
2858 built-in equivalent `LFRicXMinusYKern`.
2861 _case_name =
"int_X_minus_Y"
2862 _datatype =
"integer"
2866 ''' Subtract each element of an integer-valued field, `Y`, from
2867 the corresponding element of another, integer-valued, field, `X`,
2868 and store the result back in `X`.
2869 Inherits the `lower_to_language_level` method from the real-valued
2870 built-in equivalent `LFRicIncXMinusYKern`.
2873 _case_name =
"int_inc_X_minus_Y"
2874 _datatype =
"integer"
2878 ''' Subtract each element of an integer-valued field, `X`, from
2879 an integer scalar value, `a`, and return the result as a second,
2880 integer-valued, field, `Y`.
2881 Inherits the `lower_to_language_level` method from the real-valued
2882 built-in equivalent `LFRicAMinusXKern`.
2885 _case_name =
"int_a_minus_X"
2886 _datatype =
"integer"
2890 ''' Subtract each element of an integer-valued field, `X`, from
2891 an integer scalar value, `a`, and return the result in the
2893 Inherits the `lower_to_language_level` method from the real-valued
2894 built-in equivalent `LFRicIncAMinusXKern`.
2897 _case_name =
"int_inc_a_minus_X"
2898 _datatype =
"integer"
2902 ''' Subtract an integer scalar value, `a`, from each element of an
2903 integer-valued field, `X`, and return the result as a second,
2904 integer-valued, field, `Y`.
2905 Inherits the `lower_to_language_level` method from the real-valued
2906 built-in equivalent `LFRicXMinusAKern`.
2909 _case_name =
"int_X_minus_a"
2910 _datatype =
"integer"
2914 ''' Subtract an integer scalar value, `a`, from each element of an
2915 integer-valued field, `X`, and return the result in the same field.
2916 Inherits the `lower_to_language_level` method from the real-valued
2917 built-in equivalent `LFRicIncXMinusAKern`.
2920 _case_name =
"int_inc_X_minus_a"
2921 _datatype =
"integer"
2930 ''' Multiply each element of one, integer-valued, field, `X`, by
2931 the corresponding element of another, integer-valued, field, `Y`,
2932 and return the result as a third, integer-valued, field, `Z`.
2933 Inherits the `lower_to_language_level` method from the real-valued
2934 built-in equivalent `LFRicXTimesYKern`.
2937 _case_name =
"int_X_times_Y"
2938 _datatype =
"integer"
2942 ''' Multiply each element of one, integer-valued, field, `X`, by
2943 the corresponding element of another, integer-valued, field, `Y`,
2944 and store the result back in `X`.
2945 Inherits the `lower_to_language_level` method from the real-valued
2946 built-in equivalent `LFRicIncXTimesYKern`.
2949 _case_name =
"int_inc_X_times_Y"
2950 _datatype =
"integer"
2959 ''' Multiply each element of the first, integer-valued, field, `X`,
2960 by an integer scalar, `a`, and return the result as a second,
2961 integer-valued, field `Y` (`Y = a*X`).
2962 Inherits the `lower_to_language_level` method from the real-valued
2963 built-in equivalent `LFRicATimesXKern`.
2966 _case_name =
"int_a_times_X"
2967 _datatype =
"integer"
2971 ''' Multiply each element of an integer-valued field, `X` by
2972 an integer scalar, `a`, and store the result back in `X`.
2973 Inherits the `lower_to_language_level` method from the real-valued
2974 built-in equivalent `LFRicIncATimesXKern`.
2977 _case_name =
"int_inc_a_times_X"
2978 _datatype =
"integer"
2987 ''' Assign a single constant integer scalar value, `c`, to all
2988 elements of an integer-valued field, `X`.
2989 Inherits the `lower_to_language_level` method from the real-valued
2990 built-in equivalent `LFRicSetvalCKern`.
2993 _case_name =
"int_setval_c"
2994 _datatype =
"integer"
2998 ''' Copy one element of an integer-valued field (second argument),
2999 `X`, to the corresponding element of another, integer-valued,
3000 field (first argument), `Y`.
3001 Inherits the `lower_to_language_level` method from the real-valued
3002 built-in equivalent `LFRicSetvalXKern`.
3005 _case_name =
"int_setval_X"
3006 _datatype =
"integer"
3015 ''' Returns the sign of an integer-valued field elements using the
3016 Fortran intrinsic `sign` function, `Y = sign(a, X)`.
3017 Inherits the `lower_to_language_level` method from the real-valued
3018 built-in equivalent `LFRicSignXKern`.
3021 _case_name =
"int_sign_X"
3022 _datatype =
"integer"
3031 ''' Returns the maximum of an integer scalar and integer-valued
3032 field elements. The result is stored as another, integer-valued,
3033 field: `Y = max(a, X)`.
3034 Inherits the `lower_to_language_level` method from the real-valued
3035 built-in equivalent `LFRicMaxAXKern`.
3037 _case_name =
"int_max_aX"
3038 _datatype =
"integer"
3042 ''' Returns the maximum of an integer scalar and integer-valued
3043 field elements. The result is stored in the same, integer-valued,
3044 field: `X = max(a, X)`.
3045 Inherits the `lower_to_language_level` method from the real-valued
3046 built-in equivalent `LFRicIncMaxAXKern`.
3048 _case_name =
"int_inc_max_aX"
3049 _datatype =
"integer"
3058 ''' Returns the minimum of an integer scalar and integer-valued
3059 field elements. The result is stored as another, integer-valued,
3060 field: `Y = min(a, X)`.
3061 Inherits the `lower_to_language_level` method from the real-valued
3062 built-in equivalent `LFRicMinAXKern`.
3065 _case_name =
"int_min_aX"
3066 _datatype =
"integer"
3070 ''' Returns the minimum of an integer scalar and integer-valued
3071 field elements. The result is stored in the same, integer-valued,
3072 field: `X = min(a, X)`.
3073 Inherits the `lower_to_language_level` method from the real-valued
3074 built-in equivalent `LFRicIncMinAXKern`.
3077 _case_name =
"int_inc_min_aX"
3078 _datatype =
"integer"
3086 ''' Converts integer-valued field elements to real-valued
3087 field elements using the Fortran intrinsic `REAL` function,
3088 `Y = REAL(X, kind=r_<prec>)`. Here `Y` is a real-valued
3089 field of precision `r_<prec>` and `X` is the integer-valued
3090 field being converted.
3094 _case_name =
"int_to_real_X"
3098 '''Returns the kernel metadata describing this built-in.
3100 :returns: kernel metadata describing this built-in.
3101 :rtype: :py:class:`psyclone.domain.lfric.kernel.LFRicKernelMetadata`
3109 return (f
"Built-in: {self._case_name} (convert an integer-valued "
3110 f
"to a real-valued field)")
3114 Lowers this LFRic-specific built-in kernel to language-level PSyIR.
3115 This BuiltIn node is replaced by an Assignment node.
3117 :returns: the lowered version of this node.
3118 :rtype: :py:class:`psyclone.psyir.node.Node`
3127 r_precision = arg_refs[0].datatype.precision
3128 rhs = IntrinsicCall.create(
3129 IntrinsicCall.Intrinsic.REAL,
3130 [arg_refs[1], (
"kind", Reference(r_precision))])
3141 REAL_BUILTIN_MAP_CAPITALISED = {
3143 "X_plus_Y": LFRicXPlusYKern,
3144 "inc_X_plus_Y": LFRicIncXPlusYKern,
3145 "a_plus_X": LFRicAPlusXKern,
3146 "inc_a_plus_X": LFRicIncAPlusXKern,
3147 "aX_plus_Y": LFRicAXPlusYKern,
3148 "inc_aX_plus_Y": LFRicIncAXPlusYKern,
3149 "inc_X_plus_bY": LFRicIncXPlusBYKern,
3150 "aX_plus_bY": LFRicAXPlusBYKern,
3151 "inc_aX_plus_bY": LFRicIncAXPlusBYKern,
3152 "aX_plus_aY": LFRicAXPlusAYKern,
3154 "X_minus_Y": LFRicXMinusYKern,
3155 "inc_X_minus_Y": LFRicIncXMinusYKern,
3156 "a_minus_X": LFRicAMinusXKern,
3157 "inc_a_minus_X": LFRicIncAMinusXKern,
3158 "X_minus_a": LFRicXMinusAKern,
3159 "inc_X_minus_a": LFRicIncXMinusAKern,
3160 "aX_minus_Y": LFRicAXMinusYKern,
3161 "X_minus_bY": LFRicXMinusBYKern,
3162 "inc_X_minus_bY": LFRicIncXMinusBYKern,
3163 "aX_minus_bY": LFRicAXMinusBYKern,
3165 "X_times_Y": LFRicXTimesYKern,
3166 "inc_X_times_Y": LFRicIncXTimesYKern,
3167 "inc_aX_times_Y": LFRicIncAXTimesYKern,
3169 "a_times_X": LFRicATimesXKern,
3170 "inc_a_times_X": LFRicIncATimesXKern,
3172 "X_divideby_Y": LFRicXDividebyYKern,
3173 "inc_X_divideby_Y": LFRicIncXDividebyYKern,
3174 "X_divideby_a": LFRicXDividebyAKern,
3175 "inc_X_divideby_a": LFRicIncXDividebyAKern,
3178 "a_divideby_X": LFRicADividebyXKern,
3179 "inc_a_divideby_X": LFRicIncADividebyXKern,
3181 "inc_X_powreal_a": LFRicIncXPowrealAKern,
3182 "inc_X_powint_n": LFRicIncXPowintNKern,
3185 "setval_c": LFRicSetvalCKern,
3186 "setval_X": LFRicSetvalXKern,
3187 "setval_random": LFRicSetvalRandomKern,
3189 "X_innerproduct_Y": LFRicXInnerproductYKern,
3190 "X_innerproduct_X": LFRicXInnerproductXKern,
3192 "sum_X": LFRicSumXKern,
3194 "sign_X": LFRicSignXKern,
3196 "max_aX": LFRicMaxAXKern,
3197 "inc_max_aX": LFRicIncMaxAXKern,
3199 "min_aX": LFRicMinAXKern,
3200 "inc_min_aX": LFRicIncMinAXKern,
3202 "real_to_int_X": LFRicRealToIntXKern,
3204 "real_to_real_X": LFRicRealToRealXKern}
3207 INT_BUILTIN_MAP_CAPITALISED = {
3209 "int_X_plus_Y": LFRicIntXPlusYKern,
3210 "int_inc_X_plus_Y": LFRicIntIncXPlusYKern,
3211 "int_a_plus_X": LFRicIntAPlusXKern,
3212 "int_inc_a_plus_X": LFRicIntIncAPlusXKern,
3214 "int_X_minus_Y": LFRicIntXMinusYKern,
3215 "int_inc_X_minus_Y": LFRicIntIncXMinusYKern,
3216 "int_a_minus_X": LFRicIntAMinusXKern,
3217 "int_inc_a_minus_X": LFRicIntIncAMinusXKern,
3218 "int_X_minus_a": LFRicIntXMinusAKern,
3219 "int_inc_X_minus_a": LFRicIntIncXMinusAKern,
3221 "int_X_times_Y": LFRicIntXTimesYKern,
3222 "int_inc_X_times_Y": LFRicIntIncXTimesYKern,
3224 "int_a_times_X": LFRicIntATimesXKern,
3225 "int_inc_a_times_X": LFRicIntIncATimesXKern,
3228 "int_setval_c": LFRicIntSetvalCKern,
3229 "int_setval_X": LFRicIntSetvalXKern,
3231 "int_sign_X": LFRicIntSignXKern,
3233 "int_max_aX": LFRicIntMaxAXKern,
3234 "int_inc_max_aX": LFRicIntIncMaxAXKern,
3236 "int_min_aX": LFRicIntMinAXKern,
3237 "int_inc_min_aX": LFRicIntIncMinAXKern,
3239 "int_to_real_X": LFRicIntToRealXKern}
3242 BUILTIN_MAP_CAPITALISED = REAL_BUILTIN_MAP_CAPITALISED
3243 BUILTIN_MAP_CAPITALISED.update(INT_BUILTIN_MAP_CAPITALISED)
3248 BUILTIN_MAP = get_lowercase_builtin_map(BUILTIN_MAP_CAPITALISED)
3252 __all__ = [
'LFRicBuiltInCallFactory',
3255 'LFRicIncXPlusYKern',
3257 'LFRicIncAPlusXKern',
3259 'LFRicIncAXPlusYKern',
3260 'LFRicIncXPlusBYKern',
3261 'LFRicAXPlusBYKern',
3262 'LFRicIncAXPlusBYKern',
3263 'LFRicAXPlusAYKern',
3265 'LFRicIncXMinusYKern',
3267 'LFRicIncAMinusXKern',
3269 'LFRicIncXMinusAKern',
3270 'LFRicAXMinusYKern',
3271 'LFRicXMinusBYKern',
3272 'LFRicIncXMinusBYKern',
3273 'LFRicAXMinusBYKern',
3275 'LFRicIncXTimesYKern',
3276 'LFRicIncAXTimesYKern',
3278 'LFRicIncATimesXKern',
3279 'LFRicXDividebyYKern',
3280 'LFRicIncXDividebyYKern',
3281 'LFRicXDividebyAKern',
3282 'LFRicIncXDividebyAKern',
3283 'LFRicADividebyXKern',
3284 'LFRicIncADividebyXKern',
3285 'LFRicIncXPowrealAKern',
3286 'LFRicIncXPowintNKern',
3289 'LFRicSetvalRandomKern',
3290 'LFRicXInnerproductYKern',
3291 'LFRicXInnerproductXKern',
3295 'LFRicIncMaxAXKern',
3297 'LFRicIncMinAXKern',
3298 'LFRicRealToIntXKern',
3299 'LFRicRealToRealXKern',
3300 'LFRicIntXPlusYKern',
3301 'LFRicIntIncXPlusYKern',
3302 'LFRicIntAPlusXKern',
3303 'LFRicIntIncAPlusXKern',
3304 'LFRicIntXMinusYKern',
3305 'LFRicIntIncXMinusYKern',
3306 'LFRicIntAMinusXKern',
3307 'LFRicIntIncAMinusXKern',
3308 'LFRicIntXMinusAKern',
3309 'LFRicIntIncXMinusAKern',
3310 'LFRicIntXTimesYKern',
3311 'LFRicIntIncXTimesYKern',
3312 'LFRicIntATimesXKern',
3313 'LFRicIntIncATimesXKern',
3314 'LFRicIntSetvalCKern',
3315 'LFRicIntSetvalXKern',
3316 'LFRicIntSignXKern',
3317 'LFRicIntMaxAXKern',
3318 'LFRicIntIncMaxAXKern',
3319 'LFRicIntMinAXKern',
3320 'LFRicIntIncMinAXKern',
3321 'LFRicIntToRealXKern']
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def create(call, parent=None)
def load(self, call, parent=None)
def get_scalar_argument_references(self)
def _builtin_metadata(cls, meta_args)
def reference_accesses(self, var_accesses)
def _replace_with_assignment(self, lhs, rhs)
def reference_element(self)
def get_indexed_field_argument_references(self)
def get_dof_loop_index_symbol(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def lower_to_language_level(self)
def arg_descriptors(self, obj)
def arg_descriptors(self)
def _reduction_reference(self)